ssl.c: fix compiler warnings
[s-mailx.git] / ssl.c
blob25fa3d17fce95e99c33af18f75ec24a96ae0081e
1 /*
2 * Heirloom mailx - a mail user agent derived from Berkeley Mail.
4 * Copyright (c) 2000-2004 Gunnar Ritter, Freiburg i. Br., Germany.
5 * Copyright (c) 2012 Steffen "Daode" Nurpmeso.
6 */
7 /*
8 * Copyright (c) 2002
9 * Gunnar Ritter. All rights reserved.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. All advertising materials mentioning features or use of this software
20 * must display the following acknowledgement:
21 * This product includes software developed by Gunnar Ritter
22 * and his contributors.
23 * 4. Neither the name of Gunnar Ritter nor the names of his contributors
24 * may be used to endorse or promote products derived from this software
25 * without specific prior written permission.
27 * THIS SOFTWARE IS PROVIDED BY GUNNAR RITTER AND CONTRIBUTORS ``AS IS'' AND
28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 * ARE DISCLAIMED. IN NO EVENT SHALL GUNNAR RITTER OR CONTRIBUTORS BE LIABLE
31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 * SUCH DAMAGE.
40 #ifndef lint
41 #ifdef DOSCCS
42 static char sccsid[] = "@(#)ssl.c 1.39 (gritter) 6/12/06";
43 #endif
44 #endif /* not lint */
46 #include "config.h"
48 #ifndef USE_SSL
49 typedef int avoid_empty_file_compiler_warning;
50 #else
52 #include "rcv.h"
53 #include "extern.h"
55 void
56 ssl_set_vrfy_level(const char *uhp)
58 char *cp;
59 char *vrvar;
61 ssl_vrfy_level = VRFY_ASK;
62 vrvar = ac_alloc(strlen(uhp) + 12);
63 strcpy(vrvar, "ssl-verify-");
64 strcpy(&vrvar[11], uhp);
65 if ((cp = value(vrvar)) == NULL)
66 cp = value("ssl-verify");
67 ac_free(vrvar);
68 if (cp != NULL) {
69 if (equal(cp, "strict"))
70 ssl_vrfy_level = VRFY_STRICT;
71 else if (equal(cp, "ask"))
72 ssl_vrfy_level = VRFY_ASK;
73 else if (equal(cp, "warn"))
74 ssl_vrfy_level = VRFY_WARN;
75 else if (equal(cp, "ignore"))
76 ssl_vrfy_level = VRFY_IGNORE;
77 else
78 fprintf(stderr, catgets(catd, CATSET, 265,
79 "invalid value of ssl-verify: %s\n"),
80 cp);
84 enum okay
85 ssl_vrfy_decide(void)
87 enum okay ok = STOP;
89 switch (ssl_vrfy_level) {
90 case VRFY_STRICT:
91 ok = STOP;
92 break;
93 case VRFY_ASK:
95 char *line = NULL;
96 size_t linesize = 0;
98 fprintf(stderr, catgets(catd, CATSET, 264,
99 "Continue (y/n)? "));
100 if (readline(stdin, &line, &linesize) > 0 &&
101 *line == 'y')
102 ok = OKAY;
103 else
104 ok = STOP;
105 if (line)
106 free(line);
108 break;
109 case VRFY_WARN:
110 case VRFY_IGNORE:
111 ok = OKAY;
113 return ok;
116 char *
117 ssl_method_string(const char *uhp)
119 char *cp, *mtvar;
121 mtvar = ac_alloc(strlen(uhp) + 12);
122 strcpy(mtvar, "ssl-method-");
123 strcpy(&mtvar[11], uhp);
124 if ((cp = value(mtvar)) == NULL)
125 cp = value("ssl-method");
126 ac_free(mtvar);
127 return cp;
130 enum okay
131 smime_split(FILE *ip, FILE **hp, FILE **bp, long xcount, int keep)
133 char *buf, *hn, *bn;
134 char *savedfields = NULL;
135 size_t bufsize, buflen, count, savedsize = 0;
136 int c;
138 if ((*hp = Ftemp(&hn, "Rh", "w+", 0600, 1)) == NULL ||
139 (*bp = Ftemp(&bn, "Rb", "w+", 0600, 1)) == NULL) {
140 perror("tempfile");
141 return STOP;
143 rm(hn);
144 rm(bn);
145 Ftfree(&hn);
146 Ftfree(&bn);
147 buf = smalloc(bufsize = LINESIZE);
148 savedfields = smalloc(savedsize = 1);
149 *savedfields = '\0';
150 if (xcount < 0)
151 count = fsize(ip);
152 else
153 count = xcount;
154 while (fgetline(&buf, &bufsize, &count, &buflen, ip, 0) != NULL &&
155 *buf != '\n') {
156 if (ascncasecmp(buf, "content-", 8) == 0) {
157 if (keep)
158 fputs("X-Encoded-", *hp);
159 for (;;) {
160 savedsize += buflen;
161 savedfields = srealloc(savedfields, savedsize);
162 strcat(savedfields, buf);
163 if (keep)
164 fwrite(buf, sizeof *buf, buflen, *hp);
165 c = getc(ip);
166 ungetc(c, ip);
167 if (!blankchar(c))
168 break;
169 fgetline(&buf, &bufsize, &count, &buflen,
170 ip, 0);
172 continue;
174 fwrite(buf, sizeof *buf, buflen, *hp);
176 fflush(*hp);
177 rewind(*hp);
178 fputs(savedfields, *bp);
179 putc('\n', *bp);
180 while (fgetline(&buf, &bufsize, &count, &buflen, ip, 0) != NULL)
181 fwrite(buf, sizeof *buf, buflen, *bp);
182 fflush(*bp);
183 rewind(*bp);
184 free(buf);
185 return OKAY;
188 FILE *
189 smime_sign_assemble(FILE *hp, FILE *bp, FILE *sp)
191 char *boundary, *cp;
192 FILE *op;
193 int c, lastc = EOF;
195 if ((op = Ftemp(&cp, "Rs", "w+", 0600, 1)) == NULL) {
196 perror("tempfile");
197 return NULL;
199 rm(cp);
200 Ftfree(&cp);
201 boundary = makeboundary();
202 while ((c = getc(hp)) != EOF) {
203 if (c == '\n' && lastc == '\n')
204 break;
205 putc(c, op);
206 lastc = c;
208 fprintf(op, "Content-Type: multipart/signed;\n"
209 " protocol=\"application/x-pkcs7-signature\"; micalg=sha1;\n"
210 " boundary=\"%s\"\n\n", boundary);
211 fprintf(op, "This is an S/MIME signed message.\n\n--%s\n",
212 boundary);
213 while ((c = getc(bp)) != EOF)
214 putc(c, op);
215 fprintf(op, "\n--%s\n", boundary);
216 fputs("Content-Type: application/x-pkcs7-signature; "
217 "name=\"smime.p7s\"\n"
218 "Content-Transfer-Encoding: base64\n"
219 "Content-Disposition: attachment; filename=\"smime.p7s\"\n\n",
220 op);
221 while ((c = getc(sp)) != EOF) {
222 if (c == '-') {
223 while ((c = getc(sp)) != EOF && c != '\n');
224 continue;
226 putc(c, op);
228 fprintf(op, "\n--%s--\n", boundary);
229 Fclose(hp);
230 Fclose(bp);
231 Fclose(sp);
232 fflush(op);
233 if (ferror(op)) {
234 perror("signed output data");
235 Fclose(op);
236 return NULL;
238 rewind(op);
239 return op;
242 FILE *
243 smime_encrypt_assemble(FILE *hp, FILE *yp)
245 char *cp;
246 FILE *op;
247 int c, lastc = EOF;
249 if ((op = Ftemp(&cp, "Rs", "w+", 0600, 1)) == NULL) {
250 perror("tempfile");
251 return NULL;
253 rm(cp);
254 Ftfree(&cp);
255 while ((c = getc(hp)) != EOF) {
256 if (c == '\n' && lastc == '\n')
257 break;
258 putc(c, op);
259 lastc = c;
261 fprintf(op, "Content-Type: application/x-pkcs7-mime; "
262 "name=\"smime.p7m\"\n"
263 "Content-Transfer-Encoding: base64\n"
264 "Content-Disposition: attachment; "
265 "filename=\"smime.p7m\"\n\n");
266 while ((c = getc(yp)) != EOF) {
267 if (c == '-') {
268 while ((c = getc(yp)) != EOF && c != '\n');
269 continue;
271 putc(c, op);
273 Fclose(hp);
274 Fclose(yp);
275 fflush(op);
276 if (ferror(op)) {
277 perror("encrypted output data");
278 Fclose(op);
279 return NULL;
281 rewind(op);
282 return op;
285 struct message *
286 smime_decrypt_assemble(struct message *m, FILE *hp, FILE *bp)
288 int binary = 0, lastnl = 0;
289 char *buf = NULL, *cp;
290 size_t bufsize = 0, buflen, count;
291 long lines = 0, octets = 0;
292 struct message *x;
293 off_t offset;
295 x = salloc(sizeof *x);
296 *x = *m;
297 fflush(mb.mb_otf);
298 fseek(mb.mb_otf, 0L, SEEK_END);
299 offset = ftell(mb.mb_otf);
300 count = fsize(hp);
301 while (fgetline(&buf, &bufsize, &count, &buflen, hp, 0) != NULL) {
302 if (buf[0] == '\n')
303 break;
304 if ((cp = thisfield(buf, "content-transfer-encoding")) != NULL)
305 if (ascncasecmp(cp, "binary", 7) == 0)
306 binary = 1;
307 fwrite(buf, sizeof *buf, buflen, mb.mb_otf);
308 octets += buflen;
309 lines++;
311 octets += mkdate(mb.mb_otf, "X-Decoding-Date");
312 lines++;
313 count = fsize(bp);
314 while (fgetline(&buf, &bufsize, &count, &buflen, bp, 0) != NULL) {
315 lines++;
316 if (!binary && buf[buflen-1] == '\n' && buf[buflen-2] == '\r')
317 buf[--buflen-1] = '\n';
318 fwrite(buf, sizeof *buf, buflen, mb.mb_otf);
319 octets += buflen;
320 if (buf[0] == '\n')
321 lastnl++;
322 else if (buf[buflen-1] == '\n')
323 lastnl = 1;
324 else
325 lastnl = 0;
327 while (!binary && lastnl < 2) {
328 putc('\n', mb.mb_otf);
329 lines++;
330 octets++;
331 lastnl++;
333 Fclose(hp);
334 Fclose(bp);
335 free(buf);
336 fflush(mb.mb_otf);
337 if (ferror(mb.mb_otf)) {
338 perror("decrypted output data");
339 return NULL;
341 x->m_size = x->m_xsize = octets;
342 x->m_lines = x->m_xlines = lines;
343 x->m_block = mailx_blockof(offset);
344 x->m_offset = mailx_offsetof(offset);
345 return x;
348 int
349 ccertsave(void *v)
351 int *ip;
352 int f, *msgvec;
353 char *file = NULL, *str = v;
354 int val = 0;
355 FILE *fp;
357 msgvec = salloc((msgCount + 2) * sizeof *msgvec);
358 if ((file = laststring(str, &f, 1)) == NULL) {
359 fprintf(stderr, "No file to save certificate given.\n");
360 return 1;
362 if (!f) {
363 *msgvec = first(0, MMNORM);
364 if (*msgvec == 0) {
365 if (inhook)
366 return 0;
367 fprintf(stderr,
368 "No messages to get certificates from.\n");
369 return 1;
371 msgvec[1] = 0;
372 } else if (getmsglist(str, msgvec, 0) < 0)
373 return 1;
374 if (*msgvec == 0) {
375 if (inhook)
376 return 0;
377 fprintf(stderr, "No applicable messages.\n");
378 return 1;
380 if ((fp = Fopen(file, "a")) == NULL) {
381 perror(file);
382 return 1;
384 for (ip = msgvec; *ip && ip-msgvec < msgCount; ip++)
385 if (smime_certsave(&message[*ip-1], *ip, fp) != OKAY)
386 val = 1;
387 Fclose(fp);
388 if (val == 0)
389 printf("Certificate(s) saved.\n");
390 return val;
392 enum okay
393 rfc2595_hostname_match(const char *host, const char *pattern)
395 if (pattern[0] == '*' && pattern[1] == '.') {
396 pattern++;
397 while (*host && *host != '.')
398 host++;
400 return asccasecmp(host, pattern) == 0 ? OKAY : STOP;
402 #endif /* USE_SSL */