]> diplodocus.org Git - nmh/blobdiff - sbr/netsec.c
Garbage-collect all of this unused code.
[nmh] / sbr / netsec.c
index 5bfbea60ccc7b4d0f9f303b025eb2c8a1b2c951c..3fd31854f568c56655493f6fbf499a978931cd41 100644 (file)
@@ -56,6 +56,8 @@ static SSL_CTX *sslctx = NULL;                /* SSL Context */
 struct _netsec_context {
     int ns_fd;                 /* Descriptor for network connection */
     int ns_snoop;              /* If true, display network data */
 struct _netsec_context {
     int ns_fd;                 /* Descriptor for network connection */
     int ns_snoop;              /* If true, display network data */
+    int ns_snoop_noend;                /* If true, didn't get a CR/LF on last line */
+    netsec_snoop_callback ns_snoop_cb; /* Snoop output callback */
     int ns_timeout;            /* Network read timeout, in seconds */
     char *ns_userid;           /* Userid for authentication */
     unsigned char *ns_inbuffer;        /* Our read input buffer */
     int ns_timeout;            /* Network read timeout, in seconds */
     char *ns_userid;           /* Userid for authentication */
     unsigned char *ns_inbuffer;        /* Our read input buffer */
@@ -122,6 +124,8 @@ netsec_init(void)
 
     nsc->ns_fd = -1;
     nsc->ns_snoop = 0;
 
     nsc->ns_fd = -1;
     nsc->ns_snoop = 0;
+    nsc->ns_snoop_noend = 0;
+    nsc->ns_snoop_cb = NULL;
     nsc->ns_userid = NULL;
     nsc->ns_timeout = 60;      /* Our default */
     nsc->ns_inbufsize = NETSEC_BUFSIZE;
     nsc->ns_userid = NULL;
     nsc->ns_timeout = 60;      /* Our default */
     nsc->ns_inbufsize = NETSEC_BUFSIZE;
@@ -342,6 +346,21 @@ retry:
                *len = ptr - nsc->ns_inptr;
            nsc->ns_inptr += count;
            nsc->ns_inbuflen -= count;
                *len = ptr - nsc->ns_inptr;
            nsc->ns_inptr += count;
            nsc->ns_inbuflen -= count;
+           if (nsc->ns_snoop) {
+#ifdef CYRUS_SASL
+               if (nsc->sasl_seclayer)
+                   fprintf(stderr, "(sasl-encrypted) ");
+#endif /* CYRUS_SASL */
+#ifdef TLS_SUPPORT
+               if (nsc->tls_active)
+                   fprintf(stderr, "(tls-encrypted) ");
+#endif /* TLS_SUPPORT */
+               fprintf(stderr, "<= ");
+               if (nsc->ns_snoop_cb)
+                   nsc->ns_snoop_cb(nsc, sptr, strlen(sptr));
+               else
+                   fprintf(stderr, "%s\n", sptr);
+           }
            return sptr;
        }
     }
            return sptr;
        }
     }
@@ -711,6 +730,34 @@ retry:
        }
     }
 
        }
     }
 
+    if (nsc->ns_snoop) {
+       int outlen = rc;
+       if (outlen > 0 && nsc->ns_outptr[outlen - 1] == '\n') {
+           outlen--;
+           if (outlen > 0 && nsc->ns_outptr[outlen - 1] == '\r')
+               outlen--;
+       } else {
+           nsc->ns_snoop_noend = 1;
+       }
+       if (outlen > 0 || nsc->ns_snoop_noend == 0) {
+#ifdef CYRUS_SASL
+           if (nsc->sasl_seclayer)
+               fprintf(stderr, "(sasl-encrypted) ");
+#endif /* CYRUS_SASL */
+#ifdef TLS_SUPPORT
+           if (nsc->tls_active)
+               fprintf(stderr, "(tls-encrypted) ");
+#endif /* TLS_SUPPORT */
+           fprintf(stderr, "=> ");
+           if (nsc->ns_snoop_cb)
+               nsc->ns_snoop_cb(nsc, nsc->ns_outptr, outlen);
+           else
+                fprintf(stderr, "%.*s\n", outlen, nsc->ns_outptr); 
+       } else {
+           nsc->ns_snoop_noend = 0;
+       }
+    }
+
     nsc->ns_outptr += rc;
     nsc->ns_outbuflen += rc;
 
     nsc->ns_outptr += rc;
     nsc->ns_outbuflen += rc;
 
