summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimo Sorce <simo@redhat.com>2012-02-22 15:23:09 -0500
committerSimo Sorce <simo@redhat.com>2012-02-23 16:55:46 -0500
commit467045ad0a97cfc1edee8b3faafab53433a5b702 (patch)
tree387850030ee8d19bf51b96e64e2ef6e3f834dd05
parentd0989ef842fb3cd48265521cd139b3ffa2aa3889 (diff)
downloadgss-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.conf15
-rw-r--r--proxy/src/gp_config.c243
-rw-r--r--proxy/src/gp_proxy.h34
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;