diff options
-rw-r--r-- | src/config.c | 4 | ||||
-rw-r--r-- | src/gpg.c | 2 | ||||
-rw-r--r-- | src/verify.c | 174 | ||||
-rw-r--r-- | src/wydawca.c | 2 | ||||
-rw-r--r-- | src/wydawca.h | 12 |
5 files changed, 125 insertions, 69 deletions
diff --git a/src/config.c b/src/config.c index 75e499a..e5ee832 100644 --- a/src/config.c +++ b/src/config.c @@ -628,6 +628,8 @@ cfg_tar_program (gsc_config_file_t *file, char *kw, char *val, void *unused) static const char *stat_args[] = { "errors", "warnings", + "bad_signatures", + "access_violations", "complete_triplets", "incomplete_triplets", "bad_triplets", @@ -643,6 +645,8 @@ static const char *stat_args[] = { static unsigned long stat_types[] = { STAT_ERRORS, STAT_WARNINGS, + STAT_BAD_SIGNATURE, + STAT_ACCESS_VIOLATIONS, STAT_COMPLETE_TRIPLETS, STAT_INCOMPLETE_TRIPLETS, STAT_BAD_TRIPLETS, @@ -243,6 +243,7 @@ verify_directive_signature (struct file_triplet *trp, else { rc = 1; + UPDATE_STATS (STAT_BAD_SIGNATURE); logmsg (LOG_ERR, "%s: directive verification failed: %s", trp->name, gpgme_strerror (ec)); /* FIXME: Send mail to the project maintainer */ @@ -290,6 +291,7 @@ verify_detached_signature (struct file_triplet *trp, return 0; case exec_fail: + UPDATE_STATS (STAT_BAD_SIGNATURE); logmsg (LOG_ERR, "BAD detached signature for %s", trp->name); break; diff --git a/src/verify.c b/src/verify.c index 7869618..e63d524 100644 --- a/src/verify.c +++ b/src/verify.c @@ -38,55 +38,25 @@ trim (char *str) return len; } -/* Quote non-printable characters in INPUT. Point *OUTPUT to the malloc'ed - quoted string. Return its length. */ -static size_t -quote_string (struct access_method *method, const char *input, char **poutput) +static const char * +find_expansion (int c, const struct kw_expansion *exp, size_t nexp) { - size_t size, len; - int quote; - char *output; - - if (!input) - { - *poutput = xmalloc (1); - (*poutput)[0] = 0; - return 1; - } - - switch (method->type) - { - case method_sql: - len = strlen (input); - size = 2 * len + 1; - output = xmalloc (size); - mysql_real_escape_string (&method->v.sqlconn->mysql, output, input, len); - size = strlen (output); - break; - - default: - size = argcv_quoted_length (input, "e); - output = xmalloc (size); - argcv_quote_copy (output, input); - break; - } - - *poutput = output; - return size; + for (; nexp; nexp--, exp++) + if (exp->kw == c) + return exp->value; + return NULL; } -/* Expand PARAM by replacing %u with the quoted value of USER, %p with that - of PROJECT and %% with a single %. Return the malloc'ed result. +/* Expand PARAM by replacing %X with the values as per expansion map EXP + (of NEXP elements). FIXME: Should we quote PARAM itself? */ char * -expand_param (const char *param, const char *user, const char *project, - struct access_method *method) +expand_param (const char *param, const struct kw_expansion *exp, size_t nexp) { char *p, *q, *res; + const char *s; int len; - char *esc_user = NULL; - char *esc_project = NULL; if (!param) return NULL; @@ -96,23 +66,19 @@ expand_param (const char *param, const char *user, const char *project, { if (*p == '%') { - if (p[1] == 'u') + if (p[1] == '%') { - len += quote_string (method, user, &esc_user); + len++; p += 2; } - if (p[1] == 'p') + else if ((s = find_expansion (p[1], exp, nexp)) != NULL) { - len += quote_string (method, project, &esc_project); + len += strlen (s); p += 2; } - else if (p[1] == '%') - { - len++; - p += 2; - } - else + else { + /* FIXME: warning? */ len++; p++; } @@ -132,24 +98,19 @@ expand_param (const char *param, const char *user, const char *project, { switch (*++p) { - case 'u': - strcpy (q, esc_user); - q += strlen (q); - p++; - break; - - case 'p': - strcpy (q, esc_project); - q += strlen (q); - p++; - break; - case '%': *q++ = *p++; break; default: - *q++ = *p++; + if ((s = find_expansion (*p, exp, nexp)) != NULL) + { + strcpy (q, s); + q += strlen (s); + p++; + } + else + *q++ = *p++; } } else @@ -157,11 +118,65 @@ expand_param (const char *param, const char *user, const char *project, } *q = 0; - free (esc_user); - free (esc_project); return res; } +/* Quote non-printable characters in INPUT. Point *OUTPUT to the malloc'ed + quoted string. Return its length. */ +static size_t +quote_string (struct access_method *method, const char *input, char **poutput) +{ + size_t size, len; + int quote; + char *output; + + if (!input) + { + *poutput = xmalloc (1); + (*poutput)[0] = 0; + return 1; + } + + switch (method->type) + { + case method_sql: + len = strlen (input); + size = 2 * len + 1; + output = xmalloc (size); + mysql_real_escape_string (&method->v.sqlconn->mysql, output, input, len); + size = strlen (output); + break; + + default: + size = argcv_quoted_length (input, "e); + output = xmalloc (size); + argcv_quote_copy (output, input); + break; + } + + *poutput = output; + return size; +} + +static void +escape_kwexp (struct access_method *method, struct kw_expansion *exp, + size_t nexp) +{ + size_t i; + + for (i = 0; i < nexp; i++) + quote_string (method, exp[i].value, &exp[i].value); +} + +static void +free_kwexp (struct kw_expansion *exp, size_t nexp) +{ + size_t i; + + for (i = 0; i < nexp; i++) + free (exp[i].value); +} + /* Verify if USER has upload rights on the directory (project) requested @@ -177,6 +192,7 @@ check_access_rights (struct file_triplet *trp, struct directory_pair *dpair, int rc; char *command; const char *result; + struct kw_expansion kwexp[2]; if (directive_get_value (trp, "directory", &directory)) { @@ -199,7 +215,15 @@ check_access_rights (struct file_triplet *trp, struct directory_pair *dpair, logmsg (LOG_DEBUG, "verifying access rights for user %s to project %s", user, project); - command = expand_param (method->param[1], user, project, method); + kwexp[0].kw = 'u'; + kwexp[0].value = (char*) user; + kwexp[1].kw = 'p'; + kwexp[1].value = project; + + escape_kwexp (method, kwexp, 2); + command = expand_param (method->param[1], kwexp, 2); + free_kwexp (kwexp, 2); + rc = method_run (method, command); free (command); if (rc) @@ -213,6 +237,8 @@ check_access_rights (struct file_triplet *trp, struct directory_pair *dpair, result = method_result (method); if (strcmp (result, user)) { + /* FIXME: Notify */ + UPDATE_STATS (STAT_ACCESS_VIOLATIONS); logmsg (LOG_ERR, "%s: %s has no rights on %s", trp->name, user, project); free (project); @@ -232,7 +258,8 @@ verify_directive_file (struct file_triplet *trp, struct directory_pair *dpair) struct access_method *method = &dpair->gpg_key_method; const char *pubkey; int rc; - + struct kw_expansion kwexp[1]; + if (!trp->file[file_directive].name) return 1; @@ -246,7 +273,12 @@ verify_directive_file (struct file_triplet *trp, struct directory_pair *dpair) trp->gid = pw->pw_gid; user_name = pw->pw_name; - command = expand_param (method->param[1], user_name, NULL, method); + kwexp[0].kw = 'u'; + kwexp[0].value = user_name; + escape_kwexp (method, kwexp, 1); + command = expand_param (method->param[1], kwexp, 1); + free_kwexp (kwexp, 1); + rc = method_run (method, command); free (command); if (rc) @@ -282,7 +314,11 @@ verify_directive_file (struct file_triplet *trp, struct directory_pair *dpair) if (verify_directive_format (trp)) return 1; - + + if (check_access_rights (trp, dpair, user_name)) + /* FIXME: Notify user / admin */ + return 1; + return 0; } diff --git a/src/wydawca.c b/src/wydawca.c index 16760b3..398cadd 100644 --- a/src/wydawca.c +++ b/src/wydawca.c @@ -152,6 +152,8 @@ struct option options[] = { static char *stat_name[MAX_STAT] = { "errors", "warnings", + "bad signatures", + "access violation attempts", "complete triplets", "incomplete triplets", "bad triplets", diff --git a/src/wydawca.h b/src/wydawca.h index 6db0fca..4d96ef6 100644 --- a/src/wydawca.h +++ b/src/wydawca.h @@ -153,6 +153,8 @@ enum wydawca_stat { STAT_ERRORS, STAT_WARNINGS, + STAT_BAD_SIGNATURE, + STAT_ACCESS_VIOLATIONS, STAT_COMPLETE_TRIPLETS, STAT_INCOMPLETE_TRIPLETS, STAT_BAD_TRIPLETS, @@ -170,6 +172,16 @@ enum wydawca_stat #define STAT_MASK_ALL (STAT_MASK(MAX_STAT) - 1) +struct kw_expansion +{ + int kw; + char *value; +}; + +char *expand_param (const char *param, const struct kw_expansion *exp, + size_t nexp); + + /* Global variables */ extern char *conffile; /* Configuration file name */ extern int debug_level; /* Debugging level */ |