# define SASLminc(a) 0
#endif
+#ifndef TLS_SUPPORT
+# define TLSminc(a) (a)
+#else
+# define TLSminc(a) 0
+#endif
+
#define INC_SWITCHES \
X("audit audit-file", 0, AUDSW) \
X("noaudit", 0, NAUDSW) \
X("sasl", SASLminc(5), SASLSW) \
X("nosasl", SASLminc(3), NOSASLSW) \
X("saslmech", SASLminc(5), SASLMECHSW) \
+ X("initialtls", TLSminc(-10), INITTLSSW) \
+ X("noinitialtls", TLSminc(-12), NOINITTLSSW) \
X("authservice", SASLminc(0), AUTHSERVICESW) \
X("proxy command", 0, PROXYSW) \
int chgflag = 1, trnflag = 1;
int noisy = 1, width = -1;
int hghnum = 0, msgnum = 0;
- int sasl = 0;
+ int sasl = 0, 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;
adios (NULL, "missing argument to %s", argp[-2]);
continue;
+ case INITTLSSW:
+ tls++;
+ continue;
+
+ case NOINITTLSSW:
+ tls = 0;
+ continue;
+
case AUTHSERVICESW:
#ifdef OAUTH_SUPPORT
if (!(auth_svc = *argp++) || *auth_svc == '-')
* initialize POP connection
*/
if (pop_init (host, port, creds.user, creds.password, proxy, snoop,
- sasl, saslmech, auth_svc) == NOTOK)
+ sasl, saslmech, tls, auth_svc) == NOTOK)
adios (NULL, "%s", response);
/* Check if there are any messages */
#ifdef CYRUS_SASL
static int pop_auth_sasl(char *, char *, char *);
-static int sasl_fgetc(FILE *);
#endif /* CYRUS_SASL */
#ifdef TLS_SUPPORT
static int traverse (int (*)(char *), const char *, ...);
static int vcommand(const char *, va_list);
static int sasl_getline (char *, int, FILE *);
+static int sasl_fgetc(FILE *);
static int putline (char *, FILE *);
memset(&secprops, 0, sizeof(secprops));
secprops.maxbufsize = SASL_BUFFER_SIZE;
- secprops.max_ssf = UINT_MAX;
+ secprops.max_ssf = tls_active ? 0 : UINT_MAX;
result = sasl_setprop(conn, SASL_SEC_PROPS, &secprops);
int
pop_init (char *host, char *port, char *user, char *pass, char *proxy,
- int snoop, int sasl, int tls, char *mech, const char *oauth_svc)
+ int snoop, int sasl, char *mech, int tls, const char *oauth_svc)
{
int fd1, fd2;
char buffer[BUFSIZ];
if (poprint) {
#ifdef CYRUS_SASL
if (sasl_ssf)
- fprintf(stderr, "(encrypted) ");
+ fprintf(stderr, "(sasl-encrypted) ");
#endif /* CYRUS_SASL */
+#ifdef TLS_SUPPORT
+ if (tls_active)
+ fprintf(stderr, "(tls-encrypted) ");
+#endif /* TLS_SUPPORT */
if (pophack) {
if ((cp = strchr (buffer, ' ')))
*cp = 0;
int result;
unsigned int buflen;
- if (!sasl_complete) {
+ if (sasl_complete == 0 || sasl_ssf == 0) {
#endif /* CYRUS_SASL */
+#ifdef TLS_SUPPORT
+ if (tls_active) {
+ int ret;
+
+ BIO_printf(io, "%s\r\n");
+ ret = BIO_flush(io);
+
+ if (ret != 1) {
+ strncpy(response, "lost connection", sizeof(response));
+ return NOTOK;
+ else {
+ return OK;
+ }
+ } else
+#endif /* TLS_SUPPORT */
fprintf (iop, "%s\r\n", s);
#ifdef CYRUS_SASL
} else {
while (retbufsize == 0) {
+#ifdef TLS_SUPPORT
+ if (tls_active) {
+
cc = read(fileno(f), tmpbuf, sizeof(tmpbuf));
if (cc == 0)
BIO *ssl_bio;
if (! sslctx) {
- SSL_METHOD *method;
-
SSL_library_init();
SSL_load_error_strings();
- method = TLS_client_method();
+ sslctx = SSL_CTX_new(SSLv23_client_method());
- sslctx = SSL_CTX_new(method);
-
- if (! sslctx()) {
+ if (! sslctx) {
pop_done();
advise(NULL, "Unable to initialize OpenSSL context: %s",
ERR_error_string(ERR_get_error(), NULL));
return NOTOK;
}
+
+ SSL_CTX_set_options(sslctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 |
+ SSL_OP_NO_TLSv1);
}
ssl = SSL_new(sslctx);
if (sbior == NULL || sbiow == NULL) {
pop_done();
advise(NULL, "Unable to create BIO endpoints: %s",
- ERR_error_string(ERR_get_error(), NULL);
+ ERR_error_string(ERR_get_error(), NULL));
return NOTOK;
}
if (! io) {
pop_done();
advise(NULL, "Unable to create a buffer BIO: %s",
- ERR_error_string(ERR_get_error(), NULL);
+ ERR_error_string(ERR_get_error(), NULL));
return NOTOK;
}
if (! ssl_bio) {
pop_done();
advise(NULL, "Unable to create a SSL BIO: %s",
- ERR_error_string(ERR_get_error(), NULL);
+ ERR_error_string(ERR_get_error(), NULL));
return NOTOK;
}
if (BIO_do_handshake(io) < 1) {
pop_done();
advise(NULL, "Unable to negotiate SSL connection: %s",
- ERR_error_string(ERR_get_error(), NULL);
+ ERR_error_string(ERR_get_error(), NULL));
return NOTOK;
}
- if (popprint) {
+ if (poprint) {
const SSL_CIPHER *cipher = SSL_get_current_cipher(ssl);
printf("SSL negotiation successful: %s(%d) %s\n",
- SSL_CIPHER_get_name(cipher);
- SSL_CIPHER_get_bits(cipher, NULL);
- SSL_CIPHER_get_version(cipher);
+ SSL_CIPHER_get_name(cipher),
+ SSL_CIPHER_get_bits(cipher, NULL),
+ SSL_CIPHER_get_version(cipher));
}
tls_active = 1;