diff options
Diffstat (limited to 'src/monkey/mail_sender.c')
-rw-r--r-- | src/monkey/mail_sender.c | 235 |
1 files changed, 235 insertions, 0 deletions
diff --git a/src/monkey/mail_sender.c b/src/monkey/mail_sender.c new file mode 100644 index 000000000..ff5d13e47 --- /dev/null +++ b/src/monkey/mail_sender.c | |||
@@ -0,0 +1,235 @@ | |||
1 | #include <stdio.h> | ||
2 | #include <stdlib.h> | ||
3 | #include <ctype.h> | ||
4 | #include <unistd.h> | ||
5 | #include <getopt.h> | ||
6 | #include <string.h> | ||
7 | #include <fcntl.h> | ||
8 | #include <signal.h> | ||
9 | #include <errno.h> | ||
10 | #include <stdarg.h> | ||
11 | |||
12 | #include <openssl/ssl.h> | ||
13 | #include <auth-client.h> | ||
14 | #include <libesmtp.h> | ||
15 | |||
16 | #if !defined (__GNUC__) || __GNUC__ < 2 | ||
17 | # define __attribute__(x) | ||
18 | #endif | ||
19 | #define unused __attribute__((unused)) | ||
20 | |||
21 | |||
22 | int | ||
23 | handle_invalid_peer_certificate(long vfy_result) | ||
24 | { | ||
25 | const char *k ="rare error"; | ||
26 | switch(vfy_result) { | ||
27 | case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: | ||
28 | k="X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT"; break; | ||
29 | case X509_V_ERR_UNABLE_TO_GET_CRL: | ||
30 | k="X509_V_ERR_UNABLE_TO_GET_CRL"; break; | ||
31 | case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE: | ||
32 | k="X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE"; break; | ||
33 | case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE: | ||
34 | k="X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE"; break; | ||
35 | case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY: | ||
36 | k="X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY"; break; | ||
37 | case X509_V_ERR_CERT_SIGNATURE_FAILURE: | ||
38 | k="X509_V_ERR_CERT_SIGNATURE_FAILURE"; break; | ||
39 | case X509_V_ERR_CRL_SIGNATURE_FAILURE: | ||
40 | k="X509_V_ERR_CRL_SIGNATURE_FAILURE"; break; | ||
41 | case X509_V_ERR_CERT_NOT_YET_VALID: | ||
42 | k="X509_V_ERR_CERT_NOT_YET_VALID"; break; | ||
43 | case X509_V_ERR_CERT_HAS_EXPIRED: | ||
44 | k="X509_V_ERR_CERT_HAS_EXPIRED"; break; | ||
45 | case X509_V_ERR_CRL_NOT_YET_VALID: | ||
46 | k="X509_V_ERR_CRL_NOT_YET_VALID"; break; | ||
47 | case X509_V_ERR_CRL_HAS_EXPIRED: | ||
48 | k="X509_V_ERR_CRL_HAS_EXPIRED"; break; | ||
49 | case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: | ||
50 | k="X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD"; break; | ||
51 | case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: | ||
52 | k="X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD"; break; | ||
53 | case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD: | ||
54 | k="X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD"; break; | ||
55 | case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD: | ||
56 | k="X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD"; break; | ||
57 | case X509_V_ERR_OUT_OF_MEM: | ||
58 | k="X509_V_ERR_OUT_OF_MEM"; break; | ||
59 | case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: | ||
60 | k="X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT"; break; | ||
61 | case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: | ||
62 | k="X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN"; break; | ||
63 | case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: | ||
64 | k="X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY"; break; | ||
65 | case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE: | ||
66 | k="X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE"; break; | ||
67 | case X509_V_ERR_CERT_CHAIN_TOO_LONG: | ||
68 | k="X509_V_ERR_CERT_CHAIN_TOO_LONG"; break; | ||
69 | case X509_V_ERR_CERT_REVOKED: | ||
70 | k="X509_V_ERR_CERT_REVOKED"; break; | ||
71 | case X509_V_ERR_INVALID_CA: | ||
72 | k="X509_V_ERR_INVALID_CA"; break; | ||
73 | case X509_V_ERR_PATH_LENGTH_EXCEEDED: | ||
74 | k="X509_V_ERR_PATH_LENGTH_EXCEEDED"; break; | ||
75 | case X509_V_ERR_INVALID_PURPOSE: | ||
76 | k="X509_V_ERR_INVALID_PURPOSE"; break; | ||
77 | case X509_V_ERR_CERT_UNTRUSTED: | ||
78 | k="X509_V_ERR_CERT_UNTRUSTED"; break; | ||
79 | case X509_V_ERR_CERT_REJECTED: | ||
80 | k="X509_V_ERR_CERT_REJECTED"; break; | ||
81 | } | ||
82 | printf("SMTP_EV_INVALID_PEER_CERTIFICATE: %ld: %s\n", vfy_result, k); | ||
83 | return 1; /* Accept the problem */ | ||
84 | } | ||
85 | |||
86 | |||
87 | void event_cb (smtp_session_t session, int event_no, void *arg,...) | ||
88 | { | ||
89 | va_list alist; | ||
90 | int *ok; | ||
91 | |||
92 | va_start(alist, arg); | ||
93 | switch(event_no) { | ||
94 | case SMTP_EV_CONNECT: | ||
95 | case SMTP_EV_MAILSTATUS: | ||
96 | case SMTP_EV_RCPTSTATUS: | ||
97 | case SMTP_EV_MESSAGEDATA: | ||
98 | case SMTP_EV_MESSAGESENT: | ||
99 | case SMTP_EV_DISCONNECT: break; | ||
100 | case SMTP_EV_WEAK_CIPHER: { | ||
101 | int bits; | ||
102 | bits = va_arg(alist, long); ok = va_arg(alist, int*); | ||
103 | printf("SMTP_EV_WEAK_CIPHER, bits=%d - accepted.\n", bits); | ||
104 | *ok = 1; break; | ||
105 | } | ||
106 | case SMTP_EV_STARTTLS_OK: | ||
107 | puts("SMTP_EV_STARTTLS_OK - TLS started here."); break; | ||
108 | case SMTP_EV_INVALID_PEER_CERTIFICATE: { | ||
109 | long vfy_result; | ||
110 | vfy_result = va_arg(alist, long); ok = va_arg(alist, int*); | ||
111 | *ok = handle_invalid_peer_certificate(vfy_result); | ||
112 | break; | ||
113 | } | ||
114 | case SMTP_EV_NO_PEER_CERTIFICATE: { | ||
115 | ok = va_arg(alist, int*); | ||
116 | puts("SMTP_EV_NO_PEER_CERTIFICATE - accepted."); | ||
117 | *ok = 1; break; | ||
118 | } | ||
119 | case SMTP_EV_WRONG_PEER_CERTIFICATE: { | ||
120 | ok = va_arg(alist, int*); | ||
121 | puts("SMTP_EV_WRONG_PEER_CERTIFICATE - accepted."); | ||
122 | *ok = 1; break; | ||
123 | } | ||
124 | case SMTP_EV_NO_CLIENT_CERTIFICATE: { | ||
125 | ok = va_arg(alist, int*); | ||
126 | puts("SMTP_EV_NO_CLIENT_CERTIFICATE - accepted."); | ||
127 | *ok = 1; break; | ||
128 | } | ||
129 | default: | ||
130 | printf("Got event: %d - ignored.\n", event_no); | ||
131 | } | ||
132 | va_end(alist); | ||
133 | } | ||
134 | |||
135 | |||
136 | /* Callback to prnt the recipient status */ | ||
137 | void | ||
138 | print_recipient_status (smtp_recipient_t recipient, | ||
139 | const char *mailbox, void *arg unused) | ||
140 | { | ||
141 | const smtp_status_t *status; | ||
142 | |||
143 | status = smtp_recipient_status (recipient); | ||
144 | printf ("%s: %d %s", mailbox, status->code, status->text); | ||
145 | } | ||
146 | |||
147 | |||
148 | void sendMail() | ||
149 | { | ||
150 | smtp_session_t session; | ||
151 | smtp_message_t message; | ||
152 | smtp_recipient_t recipient; | ||
153 | auth_context_t authctx; | ||
154 | const smtp_status_t *status; | ||
155 | struct sigaction sa; | ||
156 | char *host = "localhost:25"; | ||
157 | char *from = "gnunet-monkey"; | ||
158 | char *subject = "e-mail from Libesmtp!"; | ||
159 | const char *recipient_address = "halims@in.tum.de"; | ||
160 | char tempFileName[1000]; | ||
161 | int tempFd; | ||
162 | FILE *fp; | ||
163 | enum notify_flags notify = Notify_SUCCESS | Notify_FAILURE; | ||
164 | |||
165 | auth_client_init(); | ||
166 | session = smtp_create_session(); | ||
167 | message = smtp_add_message(session); | ||
168 | |||
169 | /* Ignore sigpipe */ | ||
170 | sa.sa_handler = SIG_IGN; | ||
171 | sigemptyset(&sa.sa_mask); | ||
172 | sa.sa_flags = 0; | ||
173 | sigaction(SIGPIPE, &sa, NULL); | ||
174 | |||
175 | |||
176 | smtp_set_server(session, host); | ||
177 | smtp_set_eventcb(session, event_cb, NULL); | ||
178 | |||
179 | /* Set the reverse path for the mail envelope. (NULL is ok) | ||
180 | */ | ||
181 | smtp_set_reverse_path(message, from); | ||
182 | |||
183 | /* Set the Subject: header. For no reason, we want the supplied subject | ||
184 | to override any subject line in the message headers. */ | ||
185 | if (subject != NULL) { | ||
186 | smtp_set_header(message, "Subject", subject); | ||
187 | smtp_set_header_option(message, "Subject", Hdr_OVERRIDE, 1); | ||
188 | } | ||
189 | |||
190 | |||
191 | /* Prepare message */ | ||
192 | memset(tempFileName, 0, sizeof(tempFileName)); | ||
193 | sprintf(tempFileName, "/tmp/messageXXXXXX"); | ||
194 | tempFd = mkstemp(tempFileName); | ||
195 | fp = fdopen(tempFd, "w"); | ||
196 | fprintf(fp, "Hello! This is a test message!\r\n"); | ||
197 | fclose(fp); | ||
198 | fp = fopen(tempFileName, "r"); | ||
199 | smtp_set_message_fp(message, fp); | ||
200 | |||
201 | |||
202 | recipient = smtp_add_recipient(message, recipient_address); | ||
203 | |||
204 | smtp_dsn_set_notify (recipient, notify); | ||
205 | |||
206 | /* Initiate a connection to the SMTP server and transfer the | ||
207 | message. */ | ||
208 | if (!smtp_start_session(session)) { | ||
209 | char buf[128]; | ||
210 | |||
211 | fprintf(stderr, "SMTP server problem %s\n", smtp_strerror(smtp_errno(), | ||
212 | buf, sizeof buf)); | ||
213 | } else { | ||
214 | /* Report on the success or otherwise of the mail transfer. | ||
215 | */ | ||
216 | status = smtp_message_transfer_status(message); | ||
217 | printf("%d %s", status->code, (status->text != NULL) ? status->text | ||
218 | : "\n"); | ||
219 | smtp_enumerate_recipients(message, print_recipient_status, NULL); | ||
220 | } | ||
221 | |||
222 | /* Free resources consumed by the program. | ||
223 | */ | ||
224 | smtp_destroy_session(session); | ||
225 | auth_destroy_context(authctx); | ||
226 | fclose(fp); | ||
227 | auth_client_exit(); | ||
228 | exit(0); | ||
229 | } | ||
230 | |||
231 | int main() | ||
232 | { | ||
233 | sendMail(); | ||
234 | return 0; | ||
235 | } | ||