diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2009-11-30 21:35:14 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2009-11-30 21:35:14 +0200 |
commit | a4b8dfab94b3ca44b6e3aecd7c0281ca2f5b51d5 (patch) | |
tree | 531d41fe7bb4adfba62024e6205cbfa742f7e70e /src | |
parent | 4c68f93c0c664e13a8572b43e33c138ce3bb8d28 (diff) | |
download | wydawca-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.c | 4 | ||||
-rw-r--r-- | src/config.c | 10 | ||||
-rw-r--r-- | src/gpg.c | 56 | ||||
-rw-r--r-- | src/mail.c | 33 | ||||
-rw-r--r-- | src/triplet.c | 88 | ||||
-rw-r--r-- | src/verify.c | 278 | ||||
-rw-r--r-- | src/wydawca.c | 1 | ||||
-rw-r--r-- | src/wydawca.h | 35 |
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 | ||
156 | static int default_ncol[] = { | 156 | static 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 | ||
163 | int | 161 | int |
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 | ||
@@ -149,7 +149,8 @@ wydawca_gpg_homedir () | |||
149 | } | 149 | } |
150 | 150 | ||
151 | static int | 151 | static int |
152 | gpg_sig_ok_p (gpgme_ctx_t ctx, gpgme_signature_t sig) | 152 | gpg_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 */ |
204 | int | 219 | int |
205 | verify_directive_signature (struct file_triplet *trp, | 220 | verify_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 | { |
@@ -260,8 +260,33 @@ mail_stats () | |||
260 | } | 260 | } |
261 | 261 | ||
262 | mu_address_t | 262 | mu_address_t |
263 | get_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 | |||
287 | mu_address_t | ||
263 | get_recipient (struct access_method *method, struct file_triplet *trp, | 288 | get_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 | { |