Drop root privileges before running CSD code
authorAntonio Borneo <borneo.antonio@gmail.com>
Fri, 7 Aug 2009 08:43:44 +0000 (10:43 +0200)
committerAdam Piątyszek <ediap@users.sourceforge.net>
Fri, 7 Aug 2009 08:47:46 +0000 (10:47 +0200)
This functionallity requires a valid user provided on the command
line with "-U".

Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com>
http.c
main.c
openconnect.h

diff --git a/http.c b/http.c
index c90ddc2..696ffbd 100644 (file)
--- a/http.c
+++ b/http.c
@@ -30,7 +30,9 @@
 #include <time.h>
 #include <string.h>
 #include <ctype.h>
+#include <pwd.h>
 #include <sys/stat.h>
+#include <sys/types.h>
 
 #include <openssl/ssl.h>
 #include <openssl/err.h>
@@ -317,7 +319,7 @@ static int run_csd_script(struct openconnect_info *vpninfo, char *buf, int bufle
                return err;
        }
        write(fd, buf, buflen);
-       fchmod(fd, 0700);
+       fchmod(fd, 0755);
        close(fd);
 
        if (!fork()) {
@@ -326,6 +328,28 @@ static int run_csd_script(struct openconnect_info *vpninfo, char *buf, int bufle
                char *csd_argv[32];
                int i = 0;
 
+               if (vpninfo->uid != getuid()) {
+                       struct passwd *pw;
+
+                       if (setuid(vpninfo->uid)) {
+                               fprintf(stderr, "Failed to set uid %d\n",
+                                       vpninfo->uid);
+                               exit(1);
+                       }
+                       if (!(pw = getpwuid(vpninfo->uid))) {
+                               fprintf(stderr, "Invalid user uid=%d\n",
+                                       vpninfo->uid);
+                               exit(1);
+                       }
+                       setenv("HOME", pw->pw_dir, 1);
+                       chdir(pw->pw_dir);
+               }
+               if (vpninfo->uid == 0) {
+                       fprintf(stderr, "Warning: you are running unsecure "
+                               "CSD code with root privileges\n"
+                               "\t Use command line option \"-U\"\n");
+               }
+
                csd_argv[i++] = fname;
                csd_argv[i++] = "-ticket";
                asprintf(&csd_argv[i++], "\"%s\"", vpninfo->csd_ticket);
diff --git a/main.c b/main.c
index b831417..bab814e 100644 (file)
--- a/main.c
+++ b/main.c
@@ -155,7 +155,6 @@ 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();
@@ -176,6 +175,7 @@ int main(int argc, char **argv)
        vpninfo->max_qlen = 10;
        vpninfo->reconnect_interval = RECONNECT_INTERVAL_MIN;
        vpninfo->reconnect_timeout = 300;
+       vpninfo->uid = getuid();
 
        if (RAND_bytes(vpninfo->dtls_secret, sizeof(vpninfo->dtls_secret)) != 1) {
                fprintf(stderr, "Failed to initialise DTLS secret\n");
@@ -293,7 +293,7 @@ int main(int argc, char **argv)
                        break;
                case 'U': {
                        char *strend;
-                       uid = strtol(optarg, &strend, 0);
+                       vpninfo->uid = strtol(optarg, &strend, 0);
                        if (strend[0]) {
                                struct passwd *pw = getpwnam(optarg);
                                if (!pw) {
@@ -301,7 +301,7 @@ int main(int argc, char **argv)
                                                optarg);
                                        exit(1);
                                }
-                               uid = pw->pw_uid;
+                               vpninfo->uid = pw->pw_uid;
                        }
                        break;
                }
@@ -385,9 +385,9 @@ int main(int argc, char **argv)
                exit(1);
        }
 
-       if (uid != getuid()) {
-               if (setuid(uid)) {
-                       fprintf(stderr, "Failed to set uid %d\n", uid);
+       if (vpninfo->uid != getuid()) {
+               if (setuid(vpninfo->uid)) {
+                       fprintf(stderr, "Failed to set uid %d\n", vpninfo->uid);
                        exit(1);
                }
        }
index f2b7b65..e216a9f 100644 (file)
@@ -161,6 +161,7 @@ struct openconnect_info {
        char *authgroup;
        int nopasswd;
        char *dtls_ciphers;
+       uid_t uid;
 
        char *cookie;
        struct vpn_option *cookies;