]> diplodocus.org Git - nmh/commitdiff
Okay, we're finally getting to implementation stage! Hopefully we'll be
authorKen Hornstein <kenh@pobox.com>
Mon, 19 Sep 2016 02:03:18 +0000 (22:03 -0400)
committerKen Hornstein <kenh@pobox.com>
Mon, 19 Sep 2016 02:03:18 +0000 (22:03 -0400)
able to make it all work with POP first, then SMTP.

h/netsec.h
sbr/netsec.c
uip/popsbr.c

index ad50d9f7464fb9ab38063d900ffc8b540bad758e..65b867bde760e376c0638031cefe4484c285ce3d 100644 (file)
@@ -22,9 +22,10 @@ netsec_context *netsec_init(void);
  * Arguments:
  *
  * ns_context  - Network security context
  * Arguments:
  *
  * ns_context  - Network security context
+ * closeflag   - If set to 1, close the socket descriptor as well.
  */
 
  */
 
-void netsec_shutdown(netsec_context *ns_context);
+void netsec_shutdown(netsec_context *ns_context, int closeflag);
 
 /*
  * Sets the file descriptor for this connection.  This will be used by
 
 /*
  * Sets the file descriptor for this connection.  This will be used by
@@ -151,6 +152,22 @@ int netsec_write(netsec_context *ns_context, const void *buffer, size_t size,
 int netsec_printf(netsec_context *ns_context, char **errstr,
                  const char *format, ...);
 
 int netsec_printf(netsec_context *ns_context, char **errstr,
                  const char *format, ...);
 
+/*
+ * Write bytes using a va_list argument.
+ *
+ * Arguments:
+ *
+ * ns_context  - Network security context
+ * errstr      - Error string
+ * format      - Format string
+ * ap          - stdarg list.
+ *
+ * Returns OK on success, NOTOK on error.
+ */
+
+int netsec_vprintf(netsec_context *ns_context, char **errstr,
+                  const char *format, va_list ap);
+
 /*
  * Flush any buffered bytes to the network.
  *
 /*
  * Flush any buffered bytes to the network.
  *
@@ -244,7 +261,6 @@ typedef int (*netsec_sasl_callback)(enum sasl_message_type mtype,
  * ns_context  - Network security context
  * hostname    - Fully qualified hostname of remote host.
  * service     - Service name (set to NULL to disable SASL).
  * ns_context  - Network security context
  * hostname    - Fully qualified hostname of remote host.
  * service     - Service name (set to NULL to disable SASL).
- * mechlist    - A space-separated list of mechanisms supported by the server.
  * mechanism   - The mechanism desired by the user.  If NULL, the SASL
  *               library will attempt to negotiate the best mechanism.
  * callback    - SASL protocol callbacks 
  * mechanism   - The mechanism desired by the user.  If NULL, the SASL
  *               library will attempt to negotiate the best mechanism.
  * callback    - SASL protocol callbacks 
index cb297cc1b9714c61f16026c6c7956aada8b3cde4..372732c3540ce986f9d215aa7ec5eb78fc9636c6 100644 (file)
@@ -11,6 +11,7 @@
 #include <h/mh.h>
 #include <h/utils.h>
 #include <h/netsec.h>
 #include <h/mh.h>
 #include <h/utils.h>
 #include <h/netsec.h>
+#include <h/oauth.h>
 #include <stdarg.h>
 #include <sys/select.h>
 
 #include <stdarg.h>
 #include <sys/select.h>
 
@@ -65,9 +66,12 @@ struct _netsec_context {
     unsigned char *ns_outptr;  /* Output buffer pointer */
     unsigned int ns_outbuflen; /* Output buffer data length */
     unsigned int ns_outbufsize;        /* Output buffer size */
     unsigned char *ns_outptr;  /* Output buffer pointer */
     unsigned int ns_outbuflen; /* Output buffer data length */
     unsigned int ns_outbufsize;        /* Output buffer size */
+    char *sasl_mech;           /* User-requested mechanism */
+#ifdef OAUTH_SUPPORT
+    char *oauth_service;       /* OAuth2 service name */
+#endif /* OAUTH_SUPPORT */
 #ifdef CYRUS_SASL
     char *sasl_hostname;       /* Hostname we've connected to */
 #ifdef CYRUS_SASL
     char *sasl_hostname;       /* Hostname we've connected to */
