Skip to content

Commit

Permalink
Drop root privileges during execution of CSD script
Browse files Browse the repository at this point in the history
A new option "--setuid-csd=USER" is provided, which means that
a separate user can be used for CSD script execution.

Signed-off-by: Adam Piątyszek <ediap@users.sourceforge.net>
  • Loading branch information
Adam Piątyszek committed Aug 21, 2009
1 parent 041f7b2 commit 4f46416
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 16 deletions.
14 changes: 7 additions & 7 deletions http.c
Expand Up @@ -328,26 +328,26 @@ static int run_csd_script(struct openconnect_info *vpninfo, char *buf, int bufle
char *csd_argv[32];
int i = 0;

if (vpninfo->uid != getuid()) {
if (vpninfo->uid_csd != getuid()) {
struct passwd *pw;

if (setuid(vpninfo->uid)) {
if (setuid(vpninfo->uid_csd)) {
fprintf(stderr, "Failed to set uid %d\n",
vpninfo->uid);
vpninfo->uid_csd);
exit(1);
}
if (!(pw = getpwuid(vpninfo->uid))) {
if (!(pw = getpwuid(vpninfo->uid_csd))) {
fprintf(stderr, "Invalid user uid=%d\n",
vpninfo->uid);
vpninfo->uid_csd);
exit(1);
}
setenv("HOME", pw->pw_dir, 1);
chdir(pw->pw_dir);
}
if (vpninfo->uid == 0) {
if (vpninfo->uid_csd == 0) {
fprintf(stderr, "Warning: you are running unsecure "
"CSD code with root privileges\n"
"\t Use command line option \"-U\"\n");
"\t Use command line option \"--setuid-csd\"\n");
}

csd_argv[i++] = fname;
Expand Down
29 changes: 23 additions & 6 deletions main.c
Expand Up @@ -85,6 +85,7 @@ static struct option long_options[] = {
{"servercert", 1, 0, 0x01},
{"key-password-from-fsid", 0, 0, 0x02},
{"useragent", 1, 0, 0x03},
{"setuid-csd", 1, 0, 0x04},
{NULL, 0, 0, 0},
};

Expand All @@ -105,6 +106,7 @@ void usage(void)
printf(" -i, --interface=IFNAME Use IFNAME for tunnel interface\n");
printf(" -l, --syslog Use syslog for progress messages\n");
printf(" -U, --setuid=USER Drop privileges after connecting\n");
printf(" --setuid-csd=USER Drop privileges during CSD execution\n");
printf(" -m, --mtu=MTU Request MTU from server\n");
printf(" -p, --key-password=PASS Set key passphrase or TPM SRK PIN\n");
printf(" --key-password-from-fsid Key passphrase is fsid of file system\n");
Expand Down Expand Up @@ -155,6 +157,7 @@ int main(int argc, char **argv)
struct utsname utsbuf;
int cookieonly = 0;
int use_syslog = 0;
uid_t uid = getuid();
int opt;

openconnect_init_openssl();
Expand All @@ -175,7 +178,7 @@ int main(int argc, char **argv)
vpninfo->max_qlen = 10;
vpninfo->reconnect_interval = RECONNECT_INTERVAL_MIN;
vpninfo->reconnect_timeout = 300;
vpninfo->uid = getuid();
vpninfo->uid_csd = uid;

if (RAND_bytes(vpninfo->dtls_secret, sizeof(vpninfo->dtls_secret)) != 1) {
fprintf(stderr, "Failed to initialise DTLS secret\n");
Expand Down Expand Up @@ -293,15 +296,29 @@ int main(int argc, char **argv)
break;
case 'U': {
char *strend;
vpninfo->uid = strtol(optarg, &strend, 0);
uid = strtol(optarg, &strend, 0);
if (strend[0]) {
struct passwd *pw = getpwnam(optarg);
if (!pw) {
fprintf(stderr, "Invalid user \"%s\"\n",
optarg);
exit(1);
}
vpninfo->uid = pw->pw_uid;
uid = pw->pw_uid;
}
break;
}
case 0x04: {
char *strend;
vpninfo->uid_csd = strtol(optarg, &strend, 0);
if (strend[0]) {
struct passwd *pw = getpwnam(optarg);
if (!pw) {
fprintf(stderr, "Invalid user \"%s\"\n",
optarg);
exit(1);
}
vpninfo->uid_csd = pw->pw_uid;
}
break;
}
Expand Down Expand Up @@ -385,9 +402,9 @@ int main(int argc, char **argv)
exit(1);
}

if (vpninfo->uid != getuid()) {
if (setuid(vpninfo->uid)) {
fprintf(stderr, "Failed to set uid %d\n", vpninfo->uid);
if (uid != getuid()) {
if (setuid(uid)) {
fprintf(stderr, "Failed to set uid %d\n", uid);
exit(1);
}
}
Expand Down
11 changes: 9 additions & 2 deletions openconnect.8
Expand Up @@ -50,6 +50,10 @@ openconnect \- Connect to Cisco AnyConnect VPN
.I USER
]
[
.B --setuid-csd
.I USER
]
[
.B -m,--mtu
.I MTU
]
Expand Down Expand Up @@ -147,7 +151,7 @@ certificate, or password or SecurID, etc. Having authenticated, the
user is rewarded with an HTTP cookie which can be used to make the
real VPN connection.

The second phase uses that cookie in an HTTPS
The second phase uses that cookie in an HTTPS
.I CONNECT
request, and data packets can be passed over the resulting
connection. In auxiliary headers exchanged with the
Expand Down Expand Up @@ -202,6 +206,9 @@ Use syslog for progress messages
Drop privileges after connecting, to become user
.I USER
.TP
.B --setuid-csd=USER
Drop privileges during CSD execution
.TP
.B -m,--mtu=MTU
Request
.I MTU
Expand All @@ -221,7 +228,7 @@ Type of private key file (PKCS#12, TPM or PEM)
Less output
.TP
.B -Q,--queue-len=LEN
Set packet queue limit to
Set packet queue limit to
.I LEN
pkts
.TP
Expand Down
2 changes: 1 addition & 1 deletion openconnect.h
Expand Up @@ -161,7 +161,7 @@ struct openconnect_info {
char *authgroup;
int nopasswd;
char *dtls_ciphers;
uid_t uid;
uid_t uid_csd;

char *cookie;
struct vpn_option *cookies;
Expand Down

0 comments on commit 4f46416

Please sign in to comment.