X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=citadel%2Fmsgbase.c;h=089d50b23edee2a9d5b6e8a603cb26f88a3c65cd;hb=fe4ad631ada6d1c97bd16abf3ed39f6b25a0c6b6;hp=4af4355cb2a6b0922f78ee3d17c6505785419d81;hpb=7555d277f2ccfa8d3f484e5e1dc76e64284afe11;p=citadel.git diff --git a/citadel/msgbase.c b/citadel/msgbase.c index 4af4355cb..089d50b23 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" @@ -85,32 +88,43 @@ char *msgkeys[] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - "from", - NULL, NULL, NULL, - "exti", - "rfca", - NULL, - "hnod", - "msgn", - "jrnl", - "rep2", - "list", - "text", - "node", - "room", - "path", - NULL, - "rcpt", - "spec", - "time", - "subj", - NULL, - "wefw", - NULL, - "cccc", - NULL + "from", /* A */ + NULL, /* B */ + NULL, /* C */ + NULL, /* D */ + "exti", /* E */ + "rfca", /* F */ + NULL, /* G */ + "hnod", /* H */ + "msgn", /* I */ + "jrnl", /* J */ + "rep2", /* K */ + "list", /* L */ + "text", /* M */ + "node", /* N */ + "room", /* O */ + "path", /* P */ + NULL, /* Q */ + "rcpt", /* R */ + "spec", /* S */ + "time", /* T */ + "subj", /* U */ + "nvto", /* V */ + "wefw", /* W */ + NULL, /* X */ + "cccc", /* Y */ + NULL /* Z */ }; +void CtdlMsgSetCM_Fields(struct CtdlMessage *Msg, const char which, const char *buf, long length) +{ + if (Msg->cm_fields[which] != NULL) + free (Msg->cm_fields[which]); + Msg->cm_fields[which] = malloc(length + 1); + memcpy(Msg->cm_fields[which], buf, length); + Msg->cm_fields[which][length] = '\0'; +} + /* * This function is self explanatory. * (What can I say, I'm in a weird mood today...) @@ -1133,7 +1147,7 @@ void mime_download(char *name, char *filename, char *partnum, char *disp, return; } - rv = fwrite(content, length, 1, CC->download_fp); + rv = fwrite(content, length, 1, CCC->download_fp); if (rv <= 0) { MSG_syslog(LOG_EMERG, "mime_download(): Couldn't write: %s\n", strerror(errno)); @@ -1307,6 +1321,49 @@ void CtdlFreeMessage(struct CtdlMessage *msg) free(msg); } +int DupCMField(int i, struct CtdlMessage *OrgMsg, struct CtdlMessage *NewMsg) +{ + long len; + len = strlen(OrgMsg->cm_fields[i]); + NewMsg->cm_fields[i] = malloc(len + 1); + if (NewMsg->cm_fields[i] == NULL) + return 0; + memcpy(NewMsg->cm_fields[i], OrgMsg->cm_fields[i], len); + NewMsg->cm_fields[i][len] = '\0'; + return 1; +} + +struct CtdlMessage * CtdlDuplicateMessage(struct CtdlMessage *OrgMsg) +{ + int i; + struct CtdlMessage *NewMsg; + + if (is_valid_message(OrgMsg) == 0) + return NULL; + NewMsg = (struct CtdlMessage *)malloc(sizeof(struct CtdlMessage)); + if (NewMsg == NULL) + return NULL; + + memcpy(NewMsg, OrgMsg, sizeof(struct CtdlMessage)); + + memset(&NewMsg->cm_fields, 0, sizeof(char*) * 256); + + for (i = 0; i < 256; ++i) + { + if (OrgMsg->cm_fields[i] != NULL) + { + if (!DupCMField(i, OrgMsg, NewMsg)) + { + CtdlFreeMessage(NewMsg); + return NULL; + } + } + } + + return NewMsg; +} + + /* * Pre callback function for multipart/alternative @@ -1813,7 +1870,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); @@ -3489,18 +3546,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, + const char *to, + char *room, + const char *text, + int format_type, + const char *subject) { struct CtdlMessage *msg; struct recptypes *recp = NULL; @@ -3541,6 +3596,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, + const 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); +} /* @@ -3549,7 +3672,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 */ @@ -3566,8 +3689,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? */ @@ -3630,7 +3752,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 */ @@ -3653,8 +3775,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 == '.')) { @@ -3787,7 +3908,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 */ @@ -3942,11 +4063,6 @@ struct CtdlMessage *CtdlMakeMessage( return(msg); } -extern int netconfig_check_roomaccess( - char *errmsgbuf, - size_t n, - const char* RemoteIdentifier); /* TODO: find a smarter way */ - /* * Check to see whether we have permission to post a message in the current * room. Returns a *CITADEL ERROR CODE* and puts a message in errmsgbuf, or @@ -3981,7 +4097,7 @@ int CtdlDoIHavePermissionToPostInThisRoom( } if ((PostPublic!=POST_LMTP) &&(CC->room.QRflags2 & QR2_SMTP_PUBLIC) == 0) { - return netconfig_check_roomaccess(errmsgbuf, n, RemoteIdentifier); + return CtdlNetconfigCheckRoomaccess(errmsgbuf, n, RemoteIdentifier); } return (0);