SMTP-Relaying: implement a method to choose a relay by sender email address or username
authorWilfried Goesgens <dothebart@citadel.org>
Fri, 27 Jul 2012 12:08:11 +0000 (14:08 +0200)
committerWilfried Goesgens <dothebart@citadel.org>
Fri, 27 Jul 2012 12:08:11 +0000 (14:08 +0200)
citadel/modules/imap/imap_fetch.c
citadel/modules/pop3/serv_pop3.c
citadel/modules/smtp/serv_smtpqueue.c
citadel/modules/smtp/smtp_util.c
citadel/msgbase.c
citadel/msgbase.h

index 82168170f9d14a7b6ca53433f6bb649169cade88..396e6070c6808516cdee483925cec7f8bbad8589 100644 (file)
@@ -190,7 +190,7 @@ void imap_fetch_rfc822(long msgnum, const char *whichfmt) {
                CCC->redirect_buffer = NewStrBufPlain(NULL, SIZ);
                CtdlOutputMsg(msgnum, MT_RFC822,
                        (need_body ? HEADERS_ALL : HEADERS_FAST),
-                       0, 1, NULL, SUPPRESS_ENV_TO
+                       0, 1, NULL, SUPPRESS_ENV_TO, NULL, NULL
                );
                if (!need_body) IAPuts("\r\n"); /* extra trailing newline */
                Imap->cached_rfc822 = CCC->redirect_buffer;
index de4d7a0653efb9b7e6b77ce189cbcf239ab16a10..97681da8366e36b2fa5be74b9b936b79af9f9cda 100644 (file)
@@ -166,7 +166,14 @@ void pop3_add_message(long msgnum, void *userdata) {
        GetMetaData(&smi, msgnum);
        if (smi.meta_rfc822_length <= 0L) {
                CC->redirect_buffer = NewStrBufPlain(NULL, SIZ);
-               CtdlOutputMsg(msgnum, MT_RFC822, HEADERS_ALL, 0, 1, NULL, SUPPRESS_ENV_TO);
+
+               CtdlOutputMsg(msgnum,
+                             MT_RFC822,
+                             HEADERS_ALL,
+                             0, 1, NULL,
+                             SUPPRESS_ENV_TO,
+                             NULL, NULL);
+
                smi.meta_rfc822_length = StrLength(CC->redirect_buffer);
                FreeStrBuf(&CC->redirect_buffer); /* TODO: WHEW, all this for just knowing the length???? */
                PutMetaData(&smi);
@@ -324,9 +331,9 @@ void pop3_retr(char *argbuf) {
 
        cprintf("+OK Message %d:\r\n", which_one);
        CtdlOutputMsg(POP3->msgs[which_one - 1].msgnum,
-               MT_RFC822, HEADERS_ALL, 0, 1, NULL,
-               (ESC_DOT|SUPPRESS_ENV_TO)
-       );
+                     MT_RFC822, HEADERS_ALL, 0, 1, NULL,
+                     (ESC_DOT|SUPPRESS_ENV_TO),
+                     NULL, NULL);
        cprintf(".\r\n");
 }
 
@@ -356,7 +363,14 @@ void pop3_top(char *argbuf) {
        }
 
        CC->redirect_buffer = NewStrBufPlain(NULL, SIZ);
-       CtdlOutputMsg(POP3->msgs[which_one - 1].msgnum, MT_RFC822, HEADERS_ALL, 0, 1, NULL, SUPPRESS_ENV_TO);
+
+       CtdlOutputMsg(POP3->msgs[which_one - 1].msgnum,
+                     MT_RFC822,
+                     HEADERS_ALL,
+                     0, 1, NULL,
+                     SUPPRESS_ENV_TO,
+                     NULL, NULL);
+
        msgtext = CC->redirect_buffer;
        CC->redirect_buffer = NULL;
 
index 0fa65bea2000901c0098d814f5fcabbc9f0cb481..3c4c2cb3e5c7b53d121c676e8d36fd79835c934f 100644 (file)
@@ -473,7 +473,7 @@ void QItem_Handle_Attempted(OneQueItem *Item, StrBuf *Line, const char **Pos)
 /**
  * this one has to have the context for loading the message via the redirect buffer...
  */
-StrBuf *smtp_load_msg(OneQueItem *MyQItem, int n)
+StrBuf *smtp_load_msg(OneQueItem *MyQItem, int n, char **Author, char **Address)
 {
        CitContext *CCC=CC;
        StrBuf *SendMsg;
@@ -482,7 +482,9 @@ StrBuf *smtp_load_msg(OneQueItem *MyQItem, int n)
        CtdlOutputMsg(MyQItem->MessageID,
                      MT_RFC822, HEADERS_ALL,
                      0, 1, NULL,
-                     (ESC_DOT|SUPPRESS_ENV_TO) );
+                     (ESC_DOT|SUPPRESS_ENV_TO),
+                     Author,
+                     Address);
 
        SendMsg = CCC->redirect_buffer;
        CCC->redirect_buffer = NULL;
@@ -704,6 +706,80 @@ void smtpq_do_bounce(OneQueItem *MyQItem, StrBuf *OMsgTxt)
        SMTPCM_syslog(LOG_DEBUG, "Done processing bounces\n");
 }
 
+ParsedURL *LoadRelayUrls(OneQueItem *MyQItem,
+                        char *Author,
+                        char *Address)
+{
+       int nRelays = 0;
+       ParsedURL *RelayUrls = NULL;
+       char mxbuf[SIZ];
+       ParsedURL **Url = &MyQItem->URL;
+
+       nRelays = get_hosts(mxbuf, "fallbackhost");
+       if (nRelays > 0) {
+               StrBuf *All;
+               StrBuf *One;
+               const char *Pos = NULL;
+               All = NewStrBufPlain(mxbuf, -1);
+               One = NewStrBufPlain(NULL, StrLength(All) + 1);
+               
+               while ((Pos != StrBufNOTNULL) &&
+                      ((Pos == NULL) ||
+                       !IsEmptyStr(Pos)))
+               {
+                       StrBufExtract_NextToken(One, All, &Pos, '|');
+                       if (!ParseURL(Url, One, DefaultMXPort)) {
+                               SMTPC_syslog(LOG_DEBUG,
+                                            "Failed to parse: %s\n",
+                                            ChrPtr(One));
+                       }
+                       else {
+                               (*Url)->IsRelay = 1;
+                               MyQItem->HaveRelay = 1;
+                       }
+               }
+               FreeStrBuf(&All);
+               FreeStrBuf(&One);
+       }
+       nRelays = get_hosts(mxbuf, "smarthost");
+       if (nRelays > 0) {
+               char *User;
+               StrBuf *All;
+               StrBuf *One;
+               const char *Pos = NULL;
+               All = NewStrBufPlain(mxbuf, -1);
+               One = NewStrBufPlain(NULL, StrLength(All) + 1);
+               
+               while ((Pos != StrBufNOTNULL) &&
+                      ((Pos == NULL) ||
+                       !IsEmptyStr(Pos)))
+               {
+                       StrBufExtract_NextToken(One, All, &Pos, '|');
+                       User = strchr(ChrPtr(One), ' ');
+                       if (User != NULL) {
+                               if (!strcmp(User + 1, Author) ||
+                                   !strcmp(User + 1, Address))
+                                       StrBufCutAt(One, 0, User);
+                               else
+                                       continue;
+
+                       }
+                       if (!ParseURL(Url, One, DefaultMXPort)) {
+                               SMTPC_syslog(LOG_DEBUG,
+                                            "Failed to parse: %s\n",
+                                            ChrPtr(One));
+                       }
+                       else {
+                               ///if (!Url->IsIP)) // todo dupe me fork ipv6
+                               (*Url)->IsRelay = 1;
+                               MyQItem->HaveRelay = 1;
+                       }
+               }
+               FreeStrBuf(&All);
+               FreeStrBuf(&One);
+       }
+       return RelayUrls;
+}
 /*
  * smtp_do_procmsg()
  *
@@ -713,6 +789,8 @@ void smtp_do_procmsg(long msgnum, void *userdata) {
        time_t now;
        int mynumsessions = num_sessions;
        struct CtdlMessage *msg = NULL;
+       char *Author = NULL;
+       char *Address = NULL;
        char *instr = NULL;
        StrBuf *PlainQItem;
        OneQueItem *MyQItem;
@@ -721,8 +799,6 @@ void smtp_do_procmsg(long msgnum, void *userdata) {
        void *vQE;
        long len;
        const char *Key;
-       int nRelays = 0;
-       ParsedURL *RelayUrls = NULL;
        int HaveBuffers = 0;
        StrBuf *Msg =NULL;
 
@@ -814,64 +890,6 @@ void smtp_do_procmsg(long msgnum, void *userdata) {
                return;
        }
 
-       {
-               char mxbuf[SIZ];
-               ParsedURL **Url = &MyQItem->URL;
-               nRelays = get_hosts(mxbuf, "fallbackhost");
-               if (nRelays > 0) {
-                       StrBuf *All;
-                       StrBuf *One;
-                       const char *Pos = NULL;
-                       All = NewStrBufPlain(mxbuf, -1);
-                       One = NewStrBufPlain(NULL, StrLength(All) + 1);
-
-                       while ((Pos != StrBufNOTNULL) &&
-                              ((Pos == NULL) ||
-                               !IsEmptyStr(Pos)))
-                       {
-                               StrBufExtract_NextToken(One, All, &Pos, '|');
-                               if (!ParseURL(Url, One, DefaultMXPort)) {
-                                       SMTPC_syslog(LOG_DEBUG,
-                                                    "Failed to parse: %s\n",
-                                                    ChrPtr(One));
-                               }
-                               else {
-                                       (*Url)->IsRelay = 1;
-                                       MyQItem->HaveRelay = 1;
-                               }
-                       }
-                       FreeStrBuf(&All);
-                       FreeStrBuf(&One);
-               }
-               nRelays = get_hosts(mxbuf, "smarthost");
-               if (nRelays > 0) {
-                       StrBuf *All;
-                       StrBuf *One;
-                       const char *Pos = NULL;
-                       All = NewStrBufPlain(mxbuf, -1);
-                       One = NewStrBufPlain(NULL, StrLength(All) + 1);
-
-                       while ((Pos != StrBufNOTNULL) &&
-                              ((Pos == NULL) ||
-                               !IsEmptyStr(Pos)))
-                       {
-                               StrBufExtract_NextToken(One, All, &Pos, '|');
-                               if (!ParseURL(Url, One, DefaultMXPort)) {
-                                       SMTPC_syslog(LOG_DEBUG,
-                                                    "Failed to parse: %s\n",
-                                                    ChrPtr(One));
-                               }
-                               else {
-                                       ///if (!Url->IsIP)) // todo dupe me fork ipv6
-                                       (*Url)->IsRelay = 1;
-                                       MyQItem->HaveRelay = 1;
-                               }
-                       }
-                       FreeStrBuf(&All);
-                       FreeStrBuf(&One);
-               }
-
-       }
 
        It = GetNewHashPos(MyQItem->MailQEntries, 0);
        while (GetNextHashPos(MyQItem->MailQEntries, It, &len, &Key, &vQE))
@@ -910,11 +928,17 @@ void smtp_do_procmsg(long msgnum, void *userdata) {
 
        if (MyQItem->ActiveDeliveries > 0)
        {
+               ParsedURL *RelayUrls = NULL;
                int nActivated = 0;
                int n = MsgCount++;
                int m = MyQItem->ActiveDeliveries;
                int i = 1;
-               Msg = smtp_load_msg(MyQItem, n);
+
+               Msg = smtp_load_msg(MyQItem, n, &Author, &Address);
+               RelayUrls = LoadRelayUrls(MyQItem, Author, Address);
+               if (Author != NULL) free (Author);
+               if (Address != NULL) free (Address);
+
                It = GetNewHashPos(MyQItem->MailQEntries, 0);
                while ((i <= m) &&
                       (GetNextHashPos(MyQItem->MailQEntries,
index 861ee97636efe375be66af2fe15278f1a253832e..589f8855305f4eb889d087a745e598d10cfba435 100644 (file)
@@ -271,7 +271,8 @@ void smtp_do_bounce(char *instr, StrBuf *OMsgTxt)
                        CtdlOutputMsg(omsgid,
                                      MT_RFC822,
                                      HEADERS_ALL,
-                                     0, 1, NULL, 0);
+                                     0, 1, NULL, 0,
+                                     NULL, NULL);
 
                        StrBufAppendBuf(BounceMB, CC->redirect_buffer, 0);
                        FreeStrBuf(&CC->redirect_buffer);
index 8cc816e8184a368e0a096ae6f6a6a94671035de7..abb47ca161e0c8767c62bd323faff5690eefb1e0 100644 (file)
@@ -1654,7 +1654,9 @@ int CtdlOutputMsg(long msg_num,           /* message number (local) to fetch */
                  int do_proto,         /* do Citadel protocol responses? */
                  int crlf,             /* Use CRLF newlines instead of LF? */
                  char *section,        /* NULL or a message/rfc822 section */
-                 int flags             /* various flags; see msgbase.h */
+                 int flags,            /* various flags; see msgbase.h */
+                 char **Author,
+                 char **Address
 ) {
        struct CitContext *CCC = CC;
        struct CtdlMessage *TheMessage = NULL;
@@ -1732,6 +1734,17 @@ int CtdlOutputMsg(long msg_num,          /* message number (local) to fetch */
                        *extract_encapsulated_message,
                        NULL, NULL, (void *)&encap, 0
                );
+
+               if ((Author != NULL) && (*Author == NULL))
+               {
+                       *Author = TheMessage->cm_fields['A'];
+                       TheMessage->cm_fields['A'] = NULL;
+               }
+               if ((Address != NULL) && (*Address == NULL))
+               {       
+                       *Address = TheMessage->cm_fields['F'];
+                       TheMessage->cm_fields['F'] = NULL;
+               }
                CtdlFreeMessage(TheMessage);
                TheMessage = NULL;
 
@@ -1762,6 +1775,17 @@ int CtdlOutputMsg(long msg_num,          /* message number (local) to fetch */
        /* Ok, output the message now */
        if (retcode == CIT_OK)
                retcode = CtdlOutputPreLoadedMsg(TheMessage, mode, headers_only, do_proto, crlf, flags);
+       if ((Author != NULL) && (*Author == NULL))
+       {
+               *Author = TheMessage->cm_fields['A'];
+               TheMessage->cm_fields['A'] = NULL;
+       }
+       if ((Address != NULL) && (*Address == NULL))
+       {       
+               *Address = TheMessage->cm_fields['F'];
+               TheMessage->cm_fields['F'] = NULL;
+       }
+
        CtdlFreeMessage(TheMessage);
 
        return(retcode);
@@ -2541,7 +2565,7 @@ void cmd_msg0(char *cmdbuf)
        msgid = extract_long(cmdbuf, 0);
        headers_only = extract_int(cmdbuf, 1);
 
-       CtdlOutputMsg(msgid, MT_CITADEL, headers_only, 1, 0, NULL, 0);
+       CtdlOutputMsg(msgid, MT_CITADEL, headers_only, 1, 0, NULL, 0, NULL, NULL);
        return;
 }
 
@@ -2557,7 +2581,7 @@ void cmd_msg2(char *cmdbuf)
        msgid = extract_long(cmdbuf, 0);
        headers_only = extract_int(cmdbuf, 1);
 
-       CtdlOutputMsg(msgid, MT_RFC822, headers_only, 1, 1, NULL, 0);
+       CtdlOutputMsg(msgid, MT_RFC822, headers_only, 1, 1, NULL, 0, NULL, NULL);
 }
 
 
