aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2009-11-30 21:35:14 +0200
committerSergey Poznyakoff <gray@gnu.org.ua>2009-11-30 21:35:14 +0200
commita4b8dfab94b3ca44b6e3aecd7c0281ca2f5b51d5 (patch)
tree531d41fe7bb4adfba62024e6205cbfa742f7e70e /src
parent4c68f93c0c664e13a8572b43e33c138ce3bb8d28 (diff)
downloadwydawca-a4b8dfab94b3ca44b6e3aecd7c0281ca2f5b51d5.tar.gz
wydawca-a4b8dfab94b3ca44b6e3aecd7c0281ca2f5b51d5.tar.bz2
Do not require uploaders to be present in the system passwd database.
* src/wydawca.h (access_method_id): Remove verify_method, gpg_key_method and user_data_method. Add project_uploader_method. (uploader_info): New structure. (struct file_triplet): Remove gid and user data fields. Add uploader_count, uploader_list and uploader. (TRIPLET_GID): Change definition. (verify_directive_signature): Change signature. (uploader_find_frp): New proto. * src/verify.c (extract_plaintext): New function. (fill_project_name): Rewrite. Parse directive file. (uploader_find_frp): New function. (check_access_rights): Remove. (verify_directive_file): Rewrite. * src/config.c (string_to_access_method_id): Reflect changes to the access method system. * src/builtin.c (default_ncol): Reflect changes to the access method system. * src/gpg.c (gpg_sig_ok_p): Remove. (gpg_verify_signature): New function, based on gpg_sig_ok_p. (verify_directive_signature): Remove `pubkey' argument. Register all public keys from the uploader list. Do not call directive_parse, as the directive file must already be parsed by the time the function is called. * src/mail.c (get_uploader_email): New function. (do_notify): Use get_uploader_email for notifying users. * src/triplet.c (hash_triplet_free): Reflect changes to the triplet structure. (format_file_data): Get user name from the system passwd database. (fill_user_data): Remove. (expand_user_real_name, expand_user_email): Reflect changes to struct file_triplet. * tests/etc/wydawca.rcin: Rewrite to reflect new access method system. * tests/mailstats.at, tests/notify-upl.at, tests/upload-dry.at, tests/upload.at: Update.
Diffstat (limited to 'src')
-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
8 files changed, 311 insertions, 194 deletions
diff --git a/src/builtin.c b/src/builtin.c
index d70a511..73b1d23 100644
--- a/src/builtin.c
+++ b/src/builtin.c
@@ -154,10 +154,8 @@ struct builtin_data_storage
154}; 154};
155 155
156static int default_ncol[] = { 156static int default_ncol[] = {
157 1, /* verify-user: arbitrary return, usually user name */ 157 4, /* project-uploader: name, realname, email, pubkey */
158 1, /* gpg-key: key */
159 2, /* project-owner: email, realname */ 158 2, /* project-owner: email, realname */
160 2, /* user-data: email, realname */
161}; 159};
162 160
163int 161int
diff --git a/src/config.c b/src/config.c
index 8758802..4748a80 100644
--- a/src/config.c
+++ b/src/config.c
@@ -1039,17 +1039,13 @@ string_to_access_method_id (grecs_locus_t *locus,
1039 const char *str, enum access_method_id *idp) 1039 const char *str, enum access_method_id *idp)
1040{ 1040{
1041 static const char *id_str[] = { 1041 static const char *id_str[] = {
1042 "verify-user", 1042 "project-uploader",
1043 "gpg-key",
1044 "project-owner", 1043 "project-owner",
1045 "user-data",
1046 NULL 1044 NULL
1047 }; 1045 };
1048 static int id_num[] = { 1046 static int id_num[] = {
1049 verify_method, 1047 project_uploader_method,
1050 gpg_key_method, 1048 project_owner_method
1051 project_owner_method,
1052 user_data_method
1053 }; 1049 };
1054 ARGMATCH_VERIFY (id_str, id_num); 1050 ARGMATCH_VERIFY (id_str, id_num);
1055 1051
diff --git a/src/gpg.c b/src/gpg.c
index 6f7dfb6..71be53c 100644
--- a/src/gpg.c
+++ b/src/gpg.c
@@ -149,7 +149,8 @@ wydawca_gpg_homedir ()
149} 149}
150 150
151static int 151static int
152gpg_sig_ok_p (gpgme_ctx_t ctx, gpgme_signature_t sig) 152gpg_verify_signature (gpgme_ctx_t ctx, gpgme_signature_t sig,
153 struct file_triplet *trp)
153{ 154{
154 if (!sig) 155 if (!sig)
155 return 0; 156 return 0;
@@ -169,25 +170,39 @@ gpg_sig_ok_p (gpgme_ctx_t ctx, gpgme_signature_t sig)
169 case GPG_ERR_NO_ERROR: 170 case GPG_ERR_NO_ERROR:
170 if (debug_level) 171 if (debug_level)
171 logmsg (LOG_NOTICE, _("Good signature from %s"), uid); 172 logmsg (LOG_NOTICE, _("Good signature from %s"), uid);
173 trp->uploader = uploader_find_frp (trp->uploader_list, sig->fpr);
174 if (!trp->uploader)
175 {
176 logmsg (LOG_ERR,
177 _("good signature from %s, "
178 "but the uploader info for %s not found"),
179 uid, sig->fpr);
180 return 1;
181 }
172 break; 182 break;
173 183
174 case GPG_ERR_BAD_SIGNATURE: 184 case GPG_ERR_BAD_SIGNATURE:
185 UPDATE_STATS (STAT_BAD_SIGNATURE);
175 logmsg (LOG_ERR, _("BAD signature from %s"), uid); 186 logmsg (LOG_ERR, _("BAD signature from %s"), uid);
176 return 0; 187 return 0;
177 188
178 case GPG_ERR_NO_PUBKEY: 189 case GPG_ERR_NO_PUBKEY:
190 UPDATE_STATS (STAT_ACCESS_VIOLATIONS);
179 logmsg (LOG_ERR, _("No public key")); 191 logmsg (LOG_ERR, _("No public key"));
180 return 0; 192 return 0;
181 193
182 case GPG_ERR_NO_DATA: 194 case GPG_ERR_NO_DATA:
195 UPDATE_STATS (STAT_BAD_TRIPLETS);
183 logmsg (LOG_ERR, _("No signature")); 196 logmsg (LOG_ERR, _("No signature"));
184 return 0; 197 return 0;
185 198
186 case GPG_ERR_SIG_EXPIRED: 199 case GPG_ERR_SIG_EXPIRED:
200 UPDATE_STATS (STAT_BAD_SIGNATURE);
187 logmsg (LOG_ERR, _("Expired signature from %s"), uid); 201 logmsg (LOG_ERR, _("Expired signature from %s"), uid);
188 return 0; 202 return 0;
189 203
190 case GPG_ERR_KEY_EXPIRED: 204 case GPG_ERR_KEY_EXPIRED:
205 UPDATE_STATS (STAT_BAD_SIGNATURE);
191 logmsg (LOG_ERR, _("Key expired (%s)"), uid); 206 logmsg (LOG_ERR, _("Key expired (%s)"), uid);
192 return 0; 207 return 0;
193 208
@@ -203,19 +218,35 @@ gpg_sig_ok_p (gpgme_ctx_t ctx, gpgme_signature_t sig)
203/* FIXME: spool currently unused */ 218/* FIXME: spool currently unused */
204int 219int
205verify_directive_signature (struct file_triplet *trp, 220verify_directive_signature (struct file_triplet *trp,
206 const struct spool *spool, const char *pubkey) 221 const struct spool *spool)
207{ 222{
208 gpgme_ctx_t ctx; 223 gpgme_ctx_t ctx;
209 gpgme_data_t key_data, directive_data, plain; 224 gpgme_data_t key_data, directive_data, plain;
210 off_t size; 225 off_t size;
211 gpgme_error_t ec; 226 gpgme_error_t ec;
212 int rc; 227 int rc;
213 228 struct uploader_info *uptr;
229
214 wydawca_gpg_homedir (); 230 wydawca_gpg_homedir ();
215 fail_if_err (gpgme_new (&ctx)); 231 fail_if_err (gpgme_new (&ctx));
216 fail_if_err (gpgme_data_new_from_mem (&key_data, pubkey, strlen (pubkey), 232
217 0)); 233 for (uptr = trp->uploader_list; uptr; uptr = uptr->next)
218 fail_if_err (gpgme_op_import (ctx, key_data)); 234 {
235 gpgme_import_result_t res;
236 gpgme_import_status_t pstat;
237
238 fail_if_err (gpgme_data_new_from_mem (&key_data,
239 uptr->gpg_key,
240 strlen (uptr->gpg_key),
241 0));
242 fail_if_err (gpgme_op_import (ctx, key_data));
243 res = gpgme_op_import_result (ctx);
244 pstat = res->imports;
245 uptr->fpr = xstrdup (pstat->fpr);
246 if (debug_level > 2)
247 logmsg (LOG_DEBUG, _("imported key: user = %s, fingerprint = %s"),
248 uptr->name, uptr->fpr);
249 }
219 250
220 fail_if_err (gpgme_data_new_from_file (&directive_data, 251 fail_if_err (gpgme_data_new_from_file (&directive_data,
221 trp->file[file_directive].name, 1)); 252 trp->file[file_directive].name, 1));
@@ -225,22 +256,15 @@ verify_directive_signature (struct file_triplet *trp,
225 { 256 {
226 gpgme_verify_result_t result; 257 gpgme_verify_result_t result;
227 258
228 size = gpgme_data_seek (plain, 0, SEEK_END);
229 gpgme_data_seek (plain, 0, SEEK_SET);
230 trp->blurb = xmalloc (size + 1);
231 gpgme_data_read (plain, trp->blurb, size);
232 trp->blurb[size] = 0;
233 gpgme_data_release (plain);
234
235 rc = directive_parse (trp);
236
237 result = gpgme_op_verify_result (ctx); 259 result = gpgme_op_verify_result (ctx);
238 if (!gpg_sig_ok_p (ctx, result->signatures)) 260 if (!gpg_verify_signature (ctx, result->signatures, trp))
239 { 261 {
240 UPDATE_STATS (STAT_BAD_SIGNATURE); 262 UPDATE_STATS (STAT_BAD_SIGNATURE);
241 notify (spool->notification, trp, ev_bad_directive_signature); 263 notify (spool->notification, trp, ev_bad_directive_signature);
242 rc = 1; 264 rc = 1;
243 } 265 }
266 else
267 rc = 0;
244 } 268 }
245 else 269 else
246 { 270 {
diff --git a/src/mail.c b/src/mail.c
index 5065306..beb88d4 100644
--- a/src/mail.c
+++ b/src/mail.c
@@ -260,8 +260,33 @@ mail_stats ()
260} 260}
261 261
262mu_address_t 262mu_address_t
263get_uploader_email (struct uploader_info *info, struct file_triplet *trp,
264 const char **errp)
265{
266 mu_address_t addr;
267 mu_address_t rcpt = NULL;
268 int rc;
269
270 rc = mu_address_create (&addr, info->email);
271 if (rc)
272 {
273 *errp = mu_strerror (rc);
274 return NULL;
275 }
276
277 mu_address_set_personal (addr, 1, info->realname);
278
279 /* This hack makes sure that mu_address_to_string (rcpt) will
280 return full email address (with personal part) */
281 mu_address_union (&rcpt, addr);
282 mu_address_destroy (&addr);
283
284 return rcpt;
285}
286
287mu_address_t
263get_recipient (struct access_method *method, struct file_triplet *trp, 288get_recipient (struct access_method *method, struct file_triplet *trp,
264 char **errp) 289 const char **errp)
265{ 290{
266 unsigned nrows, ncols, i; 291 unsigned nrows, ncols, i;
267 mu_address_t rcpt = NULL; 292 mu_address_t rcpt = NULL;
@@ -327,7 +352,7 @@ do_notify (struct file_triplet *trp, enum notification_event ev,
327 struct notification *ntf) 352 struct notification *ntf)
328{