diff options
author | Simo Sorce <simo@redhat.com> | 2012-02-22 15:23:09 -0500 |
---|---|---|
committer | Simo Sorce <simo@redhat.com> | 2012-02-23 16:55:46 -0500 |
commit | 467045ad0a97cfc1edee8b3faafab53433a5b702 (patch) | |
tree | 387850030ee8d19bf51b96e64e2ef6e3f834dd05 | |
parent | d0989ef842fb3cd48265521cd139b3ffa2aa3889 (diff) | |
download | gss-proxy-467045ad0a97cfc1edee8b3faafab53433a5b702.tar.gz gss-proxy-467045ad0a97cfc1edee8b3faafab53433a5b702.tar.xz gss-proxy-467045ad0a97cfc1edee8b3faafab53433a5b702.zip |
config: parse credential/service config sections
-rw-r--r-- | proxy/examples/gssproxy-example.conf | 15 | ||||
-rw-r--r-- | proxy/src/gp_config.c | 243 | ||||
-rw-r--r-- | proxy/src/gp_proxy.h | 34 |
3 files changed, 291 insertions, 1 deletions
diff --git a/proxy/examples/gssproxy-example.conf b/proxy/examples/gssproxy-example.conf index e0a8d1b..4806585 100644 --- a/proxy/examples/gssproxy-example.conf +++ b/proxy/examples/gssproxy-example.conf @@ -1 +1,14 @@ -#Placeholder +[gssproxy] + +# socket = /var/lib/gssproxy/pipes/gp.socket + +[credential/default] + + mech = krb5 + krb5_keytab = /etc/krb5.keytab + krb5_ccache = /run/user/%u/krb5cc + +[service/default] + + credentials = default + euid = 0 diff --git a/proxy/src/gp_config.c b/proxy/src/gp_config.c index 8b86a5b..ca0f2c1 100644 --- a/proxy/src/gp_config.c +++ b/proxy/src/gp_config.c @@ -34,6 +34,247 @@ #define GP_SOCKET_NAME "gssproxy.socket" +static void gp_credcfg_free(struct gp_credcfg *cred) +{ + free(cred->name); + if (cred->mech == GP_CRED_KRB5) { + free(cred->cred.krb5.keytab); + free(cred->cred.krb5.ccache); + } + memset(cred, 0, sizeof(struct gp_credcfg)); +} + +static void gp_service_free(struct gp_service *svc) +{ + free(svc->name); + free(svc->creds); + memset(svc, 0, sizeof(struct gp_service)); +} + +static char *get_char_value(dictionary *dict, + const char *secname, + const char *key) +{ + char *skey; + char *value; + int ret; + + ret = asprintf(&skey, "%s:%s", secname, key); + if (ret == -1) { + return NULL; + } + + value = iniparser_getstring(dict, skey, NULL); + free(skey); + return value; +} + +static int get_int_value(dictionary *dict, + const char *secname, + const char *key) +{ + char *skey; + int ret; + + ret = asprintf(&skey, "%s:%s", secname, key); + if (ret == -1) { + return -1; + } + + ret = iniparser_getint(dict, skey, -1); + free(skey); + return ret; +} + +static int get_krb5_mech_cfg(struct gp_credcfg *cred, + dictionary *dict, + const char *secname) +{ + const char *value; + + cred->name = strdup(&secname[11]); /* name after 'credentials/' */ + if (!cred->name) { + return ENOMEM; + } + + cred->mech = GP_CRED_KRB5; + + value = get_char_value(dict, secname, "krb5_keytab"); + if (value) { + cred->cred.krb5.keytab = strdup(value); + if (!cred->cred.krb5.keytab) { + return ENOMEM; + } + } + + value = get_char_value(dict, secname, "krb5_ccache"); + if (value) { + cred->cred.krb5.ccache = strdup(value); + if (!cred->cred.krb5.ccache) { + return ENOMEM; + } + } + + return 0; +} + +static int get_creds_config(char *name, dictionary *dict, + struct gp_service *svc, + struct gp_credcfg **creds, int num_creds) +{ + char *value; + char *token; + char *handle; + int i, n; + + svc->name = strdup(&name[8]); /* name after 'service/' */ + if (!svc->name) { + return ENOMEM; + } + + svc->creds = calloc(num_creds, sizeof(struct gp_credcfg *)); + if (!svc->creds) { + return ENOMEM; + } + + value = get_char_value(dict, name, "credentials"); + if (value == NULL) { + /* malformed section, crentials is missing */ + syslog(LOG_INFO, + "Credentials missing from [%s], ignoring.", name); + return EINVAL; + } + + n = 0; + token = strtok_r(value, ", ", &handle); + do { + for (i = 0; i < num_creds; i++) { + if (strcmp(token, creds[i]->name) == 0) { + svc->creds[n] = creds[i]; + n++; + break; + } + } + + token = strtok_r(NULL, ", ", &handle); + } while (token != NULL); + + svc->num_creds = n; + + return 0; +} + +static int load_services(struct gp_config *cfg, dictionary *dict) +{ + int num_sec; + char *secname; + char *value; + int valnum; + int ret; + int i, n; + + num_sec = iniparser_getnsec(dict); + + /* allocate enough space for num_sec services and creds, will trim it + * later when we know what is what */ + cfg->creds = calloc(num_sec, sizeof(struct gp_credcfg *)); + if (!cfg->creds) { + ret = ENOMEM; + goto done; + } + cfg->svcs = calloc(num_sec, sizeof(struct gp_service *)); + if (!cfg->svcs) { + ret = ENOMEM; + goto done; + } + + for (i = 0; i < num_sec; i++) { + secname = iniparser_getsecname(dict, i); + ret = strncmp(secname, "credential/", 10); + if (ret == 0) { + n = cfg->num_creds; + cfg->creds[n] = calloc(1, sizeof(struct gp_credcfg)); + if (!cfg->creds[n]) { + ret = ENOMEM; + goto done; + } + cfg->num_creds++; + + value = get_char_value(dict, secname, "mech"); + if (value == NULL) { + /* malformed section, mech is missing */ + syslog(LOG_INFO, + "Mech missing from [%s], ignoring.", secname); + gp_credcfg_free(cfg->creds[n]); + cfg->num_creds--; + continue; + } + + ret = strcmp(value, "krb5"); + if (ret == 0) { + ret = get_krb5_mech_cfg(cfg->creds[n], dict, secname); + if (ret != 0) { + gp_credcfg_free(cfg->creds[n]); + cfg->num_creds--; + continue; + } + } else { + syslog(LOG_INFO, + "Unknown mech: %s in [%s], ignoring.", + value, secname); + gp_credcfg_free(cfg->creds[n]); + cfg->num_creds--; + continue; + } + } + + ret = strncmp(secname, "service/", 8); + if (ret == 0) { + n = cfg->num_svcs; + cfg->svcs[n] = calloc(1, sizeof(struct gp_service)); + if (!cfg->svcs[n]) { + ret = ENOMEM; + goto done; + } + cfg->num_svcs++; + + valnum = get_int_value(dict, secname, "euid"); + if (valnum == -1) { + /* malformed section, mech is missing */ + syslog(LOG_INFO, + "Euid missing from [%s], ignoring.", secname); + gp_service_free(cfg->svcs[n]); + cfg->num_svcs--; + continue; + } + cfg->svcs[n]->euid = valnum; + + ret = get_creds_config(secname, dict, cfg->svcs[n], + cfg->creds, cfg->num_creds); + if (ret) { + gp_service_free(cfg->svcs[n]); + cfg->num_svcs--; + continue; + } + } + } + + if (cfg->num_creds == 0){ + syslog(LOG_ERR, "No credentials sections configured!"); + return ENOENT; + } + + if (cfg->num_svcs == 0) { + syslog(LOG_ERR, "No service sections configured!"); + return ENOENT; + } + + ret = 0; + +done: + return ret; +} + int load_config(struct gp_config *cfg) { dictionary *d; @@ -63,6 +304,8 @@ int load_config(struct gp_config *cfg) cfg->num_workers = iniparser_getint(d, "gssproxy:worker threads", 0); + ret = load_services(cfg, d); + done: iniparser_freedict(d); return ret; diff --git a/proxy/src/gp_proxy.h b/proxy/src/gp_proxy.h index 0cf24bb..bd3d181 100644 --- a/proxy/src/gp_proxy.h +++ b/proxy/src/gp_proxy.h @@ -34,11 +34,45 @@ #define _(STRING) gettext(STRING) +struct gp_cred_krb5 { + char *keytab; + char *ccache; +}; + +struct gp_credcfg { + char *name; + + enum { + GP_CRED_NONE = 0, + GP_CRED_KRB5, + } mech; + + union { + struct gp_cred_krb5 krb5; + } cred; +}; + +struct gp_service { + char *name; + + uid_t euid; + gid_t egid; + + struct gp_credcfg **creds; + int num_creds; +}; + struct gp_config { char *config_file; /* gssproxy configuration file */ bool daemonize; /* let gssproxy daemonize */ char *socket_name; /* the socket name to use for */ int num_workers; /* number of worker threads */ + + struct gp_credcfg **creds; + int num_creds; + + struct gp_service **svcs; + int num_svcs; }; struct gp_workers; |