/** * @brief Perform a series of security-related checks on an outbound email message in a transport-independent manner. * @see smtp_data_outbound() * @note The checks include: Pattern matching for junk mail, authorization for the user to use the email address or domain * specified in the From address, and finally, a virus check. * @param cred a credential structure obtained for the authenticated user's session. * @param usernum the numerical id of the user attempting to send the message. * @param from a managed string containing the email address specified as the From address. * @param nrecipients the number of recipients that will receive the sent message. * @param body_plain a managed string containing the plain text body of the message. * @param body_html a managed string containing the html body of the message. * @param errmsg the address of a pointer to a null-terminated string that will be set to a descriptive error message on failure. * @return true if all security checks were passed or false otherwise. */ bool_t portal_outbound_checks(credential_t *cred, uint64_t usernum, stringer_t *from, size_t num_recipients, stringer_t *body_plain, stringer_t *body_html, chr_t **errmsg) { smtp_outbound_prefs_t *prefs; int_t state, nstate; if (!usernum || !from || !num_recipients || (!body_plain && !body_html) || !errmsg) { *errmsg = "Unexpected internal failure occurred while sending message."; return false; } // Check the outbound blocker list. if ((pattern_check(body_plain) == -2) || (pattern_check(body_html) == -2)) { *errmsg = "Message was blocked on suspicion of being junk mail."; return false; } // We need to grab the user's outbound credentials before we can check the transmit quota. if (smtp_fetch_authorization(cred, &prefs) <= 0) { *errmsg = "User failed to meet authorization check."; return false; } // Check the transmit quota one more time before we actually send the message. else if (smtp_check_transmit_quota(usernum, num_recipients, prefs) == 1) { *errmsg = "User is over maximum 24 hour send limit."; //con_print(con, "451 DATA BLOCKED - THIS USER ACCOUNT IS ONLY ALLOWED TO SEND %u %s IN A TWENTY-FOUR HOUR PERIOD - PLEASE TRY AGAIN LATER\r\n", // con->smtp.out_prefs->daily_send_limit, (con->smtp.out_prefs->daily_send_limit != 1) ? "MESSAGES" : "MESSAGE"); return false; } // Now check the from address. else if (!(state = smtp_check_authorized_from(usernum, from))) { *errmsg = "Account was not authorized to send emails from this address."; return false; } else if (state < 0) { *errmsg = "An unexpected error occurred while authorizing this email to be sent."; return false; } // Make sure this message does not contain a virus. else if (((state = virus_check(body_plain)) == -2) || ((nstate = virus_check(body_html)) == -2)) { *errmsg = "Email message was blocked because it failed virus scan."; return false; } else if (state == -3 || nstate == -3) { *errmsg = "Email message was blocked because it was detected as a phishing attempt."; return false; } return true; }
char *filter(char *str, Regexfilter *filterList) { xmlDocPtr doc; xmlNodePtr item_node, title_node; xmlChar *xmlbuff, *title_content; int buffersize; doc = xmlReadMemory(str, strlen(str), "noname.xml", NULL, 0); if (doc == NULL) { fprintf(stderr, "Failed to parse document\n"); return; } item_node = feed_first_item(doc); /* loop through items */ while (item_node != NULL) { title_node = xmlFirstElementChild(item_node); title_content = xmlNodeGetContent(title_node); if (!pattern_check((char *)title_content, filterList)) { /* remove <item> node and leftover space*/ feed_remove_node(&item_node); feed_remove_node(&item_node); } item_node = xmlNextElementSibling(item_node); } /* * Convert rss doc to string * and return. */ xmlDocDumpFormatMemory(doc, &xmlbuff, &buffersize,1); xmlFreeDoc(doc); return xmlbuff; }
static void back_selectRule () { /*check for valid back-translations */ int length = srcmax - src; TranslationTableOffset ruleOffset = 0; static TranslationTableRule pseudoRule = { 0 }; unsigned long int makeHash = 0; const TranslationTableCharacter *dots = back_findCharOrDots (currentInput[src], 1); int tryThis; if (handleMultind ()) return; for (tryThis = 0; tryThis < 3; tryThis++) { switch (tryThis) { case 0: if (length < 2 || (itsANumber && (dots->attributes & CTC_LitDigit))) break; /*Hash function optimized for backward translation */ makeHash = (unsigned long int) dots->realchar << 8; makeHash += (unsigned long int) (back_findCharOrDots (currentInput[src + 1], 1))->realchar; makeHash %= HASHNUM; ruleOffset = table->backRules[makeHash]; break; case 1: if (!(length >= 1)) break; length = 1; ruleOffset = dots->otherRules; break; case 2: /*No rule found */ currentRule = &pseudoRule; currentOpcode = pseudoRule.opcode = CTO_None; currentDotslen = pseudoRule.dotslen = 1; pseudoRule.charsdots[0] = currentInput[src]; pseudoRule.charslen = 0; return; break; } while (ruleOffset) { currentRule = (TranslationTableRule *) & table->ruleArea[ruleOffset]; currentOpcode = currentRule->opcode; currentDotslen = currentRule->dotslen; if (((currentDotslen <= length) && compareDots (¤tInput[src], ¤tRule->charsdots[currentRule->charslen], currentDotslen))) { /* check this rule */ back_setAfter (currentDotslen); if ((!currentRule->after || (beforeAttributes & currentRule->after)) && (!currentRule->before || (afterAttributes & currentRule->before))) { switch (currentOpcode) { /*check validity of this Translation */ case CTO_Space: case CTO_Digit: case CTO_Letter: case CTO_UpperCase: case CTO_LowerCase: case CTO_Punctuation: case CTO_Math: case CTO_Sign: case CTO_ExactDots: case CTO_NoCross: case CTO_Repeated: case CTO_Replace: case CTO_Hyphen: return; case CTO_LitDigit: if (itsANumber) return; break; case CTO_CapsLetterRule: case CTO_BegCapsRule: case CTO_EndCapsRule: case CTO_BegCapsWordRule: case CTO_EndCapsWordRule: case CTO_BegEmph1Rule: case CTO_EndEmph1Rule: case CTO_BegEmph2Rule: case CTO_EndEmph2Rule: case CTO_BegEmph3Rule: case CTO_EndEmph3Rule: case CTO_NumberRule: case CTO_BegCompRule: case CTO_EndCompRule: return; case CTO_LetterRule: if (!(beforeAttributes & CTC_Letter) && (afterAttributes & CTC_Letter)) return; break; case CTO_MultInd: doingMultind = currentDotslen; multindRule = currentRule; if (handleMultind ()) return; break; case CTO_LargeSign: return; case CTO_WholeWord: if (itsALetter || itsANumber) break; case CTO_Contraction: if ((beforeAttributes & (CTC_Space | CTC_Punctuation)) && ((afterAttributes & CTC_Space) || isEndWord ())) return; break; case CTO_LowWord: if ((beforeAttributes & CTC_Space) && (afterAttributes & CTC_Space) && (previousOpcode != CTO_JoinableWord)) return; break; case CTO_JoinNum: case CTO_JoinableWord: if ((beforeAttributes & (CTC_Space | CTC_Punctuation)) && !((afterAttributes & CTC_Space))) return; break; case CTO_SuffixableWord: if (beforeAttributes & (CTC_Space | CTC_Punctuation)) return; break; case CTO_PrefixableWord: if ((beforeAttributes & (CTC_Space | CTC_Letter | CTC_Punctuation)) && isEndWord ()) return; break; case CTO_BegWord: if ((beforeAttributes & (CTC_Space | CTC_Punctuation)) && (!isEndWord ())) return; break; case CTO_BegMidWord: if ((beforeAttributes & (CTC_Letter | CTC_Space | CTC_Punctuation)) && (!isEndWord ())) return; break; case CTO_PartWord: if (!(beforeAttributes & CTC_LitDigit) && (beforeAttributes & CTC_Letter || !isEndWord ())) return; break; case CTO_MidWord: if (beforeAttributes & CTC_Letter && !isEndWord ()) return; break; case CTO_MidEndWord: if ((beforeAttributes & CTC_Letter)) return; break; case CTO_EndWord: if ((beforeAttributes & CTC_Letter) && isEndWord ()) return; break; case CTO_BegNum: if (beforeAttributes & (CTC_Space | CTC_Punctuation) && (afterAttributes & (CTC_LitDigit | CTC_Sign))) return; break; case CTO_MidNum: if (beforeAttributes & CTC_Digit && afterAttributes & CTC_LitDigit) return; break; case CTO_EndNum: if (itsANumber && !(afterAttributes & CTC_LitDigit)) return; break; case CTO_DecPoint: if (afterAttributes & (CTC_Digit | CTC_LitDigit)) return; break; case CTO_PrePunc: if (isBegWord ()) return; break; case CTO_PostPunc: if (isEndWord ()) return; break; case CTO_Always: if ((beforeAttributes & CTC_LitDigit) && (afterAttributes & CTC_LitDigit) && currentRule->charslen > 1) break; return; case CTO_BackMatch: { widechar *patterns, *pattern; //if(dontContract || (mode & noContractions)) // break; //if(checkEmphasisChange(0)) // break; patterns = (widechar*)&table->ruleArea[currentRule->patterns]; /* check before pattern */ pattern = &patterns[1]; if(!pattern_check(currentInput, src - 1, -1, -1, pattern, table)) break; /* check after pattern */ pattern = &patterns[patterns[0]]; if(!pattern_check(currentInput, src + currentRule->dotslen, srcmax, 1, pattern, table)) break; return; } default: break; } } } /*Done with checking this rule */ ruleOffset = currentRule->dotsnext; } } }