From: Emmanuel D. <ma...@us...> - 2005-03-16 23:19:12
|
Update of /cvsroot/ipsec-tools/ipsec-tools/src/racoon In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20634/src/racoon Modified Files: Tag: ipsec-tools-0_6-branch cftoken.l localconf.h privsep.c racoon.conf.5 remoteconf.c Log Message: When running in privsep mode, check that private key and script paths match those given in the path section. This change was introduced in HEAD in order to make privsep working with upcoming config reload support. It is propagated in 0.6 so that we don't get working setups that won't work anymore with future releases Index: remoteconf.c =================================================================== RCS file: /cvsroot/ipsec-tools/ipsec-tools/src/racoon/remoteconf.c,v retrieving revision 1.26.2.1 retrieving revision 1.26.2.2 diff -u -d -r1.26.2.1 -r1.26.2.2 --- remoteconf.c 17 Feb 2005 21:24:17 -0000 1.26.2.1 +++ remoteconf.c 16 Mar 2005 23:18:43 -0000 1.26.2.2 @@ -605,11 +605,34 @@ script_path_add(path) vchar_t *path; { + char *script_dir; vchar_t *new_storage; + vchar_t *new_path; vchar_t **sp; size_t len; size_t size; + script_dir = lcconf->pathinfo[LC_PATHTYPE_SCRIPT]; + + /* Try to find the script in the script directory */ + if ((path->v[0] != '/') && (script_dir != NULL)) { + len = strlen(script_dir) + sizeof("/") + path->l + 1; + + if ((new_path = vmalloc(len)) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "Cannot allocate memory: %s\n", strerror(errno)); + return -1; + } + + new_path->v[0] = '\0'; + (void)strncat(new_path->v, script_dir, len); + (void)strncat(new_path->v, "/", len); + (void)strncat(new_path->v, path->v, len); + + vfree(path); + path = new_path; + } + /* First time, initialize */ if (script_paths == NULL) len = sizeof(vchar_t *); Index: localconf.h =================================================================== RCS file: /cvsroot/ipsec-tools/ipsec-tools/src/racoon/localconf.h,v retrieving revision 1.9.2.1 retrieving revision 1.9.2.2 diff -u -d -r1.9.2.1 -r1.9.2.2 --- localconf.h 24 Feb 2005 18:31:56 -0000 1.9.2.1 +++ localconf.h 16 Mar 2005 23:18:43 -0000 1.9.2.2 @@ -40,7 +40,8 @@ #define LC_PATHTYPE_PSK 1 #define LC_PATHTYPE_CERT 2 #define LC_PATHTYPE_BACKUPSA 3 -#define LC_PATHTYPE_MAX 4 +#define LC_PATHTYPE_SCRIPT 4 +#define LC_PATHTYPE_MAX 5 #define LC_DEFAULT_PAD_MAXSIZE 20 #define LC_DEFAULT_PAD_RANDOM TRUE Index: racoon.conf.5 =================================================================== RCS file: /cvsroot/ipsec-tools/ipsec-tools/src/racoon/racoon.conf.5,v retrieving revision 1.27.2.1 retrieving revision 1.27.2.2 diff -u -d -r1.27.2.1 -r1.27.2.2 --- racoon.conf.5 24 Feb 2005 18:31:56 -0000 1.27.2.1 +++ racoon.conf.5 16 Mar 2005 23:18:43 -0000 1.27.2.2 @@ -163,6 +163,12 @@ .El .El .Ss Path Specification +This section specify various paths used by racoon. When running in privilege +separation mode, +.Ic certificate +and +.Ic script +paths are mandatory. .Bl -tag -width Ds -compact .It Ic path include Ar path ; specifies a path to include a file. @@ -175,6 +181,10 @@ .It Ic path certificate Ar path ; .Xr racoon 8 will search this directory if a certificate or certificate request is received. +If you run with privilege separation, +.Xr racoon 8 +will refuse to use a certificate +stored outside of this directory. .It Ic path backupsa Ar file ; specifies a file to be stored a SA information which is negotiated by racoon. .Xr racoon 8 @@ -184,6 +194,12 @@ .Xr racoon 8 simply add a SA to the file at the moment. You should maintain the file manually. +.It Ic path script Ar path +.Xr racoon 8 +will search this directory for scripts hooks. If you run with privilege +separation, +.Xr racoon 8 +will refuse to execute a script stored outside of this directory. .El .\" .Ss File Inclusion Index: privsep.c =================================================================== RCS file: /cvsroot/ipsec-tools/ipsec-tools/src/racoon/privsep.c,v retrieving revision 1.6.2.3 retrieving revision 1.6.2.4 diff -u -d -r1.6.2.3 -r1.6.2.4 --- privsep.c 16 Mar 2005 00:13:38 -0000 1.6.2.3 +++ privsep.c 16 Mar 2005 23:18:43 -0000 1.6.2.4 @@ -71,6 +71,8 @@ static int unsafe_env(char *const *); static int unknown_name(int); static int unknown_script(int); +static int unsafe_path(char *, int); +static char *script_name2path(int); static int privsep_send(sock, buf, len) @@ -167,6 +169,18 @@ if (lcconf->uid == 0) return 0; + /* + * When running privsep, certificate and script paths + * are mandatory, as they enable us to check path safety + * in the privilegied instance + */ + if ((lcconf->pathinfo[LC_PATHTYPE_CERT] == NULL) || + (lcconf->pathinfo[LC_PATHTYPE_SCRIPT] == NULL)) { + plog(LLV_ERROR, LOCATION, NULL, "privilege separation " + "require path cert and path script in the config file\n"); + return -1; + } + if (socketpair(PF_LOCAL, SOCK_DGRAM, 0, privsep_sock) != 0) { plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate privsep_sock: %s\n", strerror(errno)); @@ -327,6 +341,13 @@ if (safety_check(combuf, 0) != 0) break; bufs[0][combuf->bufs.buflen[0] - 1] = '\0'; + + if (unsafe_path(bufs[0], LC_PATHTYPE_CERT) != 0) { + plog(LLV_ERROR, LOCATION, NULL, + "privsep_eay_get_pkcs1privkey: " + "unsafe key \"%s\"\n", bufs[0]); + } + if ((privkey = eay_get_pkcs1privkey(bufs[0])) == NULL){ reply->hdr.ac_errno = errno; break; @@ -425,8 +446,15 @@ */ if ((unsafe_env(envp) == 0) && (unknown_name(name) == 0) && - (unknown_script(script) == 0)) + (unknown_script(script) == 0) && + (unsafe_path(script_name2path(script), + LC_PATHTYPE_SCRIPT) == 0)) (void)script_exec(script, name, envp); + else + plog(LLV_ERROR, LOCATION, NULL, + "privsep_script_exec: " + "unsafe script \"%s\"\n", + script_name2path(script)); racoon_free(envp); break; @@ -935,6 +963,57 @@ return -1; } +/* + * Check path safety + */ +static int +unsafe_path(script, pathtype) + char *script; + int pathtype; +{ + char *path; + char rpath[MAXPATHLEN + 1]; + size_t len; + + if (script == NULL) + return -1; + + path = lcconf->pathinfo[pathtype]; + + /* No path was given for scripts: skip the check */ + if (path == NULL) + return 0; + + if (realpath(script, rpath) == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "script path \"%s\" is invalid\n", script); + return -1; + } + + len = strlen(path); + if (strncmp(path, rpath, len) != 0) + return -1; + + return 0; +} + +static char * +script_name2path(name) + int name; +{ + vchar_t **sp; + + if (script_paths == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "script_name2path: script_paths was not initialized\n"); + return NULL; + } + + sp = (vchar_t **)(script_paths->v); + + return sp[name]->v; +} + /* * Check the script path index is correct */ Index: cftoken.l =================================================================== RCS file: /cvsroot/ipsec-tools/ipsec-tools/src/racoon/cftoken.l,v retrieving revision 1.31.2.1 retrieving revision 1.31.2.2 diff -u -d -r1.31.2.1 -r1.31.2.2 --- cftoken.l 24 Feb 2005 18:31:56 -0000 1.31.2.1 +++ cftoken.l 16 Mar 2005 23:18:43 -0000 1.31.2.2 @@ -163,6 +163,8 @@ return(PATHTYPE); } <S_PTH>certificate { YYD; yylval.num = LC_PATHTYPE_CERT; return(PATHTYPE); } +<S_PTH>script { YYD; yylval.num = LC_PATHTYPE_SCRIPT; + return(PATHTYPE); } <S_PTH>backupsa { YYD; yylval.num = LC_PATHTYPE_BACKUPSA; return(PATHTYPE); } <S_PTH>{semi} { BEGIN S_INI; YYDB; return(EOS); } |