Drop root privileges during execution of CSD script
authorAdam Piątyszek <ediap@users.sourceforge.net>
Fri, 21 Aug 2009 20:27:59 +0000 (22:27 +0200)
committerAdam Piątyszek <ediap@users.sourceforge.net>
Fri, 21 Aug 2009 20:27:59 +0000 (22:27 +0200)
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>
http.c
main.c
openconnect.8
openconnect.h

diff --git a/http.c b/http.c
index 696ffbd..5acf1e0 100644 (file)
--- 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 (file)
--- 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);
                }
        }
index 03b4a39..a80c4e8 100644 (file)
@@ -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
index e216a9f..6e550f6 100644 (file)
@@ -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;