aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2009-12-08 22:08:36 +0200
committerSergey Poznyakoff <gray@gnu.org.ua>2009-12-08 22:11:04 +0200
commit67ca2ef061a73bc90e4399471ee0cb3ce6f0ee41 (patch)
treed45493df75f3f613ca6b3d13a7f5d7a0280650a6
parente1afd42340c0b2c22660744e0f88258a44617e88 (diff)
downloadwydawca-67ca2ef061a73bc90e4399471ee0cb3ce6f0ee41.tar.gz
wydawca-67ca2ef061a73bc90e4399471ee0cb3ce6f0ee41.tar.bz2
Implement GPG signing of the outgoing notifications.
* src/config.c (mail_statistics_kw): New keyword gpg-sign. (notify_event_kw): Likewise. (wydawca_kw): New keyword gpg-homedir. * src/gpg.c (wydawca_gpg_homedir): Rename to create_gpg_homedir. Make static. All uses updated. * src/mail.c (admin_stat_sign_key): New global. (mu_stream_data_read_cb) (gpg_sign, sign_message): New functions. (mail_send_message): Take 3rd argument: ID of the PGP key to sign the message with. All callers updated. (do_notify): Rewrite. * src/wydawca.c (wydawca_gpg_homedir): New variable. * src/wydawca.h (struct notification): New member sign_keys. (admin_stat_sign_key): New extern. (wydawca_gpg_homedir): New extern.
-rw-r--r--doc/Makefile.am9
-rw-r--r--src/config.c9
-rw-r--r--src/gpg.c9
-rw-r--r--src/mail.c222
-rw-r--r--src/wydawca.c1
-rw-r--r--src/wydawca.h4
6 files changed, 238 insertions, 16 deletions
diff --git a/doc/Makefile.am b/doc/Makefile.am
index f53e47c..721ea29 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -99,6 +99,15 @@ check-unrevised:
99 rm $@-t; \ 99 rm $@-t; \
100 fi 100 fi
101 101
102check-config:
103 @check-docs.sh 'configuration statements' \
104 '/wydawca_keywords\[\] *= *{/,/^}/s/[ \t]*{ *"\([^,"]*\)".*/\1/pg' \
105 's/@deffnx\{0,1\} {Config} *\([^@,]*\).*/\1/p' \
106 $(top_srcdir)/src/config.c -- \
107 $(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) -E - \
108 $(info_TEXINFOS)
109
110
102all-check-docs: check-format check-options check-refs check-fixmes check-unrevised check-writeme 111all-check-docs: check-format check-options check-refs check-fixmes check-unrevised check-writeme
103 112
104check-docs: 113check-docs:
diff --git a/src/config.c b/src/config.c
index 559f766..f0a7042 100644
--- a/src/config.c
+++ b/src/config.c
@@ -863,6 +863,9 @@ static struct grecs_keyword mail_statistics_kw[] = {
863 { "statistics", 863 { "statistics",
864 N_("items"), N_("Send mail if one or more of these items are set"), 864 N_("items"), N_("Send mail if one or more of these items are set"),
865 grecs_type_string, &mail_admin_mask, 0, cb_statistics }, 865 grecs_type_string, &mail_admin_mask, 0, cb_statistics },
866 { "gpg-sign",
867 N_("key"), N_("Sign message with this key"),
868 grecs_type_string, &admin_stat_sign_key },
866 { NULL } 869 { NULL }
867}; 870};
868 871
@@ -907,6 +910,9 @@ static struct grecs_keyword notify_event_kw[] = {
907 { "message", N_("text-or-id"), 910 { "message", N_("text-or-id"),
908 N_("Text of the notification or identifier of a defined message template"), 911 N_("Text of the notification or identifier of a defined message template"),
909 grecs_type_string, NULL, offsetof(struct notification, msg) }, 912 grecs_type_string, NULL, offsetof(struct notification, msg) },
913 { "gpg-sign", N_("key"),
914 N_("Sign message with this key"),
915 grecs_type_string, NULL, offsetof(struct notification, sign_keys) },
910 { NULL } 916 { NULL }
911}; 917};
912 918
@@ -1457,6 +1463,9 @@ static struct grecs_keyword wydawca_kw[] = {
1457 { "all-spools", NULL, N_("Service names that request scanning all spools"), 1463 { "all-spools", NULL, N_("Service names that request scanning all spools"),
1458 grecs_type_string|GRECS_LIST, &all_spool_aliases }, 1464 grecs_type_string|GRECS_LIST, &all_spool_aliases },
1459 1465
1466 { "gpg-homedir", NULL, N_("GPG home directory"),
1467 grecs_type_string, &wydawca_gpg_homedir },
1468
1460 { NULL } 1469 { NULL }
1461}; 1470};
1462 1471
diff --git a/src/gpg.c b/src/gpg.c
index 71be53c..1389845 100644
--- a/src/gpg.c
+++ b/src/gpg.c
@@ -128,8 +128,8 @@ remove_homedir ()
128} 128}
129 129
130/* Create a temporary GPG home directory */ 130/* Create a temporary GPG home directory */
131int 131static int
132wydawca_gpg_homedir () 132create_gpg_homedir ()
133{ 133{
134 if (homedir) 134 if (homedir)
135 return 0; 135 return 0;
@@ -222,12 +222,11 @@ verify_directive_signature (struct file_triplet *trp,
222{ 222{
223 gpgme_ctx_t ctx; 223 gpgme_ctx_t ctx;
224 gpgme_data_t key_data, directive_data, plain; 224 gpgme_data_t key_data, directive_data, plain;
225 off_t size;
226 gpgme_error_t ec; 225 gpgme_error_t ec;
227 int rc; 226 int rc;
228 struct uploader_info *uptr; 227 struct uploader_info *uptr;
229 228
230 wydawca_gpg_homedir (); 229 create_gpg_homedir ();
231 fail_if_err (gpgme_new (&ctx)); 230 fail_if_err (gpgme_new (&ctx));
232 231
233 for (uptr = trp->uploader_list; uptr; uptr = uptr->next) 232 for (uptr = trp->uploader_list; uptr; uptr = uptr->next)
@@ -301,7 +300,7 @@ verify_detached_signature (struct file_triplet *trp,
301 return 1; 300 return 1;
302 } 301 }
303 302
304 wydawca_gpg_homedir (); 303 create_gpg_homedir ();
305 argv[0] = info->file_name; 304 argv[0] = info->file_name;
306 argv[1] = "--verify"; 305 argv[1] = "--verify";
307 argv[2] = trp->file[file_signature].name; 306 argv[2] = trp->file[file_signature].name;
diff --git a/src/mail.c b/src/mail.c
index 91ea502..15c2937 100644
--- a/src/mail.c
+++ b/src/mail.c
@@ -17,6 +17,7 @@
17#include "wydawca.h" 17#include "wydawca.h"
18#include <mail.h> 18#include <mail.h>
19#include <hash.h> 19#include <hash.h>
20#include <gpgme.h>
20 21
21int mailer_opened; 22int mailer_opened;
22mu_mailer_t mailer; 23mu_mailer_t mailer;
@@ -27,6 +28,7 @@ unsigned long owner_notification_flags;
27char *user_message_template[MAX_EVENT]; 28char *user_message_template[MAX_EVENT];
28 29
29char *admin_stat_message; 30char *admin_stat_message;
31char *admin_stat_sign_key;
30 32
31void 33void
32mail_init () 34mail_init ()
@@ -44,8 +46,203 @@ mail_init ()
44 } 46 }
45} 47}
46 48
49struct mu_stream_handle
50{
51 mu_stream_t str;
52 mu_off_t off;
53};
54
55static ssize_t
56mu_stream_data_read_cb (void *handle, void *buffer, size_t size)
57{
58 struct mu_stream_handle *mhp = handle;
59 size_t nread;
60 int rc;
61
62 rc = mu_stream_read (mhp->str, buffer, size, mhp->off, &nread);
63 if (rc)
64 {
65 logmsg (LOG_ERR, "mu_stream_read: %s", mu_strerror (rc));
66 errno = EIO;
67 return -1;
68 }
69
70 mhp->off += nread;
71 return nread;
72}
73
74static int
75gpg_sign (gpgme_data_t *output, gpgme_data_t input, const char *sign_keys)
76{
77 gpgme_ctx_t ctx;
78 gpgme_error_t err = 0;
79 gpgme_key_t key;
80
81 err = gpgme_new (&ctx);
82 if (err)
83 {
84 logmsg (LOG_ERR, _("GPGME: cannot create context: %s"),
85 gpgme_strerror (err));
86 return 1;
87 }
88
89 err = gpgme_op_keylist_start (ctx, sign_keys, 0);
90 if (!err)
91 {
92 while ((err = gpgme_op_keylist_next (ctx, &key)) == 0)
93 {
94 err = gpgme_signers_add (ctx, key);
95 gpgme_key_release (key);
96 }
97 }
98
99 if (err && gpg_err_code (err) != GPG_ERR_EOF)
100 {
101 logmsg (LOG_ERR, _("GPGME: cannot list keys: %s"),
102 gpgme_strerror (err));
103 gpgme_release (ctx);
104 return 1;
105 }
106
107 err = gpgme_data_new (output);
108 if (err)
109 {
110 logmsg (LOG_ERR, _("%s: GPGME error: %s"),
111 "gpgme_data_new",
112 gpgme_strerror (err));
113 gpgme_release (ctx);
114 return 1;
115 }
116
117 /* FIXME: Passphrase */
118 gpgme_set_textmode (ctx, 1);
119 gpgme_set_armor (ctx, 1);
120
121 err = gpgme_op_sign (ctx, input, *output, GPGME_SIG_MODE_CLEAR);
122 if (err)
123 logmsg (LOG_ERR, _("%s: GPGME error: %s"),
124 "gpgme_op_sign",
125 gpgme_strerror (err));
126#if 0
127 /* FIXME: */
128 else if (debug_level > 1)
129 gpgme_debug_info (ctx);
130#endif
131
132 gpgme_release (ctx);
133 return err != 0;
134}
135
136static int
137sign_message (mu_message_t *pmsg, const char *key)
138{
139 mu_message_t msg = *pmsg;
140 mu_message_t newmsg;
141 mu_body_t body;
142 mu_header_t hdr;
143 struct mu_stream_handle mhn;
144 mu_stream_t istr, ostr;
145 int rc;
146 struct gpgme_data_cbs cbs;
147 gpgme_data_t input, output;
148 gpgme_error_t err;
149 char *buf = NULL;
150 size_t size = 0;
151 size_t nread;
152
153 if (debug_level)
154 logmsg (LOG_DEBUG, _("signing message as %s"), key);
155
156 if (wydawca_gpg_homedir)
157 {
158 if (debug_level > 1)