-    char *sasl_mech;           /* User-requested mechanism */
     sasl_conn_t *sasl_conn;    /* SASL connection context */
     sasl_ssf_t sasl_ssf;       /* SASL Security Strength Factor */
     netsec_sasl_callback sasl_proto_cb; /* SASL callback we use */
     sasl_conn_t *sasl_conn;    /* SASL connection context */
     sasl_ssf_t sasl_ssf;       /* SASL Security Strength Factor */
     netsec_sasl_callback sasl_proto_cb; /* SASL callback we use */
@@ -134,10 +138,13 @@ netsec_init(void)
     nsc->ns_outbuffer = mh_xmalloc(nsc->ns_outbufsize);
     nsc->ns_outptr = nsc->ns_outbuffer;
     nsc->ns_outbuflen = 0;
     nsc->ns_outbuffer = mh_xmalloc(nsc->ns_outbufsize);
     nsc->ns_outptr = nsc->ns_outbuffer;
     nsc->ns_outbuflen = 0;
+    nsc->sasl_mech = NULL;
+#ifdef OAUTH_SUPPORT
+    nsc->oauth_service = NULL;
+#endif /* OAUTH_SUPPORT */
 #ifdef CYRUS_SASL
     nsc->sasl_conn = NULL;
     nsc->sasl_hostname = NULL;
 #ifdef CYRUS_SASL
     nsc->sasl_conn = NULL;
     nsc->sasl_hostname = NULL;
-    nsc->sasl_mech = NULL;
     nsc->sasl_cbs = NULL;
     nsc->sasl_creds = NULL;
     nsc->sasl_secret = NULL;
     nsc->sasl_cbs = NULL;
     nsc->sasl_creds = NULL;
     nsc->sasl_secret = NULL;
@@ -156,11 +163,11 @@ netsec_init(void)
 
 /*
  * Shutdown the connection completely and free all resources.
 
 /*
  * Shutdown the connection completely and free all resources.
- * The connection is not closed, however.
+ * The connection is only closed if the flag is given.
  */
 
 void
  */
 
 void
