aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/builtin.c4
-rw-r--r--src/config.c10
-rw-r--r--src/gpg.c56
-rw-r--r--src/mail.c33
-rw-r--r--src/triplet.c88
-rw-r--r--src/verify.c278
-rw-r--r--src/wydawca.c1
-rw-r--r--src/wydawca.h35
-rw-r--r--tests/etc/wydawca.rcin20
-rw-r--r--tests/mailstats.at1
-rw-r--r--tests/notify-upl.at1
-rw-r--r--tests/upload-dry.at2
-rw-r--r--tests/upload.at1
13 files changed, 314 insertions, 216 deletions
diff --git a/src/builtin.c b/src/builtin.c
index d70a511..73b1d23 100644
--- a/src/builtin.c
+++ b/src/builtin.c
@@ -151,16 +151,14 @@ struct builtin_data_storage
{
struct obstack stk;
char **wp;
};
static int default_ncol[] = {
- 1, /* verify-user: arbitrary return, usually user name */
- 1, /* gpg-key: key */
+ 4, /* project-uploader: name, realname, email, pubkey */
2, /* project-owner: email, realname */
- 2, /* user-data: email, realname */
};
int
builtin_run (struct access_method *meth, void *handle, const char *req)
{
int i;
diff --git a/src/config.c b/src/config.c
index 8758802..4748a80 100644
--- a/src/config.c
+++ b/src/config.c
@@ -1036,23 +1036,19 @@ static struct grecs_keyword access_method_kw[] = {
int
string_to_access_method_id (grecs_locus_t *locus,
const char *str, enum access_method_id *idp)
{
static const char *id_str[] = {
- "verify-user",
- "gpg-key",
+ "project-uploader",
"project-owner",
- "user-data",
NULL
};
static int id_num[] = {
- verify_method,
- gpg_key_method,
- project_owner_method,
- user_data_method
+ project_uploader_method,
+ project_owner_method
};
ARGMATCH_VERIFY (id_str, id_num);
int rc, res;
rc = string_to ("access method", str,
id_str, id_num,
diff --git a/src/gpg.c b/src/gpg.c
index 6f7dfb6..71be53c 100644
--- a/src/gpg.c
+++ b/src/gpg.c
@@ -146,13 +146,14 @@ wydawca_gpg_homedir ()
logmsg (LOG_DEBUG, _("GNUPG home directory: %s"), homedir);
setenv ("GNUPGHOME", homedir, 1);
return 0;
}
static int
-gpg_sig_ok_p (gpgme_ctx_t ctx, gpgme_signature_t sig)
+gpg_verify_signature (gpgme_ctx_t ctx, gpgme_signature_t sig,
+ struct file_triplet *trp)
{
if (!sig)
return 0;
for (; sig; sig = sig->next)
{
@@ -166,31 +167,45 @@ gpg_sig_ok_p (gpgme_ctx_t ctx, gpgme_signature_t sig)
switch (gpg_err_code (sig->status))
{
case GPG_ERR_NO_ERROR:
if (debug_level)
logmsg (LOG_NOTICE, _("Good signature from %s"), uid);
+ trp->uploader = uploader_find_frp (trp->uploader_list, sig->fpr);
+ if (!trp->uploader)
+ {
+ logmsg (LOG_ERR,
+ _("good signature from %s, "
+ "but the uploader info for %s not found"),
+ uid, sig->fpr);
+ return 1;
+ }
break;
case GPG_ERR_BAD_SIGNATURE:
+ UPDATE_STATS (STAT_BAD_SIGNATURE);
logmsg (LOG_ERR, _("BAD signature from %s"), uid);
return 0;
case GPG_ERR_NO_PUBKEY:
+ UPDATE_STATS (STAT_ACCESS_VIOLATIONS);
logmsg (LOG_ERR, _("No public key"));
return 0;
case GPG_ERR_NO_DATA:
+ UPDATE_STATS (STAT_BAD_TRIPLETS);
logmsg (LOG_ERR, _("No signature"));
return 0;
case GPG_ERR_SIG_EXPIRED:
+ UPDATE_STATS (STAT_BAD_SIGNATURE);
logmsg (LOG_ERR, _("Expired signature from %s"), uid);
return 0;
case GPG_ERR_KEY_EXPIRED:
+ UPDATE_STATS (STAT_BAD_SIGNATURE);
logmsg (LOG_ERR, _("Key expired (%s)"), uid);
return 0;
default:
logmsg (LOG_ERR, _("Unknown signature error"));
return 0;
@@ -200,50 +215,59 @@ gpg_sig_ok_p (gpgme_ctx_t ctx, gpgme_signature_t sig)
}
/* Verify the directive file from TRP using public key PUBKEY */
/* FIXME: spool currently unused */
int
verify_directive_signature (struct file_triplet *trp,
- const struct spool *spool, const char *pubkey)
+ const struct spool *spool)
{
gpgme_ctx_t ctx;
gpgme_data_t key_data, directive_data, plain;
off_t size;
gpgme_error_t ec;
int rc;
-
+ struct uploader_info *uptr;
+
wydawca_gpg_homedir ();
fail_if_err (gpgme_new (&ctx));
- fail_if_err (gpgme_data_new_from_mem (&key_data, pubkey, strlen (pubkey),
- 0));
- fail_if_err (gpgme_op_import (ctx, key_data));
+
+ for (uptr = trp->uploader_list; uptr; uptr = uptr->next)
+ {
+ gpgme_import_result_t res;
+ gpgme_import_status_t pstat;
+
+ fail_if_err (gpgme_data_new_from_mem (&key_data,
+ uptr->gpg_key,
+ strlen (uptr->gpg_key),
+ 0));
+ fail_if_err (gpgme_op_import (ctx, key_data));
+ res = gpgme_op_import_result (ctx);
+ pstat = res->imports;
+ uptr->fpr = xstrdup (pstat->fpr);
+ if (debug_level > 2)
+ logmsg (LOG_DEBUG, _("imported key: user = %s, fingerprint = %s"),
+ uptr->name, uptr->fpr);
+ }
fail_if_err (gpgme_data_new_from_file (&directive_data,
trp->file[file_directive].name, 1));
gpgme_data_new (&plain);
ec = gpgme_op_verify (ctx, directive_data, NULL, plain);
if (ec == GPG_ERR_NO_ERROR)
{
gpgme_verify_result_t result;
- size = gpgme_data_seek (plain, 0, SEEK_END);
- gpgme_data_seek (plain, 0, SEEK_SET);
- trp->blurb = xmalloc (size + 1);
- gpgme_data_read (plain, trp->blurb, size);
- trp->blurb[size] = 0;
- gpgme_data_release (plain);
-
- rc = directive_parse (trp);
-
result = gpgme_op_verify_result (ctx);
- if (!gpg_sig_ok_p (ctx, result->signatures))
+ if (!gpg_verify_signature (ctx, result->signatures, trp))
{
UPDATE_STATS (STAT_BAD_SIGNATURE);
notify (spool->notification, trp, ev_bad_directive_signature);
rc = 1;
}
+ else
+ rc = 0;
}
else
{
rc = 1;
UPDATE_STATS (STAT_BAD_SIGNATURE);
logmsg (LOG_ERR, _("%s: directive verification failed: %s"),
diff --git a/src/mail.c b/src/mail.c
index 5065306..beb88d4 100644
--- a/src/mail.c
+++ b/src/mail.c
@@ -257,14 +257,39 @@ mail_stats ()
meta_free (exp);
timer_free_meta (exp + 1, tc);
free (exp);
}
mu_address_t
+get_uploader_email (struct uploader_info *info, struct file_triplet *trp,
+ const char **errp)
+{
+ mu_address_t addr;
+ mu_address_t rcpt = NULL;
+ int rc;
+
+ rc = mu_address_create (&addr, info->email);
+ if (rc)
+ {
+ *errp = mu_strerror (rc);
+ return NULL;
+ }
+
+ mu_address_set_personal (addr, 1, info->realname);
+
+ /* This hack makes sure that mu_address_to_string (rcpt) will
+ return full email address (with personal part) */
+ mu_address_union (&rcpt, addr);
+ mu_address_destroy (&addr);
+
+ return rcpt;
+}
+
+mu_address_t
get_recipient (struct access_method *method, struct file_triplet *trp,
- char **errp)
+ const char **errp)
{
unsigned nrows, ncols, i;
mu_address_t rcpt = NULL;
char *text;
int rc;
void *md;
@@ -324,22 +349,21 @@ get_recipient (struct access_method *method, struct file_triplet *trp,
void
do_notify (struct file_triplet *trp, enum notification_event ev,
struct notification *ntf)
{
mu_address_t rcpt = NULL;
- char *errp;
+ const char *errp;
switch (ntf->tgt)
{
case notify_admin:
rcpt = mu_address_dup (admin_address);
break;
case notify_user:
- rcpt = get_recipient (trp->spool->access_method[user_data_method],
- trp, &errp);
+ rcpt = get_uploader_email (trp->uploader, trp, &errp);
break;
case notify_owner:
rcpt = get_recipient (trp->spool->access_method[project_owner_method],
trp, &errp);
}
@@ -384,12 +408,11 @@ do_notify (struct file_triplet *trp, enum notification_event ev,
void
notify (struct notification *notification_list,
struct file_triplet *trp, enum notification_event ev)
{
struct notification *p;
- fill_project_name (trp);
for (p = notification_list; p; p = p->next)
if (p->ev == ev)
do_notify (trp, ev, p);
/* FIXME */
}
diff --git a/src/triplet.c b/src/triplet.c
index 0ddf997..048cdcb 100644
--- a/src/triplet.c
+++ b/src/triplet.c
@@ -49,21 +49,14 @@ hash_triplet_free (void *data)
free (tp->file[i].name);
}
free (tp->directive);
free (tp->blurb);
free (tp->tmp);
- free (tp->user);
-
- if (tp->user_data)
- {
- for (i = 0; i < NITEMS (tp->user_data); i++)
- free (tp->user_data[i]);
- free (tp->user_data);
- }
-
+ /* FIXME: free uploader list */
+
free (tp);
}
/* Register a file in the triplet table */
void
register_file (struct file_info *finfo)
@@ -319,40 +312,44 @@ static int ugswidth = 19;
static int
format_file_data (struct file_triplet *trp, enum file_type type, char **pret)
{
char modes[11];
struct file_info *info = trp->file + type;
char timebuf[sizeof "YYYY-MM-DD HH:MM:SS +0000"];
+ struct passwd *pw;
struct group *grp;
char sbuf[INT_BUFSIZE_BOUND (uintmax_t)];
char *sptr;
size_t slen;
int pad;
char *user_name;
char *group_name;
struct tm *tm;
char *buf;
-
+
if (!info->name)
return 1;
/* MODE OWNER GROUP SIZE MTIME FILE_NAME MD5SUM? */
modes[0] = '-'; /* Only regular files are allowed */
decode_file_mode (info->sb.st_mode, modes + 1);
/* File time */
tm = localtime (&info->sb.st_mtime);
strftime (timebuf, sizeof timebuf, "%Y-%m-%d %H:%M:%S %z", tm);
- user_name = trp->user;
+ pw = getpwuid (TRIPLET_UID (trp));
+ if (!pw)
+ user_name = "unknown";
+ else
+ user_name = pw->pw_name;
- /* FIXME: group name should be stored in TRP after verification */
grp = getgrgid (TRIPLET_GID (trp));
if (!grp)
- group_name = "UNKNOWN"; /* should not happen */
+ group_name = "unknown"; /* should not happen */
else
group_name = grp->gr_name;
/* Size */
sptr = umaxtostr (info->sb.st_size, sbuf);
@@ -468,83 +465,34 @@ expand_triplet_directive (struct metadef *def, void *data)
}
static const char *
expand_user_name (struct metadef *def, void *data)
{
struct file_triplet *trp = data;
- return trp->user;
-}
-
-static void
-fill_user_data (struct file_triplet *trp)
-{
- int rc;
- struct access_method *method = trp->spool->access_method[user_data_method];
- char *text;
- unsigned nrows, ncols;
- struct passwd *pw;
- void *md;
-
- if (trp->user_data)
- return;
-
- if (method->type == method_none)
- return;
-
- md = method_open (method);
- if (!md)
- return;
-
- pw = getpwuid (TRIPLET_UID (trp));
- if (!pw)
- return;
- text = triplet_expand_method_query (method, md, trp);
-
- rc = method_run (method, md, text);
- free (text);
- if (rc)
- {
- method_close (method, md);
- return;
- }
-
- nrows = method_num_rows (method);
- ncols = method_num_cols (method);
-
- if (nrows > 0)
- {
- int i;
- trp->user_data = xcalloc (ncols, sizeof (trp->user_data[0]));
- for (i = 0; i < ncols; i++)
- {
- const char *str = method_result (method, md, 0, i);
- if (str)
- trp->user_data[i] = xstrdup (str);
- }
- }
- method_close (method, md);
+ if (trp->uploader)
+ return trp->uploader->name;
+ def->value = "UNKNOWN";
+ return def->value;
}
static const char *
expand_user_real_name (struct metadef *def, void *data)
{
struct file_triplet *trp = data;
- fill_user_data (trp);
- if (trp->user_data && trp->user_data[1])
- return trp->user_data[1];
+ if (trp->uploader)
+ return trp->uploader->realname;
def->value = "UNKNOWN";
return def->value;
}
static const char *
expand_user_email (struct metadef *def, void *data)
{
struct file_triplet *trp = data;
- fill_user_data (trp);
- if (trp->user_data && trp->user_data[0])
- return trp->user_data[0];
+ if (trp->uploader)
+ return trp->uploader->email;
def->value = "UNKNOWN";
return def->value;
}
static const char *
expand_report (struct metadef *def, void *data)
diff --git a/src/verify.c b/src/verify.c
index 15a2d8b..ed5f0cf 100644
--- a/src/verify.c
+++ b/src/verify.c
@@ -35,21 +35,118 @@ trim (char *str)
{
size_t len = trim_length (str);
str[len] = 0;
return len;
}
+#define MSG_BEGIN_MARKER_STR "-----BEGIN PGP SIGNED MESSAGE-----\n"
+#define MSG_BEGIN_MARKER_LEN (sizeof (MSG_BEGIN_MARKER_STR) - 1)
+
+#define SIG_BEGIN_MARKER_STR "-----BEGIN PGP SIGNATURE-----\n"
+#define SIG_BEGIN_MARKER_LEN (sizeof (SIG_BEGIN_MARKER_STR) - 1)
+
+static int
+extract_plaintext (char *blurb)
+{
+ char *start, *p;
+
+ if (memcmp (blurb, MSG_BEGIN_MARKER_STR, MSG_BEGIN_MARKER_LEN))
+ return 1;
+
+ p = blurb + MSG_BEGIN_MARKER_LEN;
+ while (*p)
+ {
+ if (*p == '\n')
+ {
+ p++;
+ break;
+ }
+
+ p = strchr (p, '\n');
+ if (!p)
+ return 1;
+ p++;
+ }
+
+ if (!*p)
+ return 1;
+
+ start = p;
+ while (*p)
+ {
+ if (strncmp (p, SIG_BEGIN_MARKER_STR, SIG_BEGIN_MARKER_LEN) == 0)
+ {
+ *p++ = 0;
+ memmove (blurb, start, p - start);
+ return 0;
+ }
+ p = strchr (p, '\n');
+ if (!p)
+ return 1;
+ p++;
+ }
+ return 1;
+}
+
int
fill_project_name (struct file_triplet *trp)
{
- char *project;
- const char *directory;
- char *p;
+ char *blurb;
+ size_t size;
+ FILE *fp;
+ char *project, *p;
+ const char *directory;
+ int rc;
+
+ size = trp->file[file_directive].sb.st_size;
+ if (size <= MSG_BEGIN_MARKER_LEN)
+ {
+ logmsg (LOG_ERR, _("too small directive file %s"),
+ trp->file[file_directive].name);
+ return 1;
+ }
+
+ fp = fopen (trp->file[file_directive].name, "r");
+ if (!fp)
+ {
+ logmsg (LOG_ERR, _("cannot open file %s: %s"),
+ trp->file[file_directive].name, strerror (errno));
+ return 1;
+ }
- if (trp->project)
- return 1;
+ blurb = xmalloc (size + 1);
+
+ rc = fread (blurb, size, 1, fp);
+ fclose (fp);
+
+ if (rc != 1)
+ {
+ logmsg (LOG_ERR, _("error reading file %s: %s"),
+ trp->file[file_directive].name, strerror (errno));
+ free (blurb);
+ return 1;
+ }
+
+ blurb[size] = 0;
+ if (extract_plaintext (blurb))
+ {
+ logmsg (LOG_ERR, _("%s: unrecognized format"),
+ trp->file[file_directive].name);
+ free (blurb);
+ return 1;
+ }
+
+ trp->blurb = blurb;
+
+ if (directive_parse (trp))
+ {
+ free (blurb);
+ trp->blurb = NULL;
+ return 1;
+ }
+
if (directive_get_value (trp, "directory", &directory))
{
logmsg (LOG_ERR, _("%s: missing `directory' directive"),
trp->file[file_directive].name);
return 1;
}
@@ -66,141 +163,164 @@ fill_project_name (struct file_triplet *trp)
project = xmalloc (len + 1);
memcpy (project, directory, len);
project[len] = 0;
}
else
project = xstrdup (directory);
- trp->project = project;
+ trp->project = xstrdup (project);
return 0;
}
-/* Verify if USER has upload rights on the directory (project) requested
- by TRP */
+struct uploader_info *
+new_uploader_info (struct uploader_info *src)
+{
+ struct uploader_info *p = xmalloc (sizeof (*p));
+ p->next = NULL;
+ p->name = src->name;
+ p->realname = src->realname;
+ p->gpg_key = src->gpg_key;
+ p->email = src->email;
+ p->fpr = NULL;
+ return p;
+}
+
+struct uploader_info *
+uploader_find_frp (struct uploader_info *list, const char *fpr)
+{
+ for (; list; list = list->next)
+ if (list->fpr && strcmp (list->fpr, fpr) == 0)
+ break;
+ return list;
+}
+
int
-check_access_rights (struct file_triplet *trp, const struct spool *spool,
- const char *user)
+verify_directive_file (struct file_triplet *trp, const struct spool *spool)
{
- struct access_method *method = spool->access_method[verify_method];
- int rc;
char *command;
- const char *result;
+ struct access_method *method = spool->access_method[project_uploader_method];
+ int rc;
void *md;
- struct group *grp;
+
+ size_t nrows, ncols, i;
+ struct uploader_info *head, *tail;
+ if (!trp->file[file_directive].name)
+ return 1;
+
if (fill_project_name (trp))
return 1;
- grp = getgrnam (trp->project);
- if (grp)
- trp->gid = grp->gr_gid;
- else
- logmsg (LOG_NOTICE, _("no such group: %s"), trp->project);
- if (debug_level)
- logmsg (LOG_DEBUG, _("verifying access rights for user %s to project %s"),
- user, trp->project);
-
md = method_open (method);
if (!md)
return 1;
command = triplet_expand_method_query (method, md, trp);
rc = method_run (method, md, command);
free (command);
- method_close (method, md);
if (rc)
{
- logmsg (LOG_ERR, _("cannot verify access rights for %s on %s"),
- user, trp->project);
+ logmsg (LOG_ERR, _("cannot get uploaders for %s"), trp->name);
+ method_close (method, md);
return 1;
}
- result = method_result (method, md, 0, 0);
- if (!result || strcmp (result, user))
+ nrows = method_num_rows (method);
+ if (nrows == 0)
{
- UPDATE_STATS (STAT_ACCESS_VIOLATIONS);
- logmsg (LOG_ERR, _("%s: %s has no rights on %s"),
- trp->name, user, trp->project);
- notify (spool->notification, trp, ev_bad_ownership);
+ logmsg (LOG_ERR, _("found no uploaders for %s"), trp->name);
+ method_close (method, md);
return 1;
}
- return 0;
-}
-
-int
-verify_directive_file (struct file_triplet *trp, const struct spool *spool)
-{
- struct passwd *pw;
- char *command;
- struct access_method *method = spool->access_method[gpg_key_method];
- const char *pubkey;
- int rc;
- void *md;
-
- if (!trp->file[file_directive].name)
- return 1;
-
- md = method_open (method);
- if (!md)
- return 1;
- pw = getpwuid (TRIPLET_UID (trp));
- if (!pw)
+ ncols = method_num_cols (method);
+ if (ncols < 4)
{
- logmsg (LOG_ERR, _("%s: getpwuid failed: %s"),
- trp->name, strerror (errno));
+ logmsg (LOG_ERR,
+ _("project-uploader method error: too few columns (%lu)"),
+ (unsigned long) ncols);
method_close (method, md);
return 1;
}
- trp->gid = pw->pw_gid;
- trp->user = xstrdup (pw->pw_name);
-
- command = triplet_expand_method_query (method, md, trp);
- rc = method_run (method, md, command);
- free (command);
- if (rc)
+ head = tail = NULL;
+ for (i = 0; i < nrows; i++)
{
- logmsg (LOG_ERR, _("cannot get PGP key for %s"), trp->user);
- method_close (method, md);
- return 1;
+ const char *p;
+ struct uploader_info info, *ptr;
+
+ memset (&info, 0, sizeof (info));
+ p = method_result (method, md, i, 0);
+ if (p)
+ info.name = xstrdup (p);
+ p = method_result (method, md, i, 1);
+ if (p)
+ info.realname = xstrdup (p);
+ p = method_result (method, md, i, 2);
+ if (p)
+ info.email = xstrdup (p);
+ p = method_result (method, md, i, 3);
+ if (p)
+ info.gpg_key = xstrdup (p);
+
+ if (debug_level > 3)
+ {
+ logmsg (LOG_DEBUG, _("name: %s"), SP (info.name));
+ logmsg (LOG_DEBUG, _("realname: %s"), SP (info.realname));
+ logmsg (LOG_DEBUG, _("gpg-key: %s"), SP (info.gpg_key));
+ logmsg (LOG_DEBUG, _("email: %s"), SP (info.email));
+ }
+
+ if (!info.name || !info.realname || !info.gpg_key || !info.email)
+ {
+ logmsg (LOG_ERR,
+ _("project-uploader method error: malformed row %lu"),
+ (unsigned long) i);
+ free (info.name);
+ free (info.realname);
+ free (info.gpg_key);
+ free (info.email);
+ continue;
+ }
+
+ ptr = new_uploader_info (&info);
+ if (tail)
+ tail->next = ptr;
+ else
+ head = ptr;
+ tail = ptr;
}
+
+ method_close (method, md);
- pubkey = method_result (method, md, 0, 0);
- if (!pubkey || pubkey[0] == 0)
+ if (!head)
{
- logmsg (LOG_ERR, _("no GPG key for %s"), trp->user);
- method_close (method, md);
+ logmsg (LOG_ERR, _("no valid uploaders found for %s"), trp->name);
return 1;
}
- if (debug_level > 3)
- logmsg (LOG_DEBUG, _("public key: %s"), pubkey);
+ trp->uploader_list = head;
+ trp->uploader = NULL;
- if (verify_directive_signature (trp, spool, pubkey))
+ if (verify_directive_signature (trp, spool))
{
/*FIXME: Update stats */
- logmsg (LOG_ERR, _("invalid signature for %s"), trp->name);
- method_close (method, md);
+ logmsg (LOG_ERR, _("invalid signature for %s"),
+ trp->name ? trp->name : "[unknown]");
return 1;
}
else if (debug_level)
logmsg (LOG_DEBUG, _("%s: directive file signature OK"), trp->name);
- method_close (method, md);
-
if (debug_level > 1)
{
int i;
for (i = 0; trp->directive[i]; i++)
logmsg (LOG_DEBUG, "directive[%d] = %s", i, trp->directive[i]);
}
if (verify_directive_format (trp))
return 1;
- if (check_access_rights (trp, spool, trp->user))
- return 1;
-
return 0;
}
diff --git a/src/wydawca.c b/src/wydawca.c
index 60cc628..07cac5c 100644
--- a/src/wydawca.c
+++ b/src/wydawca.c
@@ -235,13 +235,12 @@ grecs_print_diag (grecs_locus_t *locus, int err, int errcode, const char *msg)
else
logmsg (err ? LOG_ERR : LOG_WARNING, "%s", msg);
}
}
-
static int uidc;
static uid_t *uidv;
static void
collect_uids (int argc, char **argv)
{
diff --git a/src/wydawca.h b/src/wydawca.h
index b390bff..15d803b 100644
--- a/src/wydawca.h
+++ b/src/wydawca.h
@@ -81,19 +81,16 @@
#define __cat2__(a,b) a ## b
#define __cat3__(a,b,c) a ## b ## c
#define NITEMS(a) (sizeof(a)/sizeof((a)[0]))
enum access_method_id {
- verify_method, /* Method for verification user's access to
- the project */
- gpg_key_method, /* Method for retrieving the user public key */
- project_owner_method, /* Method for retrieving the names
- and emails of the project owners */
- user_data_method, /* Method for retrieving the user name
- and real name by his uid */
+ project_uploader_method, /* Retrieves names, gpg-keys, emails and
+ real names of the project uploaders */
+ project_owner_method, /* Retrieves names and emails of the project
+ owners */
access_method_count
};
enum access_method_type
{
method_none, /* Undefined or no method */
@@ -158,34 +155,45 @@ struct file_info
enum file_type type; /* Part type */
char *name; /* File name */
unsigned root_len; /* Length of root part in name */
struct stat sb;
};
+struct uploader_info
+{
+ struct uploader_info *next;
+ char *name;
+ char *realname;
+ char *email;
+ char *gpg_key;
+ char *fpr;
+};
+
/* File triplet */
struct file_triplet
{
char *name; /* Triplet base name */
- gid_t gid; /* Owner GID */
struct file_info file[FILE_TYPE_COUNT]; /* Components */
const struct spool *spool; /* Owning spool */
char **directive; /* Decoded directive pairs (key: value\0) */
char *blurb; /* Block of directives: directive[i] points here */
char *tmp; /* Temporary storage */
size_t tmpsize; /* Size of memory allocated in tmp */
+ /* User data */
+ size_t uploader_count;
+ struct uploader_info *uploader_list;
+ struct uploader_info *uploader;
/* Special data for template formatting */
char *project; /* Triplet project name (if known) */
- char *user; /* User name (if known) */
- char **user_data;
};
/* Macros to access owner UID and GID. */
/* The directive file is always present in the triplet */
#define TRIPLET_UID(t) ((t)->file[file_directive].sb.st_uid)
/* GID is filled in after the triplet is finalized and verified */
-#define TRIPLET_GID(t) ((t)->gid)
+#define TRIPLET_GID(t) ((t)->file[file_directive].sb.st_gid)
struct virt_tab
{
int (*test_url) (mu_url_t url, grecs_locus_t *loc);
@@ -406,17 +414,18 @@ unsigned method_num_rows (struct access_method *method);
unsigned method_num_cols (struct access_method *method);
/* Verification functions */
int verify_directive_file (struct file_triplet *trp,
const struct spool *spool);
int verify_directive_signature (struct file_triplet *trp,
- const struct spool *spool,
- const char *pubkey);
+ const struct spool *spool);
int verify_detached_signature (struct file_triplet *trp,
const struct spool *spool);
int fill_project_name (struct file_triplet *trp);
+struct uploader_info *uploader_find_frp (struct uploader_info *list,
+ const char *frp);
/* Directive file support */
int directive_parse (struct file_triplet *trp);
int directive_get_value (struct file_triplet *trp, const char *key,
const char **pval);
int directive_pack_version (const char *val, unsigned *pversion);
diff --git a/tests/etc/wydawca.rcin b/tests/etc/wydawca.rcin
index bc6aaa4..2ac40e9 100644
--- a/tests/etc/wydawca.rcin
+++ b/tests/etc/wydawca.rcin
@@ -24,31 +24,17 @@ access-method project-owner {
type builtin;
query "${project}";
params ("/exact",
"proj", "proj-owner@localhost", "Project Admin");
}
-access-method user-data {
+access-method project-uploader {
type builtin;
- query "${user}";
- params ("/exact",
- "@USER@", "@USER@@localhost", "Wydawca Test User");
-}
-
-access-method verify-user {
- type builtin;
- query "${user}";
- params ("/exact",
- "@USER@", "@USER@");
-}
-
-access-method gpg-key {
- type builtin;
- query "${user}";
+ query "${project}";
params ("/exact",
- "@USER@",
+ "proj", "gray", "Wydawca Test User", "gray@localhost",
"-----BEGIN PGP PUBLIC KEY BLOCK-----\n"
"Version: GnuPG v1.4.7 (GNU/Linux)\n"
"\n"
"mQGhBEmZcTERBAD9sD9d3xhVHURwbLcHUHIK6LGSHAlFzKv4MSOk+6nJhdvbQfIV\n"
"YAe6VZ8fTX8EX7f0Vw53or1mlBOZpMNeEHp/IejFwnT3pAF3xiHTwbmwJg+0RuKo\n"
"dwfN0vO9xECj3/ZsBvSYbYty8Vmy2e8osrNdXAXd+8Z3xJ3reAWOujGj9wCg1qg5\n"
diff --git a/tests/mailstats.at b/tests/mailstats.at
index 88e0aed..ff16f2a 100644
--- a/tests/mailstats.at
+++ b/tests/mailstats.at
@@ -15,13 +15,12 @@
# along with Wydawca. If not, see <http://www.gnu.org/licenses/>.
AT_SETUP([Simple upload statistics])
AT_DATA([errtmpl],
[wydawca: [[NOTICE]] AT_PACKAGE_TARNAME (AT_PACKAGE_NAME AT_PACKAGE_VERSION) started
-wydawca: [[NOTICE]] no such group: proj
wydawca: [[NOTICE]] file.directive.asc: COMMENT: Gnupload for Wydawca testsuite
wydawca: [[INFO]] errors: 0
wydawca: [[INFO]] warnings: 0
wydawca: [[INFO]] bad signatures: 0
wydawca: [[INFO]] access violation attempts: 0
wydawca: [[INFO]] complete triplets: 1
diff --git a/tests/notify-upl.at b/tests/notify-upl.at
index dc8b77a..9efe1d9 100644
--- a/tests/notify-upl.at
+++ b/tests/notify-upl.at
@@ -15,13 +15,12 @@
# along with Wydawca. If not, see <http://www.gnu.org/licenses/>.
AT_SETUP([Simple upload and notification])
AT_DATA([errtmpl],
[wydawca: [[NOTICE]] AT_PACKAGE_TARNAME (AT_PACKAGE_NAME AT_PACKAGE_VERSION) started
-wydawca: [[NOTICE]] no such group: proj
wydawca: [[NOTICE]] file.directive.asc: COMMENT: Gnupload for Wydawca testsuite
wydawca: [[INFO]] errors: 0
wydawca: [[INFO]] warnings: 0
wydawca: [[INFO]] bad signatures: 0
wydawca: [[INFO]] access violation attempts: 0
wydawca: [[INFO]] complete triplets: 1
diff --git a/tests/upload-dry.at b/tests/upload-dry.at
index 5f79fa8..a6317a2 100644
--- a/tests/upload-dry.at
+++ b/tests/upload-dry.at
@@ -23,14 +23,12 @@ wydawca: [[DEBUG]] found file file: distributive, stem: file
wydawca: [[DEBUG]] found file file.directive.asc: signed upload directive, stem: file
wydawca: [[DEBUG]] found file file.sig: detached signature, stem: file
wydawca: [[DEBUG]] processing spool test (@WD_DST@)
wydawca: [[DEBUG]] FILE file, DIST=file, SIG=file.sig, DIRECTIVE=file.directive.asc
wydawca: [[NOTICE]] Good signature from Wydawca (Testsuite) <bug-wydawca@gnu.org.ua>
wydawca: [[DEBUG]] file: directive file signature OK
-wydawca: [[NOTICE]] no such group: proj
-wydawca: [[DEBUG]] verifying access rights for user gray to project proj
wydawca: [[DEBUG]] processing triplet `file'
wydawca: [[NOTICE]] file.directive.asc: COMMENT: Gnupload for Wydawca testsuite
wydawca: [[DEBUG]] good detached signature for file
wydawca: [[DEBUG]] installing file to @WD_DST@/proj
wydawca: [[DEBUG]] installing file.sig to @WD_DST@/proj
wydawca: [[INFO]] errors: 0
diff --git a/tests/upload.at b/tests/upload.at
index 22e12fc..1968658 100644
--- a/tests/upload.at
+++ b/tests/upload.at
@@ -15,13 +15,12 @@
# along with Wydawca. If not, see <http://www.gnu.org/licenses/>.
AT_SETUP([Simple upload])
AT_DATA([template],
[wydawca: [[NOTICE]] AT_PACKAGE_TARNAME (AT_PACKAGE_NAME AT_PACKAGE_VERSION) started
-wydawca: [[NOTICE]] no such group: proj
wydawca: [[NOTICE]] file.directive.asc: COMMENT: Gnupload for Wydawca testsuite
wydawca: [[INFO]] errors: 0
wydawca: [[INFO]] warnings: 0
wydawca: [[INFO]] bad signatures: 0
wydawca: [[INFO]] access violation attempts: 0
wydawca: [[INFO]] complete triplets: 1

Return to:

Send suggestions and report system problems to the System administrator.