summaryrefslogtreecommitdiff
path: root/sys/src/cmd/upas/smtp
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@gmx.de>2013-06-12 23:39:41 +0200
committercinap_lenrek <cinap_lenrek@gmx.de>2013-06-12 23:39:41 +0200
commit646eb150e1c30378256eb5a86c12374bfe0e3c8b (patch)
treef1d079318d03c2649325b3d25176377a8d74f625 /sys/src/cmd/upas/smtp
parent0dbde06bc74732e844879e11fff12b033ca28e65 (diff)
smtp: add SMTPS support (-t)
Diffstat (limited to 'sys/src/cmd/upas/smtp')
-rw-r--r--sys/src/cmd/upas/smtp/smtp.c55
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));
}