Deleted Added
full compact
sfsasl.c (203004) sfsasl.c (249729)
1/*
2 * Copyright (c) 1999-2006, 2008 Sendmail, Inc. and its suppliers.
3 * All rights reserved.
4 *
5 * By using this file, you agree to the terms and conditions set
6 * forth in the LICENSE file which can be found at the top level of
7 * the sendmail distribution.
8 *
9 */
10
11#include <sm/gen.h>
1/*
2 * Copyright (c) 1999-2006, 2008 Sendmail, Inc. and its suppliers.
3 * All rights reserved.
4 *
5 * By using this file, you agree to the terms and conditions set
6 * forth in the LICENSE file which can be found at the top level of
7 * the sendmail distribution.
8 *
9 */
10
11#include <sm/gen.h>
12SM_RCSID("@(#)$Id: sfsasl.c,v 8.118 2008/07/22 15:12:48 ca Exp $")
12SM_RCSID("@(#)$Id: sfsasl.c,v 8.120 2013/03/15 17:49:12 guenther Exp $")
13#include <stdlib.h>
14#include <sendmail.h>
15#include <sm/time.h>
16#include <errno.h>
17
18/* allow to disable error handling code just in case... */
19#ifndef DEAL_WITH_ERROR_SSL
20# define DEAL_WITH_ERROR_SSL 1
21#endif /* ! DEAL_WITH_ERROR_SSL */
22
23#if SASL
24# include "sfsasl.h"
25
26/* Structure used by the "sasl" file type */
27struct sasl_obj
28{
29 SM_FILE_T *fp;
30 sasl_conn_t *conn;
31};
32
33struct sasl_info
34{
35 SM_FILE_T *fp;
36 sasl_conn_t *conn;
37};
38
39/*
40** SASL_GETINFO - returns requested information about a "sasl" file
41** descriptor.
42**
43** Parameters:
44** fp -- the file descriptor
45** what -- the type of information requested
46** valp -- the thang to return the information in
47**
48** Returns:
49** -1 for unknown requests
50** >=0 on success with valp filled in (if possible).
51*/
52
53static int sasl_getinfo __P((SM_FILE_T *, int, void *));
54
55static int
56sasl_getinfo(fp, what, valp)
57 SM_FILE_T *fp;
58 int what;
59 void *valp;
60{
61 struct sasl_obj *so = (struct sasl_obj *) fp->f_cookie;
62
63 switch (what)
64 {
65 case SM_IO_WHAT_FD:
66 if (so->fp == NULL)
67 return -1;
68 return so->fp->f_file; /* for stdio fileno() compatability */
69
70 case SM_IO_IS_READABLE:
71 if (so->fp == NULL)
72 return 0;
73
74 /* get info from underlying file */
75 return sm_io_getinfo(so->fp, what, valp);
76
77 default:
78 return -1;
79 }
80}
81
82/*
83** SASL_OPEN -- creates the sasl specific information for opening a
84** file of the sasl type.
85**
86** Parameters:
87** fp -- the file pointer associated with the new open
88** info -- contains the sasl connection information pointer and
89** the original SM_FILE_T that holds the open
90** flags -- ignored
91** rpool -- ignored
92**
93** Returns:
94** 0 on success
95*/
96
97static int sasl_open __P((SM_FILE_T *, const void *, int, const void *));
98
99/* ARGSUSED2 */
100static int
101sasl_open(fp, info, flags, rpool)
102 SM_FILE_T *fp;
103 const void *info;
104 int flags;
105 const void *rpool;
106{
107 struct sasl_obj *so;
108 struct sasl_info *si = (struct sasl_info *) info;
109
110 so = (struct sasl_obj *) sm_malloc(sizeof(struct sasl_obj));
111 if (so == NULL)
112 {
113 errno = ENOMEM;
114 return -1;
115 }
116 so->fp = si->fp;
117 so->conn = si->conn;
118
119 /*
120 ** The underlying 'fp' is set to SM_IO_NOW so that the entire
121 ** encoded string is written in one chunk. Otherwise there is
122 ** the possibility that it may appear illegal, bogus or
123 ** mangled to the other side of the connection.
124 ** We will read or write through 'fp' since it is the opaque
125 ** connection for the communications. We need to treat it this
126 ** way in case the encoded string is to be sent down a TLS
127 ** connection rather than, say, sm_io's stdio.
128 */
129
130 (void) sm_io_setvbuf(so->fp, SM_TIME_DEFAULT, NULL, SM_IO_NOW, 0);
131 fp->f_cookie = so;
132 return 0;
133}
134
135/*
136** SASL_CLOSE -- close the sasl specific parts of the sasl file pointer
137**
138** Parameters:
139** fp -- the file pointer to close
140**
141** Returns:
142** 0 on success
143*/
144
145static int sasl_close __P((SM_FILE_T *));
146
147static int
148sasl_close(fp)
149 SM_FILE_T *fp;
150{
151 struct sasl_obj *so;
152
153 so = (struct sasl_obj *) fp->f_cookie;
154 if (so == NULL)
155 return 0;
156 if (so->fp != NULL)
157 {
158 sm_io_close(so->fp, SM_TIME_DEFAULT);
159 so->fp = NULL;
160 }
161 sm_free(so);
162 so = NULL;
163 return 0;
164}
165
166/* how to deallocate a buffer allocated by SASL */
167extern void sm_sasl_free __P((void *));
168# define SASL_DEALLOC(b) sm_sasl_free(b)
169
170/*
171** SASL_READ -- read encrypted information and decrypt it for the caller
172**
173** Parameters:
174** fp -- the file pointer
175** buf -- the location to place the decrypted information
176** size -- the number of bytes to read after decryption
177**
178** Results:
179** -1 on error
180** otherwise the number of bytes read
181*/
182
183static ssize_t sasl_read __P((SM_FILE_T *, char *, size_t));
184
185static ssize_t
186sasl_read(fp, buf, size)
187 SM_FILE_T *fp;
188 char *buf;
189 size_t size;
190{
191 int result;
192 ssize_t len;
193# if SASL >= 20000
194 static const char *outbuf = NULL;
195# else /* SASL >= 20000 */
196 static char *outbuf = NULL;
197# endif /* SASL >= 20000 */
198 static unsigned int outlen = 0;
199 static unsigned int offset = 0;
200 struct sasl_obj *so = (struct sasl_obj *) fp->f_cookie;
201
202 /*
203 ** sasl_decode() may require more data than a single read() returns.
204 ** Hence we have to put a loop around the decoding.
205 ** This also requires that we may have to split up the returned
206 ** data since it might be larger than the allowed size.
207 ** Therefore we use a static pointer and return portions of it
208 ** if necessary.
209 ** XXX Note: This function is not thread-safe nor can it be used
210 ** on more than one file. A correct implementation would store
211 ** this data in fp->f_cookie.
212 */
213
214# if SASL >= 20000
215 while (outlen == 0)
216# else /* SASL >= 20000 */
217 while (outbuf == NULL && outlen == 0)
218# endif /* SASL >= 20000 */
219 {
220 len = sm_io_read(so->fp, SM_TIME_DEFAULT, buf, size);
221 if (len <= 0)
222 return len;
223 result = sasl_decode(so->conn, buf,
224 (unsigned int) len, &outbuf, &outlen);
225 if (result != SASL_OK)
226 {
227 if (LogLevel > 7)
228 sm_syslog(LOG_WARNING, NOQID,
229 "AUTH: sasl_decode error=%d", result);
230 outbuf = NULL;
231 offset = 0;
232 outlen = 0;
233 return -1;
234 }
235 }
236
237 if (outbuf == NULL)
238 {
239 /* be paranoid: outbuf == NULL but outlen != 0 */
240 syserr("@sasl_read failure: outbuf == NULL but outlen != 0");
241 /* NOTREACHED */
242 }
243 if (outlen - offset > size)
244 {
245 /* return another part of the buffer */
246 (void) memcpy(buf, outbuf + offset, size);
247 offset += size;
248 len = size;
249 }
250 else
251 {
252 /* return the rest of the buffer */
253 len = outlen - offset;
254 (void) memcpy(buf, outbuf + offset, (size_t) len);
255# if SASL < 20000
256 SASL_DEALLOC(outbuf);
257# endif /* SASL < 20000 */
258 outbuf = NULL;
259 offset = 0;
260 outlen = 0;
261 }
262 return len;
263}
264
265/*
266** SASL_WRITE -- write information out after encrypting it
267**
268** Parameters:
269** fp -- the file pointer
270** buf -- holds the data to be encrypted and written
271** size -- the number of bytes to have encrypted and written
272**
273** Returns:
274** -1 on error
275** otherwise number of bytes written
276*/
277
278static ssize_t sasl_write __P((SM_FILE_T *, const char *, size_t));
279
280static ssize_t
281sasl_write(fp, buf, size)
282 SM_FILE_T *fp;
283 const char *buf;
284 size_t size;
285{
286 int result;
287# if SASL >= 20000
288 const char *outbuf;
289# else /* SASL >= 20000 */
290 char *outbuf;
291# endif /* SASL >= 20000 */
292 unsigned int outlen, *maxencode;
293 size_t ret = 0, total = 0;
294 struct sasl_obj *so = (struct sasl_obj *) fp->f_cookie;
295
296 /*
297 ** Fetch the maximum input buffer size for sasl_encode().
298 ** This can be less than the size set in attemptauth()
299 ** due to a negotiation with the other side, e.g.,
300 ** Cyrus IMAP lmtp program sets maxbuf=4096,
301 ** digestmd5 substracts 25 and hence we'll get 4071
302 ** instead of 8192 (MAXOUTLEN).
303 ** Hack (for now): simply reduce the size, callers are (must be)
304 ** able to deal with that and invoke sasl_write() again with
305 ** the rest of the data.
306 ** Note: it would be better to store this value in the context
307 ** after the negotiation.
308 */
309
310 result = sasl_getprop(so->conn, SASL_MAXOUTBUF,
311 (const void **) &maxencode);
312 if (result == SASL_OK && size > *maxencode && *maxencode > 0)
313 size = *maxencode;
314
315 result = sasl_encode(so->conn, buf,
316 (unsigned int) size, &outbuf, &outlen);
317
318 if (result != SASL_OK)
319 {
320 if (LogLevel > 7)
321 sm_syslog(LOG_WARNING, NOQID,
322 "AUTH: sasl_encode error=%d", result);
323 return -1;
324 }
325
326 if (outbuf != NULL)
327 {
328 while (outlen > 0)
329 {
330 errno = 0;
331 /* XXX result == 0? */
332 ret = sm_io_write(so->fp, SM_TIME_DEFAULT,
333 &outbuf[total], outlen);
334 if (ret <= 0)
335 return ret;
336 outlen -= ret;
337 total += ret;
338 }
339# if SASL < 20000
340 SASL_DEALLOC(outbuf);
341# endif /* SASL < 20000 */
342 }
343 return size;
344}
345
346/*
347** SFDCSASL -- create sasl file type and open in and out file pointers
348** for sendmail to read from and write to.
349**
350** Parameters:
351** fin -- the sm_io file encrypted data to be read from
352** fout -- the sm_io file encrypted data to be written to
353** conn -- the sasl connection pointer
354** tmo -- timeout
355**
356** Returns:
357** -1 on error
358** 0 on success
359**
360** Side effects:
361** The arguments "fin" and "fout" are replaced with the new
362** SM_FILE_T pointers.
363*/
364
365int
366sfdcsasl(fin, fout, conn, tmo)
367 SM_FILE_T **fin;
368 SM_FILE_T **fout;
369 sasl_conn_t *conn;
370 int tmo;
371{
372 SM_FILE_T *newin, *newout;
373 SM_FILE_T SM_IO_SET_TYPE(sasl_vector, "sasl", sasl_open, sasl_close,
374 sasl_read, sasl_write, NULL, sasl_getinfo, NULL,
375 SM_TIME_DEFAULT);
376 struct sasl_info info;
377
378 if (conn == NULL)
379 {
380 /* no need to do anything */
381 return 0;
382 }
383
384 SM_IO_INIT_TYPE(sasl_vector, "sasl", sasl_open, sasl_close,
385 sasl_read, sasl_write, NULL, sasl_getinfo, NULL,
386 SM_TIME_DEFAULT);
387 info.fp = *fin;
388 info.conn = conn;
389 newin = sm_io_open(&sasl_vector, SM_TIME_DEFAULT, &info,
390 SM_IO_RDONLY_B, NULL);
391
392 if (newin == NULL)
393 return -1;
394
395 info.fp = *fout;
396 info.conn = conn;
397 newout = sm_io_open(&sasl_vector, SM_TIME_DEFAULT, &info,
398 SM_IO_WRONLY_B, NULL);
399
400 if (newout == NULL)
401 {
402 (void) sm_io_close(newin, SM_TIME_DEFAULT);
403 return -1;
404 }
405 sm_io_automode(newin, newout);
406
407 sm_io_setinfo(*fin, SM_IO_WHAT_TIMEOUT, &tmo);
408 sm_io_setinfo(*fout, SM_IO_WHAT_TIMEOUT, &tmo);
409
410 *fin = newin;
411 *fout = newout;
412 return 0;
413}
414#endif /* SASL */
415
416#if STARTTLS
417# include "sfsasl.h"
418# include <openssl/err.h>
419
420/* Structure used by the "tls" file type */
421struct tls_obj
422{
423 SM_FILE_T *fp;
424 SSL *con;
425};
426
427struct tls_info
428{
429 SM_FILE_T *fp;
430 SSL *con;
431};
432
433/*
434** TLS_GETINFO - returns requested information about a "tls" file
435** descriptor.
436**
437** Parameters:
438** fp -- the file descriptor
439** what -- the type of information requested
440** valp -- the thang to return the information in (unused)
441**
442** Returns:
443** -1 for unknown requests
444** >=0 on success with valp filled in (if possible).
445*/
446
447static int tls_getinfo __P((SM_FILE_T *, int, void *));
448
449/* ARGSUSED2 */
450static int
451tls_getinfo(fp, what, valp)
452 SM_FILE_T *fp;
453 int what;
454 void *valp;
455{
456 struct tls_obj *so = (struct tls_obj *) fp->f_cookie;
457
458 switch (what)
459 {
460 case SM_IO_WHAT_FD:
461 if (so->fp == NULL)
462 return -1;
463 return so->fp->f_file; /* for stdio fileno() compatability */
464
465 case SM_IO_IS_READABLE:
466 return SSL_pending(so->con) > 0;
467
468 default:
469 return -1;
470 }
471}
472
473/*
474** TLS_OPEN -- creates the tls specific information for opening a
475** file of the tls type.
476**
477** Parameters:
478** fp -- the file pointer associated with the new open
479** info -- the sm_io file pointer holding the open and the
480** TLS encryption connection to be read from or written to
481** flags -- ignored
482** rpool -- ignored
483**
484** Returns:
485** 0 on success
486*/
487
488static int tls_open __P((SM_FILE_T *, const void *, int, const void *));
489
490/* ARGSUSED2 */
491static int
492tls_open(fp, info, flags, rpool)
493 SM_FILE_T *fp;
494 const void *info;
495 int flags;
496 const void *rpool;
497{
498 struct tls_obj *so;
499 struct tls_info *ti = (struct tls_info *) info;
500
501 so = (struct tls_obj *) sm_malloc(sizeof(struct tls_obj));
502 if (so == NULL)
503 {
504 errno = ENOMEM;
505 return -1;
506 }
507 so->fp = ti->fp;
508 so->con = ti->con;
509
510 /*
511 ** We try to get the "raw" file descriptor that TLS uses to
512 ** do the actual read/write with. This is to allow us control
513 ** over the file descriptor being a blocking or non-blocking type.
514 ** Under the covers TLS handles the change and this allows us
515 ** to do timeouts with sm_io.
516 */
517
518 fp->f_file = sm_io_getinfo(so->fp, SM_IO_WHAT_FD, NULL);
519 (void) sm_io_setvbuf(so->fp, SM_TIME_DEFAULT, NULL, SM_IO_NOW, 0);
520 fp->f_cookie = so;
521 return 0;
522}
523
524/*
525** TLS_CLOSE -- close the tls specific parts of the tls file pointer
526**
527** Parameters:
528** fp -- the file pointer to close
529**
530** Returns:
531** 0 on success
532*/
533
534static int tls_close __P((SM_FILE_T *));
535
536static int
537tls_close(fp)
538 SM_FILE_T *fp;
539{
540 struct tls_obj *so;
541
542 so = (struct tls_obj *) fp->f_cookie;
543 if (so == NULL)
544 return 0;
545 if (so->fp != NULL)
546 {
547 sm_io_close(so->fp, SM_TIME_DEFAULT);
548 so->fp = NULL;
549 }
550 sm_free(so);
551 so = NULL;
552 return 0;
553}
554
555/* maximum number of retries for TLS related I/O due to handshakes */
556# define MAX_TLS_IOS 4
557
558/*
559** TLS_RETRY -- check whether a failed SSL operation can be retried
560**
561** Parameters:
562** ssl -- TLS structure
563** rfd -- read fd
564** wfd -- write fd
565** tlsstart -- start time of TLS operation
566** timeout -- timeout for TLS operation
567** err -- SSL error
568** where -- description of operation
569**
570** Results:
571** >0 on success
572** 0 on timeout
573** <0 on error
574*/
575
576int
577tls_retry(ssl, rfd, wfd, tlsstart, timeout, err, where)
578 SSL *ssl;
579 int rfd;
580 int wfd;
581 time_t tlsstart;
582 int timeout;
583 int err;
584 const char *where;
585{
586 int ret;
587 time_t left;
588 time_t now = curtime();
589 struct timeval tv;
590
591 ret = -1;
592
593 /*
594 ** For SSL_ERROR_WANT_{READ,WRITE}:
595 ** There is not a complete SSL record available yet
596 ** or there is only a partial SSL record removed from
597 ** the network (socket) buffer into the SSL buffer.
598 ** The SSL_connect will only succeed when a full
599 ** SSL record is available (assuming a "real" error
600 ** doesn't happen). To handle when a "real" error
601 ** does happen the select is set for exceptions too.
602 ** The connection may be re-negotiated during this time
603 ** so both read and write "want errors" need to be handled.
604 ** A select() exception loops back so that a proper SSL
605 ** error message can be gotten.
606 */
607
608 left = timeout - (now - tlsstart);
609 if (left <= 0)
610 return 0; /* timeout */
611 tv.tv_sec = left;
612 tv.tv_usec = 0;
613
614 if (LogLevel > 14)
615 {
616 sm_syslog(LOG_INFO, NOQID,
617 "STARTTLS=%s, info: fds=%d/%d, err=%d",
618 where, rfd, wfd, err);
619 }
620
621 if (FD_SETSIZE > 0 &&
622 ((err == SSL_ERROR_WANT_READ && rfd >= FD_SETSIZE) ||
623 (err == SSL_ERROR_WANT_WRITE && wfd >= FD_SETSIZE)))
624 {
625 if (LogLevel > 5)
626 {
627 sm_syslog(LOG_ERR, NOQID,
628 "STARTTLS=%s, error: fd %d/%d too large",
629 where, rfd, wfd);
630 if (LogLevel > 8)
13#include <stdlib.h>
14#include <sendmail.h>
15#include <sm/time.h>
16#include <errno.h>
17
18/* allow to disable error handling code just in case... */
19#ifndef DEAL_WITH_ERROR_SSL
20# define DEAL_WITH_ERROR_SSL 1
21#endif /* ! DEAL_WITH_ERROR_SSL */
22
23#if SASL
24# include "sfsasl.h"
25
26/* Structure used by the "sasl" file type */
27struct sasl_obj
28{
29 SM_FILE_T *fp;
30 sasl_conn_t *conn;
31};
32
33struct sasl_info
34{
35 SM_FILE_T *fp;
36 sasl_conn_t *conn;
37};
38
39/*
40** SASL_GETINFO - returns requested information about a "sasl" file
41** descriptor.
42**
43** Parameters:
44** fp -- the file descriptor
45** what -- the type of information requested
46** valp -- the thang to return the information in
47**
48** Returns:
49** -1 for unknown requests
50** >=0 on success with valp filled in (if possible).
51*/
52
53static int sasl_getinfo __P((SM_FILE_T *, int, void *));
54
55static int
56sasl_getinfo(fp, what, valp)
57 SM_FILE_T *fp;
58 int what;
59 void *valp;
60{
61 struct sasl_obj *so = (struct sasl_obj *) fp->f_cookie;
62
63 switch (what)
64 {
65 case SM_IO_WHAT_FD:
66 if (so->fp == NULL)
67 return -1;
68 return so->fp->f_file; /* for stdio fileno() compatability */
69
70 case SM_IO_IS_READABLE:
71 if (so->fp == NULL)
72 return 0;
73
74 /* get info from underlying file */
75 return sm_io_getinfo(so->fp, what, valp);
76
77 default:
78 return -1;
79 }
80}
81
82/*
83** SASL_OPEN -- creates the sasl specific information for opening a
84** file of the sasl type.
85**
86** Parameters:
87** fp -- the file pointer associated with the new open
88** info -- contains the sasl connection information pointer and
89** the original SM_FILE_T that holds the open
90** flags -- ignored
91** rpool -- ignored
92**
93** Returns:
94** 0 on success
95*/
96
97static int sasl_open __P((SM_FILE_T *, const void *, int, const void *));
98
99/* ARGSUSED2 */
100static int
101sasl_open(fp, info, flags, rpool)
102 SM_FILE_T *fp;
103 const void *info;
104 int flags;
105 const void *rpool;
106{
107 struct sasl_obj *so;
108 struct sasl_info *si = (struct sasl_info *) info;
109
110 so = (struct sasl_obj *) sm_malloc(sizeof(struct sasl_obj));
111 if (so == NULL)
112 {
113 errno = ENOMEM;
114 return -1;
115 }
116 so->fp = si->fp;
117 so->conn = si->conn;
118
119 /*
120 ** The underlying 'fp' is set to SM_IO_NOW so that the entire
121 ** encoded string is written in one chunk. Otherwise there is
122 ** the possibility that it may appear illegal, bogus or
123 ** mangled to the other side of the connection.
124 ** We will read or write through 'fp' since it is the opaque
125 ** connection for the communications. We need to treat it this
126 ** way in case the encoded string is to be sent down a TLS
127 ** connection rather than, say, sm_io's stdio.
128 */
129
130 (void) sm_io_setvbuf(so->fp, SM_TIME_DEFAULT, NULL, SM_IO_NOW, 0);
131 fp->f_cookie = so;
132 return 0;
133}
134
135/*
136** SASL_CLOSE -- close the sasl specific parts of the sasl file pointer
137**
138** Parameters:
139** fp -- the file pointer to close
140**
141** Returns:
142** 0 on success
143*/
144
145static int sasl_close __P((SM_FILE_T *));
146
147static int
148sasl_close(fp)
149 SM_FILE_T *fp;
150{
151 struct sasl_obj *so;
152
153 so = (struct sasl_obj *) fp->f_cookie;
154 if (so == NULL)
155 return 0;
156 if (so->fp != NULL)
157 {
158 sm_io_close(so->fp, SM_TIME_DEFAULT);
159 so->fp = NULL;
160 }
161 sm_free(so);
162 so = NULL;
163 return 0;
164}
165
166/* how to deallocate a buffer allocated by SASL */
167extern void sm_sasl_free __P((void *));
168# define SASL_DEALLOC(b) sm_sasl_free(b)
169
170/*
171** SASL_READ -- read encrypted information and decrypt it for the caller
172**
173** Parameters:
174** fp -- the file pointer
175** buf -- the location to place the decrypted information
176** size -- the number of bytes to read after decryption
177**
178** Results:
179** -1 on error
180** otherwise the number of bytes read
181*/
182
183static ssize_t sasl_read __P((SM_FILE_T *, char *, size_t));
184
185static ssize_t
186sasl_read(fp, buf, size)
187 SM_FILE_T *fp;
188 char *buf;
189 size_t size;
190{
191 int result;
192 ssize_t len;
193# if SASL >= 20000
194 static const char *outbuf = NULL;
195# else /* SASL >= 20000 */
196 static char *outbuf = NULL;
197# endif /* SASL >= 20000 */
198 static unsigned int outlen = 0;
199 static unsigned int offset = 0;
200 struct sasl_obj *so = (struct sasl_obj *) fp->f_cookie;
201
202 /*
203 ** sasl_decode() may require more data than a single read() returns.
204 ** Hence we have to put a loop around the decoding.
205 ** This also requires that we may have to split up the returned
206 ** data since it might be larger than the allowed size.
207 ** Therefore we use a static pointer and return portions of it
208 ** if necessary.
209 ** XXX Note: This function is not thread-safe nor can it be used
210 ** on more than one file. A correct implementation would store
211 ** this data in fp->f_cookie.
212 */
213
214# if SASL >= 20000
215 while (outlen == 0)
216# else /* SASL >= 20000 */
217 while (outbuf == NULL && outlen == 0)
218# endif /* SASL >= 20000 */
219 {
220 len = sm_io_read(so->fp, SM_TIME_DEFAULT, buf, size);
221 if (len <= 0)
222 return len;
223 result = sasl_decode(so->conn, buf,
224 (unsigned int) len, &outbuf, &outlen);
225 if (result != SASL_OK)
226 {
227 if (LogLevel > 7)
228 sm_syslog(LOG_WARNING, NOQID,
229 "AUTH: sasl_decode error=%d", result);
230 outbuf = NULL;
231 offset = 0;
232 outlen = 0;
233 return -1;
234 }
235 }
236
237 if (outbuf == NULL)
238 {
239 /* be paranoid: outbuf == NULL but outlen != 0 */
240 syserr("@sasl_read failure: outbuf == NULL but outlen != 0");
241 /* NOTREACHED */
242 }
243 if (outlen - offset > size)
244 {
245 /* return another part of the buffer */
246 (void) memcpy(buf, outbuf + offset, size);
247 offset += size;
248 len = size;
249 }
250 else
251 {
252 /* return the rest of the buffer */
253 len = outlen - offset;
254 (void) memcpy(buf, outbuf + offset, (size_t) len);
255# if SASL < 20000
256 SASL_DEALLOC(outbuf);
257# endif /* SASL < 20000 */
258 outbuf = NULL;
259 offset = 0;
260 outlen = 0;
261 }
262 return len;
263}
264
265/*
266** SASL_WRITE -- write information out after encrypting it
267**
268** Parameters:
269** fp -- the file pointer
270** buf -- holds the data to be encrypted and written
271** size -- the number of bytes to have encrypted and written
272**
273** Returns:
274** -1 on error
275** otherwise number of bytes written
276*/
277
278static ssize_t sasl_write __P((SM_FILE_T *, const char *, size_t));
279
280static ssize_t
281sasl_write(fp, buf, size)
282 SM_FILE_T *fp;
283 const char *buf;
284 size_t size;
285{
286 int result;
287# if SASL >= 20000
288 const char *outbuf;
289# else /* SASL >= 20000 */
290 char *outbuf;
291# endif /* SASL >= 20000 */
292 unsigned int outlen, *maxencode;
293 size_t ret = 0, total = 0;
294 struct sasl_obj *so = (struct sasl_obj *) fp->f_cookie;
295
296 /*
297 ** Fetch the maximum input buffer size for sasl_encode().
298 ** This can be less than the size set in attemptauth()
299 ** due to a negotiation with the other side, e.g.,
300 ** Cyrus IMAP lmtp program sets maxbuf=4096,
301 ** digestmd5 substracts 25 and hence we'll get 4071
302 ** instead of 8192 (MAXOUTLEN).
303 ** Hack (for now): simply reduce the size, callers are (must be)
304 ** able to deal with that and invoke sasl_write() again with
305 ** the rest of the data.
306 ** Note: it would be better to store this value in the context
307 ** after the negotiation.
308 */
309
310 result = sasl_getprop(so->conn, SASL_MAXOUTBUF,
311 (const void **) &maxencode);
312 if (result == SASL_OK && size > *maxencode && *maxencode > 0)
313 size = *maxencode;
314
315 result = sasl_encode(so->conn, buf,
316 (unsigned int) size, &outbuf, &outlen);
317
318 if (result != SASL_OK)
319 {
320 if (LogLevel > 7)
321 sm_syslog(LOG_WARNING, NOQID,
322 "AUTH: sasl_encode error=%d", result);
323 return -1;
324 }
325
326 if (outbuf != NULL)
327 {
328 while (outlen > 0)
329 {
330 errno = 0;
331 /* XXX result == 0? */
332 ret = sm_io_write(so->fp, SM_TIME_DEFAULT,
333 &outbuf[total], outlen);
334 if (ret <= 0)
335 return ret;
336 outlen -= ret;
337 total += ret;
338 }
339# if SASL < 20000
340 SASL_DEALLOC(outbuf);
341# endif /* SASL < 20000 */
342 }
343 return size;
344}
345
346/*
347** SFDCSASL -- create sasl file type and open in and out file pointers
348** for sendmail to read from and write to.
349**
350** Parameters:
351** fin -- the sm_io file encrypted data to be read from
352** fout -- the sm_io file encrypted data to be written to
353** conn -- the sasl connection pointer
354** tmo -- timeout
355**
356** Returns:
357** -1 on error
358** 0 on success
359**
360** Side effects:
361** The arguments "fin" and "fout" are replaced with the new
362** SM_FILE_T pointers.
363*/
364
365int
366sfdcsasl(fin, fout, conn, tmo)
367 SM_FILE_T **fin;
368 SM_FILE_T **fout;
369 sasl_conn_t *conn;
370 int tmo;
371{
372 SM_FILE_T *newin, *newout;
373 SM_FILE_T SM_IO_SET_TYPE(sasl_vector, "sasl", sasl_open, sasl_close,
374 sasl_read, sasl_write, NULL, sasl_getinfo, NULL,
375 SM_TIME_DEFAULT);
376 struct sasl_info info;
377
378 if (conn == NULL)
379 {
380 /* no need to do anything */
381 return 0;
382 }
383
384 SM_IO_INIT_TYPE(sasl_vector, "sasl", sasl_open, sasl_close,
385 sasl_read, sasl_write, NULL, sasl_getinfo, NULL,
386 SM_TIME_DEFAULT);
387 info.fp = *fin;
388 info.conn = conn;
389 newin = sm_io_open(&sasl_vector, SM_TIME_DEFAULT, &info,
390 SM_IO_RDONLY_B, NULL);
391
392 if (newin == NULL)
393 return -1;
394
395 info.fp = *fout;
396 info.conn = conn;
397 newout = sm_io_open(&sasl_vector, SM_TIME_DEFAULT, &info,
398 SM_IO_WRONLY_B, NULL);
399
400 if (newout == NULL)
401 {
402 (void) sm_io_close(newin, SM_TIME_DEFAULT);
403 return -1;
404 }
405 sm_io_automode(newin, newout);
406
407 sm_io_setinfo(*fin, SM_IO_WHAT_TIMEOUT, &tmo);
408 sm_io_setinfo(*fout, SM_IO_WHAT_TIMEOUT, &tmo);
409
410 *fin = newin;
411 *fout = newout;
412 return 0;
413}
414#endif /* SASL */
415
416#if STARTTLS
417# include "sfsasl.h"
418# include <openssl/err.h>
419
420/* Structure used by the "tls" file type */
421struct tls_obj
422{
423 SM_FILE_T *fp;
424 SSL *con;
425};
426
427struct tls_info
428{
429 SM_FILE_T *fp;
430 SSL *con;
431};
432
433/*
434** TLS_GETINFO - returns requested information about a "tls" file
435** descriptor.
436**
437** Parameters:
438** fp -- the file descriptor
439** what -- the type of information requested
440** valp -- the thang to return the information in (unused)
441**
442** Returns:
443** -1 for unknown requests
444** >=0 on success with valp filled in (if possible).
445*/
446
447static int tls_getinfo __P((SM_FILE_T *, int, void *));
448
449/* ARGSUSED2 */
450static int
451tls_getinfo(fp, what, valp)
452 SM_FILE_T *fp;
453 int what;
454 void *valp;
455{
456 struct tls_obj *so = (struct tls_obj *) fp->f_cookie;
457
458 switch (what)
459 {
460 case SM_IO_WHAT_FD:
461 if (so->fp == NULL)
462 return -1;
463 return so->fp->f_file; /* for stdio fileno() compatability */
464
465 case SM_IO_IS_READABLE:
466 return SSL_pending(so->con) > 0;
467
468 default:
469 return -1;
470 }
471}
472
473/*
474** TLS_OPEN -- creates the tls specific information for opening a
475** file of the tls type.
476**
477** Parameters:
478** fp -- the file pointer associated with the new open
479** info -- the sm_io file pointer holding the open and the
480** TLS encryption connection to be read from or written to
481** flags -- ignored
482** rpool -- ignored
483**
484** Returns:
485** 0 on success
486*/
487
488static int tls_open __P((SM_FILE_T *, const void *, int, const void *));
489
490/* ARGSUSED2 */
491static int
492tls_open(fp, info, flags, rpool)
493 SM_FILE_T *fp;
494 const void *info;
495 int flags;
496 const void *rpool;
497{
498 struct tls_obj *so;
499 struct tls_info *ti = (struct tls_info *) info;
500
501 so = (struct tls_obj *) sm_malloc(sizeof(struct tls_obj));
502 if (so == NULL)
503 {
504 errno = ENOMEM;
505 return -1;
506 }
507 so->fp = ti->fp;
508 so->con = ti->con;
509
510 /*
511 ** We try to get the "raw" file descriptor that TLS uses to
512 ** do the actual read/write with. This is to allow us control
513 ** over the file descriptor being a blocking or non-blocking type.
514 ** Under the covers TLS handles the change and this allows us
515 ** to do timeouts with sm_io.
516 */
517
518 fp->f_file = sm_io_getinfo(so->fp, SM_IO_WHAT_FD, NULL);
519 (void) sm_io_setvbuf(so->fp, SM_TIME_DEFAULT, NULL, SM_IO_NOW, 0);
520 fp->f_cookie = so;
521 return 0;
522}
523
524/*
525** TLS_CLOSE -- close the tls specific parts of the tls file pointer
526**
527** Parameters:
528** fp -- the file pointer to close
529**
530** Returns:
531** 0 on success
532*/
533
534static int tls_close __P((SM_FILE_T *));
535
536static int
537tls_close(fp)
538 SM_FILE_T *fp;
539{
540 struct tls_obj *so;
541
542 so = (struct tls_obj *) fp->f_cookie;
543 if (so == NULL)
544 return 0;
545 if (so->fp != NULL)
546 {
547 sm_io_close(so->fp, SM_TIME_DEFAULT);
548 so->fp = NULL;
549 }
550 sm_free(so);
551 so = NULL;
552 return 0;
553}
554
555/* maximum number of retries for TLS related I/O due to handshakes */
556# define MAX_TLS_IOS 4
557
558/*
559** TLS_RETRY -- check whether a failed SSL operation can be retried
560**
561** Parameters:
562** ssl -- TLS structure
563** rfd -- read fd
564** wfd -- write fd
565** tlsstart -- start time of TLS operation
566** timeout -- timeout for TLS operation
567** err -- SSL error
568** where -- description of operation
569**
570** Results:
571** >0 on success
572** 0 on timeout
573** <0 on error
574*/
575
576int
577tls_retry(ssl, rfd, wfd, tlsstart, timeout, err, where)
578 SSL *ssl;
579 int rfd;
580 int wfd;
581 time_t tlsstart;
582 int timeout;
583 int err;
584 const char *where;
585{
586 int ret;
587 time_t left;
588 time_t now = curtime();
589 struct timeval tv;
590
591 ret = -1;
592
593 /*
594 ** For SSL_ERROR_WANT_{READ,WRITE}:
595 ** There is not a complete SSL record available yet
596 ** or there is only a partial SSL record removed from
597 ** the network (socket) buffer into the SSL buffer.
598 ** The SSL_connect will only succeed when a full
599 ** SSL record is available (assuming a "real" error
600 ** doesn't happen). To handle when a "real" error
601 ** does happen the select is set for exceptions too.
602 ** The connection may be re-negotiated during this time
603 ** so both read and write "want errors" need to be handled.
604 ** A select() exception loops back so that a proper SSL
605 ** error message can be gotten.
606 */
607
608 left = timeout - (now - tlsstart);
609 if (left <= 0)
610 return 0; /* timeout */
611 tv.tv_sec = left;
612 tv.tv_usec = 0;
613
614 if (LogLevel > 14)
615 {
616 sm_syslog(LOG_INFO, NOQID,
617 "STARTTLS=%s, info: fds=%d/%d, err=%d",
618 where, rfd, wfd, err);
619 }
620
621 if (FD_SETSIZE > 0 &&
622 ((err == SSL_ERROR_WANT_READ && rfd >= FD_SETSIZE) ||
623 (err == SSL_ERROR_WANT_WRITE && wfd >= FD_SETSIZE)))
624 {
625 if (LogLevel > 5)
626 {
627 sm_syslog(LOG_ERR, NOQID,
628 "STARTTLS=%s, error: fd %d/%d too large",
629 where, rfd, wfd);
630 if (LogLevel > 8)
631 tlslogerr(where);
631 tlslogerr(LOG_WARNING, where);
632 }
633 errno = EINVAL;
634 }
635 else if (err == SSL_ERROR_WANT_READ)
636 {
637 fd_set ssl_maskr, ssl_maskx;
632 }
633 errno = EINVAL;
634 }
635 else if (err == SSL_ERROR_WANT_READ)
636 {
637 fd_set ssl_maskr, ssl_maskx;
638 int save_errno = errno;
638
639 FD_ZERO(&ssl_maskr);
640 FD_SET(rfd, &ssl_maskr);
641 FD_ZERO(&ssl_maskx);
642 FD_SET(rfd, &ssl_maskx);
643 do
644 {
645 ret = select(rfd + 1, &ssl_maskr, NULL, &ssl_maskx,
646 &tv);
647 } while (ret < 0 && errno == EINTR);
648 if (ret < 0 && errno > 0)
649 ret = -errno;
639
640 FD_ZERO(&ssl_maskr);
641 FD_SET(rfd, &ssl_maskr);
642 FD_ZERO(&ssl_maskx);
643 FD_SET(rfd, &ssl_maskx);
644 do
645 {
646 ret = select(rfd + 1, &ssl_maskr, NULL, &ssl_maskx,
647 &tv);
648 } while (ret < 0 && errno == EINTR);
649 if (ret < 0 && errno > 0)
650 ret = -errno;
651 errno = save_errno;
650 }
651 else if (err == SSL_ERROR_WANT_WRITE)
652 {
653 fd_set ssl_maskw, ssl_maskx;
652 }
653 else if (err == SSL_ERROR_WANT_WRITE)
654 {
655 fd_set ssl_maskw, ssl_maskx;
656 int save_errno = errno;
654
655 FD_ZERO(&ssl_maskw);
656 FD_SET(wfd, &ssl_maskw);
657 FD_ZERO(&ssl_maskx);
658 FD_SET(rfd, &ssl_maskx);
659 do
660 {
661 ret = select(wfd + 1, NULL, &ssl_maskw, &ssl_maskx,
662 &tv);
663 } while (ret < 0 && errno == EINTR);
664 if (ret < 0 && errno > 0)
665 ret = -errno;
657
658 FD_ZERO(&ssl_maskw);
659 FD_SET(wfd, &ssl_maskw);
660 FD_ZERO(&ssl_maskx);
661 FD_SET(rfd, &ssl_maskx);
662 do
663 {
664 ret = select(wfd + 1, NULL, &ssl_maskw, &ssl_maskx,
665 &tv);
666 } while (ret < 0 && errno == EINTR);
667 if (ret < 0 && errno > 0)
668 ret = -errno;
669 errno = save_errno;
666 }
667 return ret;
668}
669
670/* errno to force refill() etc to stop (see IS_IO_ERROR()) */
671#ifdef ETIMEDOUT
672# define SM_ERR_TIMEOUT ETIMEDOUT
673#else /* ETIMEDOUT */
674# define SM_ERR_TIMEOUT EIO
675#endif /* ETIMEDOUT */
676
677/*
678** SET_TLS_RD_TMO -- read secured information for the caller
679**
680** Parameters:
681** rd_tmo -- read timeout
682**
683** Results:
684** none
685** This is a hack: there is no way to pass it in
686*/
687
688static int tls_rd_tmo = -1;
689
690void
691set_tls_rd_tmo(rd_tmo)
692 int rd_tmo;
693{
694 tls_rd_tmo = rd_tmo;
695}
696
697/*
698** TLS_READ -- read secured information for the caller
699**
700** Parameters:
701** fp -- the file pointer
702** buf -- the location to place the data
703** size -- the number of bytes to read from connection
704**
705** Results:
706** -1 on error
707** otherwise the number of bytes read
708*/
709
710static ssize_t tls_read __P((SM_FILE_T *, char *, size_t));
711
712static ssize_t
713tls_read(fp, buf, size)
714 SM_FILE_T *fp;
715 char *buf;
716 size_t size;
717{
718 int r, rfd, wfd, try, ssl_err;
719 struct tls_obj *so = (struct tls_obj *) fp->f_cookie;
720 time_t tlsstart;
721 char *err;
722
723 try = 99;
724 err = NULL;
725 tlsstart = curtime();
726
727 retry:
728 r = SSL_read(so->con, (char *) buf, size);
729
730 if (r > 0)
731 return r;
732
733 err = NULL;
734 switch (ssl_err = SSL_get_error(so->con, r))
735 {
736 case SSL_ERROR_NONE:
737 case SSL_ERROR_ZERO_RETURN:
738 break;
739 case SSL_ERROR_WANT_WRITE:
740 err = "read W BLOCK";
741 /* FALLTHROUGH */
742 case SSL_ERROR_WANT_READ:
743 if (err == NULL)
744 err = "read R BLOCK";
745 rfd = SSL_get_rfd(so->con);
746 wfd = SSL_get_wfd(so->con);
747 try = tls_retry(so->con, rfd, wfd, tlsstart,
748 (tls_rd_tmo < 0) ? TimeOuts.to_datablock
749 : tls_rd_tmo,
750 ssl_err, "read");
751 if (try > 0)
752 goto retry;
753 errno = SM_ERR_TIMEOUT;
754 break;
755
756 case SSL_ERROR_WANT_X509_LOOKUP:
757 err = "write X BLOCK";
758 break;
759 case SSL_ERROR_SYSCALL:
760 if (r == 0 && errno == 0) /* out of protocol EOF found */
761 break;
762 err = "syscall error";
763/*
764 get_last_socket_error());
765*/
766 break;
767 case SSL_ERROR_SSL:
768#if DEAL_WITH_ERROR_SSL
769 if (r == 0 && errno == 0) /* out of protocol EOF found */
770 break;
771#endif /* DEAL_WITH_ERROR_SSL */
772 err = "generic SSL error";
670 }
671 return ret;
672}
673
674/* errno to force refill() etc to stop (see IS_IO_ERROR()) */
675#ifdef ETIMEDOUT
676# define SM_ERR_TIMEOUT ETIMEDOUT
677#else /* ETIMEDOUT */
678# define SM_ERR_TIMEOUT EIO
679#endif /* ETIMEDOUT */
680
681/*
682** SET_TLS_RD_TMO -- read secured information for the caller
683**
684** Parameters:
685** rd_tmo -- read timeout
686**
687** Results:
688** none
689** This is a hack: there is no way to pass it in
690*/
691
692static int tls_rd_tmo = -1;
693
694void
695set_tls_rd_tmo(rd_tmo)
696 int rd_tmo;
697{
698 tls_rd_tmo = rd_tmo;
699}
700
701/*
702** TLS_READ -- read secured information for the caller
703**
704** Parameters:
705** fp -- the file pointer
706** buf -- the location to place the data
707** size -- the number of bytes to read from connection
708**
709** Results:
710** -1 on error
711** otherwise the number of bytes read
712*/
713
714static ssize_t tls_read __P((SM_FILE_T *, char *, size_t));
715
716static ssize_t
717tls_read(fp, buf, size)
718 SM_FILE_T *fp;
719 char *buf;
720 size_t size;
721{
722 int r, rfd, wfd, try, ssl_err;
723 struct tls_obj *so = (struct tls_obj *) fp->f_cookie;
724 time_t tlsstart;
725 char *err;
726
727 try = 99;
728 err = NULL;
729 tlsstart = curtime();
730
731 retry:
732 r = SSL_read(so->con, (char *) buf, size);
733
734 if (r > 0)
735 return r;
736
737 err = NULL;
738 switch (ssl_err = SSL_get_error(so->con, r))
739 {
740 case SSL_ERROR_NONE:
741 case SSL_ERROR_ZERO_RETURN:
742 break;
743 case SSL_ERROR_WANT_WRITE:
744 err = "read W BLOCK";
745 /* FALLTHROUGH */
746 case SSL_ERROR_WANT_READ:
747 if (err == NULL)
748 err = "read R BLOCK";
749 rfd = SSL_get_rfd(so->con);
750 wfd = SSL_get_wfd(so->con);
751 try = tls_retry(so->con, rfd, wfd, tlsstart,
752 (tls_rd_tmo < 0) ? TimeOuts.to_datablock
753 : tls_rd_tmo,
754 ssl_err, "read");
755 if (try > 0)
756 goto retry;
757 errno = SM_ERR_TIMEOUT;
758 break;
759
760 case SSL_ERROR_WANT_X509_LOOKUP:
761 err = "write X BLOCK";
762 break;
763 case SSL_ERROR_SYSCALL:
764 if (r == 0 && errno == 0) /* out of protocol EOF found */
765 break;
766 err = "syscall error";
767/*
768 get_last_socket_error());
769*/
770 break;
771 case SSL_ERROR_SSL:
772#if DEAL_WITH_ERROR_SSL
773 if (r == 0 && errno == 0) /* out of protocol EOF found */
774 break;
775#endif /* DEAL_WITH_ERROR_SSL */
776 err = "generic SSL error";
777
773 if (LogLevel > 9)
778 if (LogLevel > 9)
774 tlslogerr("read");
779 {
780 int pri;
775
781
782 if (errno == EAGAIN && try > 0)
783 pri = LOG_DEBUG;
784 else
785 pri = LOG_WARNING;
786 tlslogerr(pri, "read");
787 }
788
776#if DEAL_WITH_ERROR_SSL
777 /* avoid repeated calls? */
778 if (r == 0)
779 r = -1;
780#endif /* DEAL_WITH_ERROR_SSL */
781 break;
782 }
783 if (err != NULL)
784 {
785 int save_errno;
786
787 save_errno = (errno == 0) ? EIO : errno;
788 if (try == 0 && save_errno == SM_ERR_TIMEOUT)
789 {
790 if (LogLevel > 7)
791 sm_syslog(LOG_WARNING, NOQID,
792 "STARTTLS: read error=timeout");
793 }
794 else if (LogLevel > 8)
789#if DEAL_WITH_ERROR_SSL
790 /* avoid repeated calls? */
791 if (r == 0)
792 r = -1;
793#endif /* DEAL_WITH_ERROR_SSL */
794 break;
795 }
796 if (err != NULL)
797 {
798 int save_errno;
799
800 save_errno = (errno == 0) ? EIO : errno;
801 if (try == 0 && save_errno == SM_ERR_TIMEOUT)
802 {
803 if (LogLevel > 7)
804 sm_syslog(LOG_WARNING, NOQID,
805 "STARTTLS: read error=timeout");
806 }
807 else if (LogLevel > 8)
795 sm_syslog(LOG_WARNING, NOQID,
808 {
809 int pri;
810
811 if (save_errno == EAGAIN && try > 0)
812 pri = LOG_DEBUG;
813 else
814 pri = LOG_WARNING;
815 sm_syslog(pri, NOQID,
796 "STARTTLS: read error=%s (%d), errno=%d, get_error=%s, retry=%d, ssl_err=%d",
797 err, r, errno,
798 ERR_error_string(ERR_get_error(), NULL), try,
799 ssl_err);
816 "STARTTLS: read error=%s (%d), errno=%d, get_error=%s, retry=%d, ssl_err=%d",
817 err, r, errno,
818 ERR_error_string(ERR_get_error(), NULL), try,
819 ssl_err);
820 }
800 else if (LogLevel > 7)
801 sm_syslog(LOG_WARNING, NOQID,
802 "STARTTLS: read error=%s (%d), retry=%d, ssl_err=%d",
803 err, r, errno, try, ssl_err);
804 errno = save_errno;
805 }
806 return r;
807}
808
809/*
810** TLS_WRITE -- write information out through secure connection
811**
812** Parameters:
813** fp -- the file pointer
814** buf -- holds the data to be securely written
815** size -- the number of bytes to write
816**
817** Returns:
818** -1 on error
819** otherwise number of bytes written
820*/
821
822static ssize_t tls_write __P((SM_FILE_T *, const char *, size_t));
823
824static ssize_t
825tls_write(fp, buf, size)
826 SM_FILE_T *fp;
827 const char *buf;
828 size_t size;
829{
830 int r, rfd, wfd, try, ssl_err;
831 struct tls_obj *so = (struct tls_obj *) fp->f_cookie;
832 time_t tlsstart;
833 char *err;
834
835 try = 99;
836 err = NULL;
837 tlsstart = curtime();
838
839 retry:
840 r = SSL_write(so->con, (char *) buf, size);
841
842 if (r > 0)
843 return r;
844 err = NULL;
845 switch (ssl_err = SSL_get_error(so->con, r))
846 {
847 case SSL_ERROR_NONE:
848 case SSL_ERROR_ZERO_RETURN:
849 break;
850 case SSL_ERROR_WANT_WRITE:
851 err = "read W BLOCK";
852 /* FALLTHROUGH */
853 case SSL_ERROR_WANT_READ:
854 if (err == NULL)
855 err = "read R BLOCK";
856 rfd = SSL_get_rfd(so->con);
857 wfd = SSL_get_wfd(so->con);
858 try = tls_retry(so->con, rfd, wfd, tlsstart,
859 DATA_PROGRESS_TIMEOUT, ssl_err, "write");
860 if (try > 0)
861 goto retry;
862 errno = SM_ERR_TIMEOUT;
863 break;
864 case SSL_ERROR_WANT_X509_LOOKUP:
865 err = "write X BLOCK";
866 break;
867 case SSL_ERROR_SYSCALL:
868 if (r == 0 && errno == 0) /* out of protocol EOF found */
869 break;
870 err = "syscall error";
871/*
872 get_last_socket_error());
873*/
874 break;
875 case SSL_ERROR_SSL:
876 err = "generic SSL error";
877/*
878 ERR_GET_REASON(ERR_peek_error()));
879*/
880 if (LogLevel > 9)
821 else if (LogLevel > 7)
822 sm_syslog(LOG_WARNING, NOQID,
823 "STARTTLS: read error=%s (%d), retry=%d, ssl_err=%d",
824 err, r, errno, try, ssl_err);
825 errno = save_errno;
826 }
827 return r;
828}
829
830/*
831** TLS_WRITE -- write information out through secure connection
832**
833** Parameters:
834** fp -- the file pointer
835** buf -- holds the data to be securely written
836** size -- the number of bytes to write
837**
838** Returns:
839** -1 on error
840** otherwise number of bytes written
841*/
842
843static ssize_t tls_write __P((SM_FILE_T *, const char *, size_t));
844
845static ssize_t
846tls_write(fp, buf, size)
847 SM_FILE_T *fp;
848 const char *buf;
849 size_t size;
850{
851 int r, rfd, wfd, try, ssl_err;
852 struct tls_obj *so = (struct tls_obj *) fp->f_cookie;
853 time_t tlsstart;
854 char *err;
855
856 try = 99;
857 err = NULL;
858 tlsstart = curtime();
859
860 retry:
861 r = SSL_write(so->con, (char *) buf, size);
862
863 if (r > 0)
864 return r;
865 err = NULL;
866 switch (ssl_err = SSL_get_error(so->con, r))
867 {
868 case SSL_ERROR_NONE:
869 case SSL_ERROR_ZERO_RETURN:
870 break;
871 case SSL_ERROR_WANT_WRITE:
872 err = "read W BLOCK";
873 /* FALLTHROUGH */
874 case SSL_ERROR_WANT_READ:
875 if (err == NULL)
876 err = "read R BLOCK";
877 rfd = SSL_get_rfd(so->con);
878 wfd = SSL_get_wfd(so->con);
879 try = tls_retry(so->con, rfd, wfd, tlsstart,
880 DATA_PROGRESS_TIMEOUT, ssl_err, "write");
881 if (try > 0)
882 goto retry;
883 errno = SM_ERR_TIMEOUT;
884 break;
885 case SSL_ERROR_WANT_X509_LOOKUP:
886 err = "write X BLOCK";
887 break;
888 case SSL_ERROR_SYSCALL:
889 if (r == 0 && errno == 0) /* out of protocol EOF found */
890 break;
891 err = "syscall error";
892/*
893 get_last_socket_error());
894*/
895 break;
896 case SSL_ERROR_SSL:
897 err = "generic SSL error";
898/*
899 ERR_GET_REASON(ERR_peek_error()));
900*/
901 if (LogLevel > 9)
881 tlslogerr("write");
902 tlslogerr(LOG_WARNING, "write");
882
883#if DEAL_WITH_ERROR_SSL
884 /* avoid repeated calls? */
885 if (r == 0)
886 r = -1;
887#endif /* DEAL_WITH_ERROR_SSL */
888 break;
889 }
890 if (err != NULL)
891 {
892 int save_errno;
893
894 save_errno = (errno == 0) ? EIO : errno;
895 if (try == 0 && save_errno == SM_ERR_TIMEOUT)
896 {
897 if (LogLevel > 7)
898 sm_syslog(LOG_WARNING, NOQID,
899 "STARTTLS: write error=timeout");
900 }
901 else if (LogLevel > 8)
902 sm_syslog(LOG_WARNING, NOQID,
903 "STARTTLS: write error=%s (%d), errno=%d, get_error=%s, retry=%d, ssl_err=%d",
904 err, r, errno,
905 ERR_error_string(ERR_get_error(), NULL), try,
906 ssl_err);
907 else if (LogLevel > 7)
908 sm_syslog(LOG_WARNING, NOQID,
909 "STARTTLS: write error=%s (%d), errno=%d, retry=%d, ssl_err=%d",
910 err, r, errno, try, ssl_err);
911 errno = save_errno;
912 }
913 return r;
914}
915
916/*
917** SFDCTLS -- create tls file type and open in and out file pointers
918** for sendmail to read from and write to.
919**
920** Parameters:
921** fin -- data input source being replaced
922** fout -- data output source being replaced
923** con -- the tls connection pointer
924**
925** Returns:
926** -1 on error
927** 0 on success
928**
929** Side effects:
930** The arguments "fin" and "fout" are replaced with the new
931** SM_FILE_T pointers.
932** The original "fin" and "fout" are preserved in the tls file
933** type but are not actually used because of the design of TLS.
934*/
935
936int
937sfdctls(fin, fout, con)
938 SM_FILE_T **fin;
939 SM_FILE_T **fout;
940 SSL *con;
941{
942 SM_FILE_T *tlsin, *tlsout;
943 SM_FILE_T SM_IO_SET_TYPE(tls_vector, "tls", tls_open, tls_close,
944 tls_read, tls_write, NULL, tls_getinfo, NULL,
945 SM_TIME_FOREVER);
946 struct tls_info info;
947
948 SM_ASSERT(con != NULL);
949
950 SM_IO_INIT_TYPE(tls_vector, "tls", tls_open, tls_close,
951 tls_read, tls_write, NULL, tls_getinfo, NULL,
952 SM_TIME_FOREVER);
953 info.fp = *fin;
954 info.con = con;
955 tlsin = sm_io_open(&tls_vector, SM_TIME_DEFAULT, &info, SM_IO_RDONLY_B,
956 NULL);
957 if (tlsin == NULL)
958 return -1;
959
960 info.fp = *fout;
961 tlsout = sm_io_open(&tls_vector, SM_TIME_DEFAULT, &info, SM_IO_WRONLY_B,
962 NULL);
963 if (tlsout == NULL)
964 {
965 (void) sm_io_close(tlsin, SM_TIME_DEFAULT);
966 return -1;
967 }
968 sm_io_automode(tlsin, tlsout);
969
970 *fin = tlsin;
971 *fout = tlsout;
972 return 0;
973}
974#endif /* STARTTLS */
903
904#if DEAL_WITH_ERROR_SSL
905 /* avoid repeated calls? */
906 if (r == 0)
907 r = -1;
908#endif /* DEAL_WITH_ERROR_SSL */
909 break;
910 }
911 if (err != NULL)
912 {
913 int save_errno;
914
915 save_errno = (errno == 0) ? EIO : errno;
916 if (try == 0 && save_errno == SM_ERR_TIMEOUT)
917 {
918 if (LogLevel > 7)
919 sm_syslog(LOG_WARNING, NOQID,
920 "STARTTLS: write error=timeout");
921 }
922 else if (LogLevel > 8)
923 sm_syslog(LOG_WARNING, NOQID,
924 "STARTTLS: write error=%s (%d), errno=%d, get_error=%s, retry=%d, ssl_err=%d",
925 err, r, errno,
926 ERR_error_string(ERR_get_error(), NULL), try,
927 ssl_err);
928 else if (LogLevel > 7)
929 sm_syslog(LOG_WARNING, NOQID,
930 "STARTTLS: write error=%s (%d), errno=%d, retry=%d, ssl_err=%d",
931 err, r, errno, try, ssl_err);
932 errno = save_errno;
933 }
934 return r;
935}
936
937/*
938** SFDCTLS -- create tls file type and open in and out file pointers
939** for sendmail to read from and write to.
940**
941** Parameters:
942** fin -- data input source being replaced
943** fout -- data output source being replaced
944** con -- the tls connection pointer
945**
946** Returns:
947** -1 on error
948** 0 on success
949**
950** Side effects:
951** The arguments "fin" and "fout" are replaced with the new
952** SM_FILE_T pointers.
953** The original "fin" and "fout" are preserved in the tls file
954** type but are not actually used because of the design of TLS.
955*/
956
957int
958sfdctls(fin, fout, con)
959 SM_FILE_T **fin;
960 SM_FILE_T **fout;
961 SSL *con;
962{
963 SM_FILE_T *tlsin, *tlsout;
964 SM_FILE_T SM_IO_SET_TYPE(tls_vector, "tls", tls_open, tls_close,
965 tls_read, tls_write, NULL, tls_getinfo, NULL,
966 SM_TIME_FOREVER);
967 struct tls_info info;
968
969 SM_ASSERT(con != NULL);
970
971 SM_IO_INIT_TYPE(tls_vector, "tls", tls_open, tls_close,
972 tls_read, tls_write, NULL, tls_getinfo, NULL,
973 SM_TIME_FOREVER);
974 info.fp = *fin;
975 info.con = con;
976 tlsin = sm_io_open(&tls_vector, SM_TIME_DEFAULT, &info, SM_IO_RDONLY_B,
977 NULL);
978 if (tlsin == NULL)
979 return -1;
980
981 info.fp = *fout;
982 tlsout = sm_io_open(&tls_vector, SM_TIME_DEFAULT, &info, SM_IO_WRONLY_B,
983 NULL);
984 if (tlsout == NULL)
985 {
986 (void) sm_io_close(tlsin, SM_TIME_DEFAULT);
987 return -1;
988 }
989 sm_io_automode(tlsin, tlsout);
990
991 *fin = tlsin;
992 *fout = tlsout;
993 return 0;
994}
995#endif /* STARTTLS */