@@ -2611,7 +2635,7 @@ void cmd_msg4(char *cmdbuf)
 
        msgid = extract_long(cmdbuf, 0);
        extract_token(section, cmdbuf, 1, '|', sizeof section);
-       CtdlOutputMsg(msgid, MT_MIME, 0, 1, 0, (section[0] ? section : NULL) , 0);
+       CtdlOutputMsg(msgid, MT_MIME, 0, 1, 0, (section[0] ? section : NULL) , 0, NULL, NULL);
 }
 
 
@@ -2644,7 +2668,7 @@ void cmd_opna(char *cmdbuf)
        extract_token(desired_section, cmdbuf, 1, '|', sizeof desired_section);
        safestrncpy(CC->download_desired_section, desired_section,
                sizeof CC->download_desired_section);
-       CtdlOutputMsg(msgid, MT_DOWNLOAD, 0, 1, 1, NULL, 0);
+       CtdlOutputMsg(msgid, MT_DOWNLOAD, 0, 1, 1, NULL, 0, NULL, NULL);
 }                      
 
 
@@ -2660,8 +2684,8 @@ void cmd_dlat(char *cmdbuf)
        extract_token(desired_section, cmdbuf, 1, '|', sizeof desired_section);
        safestrncpy(CC->download_desired_section, desired_section,
                sizeof CC->download_desired_section);
-       CtdlOutputMsg(msgid, MT_SPEW_SECTION, 0, 1, 1, NULL, 0);
-}                      
+       CtdlOutputMsg(msgid, MT_SPEW_SECTION, 0, 1, 1, NULL, 0, NULL, NULL);
+}
 
 
 /*
index 017942f8d600f52bd001ab7382ee7f6d8ba61fe6..f33cbb44acabcbd73157c52d17f2b9a5b547a1b6 100644 (file)
@@ -165,7 +165,9 @@ int CtdlOutputMsg(long msg_num,             /* message number (local) to fetch */
                  int do_proto,         /* do Citadel protocol responses? */
                  int crlf,             /* 0=LF, 1=CRLF */
                  char *section,                /* output a message/rfc822 section */
-                 int flags             /* should the bessage be exported clean? */
+                 int flags,            /* should the bessage be exported clean? */
+                 char **Author,        /* if you want to know the author of the message... */
+                 char **Address        /* if you want to know the sender address of the message... */
 );
 
 /* Flags which may be passed to CtdlOutputMsg() and CtdlOutputPreLoadedMsg() */