~ubuntu-branches/ubuntu/oneiric/heirloom-mailx/oneiric

« back to all changes in this revision

Viewing changes to ssl.c

  • Committer: Bazaar Package Importer
  • Author(s): Hilko Bengen
  • Date: 2008-02-18 20:45:00 UTC
  • Revision ID: james.westby@ubuntu.com-20080218204500-ezficstzczzr7v19
Tags: upstream-12.3
ImportĀ upstreamĀ versionĀ 12.3

Show diffs side-by-side

added added

removed removed

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