int do_passphrase_from_fsid;
int nocertcheck;
int non_inter;
+int cookieonly;
enum {
- OPT_AUTHGROUP = 0x100,
+ OPT_AUTHENTICATE = 0x100,
+ OPT_AUTHGROUP,
OPT_BASEMTU,
OPT_CAFILE,
OPT_CONFIGFILE,
OPTION("cafile", 1, OPT_CAFILE),
OPTION("config", 1, OPT_CONFIGFILE),
OPTION("no-dtls", 0, OPT_NO_DTLS),
+ OPTION("authenticate", 0, OPT_AUTHENTICATE),
OPTION("cookieonly", 0, OPT_COOKIEONLY),
OPTION("printcookie", 0, OPT_PRINTCOOKIE),
OPTION("quiet", 0, 'q'),
printf(" -v, --verbose %s\n", _("More output"));
printf(" -x, --xmlconfig=CONFIG %s\n", _("XML config file"));
printf(" --authgroup=GROUP %s\n", _("Choose authentication login selection"));
+ printf(" --authenticate %s\n", _("Authenticate only and print login info"));
printf(" --cookieonly %s\n", _("Fetch webvpn cookie only; don't connect"));
printf(" --printcookie %s\n", _("Print webvpn cookie before connecting"));
printf(" --cafile=FILE %s\n", _("Cert file for server verification"));
struct openconnect_info *vpninfo;
struct utsname utsbuf;
struct sigaction sa;
- int cookieonly = 0;
int use_syslog = 0;
char *urlpath = NULL;
char *proxy = getenv("https_proxy");
case OPT_PRINTCOOKIE:
cookieonly = 2;
break;
+ case OPT_AUTHENTICATE:
+ cookieonly = 3;
+ break;
case OPT_COOKIE_ON_STDIN:
read_stdin(&vpninfo->cookie);
/* If the cookie is empty, ignore it */
exit(1);
}
- if (cookieonly) {
+ if (cookieonly == 3) {
+ /* --authenticate */
+ printf("COOKIE='%s'\n", vpninfo->cookie);
+ printf("HOST='%s'\n", vpninfo->hostname);
+ if (vpninfo->peer_cert) {
+ char buf[41] = {0, };
+ openconnect_get_cert_sha1(vpninfo, vpninfo->peer_cert, buf);
+ printf("FINGERPRINT='%s'\n", buf);
+ }
+ exit(0);
+ } else if (cookieonly) {
printf("%s\n", vpninfo->cookie);
if (cookieonly == 1)
/* We use cookieonly=2 for 'print it and continue' */
FILE *outf = level ? stdout : stderr;
va_list args;
+ if (cookieonly)
+ outf = stderr;
+
if (verbose >= level) {
va_start(args, fmt);
vfprintf(outf, fmt, args);
char *details;
char *p;
- printf(_("\nCertificate from VPN server \"%s\" failed verification.\n"
+ fprintf(stderr, _("\nCertificate from VPN server \"%s\" failed verification.\n"
"Reason: %s\n"), vpninfo->hostname, reason);
if (non_inter)
return -EINVAL;
- printf(_("Enter '%s' to accept, '%s' to abort; anything else to view: "),
+ fprintf(stderr, _("Enter '%s' to accept, '%s' to abort; anything else to view: "),
_("yes"), _("no"));
if (!fgets(buf, sizeof(buf), stdin))
return -EINVAL;
char *p;
if (form->banner)
- puts(form->banner);
+ fprintf(stderr, "%s\n", form->banner);
if (form->error)
- puts(form->error);
+ fprintf(stderr, "%s\n", form->error);
if (form->message)
- puts(form->message);
+ fprintf(stderr, "%s\n", form->message);
/* scan for select options first so they are displayed first */
for (opt = form->opts; opt; opt = opt->next) {
_("User input required in non-interactive mode\n"));
return -EINVAL;
}
- printf("%s [", opt->label);
+ fprintf(stderr, "%s [", opt->label);
for (i = 0; i < select_opt->nr_choices; i++) {
choice = &select_opt->choices[i];
if (i)
- printf("|");
+ fprintf(stderr, "|");
- printf("%s", choice->label);
+ fprintf(stderr, "%s", choice->label);
}
- printf("]:");
+ fprintf(stderr, "]:");
+ fflush(stderr);
if (!fgets(response, sizeof(response), stdin) || !strlen(response))
return -EINVAL;
if (!opt->value)
return -ENOMEM;
- printf("%s", opt->label);
-
+ fprintf(stderr, "%s", opt->label);
+ fflush(stderr);
+
if (!fgets(opt->value, 80, stdin) || !strlen(opt->value))
return -EINVAL;
if (!opt->value)
return -ENOMEM;
- printf("%s", opt->label);
+ fprintf(stderr, "%s", opt->label);
+ fflush(stderr);
tcgetattr(0, &t);
t.c_lflag &= ~ECHO;
t.c_lflag |= ECHO;
tcsetattr(0, TCSANOW, &t);
- printf("\n");
+ fprintf(stderr, "\n");
if (!p || !strlen(opt->value))
return -EINVAL;
.OP \-v,\-\-verbose
.OP \-x,\-\-xmlconfig config
.OP \-\-authgroup group
+.OP \-\-authenticate
.OP \-\-cookieonly
.OP \-\-printcookie
.OP \-\-cafile file
.B \-\-authgroup=GROUP
Choose authentication login selection
.TP
+.B \-\-authentiate
+Authenticate only, and output the information needed to make the connection
+a form which can be used to set shell environment variables. When invoked with
+this option, openconnect will not make the connection, but if successful will
+output something like the following to stdout:
+.nf
+.B COOKIE=3311180634@13561856@1339425499@B315A0E29D16C6FD92EE...
+.B HOST=10.0.0.1
+.B FINGERPRINT=469bb424ec8835944d30bc77c77e8fc1d8e23a42
+.fi
+Thus, you can invoke openconnect as a non-privileged user
+.I (with access to the user's PKCS#11 tokens, etc.)
+for authentication, and then invoke openconnect separately to make the actual
+connection as root:
+.nf
+.B eval `openconnect --authenticate https://vpnserver.example.com`;
+.B [ -n "$COOKIE" ] && echo "$COOKIE" |
+.B \ \ sudo openconnect --cookie-on-stdin $HOST --servercert $FINGERPRINT
+.fi
+.TP
.B \-\-cookieonly
Fetch webvpn cookie only; don't connect
.TP