From 4f4641629e0d275465f88df12e1075ef5a170b64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Pi=C4=85tyszek?= Date: Fri, 21 Aug 2009 22:27:59 +0200 Subject: [PATCH 1/2] Drop root privileges during execution of CSD script MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- http.c | 14 +++++++------- main.c | 29 +++++++++++++++++++++++------ openconnect.8 | 11 +++++++++-- openconnect.h | 2 +- 4 files changed, 40 insertions(+), 16 deletions(-) diff --git a/http.c b/http.c index 696ffbd..5acf1e0 100644 --- a/http.c +++ b/http.c @@ -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; diff --git a/main.c b/main.c index bab814e..1b9d3a6 100644 --- a/main.c +++ b/main.c @@ -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}, }; @@ -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"); @@ -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(); @@ -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"); @@ -293,7 +296,7 @@ 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) { @@ -301,7 +304,21 @@ int main(int argc, char **argv) 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; } @@ -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); } } diff --git a/openconnect.8 b/openconnect.8 index 03b4a39..a80c4e8 100644 --- a/openconnect.8 +++ b/openconnect.8 @@ -50,6 +50,10 @@ openconnect \- Connect to Cisco AnyConnect VPN .I USER ] [ +.B --setuid-csd +.I USER +] +[ .B -m,--mtu .I MTU ] @@ -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 @@ -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 @@ -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 diff --git a/openconnect.h b/openconnect.h index e216a9f..6e550f6 100644 --- a/openconnect.h +++ b/openconnect.h @@ -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; -- 1.6.4