-netsec_shutdown(netsec_context *nsc)
+netsec_shutdown(netsec_context *nsc, int closeflag)
 {
     if (nsc->ns_userid)
        free(nsc->ns_userid);
 {
     if (nsc->ns_userid)
        free(nsc->ns_userid);
@@ -168,13 +175,17 @@ netsec_shutdown(netsec_context *nsc)
        free(nsc->ns_inbuffer);
     if (nsc->ns_outbuffer)
        free(nsc->ns_outbuffer);
        free(nsc->ns_inbuffer);
     if (nsc->ns_outbuffer)
        free(nsc->ns_outbuffer);
+    if (nsc->sasl_mech)
+       free(nsc->sasl_mech);
+#ifdef OAUTH_SERVICE
+    if (nsc->oauth_service)
+       free(nsc->oauth_service);
+#endif /* OAUTH_SERVICE */
 #ifdef CYRUS_SASL
     if (nsc->sasl_conn)
        sasl_dispose(&nsc->sasl_conn);
     if (nsc->sasl_hostname)
        free(nsc->sasl_hostname);
 #ifdef CYRUS_SASL
     if (nsc->sasl_conn)
        sasl_dispose(&nsc->sasl_conn);
     if (nsc->sasl_hostname)
        free(nsc->sasl_hostname);
-    if (nsc->sasl_mech)
-       free(nsc->sasl_mech);
     if (nsc->sasl_cbs)
        free(nsc->sasl_cbs);
     if (nsc->sasl_creds) {
     if (nsc->sasl_cbs)
        free(nsc->sasl_cbs);
     if (nsc->sasl_creds) {
@@ -203,6 +214,9 @@ netsec_shutdown(netsec_context *nsc)
        BIO_free_all(nsc->ssl_io);
 #endif /* TLS_SUPPORT */
 
        BIO_free_all(nsc->ssl_io);
 #endif /* TLS_SUPPORT */
 
+    if (closeflag && nsc->ns_fd != -1)
+       close(nsc->ns_fd);
+
     free(nsc);
 }
 
     free(nsc);
 }
 
@@ -326,7 +340,7 @@ retry:
     while (count < nsc->ns_inbuflen) {
        count++;
        if (*ptr++ == '\n') {
     while (count < nsc->ns_inbuflen) {
        count++;
        if (*ptr++ == '\n') {
-           char *sptr = nsc->ns_inptr;
+           char *sptr = (char *) nsc->ns_inptr;
            if (count > 1 && *(ptr - 2) == '\r')
                ptr--;
            *--ptr = '\0';
            if (count > 1 && *(ptr - 2) == '\r')
                ptr--;
            *--ptr = '\0';
@@ -355,7 +369,7 @@ retry:
     offset = ptr - nsc->ns_inptr;
 
     if (netsec_fillread(nsc, errstr) != OK)
     offset = ptr - nsc->ns_inptr;
 
     if (netsec_fillread(nsc, errstr) != OK)
-       return NOTOK;
+       return NULL;
 
     ptr = nsc->ns_inptr + offset;
 
 
     ptr = nsc->ns_inptr + offset;
 
@@ -608,6 +622,22 @@ netsec_write(netsec_context *nsc, const void *buffer, size_t size,
     return OK;
 }
 
     return OK;
 }
 
+/*
+ * Our network printf() routine, which really just calls netsec_vprintf().
+
+int
+netsec_printf(netsec_context *nsc, char **errstr, const char *format, ...)
+{
+    va_list ap;
+    int rc;
+
+    va_start(format, ap);
+    rc = netsec_vprintf(nsc, errstr, format, ap);
+    va_end(ap);
+
+    return rc;
+}
+
 /*
  * Write bytes to the network using printf()-style formatting.
  *
 /*
  * Write bytes to the network using printf()-style formatting.
  *
@@ -616,9 +646,9 @@ netsec_write(netsec_context *nsc, const void *buffer, size_t size,
  */
 
 int
  */
 
 int
-netsec_printf(netsec_context *nsc, char **errstr, const char *format, ...)
+netsec_vprintf(netsec_context *nsc, char **errstr, const char *format,
+              va_list ap)
 {
 {
-    va_list ap;
     int rc;
 
     /*
     int rc;
 
     /*
@@ -626,9 +656,7 @@ netsec_printf(netsec_context *nsc, char **errstr, const char *format, ...)
      */
 #ifdef TLS_SUPPORT
     if (nsc->tls_active) {
      */
 #ifdef TLS_SUPPORT
     if (nsc->tls_active) {
-       va_start(ap, format);
        rc = BIO_vprintf(nsc->ssl_io, format, ap);
        rc = BIO_vprintf(nsc->ssl_io, format, ap);
-       va_end(ap);
 
        if (rc <= 0) {
            netsec_err(errstr, "Error writing to TLS connection: %s",
 
        if (rc <= 0) {
            netsec_err(errstr, "Error writing to TLS connection: %s",
@@ -646,10 +674,8 @@ netsec_printf(netsec_context *nsc, char **errstr, const char *format, ...)
      */
 
 retry:
      */
 
 retry:
-    va_start(ap, format);
     rc = vsnprintf((char *) nsc->ns_outptr,
                   nsc->ns_outbufsize - nsc->ns_outbuflen, format, ap);
     rc = vsnprintf((char *) nsc->ns_outptr,
                   nsc->ns_outbufsize - nsc->ns_outbuflen, format, ap);
-    va_end(ap);
 
     if (rc >= (int) (nsc->ns_outbufsize - nsc->ns_outbuflen)) {
        /*
 
     if (rc >= (int) (nsc->ns_outbufsize - nsc->ns_outbuflen)) {
        /*
@@ -936,8 +962,76 @@ netsec_negotiate_sasl(netsec_context *nsc, const char *mechlist, char **errstr)
     unsigned char *outbuf;
     unsigned int saslbuflen, outbuflen;
     sasl_ssf_t *ssf;
     unsigned char *outbuf;
     unsigned int saslbuflen, outbuflen;
     sasl_ssf_t *ssf;
-    int rc, *outbufmax;
+    int *outbufmax;
+#endif
+#ifdef OAUTH_SUPPORT
+    const char *xoauth_client_res;
+#endif /* OAUTH_SUPPORT */
+    int rc;
 
 
+    /*
+     * If we've been passed a requested mechanism, check our mechanism
+     * list from the protocol.  If it's not supported, return an error.
+     */
+
+    if (nsc->sasl_mech) {
+       char **str, *mlist = getcpy(mechlist);
+       int i;
+
+       str = brkstring(mlist, " ", NULL);
+
+       for (i = 0; str[i] != NULL; i++) {
+           if (strcasecmp(nsc->sasl_mech, str[i]) == 0) {
+               break;
+           }
+       }
+
+       i = (str[i] == NULL);
+
+       free(str);
+       free(mlist);
+
+       if (i) {
+           netsec_err(errstr, "Chosen mechanism %s not supported by server",
+                      nsc->sasl_mech);
+           return NOTOK;
+       }
+    }
+
+#ifdef OAUTH_SUPPORT
+    if (strcasecmp(nsc->sasl_mech, "XOAUTH2") == 0) {
+       /*
+        * This should be relatively straightforward, but requires some
+        * help from the plugin.  Basically, if XOAUTH2 is a success,
+        * the plugin has to return success, but no output data.  If
+        * there is output data, it will be assumed that it is the JSON
+        * error message.
+        */
+
+       if (! nsc->oauth_service) {
+           netsec_err(errstr, "Internal error: OAuth2 service name not given");
+           return NOTOK;
+       }
+
+       nsc->sasl_chosen_mech = getcpy(nsc->sasl_mech);
+
+       xoauth_client_res = mh_oauth_do_xoauth(nsc->ns_userid,
+                                              nsc->oauth_service,
+                                              nsc->ns_snoop ? stderr : NULL);
+
+       if (xoauth_client_res == NULL) {
+           netsec_err(errstr, "Internal error: mh_oauth_do_xoauth() "
+                      "returned NULL");
+           return NOTOK;
+       }
+
+#if 0
+       rc = nsc->sasl_proto_cb(NETSEC_SASL_START, 
+#endif
+    }
+#endif /* OAUTH_SUPPORT */
+
+#ifdef CYRUS_SASL
     /*
      * In netsec_set_sasl_params, we've already done all of our setup with
      * sasl_client_init() and sasl_client_new().  So time to set security
     /*
      * In netsec_set_sasl_params, we've already done all of our setup with
      * sasl_client_init() and sasl_client_new().  So time to set security
@@ -971,7 +1065,8 @@ netsec_negotiate_sasl(netsec_context *nsc, const char *mechlist, char **errstr)
      * sasl_client_step() loop (after sasl_client_start, of course).
      */
 
      * sasl_client_step() loop (after sasl_client_start, of course).
      */
 
-    rc = sasl_client_start(nsc->sasl_conn, mechlist, NULL,
+    rc = sasl_client_start(nsc->sasl_conn,
+                          nsc->sasl_mech ? nsc->sasl_mech : mechlist, NULL,
                           (const char **) &saslbuf, &saslbuflen,
                           &chosen_mech);
 
                           (const char **) &saslbuf, &saslbuflen,
                           &chosen_mech);
 
@@ -1164,6 +1259,21 @@ netsec_get_sasl_mechanism(netsec_context *nsc)
 #endif /* CYRUS_SASL */
 }
 
 #endif /* CYRUS_SASL */
 }
 
+/*
+ * Set an OAuth2 service name, if we support it.
+ */
+
+int
+netsec_set_oauth_service(netsec_context *nsc, const char *service)
+{
+#ifdef OAUTH_SUPPORT
+    nsc->oauth_service = getcpy(service);
+    return OK;
+#else /* OAUTH_SUPPORT */
+    return NOTOK;
+#endif /* OAUTH_SUPPORT */
+}
+
 /*
  * Initialize (and enable) TLS for this connection
  */
 /*
  * Initialize (and enable) TLS for this connection
  */
index b8e5a4483c52384a5ef0ef8f9b08af00d071c202..0153dcb15d6fc9bdd0e5bdab480907c6f1c53dd3 100644 (file)
@@ -9,23 +9,7 @@
 #include <h/mh.h>
 #include <h/utils.h>
 #include <h/oauth.h>
 #include <h/mh.h>
 #include <h/utils.h>
 #include <h/oauth.h>
-
-#ifdef CYRUS_SASL
-# include <sasl/sasl.h>
-# include <sasl/saslutil.h>
-# if SASL_VERSION_FULL < 0x020125
-    /* Cyrus SASL 2.1.25 introduced the sasl_callback_ft prototype,
-       which has an explicit void parameter list, according to best
-       practice.  So we need to cast to avoid compile warnings.
-       Provide this prototype for earlier versions. */
-    typedef int (*sasl_callback_ft)();
-# endif /* SASL_VERSION_FULL < 0x020125 */
-#endif /* CYRUS_SASL */
-
-#ifdef TLS_SUPPORT
-#include <openssl/ssl.h>
-#include <openssl/err.h>
-#endif /* TLS_SUPPORT */
+#include <h/netsec.h>
 
 #include <h/popsbr.h>
 #include <h/signals.h>
 
 #include <h/popsbr.h>
 #include <h/signals.h>
@@ -37,34 +21,7 @@ static int poprint = 0;
 static int pophack = 0;
 
 char response[BUFSIZ];
 static int pophack = 0;
 
 char response[BUFSIZ];
-
-static FILE *input;
-static FILE *output;
-
-#ifdef CYRUS_SASL
-static sasl_conn_t *conn;      /* SASL connection state */
-static int sasl_complete = 0;  /* Has sasl authentication succeeded? */
-static int maxoutbuf;          /* Maximum output buffer size */
-static sasl_ssf_t sasl_ssf = 0;        /* Security strength factor */
-static int sasl_get_user(void *, int, const char **, unsigned *);
-static int sasl_get_pass(sasl_conn_t *, void *, int, sasl_secret_t **);
-struct pass_context {
-    char *user;
-    char *password;
-    char *host;
-};
-
-static sasl_callback_t callbacks[] = {
-    { SASL_CB_USER, (sasl_callback_ft) sasl_get_user, NULL },
-#define POP_SASL_CB_N_USER 0
-    { SASL_CB_PASS, (sasl_callback_ft) sasl_get_pass, NULL },
-#define POP_SASL_CB_N_PASS 1
-    { SASL_CB_LOG, NULL, NULL },
-    { SASL_CB_LIST_END, NULL, NULL },
-
-#define SASL_BUFFER_SIZE 262144
-};
-#endif /* CYRUS_SASL */
+static netsec_context *nsc = NULL;
 
 /*
  * static prototypes
 
 /*
  * static prototypes
@@ -73,25 +30,9 @@ static sasl_callback_t callbacks[] = {
 static int command(const char *, ...);
 static int multiline(void);
 
 static int command(const char *, ...);
 static int multiline(void);
 
-#ifdef CYRUS_SASL
-static int pop_auth_sasl(char *, char *, char *);
-#endif /* CYRUS_SASL */
-
-#ifdef TLS_SUPPORT
-static SSL_CTX *sslctx = NULL;
-static SSL *ssl = NULL;
-static BIO *sbior = NULL;
-static BIO *sbiow = NULL;
-static BIO *io = NULL;
-
-static int tls_negotiate(void);
-#endif /* TLS_SUPPORT */
-
-static int tls_active = 0;
-
 static int traverse (int (*)(char *), const char *, ...);
 static int vcommand(const char *, va_list);
 static int traverse (int (*)(char *), const char *, ...);
 static int vcommand(const char *, va_list);
-static int sasl_getline (char *, int, FILE *);
+static int getline (char *, int, FILE *);
 static int sasl_fgetc(FILE *);
 static int putline (char *, FILE *);
 
 static int sasl_fgetc(FILE *);
 static int putline (char *, FILE *);
 
@@ -524,9 +465,9 @@ int
 pop_init (char *host, char *port, char *user, char *pass, char *proxy,
          int snoop, int sasl, char *mech, int tls, const char *oauth_svc)
 {
 pop_init (char *host, char *port, char *user, char *pass, char *proxy,
          int snoop, int sasl, char *mech, int tls, const char *oauth_svc)
 {
-    int fd1, fd2;
+    int fd1;
     char buffer[BUFSIZ];
     char buffer[BUFSIZ];
-    const char *xoauth_client_res = NULL;
+    char *errstr;
 #ifndef CYRUS_SASL
     NMH_UNUSED (sasl);
     NMH_UNUSED (mech);
 #ifndef CYRUS_SASL
     NMH_UNUSED (sasl);
     NMH_UNUSED (mech);
@@ -542,6 +483,26 @@ pop_init (char *host, char *port, char *user, char *pass, char *proxy,
     NMH_UNUSED (xoauth_client_res);
 #endif /* OAUTH_SUPPORT */
 
     NMH_UNUSED (xoauth_client_res);
 #endif /* OAUTH_SUPPORT */
 
+    nsc = netsec_init();  
+
+    if (user)
+       netsec_set_userid(nsc, user);
+
+    if (tls) {
+       if (netsec_set_tls(nsc, 1, &errstr) != OK) {
+           snprintf(response, sizeof(response), "%s", errstr);
+           free(errstr);
+           return NOTOK;
+       }
+    }
+
+    if (oauth_svc != NULL) {
+       if (netsec_set_oauth_service(nsc, oauth_svc) != OK) {
+           snprintf(response, sizeof(response), "OAuth2 not supported");
+           return NOTOK;
+       }
+    }
+
     if (proxy && *proxy) {
        int pid;
        int inpipe[2];    /* for reading from the server */
     if (proxy && *proxy) {
        int pid;
        int inpipe[2];    /* for reading from the server */
@@ -590,34 +551,35 @@ pop_init (char *host, char *port, char *user, char *pass, char *proxy,
        fd2=outpipe[1];
 
     } else {
        fd2=outpipe[1];
 
     } else {
-
        if ((fd1 = client (host, port ? port : "pop3", response,
                           sizeof(response), snoop)) == NOTOK) {
            return NOTOK;
        }
        if ((fd1 = client (host, port ? port : "pop3", response,
                           sizeof(response), snoop)) == NOTOK) {
            return NOTOK;
        }
+    }
+
+    SIGNAL (SIGPIPE, SIG_IGN);
 
 
-       if ((fd2 = dup (fd1)) == NOTOK) {
-           char *s;
+    netsec_set_fd(nsc, fd1);
+    netsec_set_snoop(nsc, snoop);
 
 
-           if ((s = strerror(errno)))
-               snprintf (response, sizeof(response),
-                   "unable to dup connection descriptor: %s", s);
-           else
-               snprintf (response, sizeof(response),
-                   "unable to dup connection descriptor: unknown error");
-           close (fd1);
+    if (tls) {
+       if (netsec_negotiate_tls(nsc, &errstr) != OK) {
+           snprintf(response, sizeof(response), "%s", errstr);
+           free(errstr);
            return NOTOK;
        }
     }
            return NOTOK;
        }
     }
-    if (pop_set (fd1, fd2, snoop) == NOTOK)
-       return NOTOK;
-
-    SIGNAL (SIGPIPE, SIG_IGN);
 
 
-    if (tls && tls_negotiate())
-       return NOTOK;
+    if (sasl) {
+       if (netsec_set_sasl_params(nsc, host, "pop", mech,
+                                  pop_sasl_callback, &errstr) != OK) {
+           snprintf(response, sizeof(response), "%s", errstr);
+           free(errstr);
+           return NOTOK;
+       }
+    }
 
 
-    switch (sasl_getline (response, sizeof response, input)) {
+    switch (getline (response, sizeof response, input)) {
        case OK: 
            if (poprint)
                fprintf (stderr, "<--- %s\n", response);
        case OK: 
            if (poprint)
                fprintf (stderr, "<--- %s\n", response);
@@ -656,35 +618,6 @@ pop_init (char *host, char *port, char *user, char *pass, char *proxy,
     return NOTOK;      /* NOTREACHED */
 }
 
     return NOTOK;      /* NOTREACHED */
 }
 
-int
-pop_set (int in, int out, int snoop)
-{
-
-    if ((input = fdopen (in, "r")) == NULL
-           || (output = fdopen (out, "w")) == NULL) {
-       strncpy (response, "fdopen failed on connection descriptor", sizeof(response));
-       if (input)
-           fclose (input);
-       else
-           close (in);
-       close (out);
-       return NOTOK;
-    }
-
-    poprint = snoop;
-
-    return OK;
-}
-
-
-int
-pop_fd (char *in, int inlen, char *out, int outlen)
-{
-    snprintf (in, inlen, "%d", fileno (input));
-    snprintf (out, outlen, "%d", fileno (output));
-    return OK;
-}
-
 
 /*
  * Find out number of messages available
 
 /*
  * Find out number of messages available
@@ -838,12 +771,8 @@ pop_quit (void)
 int
 pop_done (void)
 {
 int
 pop_done (void)
 {
-#ifdef CYRUS_SASL
-    if (conn)
-       sasl_dispose(&conn);
-#endif /* CYRUS_SASL */
-    fclose (input);
-    fclose (output);
+    if (nsc)
+       netsec_shutdown(nsc, 1);
 
     return OK;
 }
 
     return OK;
 }
@@ -871,14 +800,6 @@ vcommand (const char *fmt, va_list ap)
     vsnprintf (buffer, sizeof(buffer), fmt, ap);
 
     if (poprint) {
     vsnprintf (buffer, sizeof(buffer), fmt, ap);
 
     if (poprint) {
-#ifdef CYRUS_SASL
-       if (sasl_ssf)
-           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;
        if (pophack) {
            if ((cp = strchr (buffer, ' ')))
                *cp = 0;
@@ -1118,102 +1039,3 @@ sasl_fgetc(FILE *f)
     return (int) buffer[0];
 }
 #endif /* CYRUS_SASL */
     return (int) buffer[0];
 }
 #endif /* CYRUS_SASL */
-
-#ifdef TLS_SUPPORT
-/*
- * Negotiate TLS at this point.  Will call pop_done() on failure.
- */
-
-static int
-tls_negotiate(void)
-{
-    BIO *ssl_bio;
-
-    if (! sslctx) {
-       SSL_library_init();
-       SSL_load_error_strings();
-
-       sslctx = SSL_CTX_new(SSLv23_client_method());
-
-       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 (! ssl) {
-       pop_done();
-       advise(NULL, "Unable to create SSL connection: %s",
-              ERR_error_string(ERR_get_error(), NULL));
-       return NOTOK;
-    }
-
-    sbior = BIO_new_socket(fileno(input), BIO_NOCLOSE);
-    sbiow = BIO_new_socket(fileno(output), BIO_NOCLOSE);
-
-    if (sbior == NULL || sbiow == NULL) {
-       pop_done();
-       advise(NULL, "Unable to create BIO endpoints: %s",
-              ERR_error_string(ERR_get_error(), NULL));
-       return NOTOK;
-    }
-
-    SSL_set_bio(ssl, sbior, sbiow);
-    SSL_set_connect_state(ssl);
-
-    /*
-     * Set up a BIO to do buffering for us
-     */
-
-    io = BIO_new(BIO_f_buffer());
-
-    if (! io) {
-       pop_done();
-       advise(NULL, "Unable to create a buffer BIO: %s",
-              ERR_error_string(ERR_get_error(), NULL));
-       return NOTOK;
-    }
-     
-    ssl_bio = BIO_new(BIO_f_ssl());
-
-    if (! ssl_bio) {
-       pop_done();
-       advise(NULL, "Unable to create a SSL BIO: %s",
-              ERR_error_string(ERR_get_error(), NULL));
-       return NOTOK;
-    }
-
-    BIO_set_ssl(ssl_bio, ssl, BIO_CLOSE);
-    BIO_push(io, ssl_bio);
-
-    /*
-     * Try doing the handshake now
-     */
-
-    if (BIO_do_handshake(io) < 1) {
-       pop_done();
-       advise(NULL, "Unable to negotiate SSL connection: %s",
-              ERR_error_string(ERR_get_error(), NULL));
-       return NOTOK;
-    }
-
-    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));
-    }
-
-    tls_active = 1;
-
-    return OK;
-}
-#endif /* TLS_SUPPORT */