X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=citadel%2Fmsgbase.c;h=f44dfe66cb339cc3662ce65f8d798aa2b9cc9a05;hb=a8bb950b3da00b7933912c27e2ad92814b10d75b;hp=8cc816e8184a368e0a096ae6f6a6a94671035de7;hpb=20155853fa2a5bf356bb81ede9af9cabe06fb861;p=citadel.git diff --git a/citadel/msgbase.c b/citadel/msgbase.c index 8cc816e81..f44dfe66c 100644 --- a/citadel/msgbase.c +++ b/citadel/msgbase.c @@ -38,6 +38,9 @@ #include #include #include + +#include "md5.h" + #include #include "citadel.h" #include "server.h" @@ -1654,7 +1657,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 +1737,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 +1778,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); @@ -1789,7 +1816,7 @@ char *qp_encode_email_addrs(char *source) if (source == NULL) return source; if (IsEmptyStr(source)) return source; - cit_backtrace(); + if (MessageDebugEnabled != 0) cit_backtrace(); MSG_syslog(LOG_DEBUG, "qp_encode_email_addrs: [%s]\n", source); AddrPtr = malloc (sizeof (long) * nAddrPtrMax); @@ -2541,7 +2568,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 +2584,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 +2638,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 +2671,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 +2687,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); +} /* @@ -3465,18 +3492,16 @@ long CtdlSubmitMsg(struct CtdlMessage *msg, /* message to save */ } - -void aide_message (char *text, char *subject) -{ - quickie_message("Citadel",NULL,NULL,AIDEROOM,text,FMT_CITADEL,subject); -} - - /* * Convenience function for generating small administrative messages. */ -void quickie_message(const char *from, const char *fromaddr, char *to, char *room, const char *text, - int format_type, const char *subject) +void quickie_message(const char *from, + const char *fromaddr, + char *to, + char *room, + const char *text, + int format_type, + const char *subject) { struct CtdlMessage *msg; struct recptypes *recp = NULL; @@ -3517,6 +3542,74 @@ void quickie_message(const char *from, const char *fromaddr, char *to, char *roo if (recp != NULL) free_recipients(recp); } +void flood_protect_quickie_message(const char *from, + const char *fromaddr, + char *to, + char *room, + const char *text, + int format_type, + const char *subject, + int nCriterions, + const char **CritStr, + long *CritStrLen) +{ + int i; + struct UseTable ut; + u_char rawdigest[MD5_DIGEST_LEN]; + struct MD5Context md5context; + StrBuf *guid; + struct cdbdata *cdbut; + char timestamp[64]; + long tslen; + time_t ts = time(NULL); + time_t tsday = ts / (8*60*60); /* just care for a day... */ + + tslen = snprintf(timestamp, sizeof(timestamp), "%ld", tsday); + MD5Init(&md5context); + + for (i = 0; i < nCriterions; i++) + MD5Update(&md5context, + (const unsigned char*)CritStr[i], CritStrLen[i]); + MD5Update(&md5context, + (const unsigned char*)timestamp, tslen); + MD5Final(rawdigest, &md5context); + + guid = NewStrBufPlain(NULL, + MD5_DIGEST_LEN * 2 + 12); + StrBufHexEscAppend(guid, NULL, rawdigest, MD5_DIGEST_LEN); + StrBufAppendBufPlain(guid, HKEY("_fldpt"), 0); + if (StrLength(guid) > 40) + StrBufCutAt(guid, 40, NULL); + /* Find out if we've already sent a similar message */ + memcpy(ut.ut_msgid, SKEY(guid)); + ut.ut_timestamp = ts; + + cdbut = cdb_fetch(CDB_USETABLE, SKEY(guid)); + + if (cdbut != NULL) { + /* yes, we did. flood protection kicks in. */ + syslog(LOG_DEBUG, + "not sending message again\n"); + cdb_free(cdbut); + } + + /* rewrite the record anyway, to update the timestamp */ + cdb_store(CDB_USETABLE, + SKEY(guid), + &ut, sizeof(struct UseTable) ); + + FreeStrBuf(&guid); + + if (cdbut != NULL) return; + /* no, this message isn't sent recently; go ahead. */ + quickie_message(from, + fromaddr, + to, + room, + text, + format_type, + subject); +} /* @@ -3525,7 +3618,7 @@ void quickie_message(const char *from, const char *fromaddr, char *to, char *roo StrBuf *CtdlReadMessageBodyBuf(char *terminator, /* token signalling EOT */ long tlen, size_t maxlen, /* maximum message length */ - char *exist, /* if non-null, append to it; + StrBuf *exist, /* if non-null, append to it; exist is ALWAYS freed */ int crlf, /* CRLF newlines instead of LF */ int *sock /* socket handle or 0 for this session's client socket */ @@ -3542,8 +3635,7 @@ StrBuf *CtdlReadMessageBodyBuf(char *terminator, /* token signalling EOT */ Message = NewStrBufPlain(NULL, 4 * SIZ); } else { - Message = NewStrBufPlain(exist, -1); - free(exist); + Message = NewStrBufDup(exist); } /* Do we need to change leading ".." to "." for SMTP escaping? */ @@ -3606,7 +3698,7 @@ ReadAsyncMsg *NewAsyncMsg(const char *terminator, /* token signalling EOT */ long tlen, size_t maxlen, /* maximum message length */ size_t expectlen, /* if we expect a message, how long should it be? */ - char *exist, /* if non-null, append to it; + StrBuf *exist, /* if non-null, append to it; exist is ALWAYS freed */ long eLen, /* length of exist */ int crlf /* CRLF newlines instead of LF */ @@ -3629,8 +3721,7 @@ ReadAsyncMsg *NewAsyncMsg(const char *terminator, /* token signalling EOT */ NewMsg->MsgBuf = NewStrBufPlain(NULL, len); } else { - NewMsg->MsgBuf = NewStrBufPlain(exist, eLen); - free(exist); + NewMsg->MsgBuf = NewStrBufDup(exist); } /* Do we need to change leading ".." to "." for SMTP escaping? */ if ((tlen == 1) && (*terminator == '.')) { @@ -3763,7 +3854,7 @@ eReadState CtdlReadMessageBodyAsync(AsyncIO *IO) char *CtdlReadMessageBody(char *terminator, /* token signalling EOT */ long tlen, size_t maxlen, /* maximum message length */ - char *exist, /* if non-null, append to it; + StrBuf *exist, /* if non-null, append to it; exist is ALWAYS freed */ int crlf, /* CRLF newlines instead of LF */ int *sock /* socket handle or 0 for this session's client socket */ @@ -4013,7 +4104,7 @@ int CtdlCheckInternetMailPermission(struct ctdluser *who) { /* User flagged ok? */ if (who->flags & US_INTERNET) return(2); - /* Aide level access? */ + /* Admin level access? */ if (who->axlevel >= AxAideU) return(3); /* No mail for you! */ @@ -4896,7 +4987,7 @@ void cmd_move(char *args) */ permit = 0; - /* Aides can move/copy */ + /* Admins can move/copy */ if (CC->user.axlevel >= AxAideU) permit = 1; /* Room aides can move/copy */