@@ -974,7 +1021,8 @@ netsec_negotiate_sasl(netsec_context *nsc, const char *mechlist, char **errstr)
     int *outbufmax;
 #endif
 #ifdef OAUTH_SUPPORT
     int *outbufmax;
 #endif
 #ifdef OAUTH_SUPPORT
-    const char *xoauth_client_res;
+    unsigned char *xoauth_client_res;
+    size_t xoauth_client_res_len;
 #endif /* OAUTH_SUPPORT */
     int rc;
 
 #endif /* OAUTH_SUPPORT */
     int rc;
 
@@ -1008,11 +1056,11 @@ netsec_negotiate_sasl(netsec_context *nsc, const char *mechlist, char **errstr)
     }
 
 #ifdef OAUTH_SUPPORT
     }
 
 #ifdef OAUTH_SUPPORT
-    if (strcasecmp(nsc->sasl_mech, "XOAUTH2") == 0) {
+    if (nsc->sasl_mech && strcasecmp(nsc->sasl_mech, "XOAUTH2") == 0) {
        /*
         * This should be relatively straightforward, but requires some
         * help from the plugin.  Basically, if XOAUTH2 is a success,
        /*
         * 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
+        * the callback has to return success, but no output data.  If
         * there is output data, it will be assumed that it is the JSON
         * error message.
         */
         * there is output data, it will be assumed that it is the JSON
         * error message.
         */
@@ -1024,19 +1072,46 @@ netsec_negotiate_sasl(netsec_context *nsc, const char *mechlist, char **errstr)
 
        nsc->sasl_chosen_mech = getcpy(nsc->sasl_mech);
 
 
        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");
+       if (mh_oauth_do_xoauth(nsc->ns_userid, nsc->oauth_service,
+                              &xoauth_client_res, &xoauth_client_res_len,
+                              nsc->ns_snoop ? stderr : NULL) != OK) {
+           netsec_err(errstr, "Internal error: Unable to get OAuth2 "
+                      "bearer token");
            return NOTOK;
        }
 
            return NOTOK;
        }
 
-#if 0
-       rc = nsc->sasl_proto_cb(NETSEC_SASL_START, 
-#endif
+       rc = nsc->sasl_proto_cb(NETSEC_SASL_START, xoauth_client_res,
+                               xoauth_client_res_len, NULL, 0, errstr);
+       free(xoauth_client_res);
+
+       if (rc != OK)
+           return NOTOK;
+
+       /*
+        * Okay, we need to do a NETSEC_SASL_FINISH now.  If we return
+        * success, we indicate that with no output data.  But if we
+        * fail, then send a blank message and get the resulting
+        * error.
+        */
+
+       rc = nsc->sasl_proto_cb(NETSEC_SASL_FINISH, NULL, 0, NULL, 0, errstr);
+
+       if (rc != OK) {
+           /*
+            * We're going to assume the error here is a JSON response;
+            * we ignore it and send a blank message in response.  We should
+            * then get either an +OK or -ERR
+            */
+           free(errstr);
+           nsc->sasl_proto_cb(NETSEC_SASL_WRITE, NULL, 0, NULL, 0, NULL);
+           rc = nsc->sasl_proto_cb(NETSEC_SASL_FINISH, NULL, 0, NULL, 0,
+                                   errstr);
+           if (rc == 0) {
+               netsec_err(errstr, "Unexpected success after OAuth failure!");
+           }
+           return NOTOK;
+       }
+       return OK;
     }
 #endif /* OAUTH_SUPPORT */
 
     }
 #endif /* OAUTH_SUPPORT */
 
@@ -1087,21 +1162,10 @@ netsec_negotiate_sasl(netsec_context *nsc, const char *mechlist, char **errstr)
 
     nsc->sasl_chosen_mech = getcpy(chosen_mech);
 
 
     nsc->sasl_chosen_mech = getcpy(chosen_mech);
 
