miniroon

Simplistic macaroon-based authorization for Unix systems
git clone https://ccx.te2000.cz/git/miniroon
Log | Files | Refs

envmap.c (2841B)


      1 #include <string.h>  /* memset() */
      2 #include <unistd.h>  /* write() */
      3 #include <assert.h>
      4 
      5 #include <skalibs/stralloc.h>
      6 #include <skalibs/env.h>
      7 #include <skalibs/exec.h>
      8 
      9 #include "envmap.h"
     10 #include "verify_common.h"
     11 
     12 extern char **environ;
     13 
     14 void miniroon_env_map_zero(miniroon_env_map *emap) {
     15   memset(emap, 0, sizeof(miniroon_env_map));
     16 }
     17 
     18 void miniroon_env_map_add(miniroon_env_map *emap, const bytebuffer name) {
     19   assert(miniroon_env_map_find(emap, name) == NULL);
     20   assert(emap->env_count < MAX_ENV_ALLOW); // TODO: proper check
     21   emap->env[emap->env_count++].name = name;
     22 }
     23 
     24 miniroon_env_entry * miniroon_env_map_find(miniroon_env_map *emap, const bytebuffer name) {
     25   for(size_t i=0; i < emap->env_count; i++) {
     26     if(bbcmp(emap->env[i].name, name) == 0) {
     27       return &emap->env[i];
     28     }
     29   }
     30   return NULL;
     31 }
     32 
     33 void miniroon_env_map_init(miniroon_env_map *emap) {
     34   miniroon_env_map_zero(emap);
     35   char **env = environ;
     36   char *var;
     37   while(var = *(env++)) {
     38 
     39     write(2, "env >", 5);
     40     write(2, var, strlen(var));
     41     write(2, "<\n", 2);
     42 
     43     for(size_t i=0; var[i]; i++) {
     44       if(var[i] == '-') { continue; }
     45       if(var[i] >= '0' && var[i] <= '9') { continue; }
     46       if(var[i] >= 'A' && var[i] <= 'z') { continue; }
     47       if(var[i] == '=') {
     48         if(var[i+1]) { break; }
     49         write(2, "env [allowed]\n", 14);
     50         bytebuffer bb = {var, i};
     51         miniroon_env_map_add(emap, bb);
     52       }
     53     }
     54 
     55   }
     56 }
     57 
     58 #define stralloc_catbb(sa, bb) stralloc_catb(sa, bb.data, bb.len)
     59 
     60 void env_add(stralloc *modif, miniroon_env_entry *entry) {
     61   assert(entry->state == ENV_SET || entry->state == ENV_REMOVE);
     62   assert(entry->name.len);
     63   assert(entry->name.data);
     64   for(size_t i=0; i<entry->name.len; i++) {
     65     if(entry->name.data[i] == '\0') {
     66       strerr_dief1x(111, "invalid environment variable name");
     67     }
     68   }
     69   if(!stralloc_catbb(modif, entry->name)) { goto errenv; }
     70   if(entry->state == ENV_SET) {
     71     assert(entry->value.len);
     72     assert(entry->value.data);
     73     for(size_t i=0; i<entry->value.len; i++) {
     74       if(entry->value.data[i] == '\0') {
     75         strerr_dief1x(111, "invalid environment variable value");
     76       }
     77     }
     78     if(!stralloc_catb(modif, "=", 1)) { goto errenv; }
     79     if(!stralloc_catbb(modif, entry->value)) { goto errenv; }
     80   }
     81   if(!stralloc_catb(modif, "\0", 1)) { goto errenv; }
     82   return;
     83 errenv:
     84   strerr_dief1x(111, "error preparing environment");
     85 }
     86 
     87 void miniroon_env_map_exec(miniroon_env_map *emap, char const *const *argv) {
     88   if(emap->env_count == 0) {
     89     xexec(argv);
     90   }
     91   stralloc modif = STRALLOC_ZERO;
     92   for(size_t i=0; i < emap->env_count; i++) {
     93     if(emap->env[i].state == ENV_NO_CHANGE) {
     94       continue;
     95     }
     96     env_add(&modif, &emap->env[i]);
     97   }
     98   if(modif.len) {
     99     xmexec_m(argv, modif.s, modif.len);
    100   } else {
    101     xexec(argv);
    102   }
    103 }
    104 
    105 /*  vim: sts=2 sw=2 et
    106 */