diff options
author | Sander Vrijders <[email protected]> | 2016-07-05 09:06:20 +0200 |
---|---|---|
committer | Sander Vrijders <[email protected]> | 2016-07-05 09:06:20 +0200 |
commit | 96acaa2b5732a7685725b5c46045eda3375a3839 (patch) | |
tree | 9a73dfc68725eccf2bb491e367705926dcc50214 /src/lib | |
parent | aca5db11a73e66377b8566e69c1baabb1df803ab (diff) | |
parent | 66fd022a705cf65cbe37c446dbd87919a43a7fd3 (diff) | |
download | ouroboros-96acaa2b5732a7685725b5c46045eda3375a3839.tar.gz ouroboros-96acaa2b5732a7685725b5c46045eda3375a3839.zip |
Merged in dstaesse/ouroboros/be-path-check (pull request #152)
lib: irm: search for ap using PATH variable
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/irm.c | 96 |
1 files changed, 90 insertions, 6 deletions
diff --git a/src/lib/irm.c b/src/lib/irm.c index 93963eb1..68ffdf03 100644 --- a/src/lib/irm.c +++ b/src/lib/irm.c @@ -27,7 +27,9 @@ #include <ouroboros/common.h> #include <ouroboros/logs.h> #include <ouroboros/sockets.h> +#include <ouroboros/utils.h> +#include <string.h> #include <stdlib.h> #include <sys/stat.h> @@ -238,6 +240,84 @@ int irm_enroll_ipcp(pid_t api, return ret; } +static int check_ap(char * ap_name) +{ + struct stat s; + + if (stat(ap_name, &s) != 0) + return -ENOENT; + + if (!(s.st_mode & S_IXUSR)) + return -EPERM; + + return 0; +} + +static int check_ap_path(char ** ap_name) +{ + char * path = getenv("PATH"); + char * path_end = path + strlen(path) + 1; + char * pstart; + char * pstop = path; + char * tmp; + char * tstop; + char * tstart; + bool perm = true; + int ret = 0; + + if (*ap_name == NULL || path == NULL) + return -EINVAL; + + if (!strlen(path) || strchr(*ap_name, '/') == NULL) + if ((ret = check_ap(*ap_name)) < 0) + return ret; + + tmp = malloc(strlen(path) + strlen(*ap_name) + 2); + if (tmp == NULL) + return -ENOMEM; + + tstop = tmp + strlen(path) + 1; + strcpy(tstop--, *ap_name); + + while (pstop < path_end) { + ret = 0; + pstart = pstop; + if (*pstart != '/') { + free(tmp); + return -EINVAL; + } + + while (*pstop != '\0' && *pstop != ':') + pstop++; + + *pstop = '\0'; + tstart = tstop - (pstop++ - pstart); + strcpy(tstart, pstart); + *tstop = '/'; + + if ((ret = check_ap(tstart)) < 0) { + if (ret == -EPERM) + perm = false; + continue; + } + + free(*ap_name); + *ap_name = strdup(tstart); + free(tmp); + + if (*ap_name == NULL) + return -ENOMEM; + + return 0; + } + + free(tmp); + if (!perm) + return -EPERM; + + return -ENOENT; +} + int irm_bind(char * name, char * ap_name, uint16_t opts, @@ -247,20 +327,23 @@ int irm_bind(char * name, irm_msg_t msg = IRM_MSG__INIT; irm_msg_t * recv_msg = NULL; int ret = -1; - struct stat s; + char * full_ap_name; if (name == NULL || ap_name == NULL) return -EINVAL; - if (stat(ap_name, &s) != 0) - return -ENOENT; + full_ap_name = strdup(ap_name); + if (full_ap_name == NULL) + return -ENOMEM; - if (!(s.st_mode & S_IXUSR)) - return -EPERM; + if ((ret = check_ap_path(&full_ap_name)) < 0) { + free(full_ap_name); + return ret; + } msg.code = IRM_MSG_CODE__IRM_BIND; msg.dst_name = name; - msg.ap_name = ap_name; + msg.ap_name = full_ap_name; if (argv != NULL) { msg.n_args = argc; @@ -282,6 +365,7 @@ int irm_bind(char * name, ret = recv_msg->result; irm_msg__free_unpacked(recv_msg, NULL); + free(full_ap_name); return ret; } |