diff options
author | cinap_lenrek <cinap_lenrek@gmx.de> | 2013-06-12 23:39:41 +0200 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@gmx.de> | 2013-06-12 23:39:41 +0200 |
commit | 646eb150e1c30378256eb5a86c12374bfe0e3c8b (patch) | |
tree | f1d079318d03c2649325b3d25176377a8d74f625 /sys/src/cmd/upas/smtp | |
parent | 0dbde06bc74732e844879e11fff12b033ca28e65 (diff) |
smtp: add SMTPS support (-t)
Diffstat (limited to 'sys/src/cmd/upas/smtp')
-rw-r--r-- | sys/src/cmd/upas/smtp/smtp.c | 55 |
1 files changed, 37 insertions, 18 deletions
diff --git a/sys/src/cmd/upas/smtp/smtp.c b/sys/src/cmd/upas/smtp/smtp.c index c336d3a7d..8c9e9d50b 100644 --- a/sys/src/cmd/upas/smtp/smtp.c +++ b/sys/src/cmd/upas/smtp/smtp.c @@ -6,6 +6,7 @@ #include <auth.h> static char* connect(char*); +static char* wraptls(void); static char* dotls(char*); static char* doauth(char*); @@ -26,7 +27,7 @@ int printheader(void); void putcrnl(char*, int); void quit(char*); char* rcptto(char*); -char *rewritezone(char *); +char* rewritezone(char *); #define Retry "Retry, Temporary Failure" #define Giveup "Permanent Failure" @@ -151,6 +152,9 @@ main(int argc, char **argv) case 's': trysecure = 1; break; + case 't': + trysecure = 2; + break; case 'u': user = EARGF(usage()); break; @@ -217,7 +221,9 @@ main(int argc, char **argv) /* 10 minutes to get through the initial handshake */ atnotify(timeout, 1); alarm(10*alarmscale); - if((rv = hello(hellodomain, 0)) != 0) + if(trysecure > 1 && (rv = wraptls()) != nil) + goto error; + if((rv = hello(hellodomain, trysecure > 1)) != 0) goto error; alarm(10*alarmscale); if((rv = mailfrom(s_to_c(from))) != 0) @@ -313,13 +319,8 @@ connect(char* net) static char smtpthumbs[] = "/sys/lib/tls/smtp"; static char smtpexclthumbs[] = "/sys/lib/tls/smtp.exclude"; -/* - * exchange names with remote host, attempt to - * enable encryption and optionally authenticate. - * not fatal if we can't. - */ static char * -dotls(char *me) +wraptls(void) { TLSconn *c; Thumbprint *goodcerts; @@ -327,33 +328,27 @@ dotls(char *me) int fd; uchar hash[SHA1dlen]; - c = mallocz(sizeof(*c), 1); /* Note: not freed on success */ + c = mallocz(sizeof(*c), 1); if (c == nil) return Giveup; - dBprint("STARTTLS\r\n"); - if (getreply() != 2) - return Giveup; - fd = tlsClient(Bfildes(&bout), c); if (fd < 0) { syslog(0, "smtp", "tlsClient to %q: %r", ddomain); + free(c); return Giveup; } goodcerts = initThumbprints(smtpthumbs, smtpexclthumbs); if (goodcerts == nil) { - free(c); - close(fd); syslog(0, "smtp", "bad thumbprints in %s", smtpthumbs); + close(fd); + free(c); return Giveup; /* how to recover? TLS is started */ } - /* compute sha1 hash of remote's certificate, see if we know it */ sha1(c->cert, c->certlen, hash, nil); if (!okThumbprint(hash, goodcerts)) { /* TODO? if not excluded, add hash to thumb list */ - free(c); - close(fd); h = malloc(2*sizeof hash + 1); if (h != nil) { enc16(h, 2*sizeof hash + 1, hash, sizeof hash); @@ -363,9 +358,12 @@ dotls(char *me) h, ddomain); free(h); } + close(fd); + free(c); return Giveup; /* how to recover? TLS is started */ } freeThumbprints(goodcerts); + free(c); Bterm(&bin); Bterm(&bout); @@ -378,6 +376,27 @@ dotls(char *me) Binit(&bout, fd, OWRITE); syslog(0, "smtp", "started TLS to %q", ddomain); + return nil; +} + +/* + * exchange names with remote host, attempt to + * enable encryption and optionally authenticate. + * not fatal if we can't. + */ +static char * +dotls(char *me) +{ + char *err; + + dBprint("STARTTLS\r\n"); + if (getreply() != 2) + return Giveup; + + err = wraptls(); + if (err != nil) + return err; + return(hello(me, 1)); } |