-    if (nsc->sasl_proto_cb(NETSEC_SASL_START, saslbuf, saslbuflen, &outbuf,
-                          &outbuflen, errstr) != OK)
+    if (nsc->sasl_proto_cb(NETSEC_SASL_START, saslbuf, saslbuflen, NULL, 0,
+                          errstr) != OK)
        return NOTOK;
 
        return NOTOK;
 
-    if (outbuflen > 0) {
-       if (netsec_write(nsc, outbuf, outbuflen, errstr) != OK) {
-           free(outbuf);
-           return NOTOK;
-       }
-       free(outbuf);
-       if (netsec_flush(nsc, errstr) != OK)
-           return NOTOK;
-    }
-
-
     /*
      * We've written out our first message; enter in the step loop
      */
     /*
      * We've written out our first message; enter in the step loop
      */
@@ -1114,14 +1178,7 @@ netsec_negotiate_sasl(netsec_context *nsc, const char *mechlist, char **errstr)
 
        if (nsc->sasl_proto_cb(NETSEC_SASL_READ, NULL, 0, &outbuf, &outbuflen,
                               errstr) != OK) {
 
        if (nsc->sasl_proto_cb(NETSEC_SASL_READ, NULL, 0, &outbuf, &outbuflen,
                               errstr) != OK) {
-           if (nsc->sasl_proto_cb(NETSEC_SASL_CANCEL, NULL, 0, &outbuf,
-                                  &outbuflen, NULL) == OK) {
-               if (outbuflen > 0) {
-                   netsec_write(nsc, outbuf, outbuflen, NULL);
-                   netsec_flush(nsc, NULL);
-                   free(outbuf);
-               }
-           }
+           nsc->sasl_proto_cb(NETSEC_SASL_CANCEL, NULL, 0, NULL, 0, NULL);
            return NOTOK;
        }
 
            return NOTOK;
        }
 
@@ -1134,39 +1191,15 @@ netsec_negotiate_sasl(netsec_context *nsc, const char *mechlist, char **errstr)
        if (rc != SASL_OK && rc != SASL_CONTINUE) {
            netsec_err(errstr, "SASL client negotiation failed: %s",
                       sasl_errdetail(nsc->sasl_conn));
        if (rc != SASL_OK && rc != SASL_CONTINUE) {
            netsec_err(errstr, "SASL client negotiation failed: %s",
                       sasl_errdetail(nsc->sasl_conn));
-           if (nsc->sasl_proto_cb(NETSEC_SASL_CANCEL, NULL, 0, &outbuf,
-                                  &outbuflen, NULL) == OK) {
-               if (outbuflen > 0) {
-                   netsec_write(nsc, outbuf, outbuflen, NULL);
-                   netsec_flush(nsc, NULL);
-                   free(outbuf);
-               }
-           }
+           nsc->sasl_proto_cb(NETSEC_SASL_CANCEL, NULL, 0, NULL, 0, NULL);
            return NOTOK;
        }
 
        if (nsc->sasl_proto_cb(NETSEC_SASL_WRITE, saslbuf, saslbuflen,
            return NOTOK;
        }
 
        if (nsc->sasl_proto_cb(NETSEC_SASL_WRITE, saslbuf, saslbuflen,
-                              &outbuf, &outbuflen, errstr) != OK) {
-           if (nsc->sasl_proto_cb(NETSEC_SASL_CANCEL, NULL, 0, &outbuf,
-                                  &outbuflen, NULL) == OK) {
-               if (outbuflen > 0) {
-                   netsec_write(nsc, outbuf, outbuflen, NULL);
-                   netsec_flush(nsc, NULL);
-                   free(outbuf);
-               }
-           }
+                              NULL, 0, errstr) != OK) {
+           nsc->sasl_proto_cb(NETSEC_SASL_CANCEL, NULL, 0, NULL, 0, NULL);
            return NOTOK;
        }
            return NOTOK;
        }
-
-       if (outbuflen > 0) {
-           if (netsec_write(nsc, outbuf, outbuflen, errstr) != OK) {
-               free(outbuf);
-               return NOTOK;
-           }
-           free(outbuf);
-           if (netsec_flush(nsc, errstr) != OK)
-               return NOTOK;
-       }
     }
 
     /*
     }
 
     /*