X("sasl", 0, SASLSW) \
X("nosasl", 0, NOSASLSW) \
X("saslmech", 0, SASLMECHSW) \
+ X("tls", TLSminc(-3), TLSSW) \
X("initialtls", TLSminc(-10), INITTLSSW) \
X("notls", TLSminc(-5), NOTLSSW) \
X("certverify", TLSminc(-10), CERTVERSW) \
int width = -1;
int hghnum = 0, msgnum = 0;
FILE *pf = NULL;
- bool sasl, tls, noverify;
+ bool sasl, noverify;
+ int tls = 0;
int incerr = 0; /* <0 if inc hits an error which means it should not truncate mailspool */
char *cp, *maildir = NULL, *folder = NULL;
char *format = NULL, *form = NULL;
die("missing argument to %s", argp[-2]);
continue;
+ case TLSSW:
+ tls = 1;
+ continue;
+
case INITTLSSW:
- tls = true;
+ tls = 2;
continue;
case NOTLSSW:
- tls = false;
+ tls = 0;
continue;
case CERTVERSW:
}
}
- if (tls)
- tlsflag |= P_INITTLS;
+ if (tls == 1)
+ tlsflag = P_STARTTLS;
+ else if (tls == 2)
+ tlsflag = P_INITTLS;
if (noverify)
tlsflag |= P_NOVERIFY;
return OK;
}
+/*
+ * If capable, issue the STLS command and start the TLS negotiation
+ */
+
+static int
+pop_start_tls(void)
+{
+ int status;
+ bool stls = false;
+ char *errstr;
+
+ /*
+ * Issue the CAPA command and see if we have the STLS capability
+ */
+
+ if (command("CAPA") == NOTOK) {
+ snprintf(response, sizeof(response),
+ "The POP CAPA command failed; POP server does not "
+ "support STLS");
+ return NOTOK;
+ }
+
+ while ((status = multiline()) != DONE) {
+ if (status == NOTOK)
+ return NOTOK;
+
+ if (strcasecmp(response, "STLS") == 0)
+ stls = true;
+ }
+
+ if (!stls) {
+ snprintf(response, sizeof(response), "POP server does not support "
+ "STLS");
+ return NOTOK;
+ }
+
+ /*
+ * Issue STLS and then start the actual TLS negotiation
+ */
+
+ if (command("STLS") == NOTOK)
+ return NOTOK;
+
+ if (netsec_negotiate_tls(nsc, &errstr) != OK) {
+ snprintf(response, sizeof(response), "%s", errstr);
+ free(errstr);
+ return NOTOK;
+ }
+
+ return OK;
+}
+
/*
* Split string containing proxy command into an array of arguments
* suitable for passing to exec. Returned array must be freed. Shouldn't
netsec_set_fd(nsc, fd1, fd2);
netsec_set_snoop(nsc, snoop);
- if (tls & P_INITTLS) {
+ if (tls & P_TLSENABLEMASK) {
if (netsec_set_tls(nsc, 1, tls & P_NOVERIFY, &errstr) != OK) {
snprintf(response, sizeof(response), "%s", errstr);
free(errstr);
return NOTOK;
}
- if (netsec_negotiate_tls(nsc, &errstr) != OK) {
- snprintf(response, sizeof(response), "%s", errstr);
- free(errstr);
- return NOTOK;
+ if (tls & P_INITTLS) {
+ if (netsec_negotiate_tls(nsc, &errstr) != OK) {
+ snprintf(response, sizeof(response), "%s", errstr);
+ free(errstr);
+ return NOTOK;
+ }
}
}
if (*response == '+') {
nmh_creds_t creds;
+ if (tls & P_STARTTLS)
+ if (pop_start_tls() != OK)
+ return NOTOK;
+
if (sasl) {
char server_mechs[256];
if (check_mech(server_mechs, sizeof(server_mechs)) != OK)
* complete copyright information. */
/* TLS flags */
-#define P_INITTLS 0x01
-#define P_NOVERIFY 0x02
+#define P_STARTTLS 0x01
+#define P_INITTLS 0x02
+#define P_TLSENABLEMASK 0x03
+#define P_NOVERIFY 0x04
int pop_init(char *, char *, char *, char *, int, int, char *, int, const char *);
int pop_stat(int *, int *);