- if (eof)
- break;
- }
- free (cp);
-
- switch (smhear ()) {
- case 250:
- case 251:
-#ifdef SENDMAILBUG
-ok_dot:
-#endif
- result = RP_OK;
- unlink (file);
- break;
-
- case 451:
-#ifdef SENDMAILBUG
- goto ok_dot;
-#endif
- case 452:
- default:
- result = RP_NO;
- if (gp) {
- snprintf (buffer, sizeof(buffer), "%*.*sA.bulk", k, k, file);
- unlink (buffer);
- fclose (gp);
- gp = NULL;
- }
- break;
-
- case 552:
- case 554:
-no_dice:
- result = RP_NDEL;
- if (k <= 0 || strcmp (sender, "<>\r\n") == 0) {
- unlink (file);
- break;
- }
- if (gp) {
- fflush (gp);
- ftruncate (fileno (gp), 0L);
- fseek (gp, 0L, SEEK_SET);
- }
- else {
- snprintf (buffer, sizeof(buffer), "%*.*sA.bulk", k, k, file);
- if ((gp = fopen (buffer, "w")) == NULL)
- break;
- }
- fprintf (gp, "MAIL FROM:<>\r\nRCPT TO:%sDATA\r\n", sender);
- i = strlen (sender);
- fprintf (gp, "To: %*.*s\r\nSubject: Failed mail (%s)\r\n",
- i - 4, i - 4, sender + 1, file);
- fprintf (gp, "Date: %s\r\nFrom: Postmaster@%s\r\n\r\n",
- dtimenow (0), LocalName ());
- break;
- }
-
- if (gp) {
- fputs ("\r\n------- Begin Returned message\r\n\r\n", gp);
- fseek (fp, pos, SEEK_SET);
- while (fgets (buffer, sizeof(buffer), fp)) {
- if (buffer[0] == '-')
- fputs ("- ", gp);
- if (strcmp (buffer, ".\r\n"))
- fputs (buffer, gp);
- }
- fputs ("\r\n------- End Returned Message\r\n\r\n.\r\n", gp);
- fflush (gp);
- if (!ferror (gp))
- unlink (file);
- fclose (gp);
- }
- fclose (fp);
-
- return result;
-}
-#endif /* MPOP */
-
-
-#ifdef CYRUS_SASL
-/*
- * This function implements SASL authentication for SMTP. If this function
- * completes successfully, then authentication is successful and we've
- * (optionally) negotiated a security layer.
- *
- * Right now we don't support session encryption.
- */
-static int
-sm_auth_sasl(char *user, char *mechlist, char *host)
-{
- int result, status, outlen;
- unsigned int buflen;
- char *buf, outbuf[BUFSIZ];
- const char *chosen_mech;
- sasl_security_properties_t secprops;
- sasl_external_properties_t extprops;
- sasl_ssf_t *ssf;
- int *outbufmax;
-
- /*
- * Initialize the callback contexts
- */
-
- if (user == NULL)
- user = getusername();
-
- callbacks[SM_SASL_N_CB_USER].context = user;
-
- /*
- * This is a _bit_ of a hack ... but if the hostname wasn't supplied
- * to us on the command line, then call getpeername and do a
- * reverse-address lookup on the IP address to get the name.
- */
-
- if (!host) {
- struct sockaddr_in sin;
- int len = sizeof(sin);
- struct hostent *hp;
-
- if (getpeername(fileno(sm_wfp), (struct sockaddr *) &sin, &len) < 0) {
- sm_ierror("getpeername on SMTP socket failed: %s",
- strerror(errno));
- return NOTOK;
- }
-
- if ((hp = gethostbyaddr((void *) &sin.sin_addr, sizeof(sin.sin_addr),
- sin.sin_family)) == NULL) {
- sm_ierror("DNS lookup on IP address %s failed",
- inet_ntoa(sin.sin_addr));
- return NOTOK;
- }
-
- host = strdup(hp->h_name);
- }
-
- sasl_pw_context[0] = host;
- sasl_pw_context[1] = user;
-
- callbacks[SM_SASL_N_CB_PASS].context = sasl_pw_context;
-
- result = sasl_client_init(callbacks);
-
- if (result != SASL_OK) {
- sm_ierror("SASL library initialization failed: %s",
- sasl_errstring(result, NULL, NULL));
- return NOTOK;
- }
-
- result = sasl_client_new("smtp", host, NULL, SASL_SECURITY_LAYER, &conn);
-
- if (result != SASL_OK) {
- sm_ierror("SASL client initialization failed: %s",
- sasl_errstring(result, NULL, NULL));
- return NOTOK;
- }
-
- /*
- * Initialize the security properties
- */
-
- memset(&secprops, 0, sizeof(secprops));
- secprops.maxbufsize = BUFSIZ;
- secprops.max_ssf = 0; /* XXX change this when we do encryption */
- memset(&extprops, 0, sizeof(extprops));
-
- result = sasl_setprop(conn, SASL_SEC_PROPS, &secprops);
-
- if (result != SASL_OK) {
- sm_ierror("SASL security property initialization failed: %s",
- sasl_errstring(result, NULL, NULL));
- return NOTOK;
- }
-
- result = sasl_setprop(conn, SASL_SSF_EXTERNAL, &extprops);
-
- if (result != SASL_OK) {
- sm_ierror("SASL external property initialization failed: %s",
- sasl_errstring(result, NULL, NULL));
- return NOTOK;