[filler] [[page]] [sub-command sub-location sub-pattern] # # Fields in SiteAdmin.WikiBoxEmailAuth (colon-separated except final) # email address # author (what name to use in the author field) # active (0 for unconfirmed subscribes or for confirmed unsubscribes, 1 # otherwise) # blacklisted # confirm code (for any email-address type confirmations) # (reserved for future use) # (reserved for future use) # (reserved for future use) # (reserved for future use) # auth ID # auth info - either (base64_encoded authpw from $_SESSION) or (default) # -if "default" then only a URL with "?code=confirm code" will be able to # update to an actual identity. All page processing will occur as the # default identity # # * Process email (subscribe/reject/confirm/command&message) # $RecipeInfo['WikiBox']['Version'] = '2008-08-17'; #require("pop3.php"); #require("mime_parser.php"); /* Uncomment when using SASL authentication mechanisms */ /* require("sasl.php"); */ # These values determine what confirmation steps are required for each area SDV($wbControl['Usage'], array('Receive', 'Complete')); SDV($wbControl['Subscribe'], array('Receive', 'UserConfirm', 'Moderate', 'Complete')); SDV($wbControl['Unsubscribe'], array('Receive', 'UserConfirm', 'Complete')); SDV($wbControl['Blacklist'], array('Receive', 'UserConfirm', 'Complete')); SDV($wbControl['Write'], array('Receive', 'UserConfirm','Moderate','Complete')); SDV($wbControl['Read'], array('Receive', 'Complete')); # This should be blank upon startup. Any message which appears here will # be reported by EmailEngine SDV($wbError, ''); # These values control which validations are necessary in each step above # BE VERY CAREFUL WHAT CHANGES YOU MAKE HERE! # Standard arguments (%%): # $pagename, $requesttype, $requestphase, $headhash, $bodytext, $authemailrecord, $inboxpagename, $wbRequire['Usage']['Receive'][10] = 'wbNotBlacklisted(%%)'; $wbRequire['Subscribe']['Receive'][10] = 'wbNotBlacklisted(%%)'; $wbRequire['Subscribe']['Receive'][20] = 'wbNotSubscribed(%%)'; // $wbRequire['Subscribe']['Receive'][40] = 'wbMkInboxPage(%%)'; $wbRequire['Subscribe']['UserConfirm'][10] = 'wbNotBlacklisted(%%)'; $wbRequire['Subscribe']['UserConfirm'][20] = 'wbInboxPageExists(%%)'; $wbRequire['Subscribe']['UserConfirm'][30] = 'wbExpectedSender(%%)'; // $wbRequire['Subscribe']['UserConfirm'][40] = 'wbValidInboxCode(%%)'; $wbRequire['Subscribe']['UserConfirm'][50] = 'wbSetPasswd(%%)'; $wbRequire['Subscribe']['UserConfirm'][60] = 'wbSetAuthor(%%, $EnablePostAuthorRequired)'; $wbRequire['Subscribe']['Moderate'][10] = 'wbNotBlacklisted(%%)'; $wbRequire['Subscribe']['Moderate'][20] = 'wbInboxPageExists(%%)'; $wbRequire['Subscribe']['Moderate'][30] = 'wbSenderIsModerator(%%)'; $wbRequire['Subscribe']['Moderate'][40] = 'wbValidPasswd(%%)'; $wbRequire['Subscribe']['Reject'][10] = 'wbNotBlacklisted(%%)'; $wbRequire['Subscribe']['Reject'][20] = 'wbInboxPageExists(%%)'; $wbRequire['Subscribe']['Reject'][30] = 'wbExpectedSender(%%)'; // $wbRequire['Subscribe']['Reject'][40] = 'wbValidInboxCode(%%)'; $wbRequire['Subscribe']['Reject'][50] = 'wbDeleteInbox(%%)'; $wbRequire['Unsubscribe']['Receive'][10] = 'wbNotBlacklisted(%%)'; $wbRequire['Unsubscribe']['Receive'][20] = 'wbSubscribed(%%)'; $wbRequire['Unsubscribe']['Receive'][30] = 'wbValidPasswd(%%)'; $wbRequire['Unsubscribe']['Receive'][40] = 'wbMkInboxPage(%%)'; $wbRequire['Unsubscribe']['UserConfirm'][10] = 'wbNotBlacklisted(%%)'; $wbRequire['Unsubscribe']['UserConfirm'][20] = 'wbSubscribed(%%)'; $wbRequire['Unsubscribe']['UserConfirm'][30] = 'wbExpectedSender(%%)'; $wbRequire['Unsubscribe']['UserConfirm'][40] = 'wbValidInboxCode(%%)'; $wbRequire['Unsubscribe']['Moderate'][10] = 'wbNotBlacklisted(%%)'; $wbRequire['Unsubscribe']['Moderate'][20] = 'wbSubscribed(%%)'; $wbRequire['Unsubscribe']['Moderate'][30] = 'wbSenderIsModerator(%%)'; $wbRequire['Unsubscribe']['Moderate'][40] = 'wbValidPasswd(%%)'; $wbRequire['Unsubscribe']['Moderate'][50] = 'wbInboxPageExists(%%)'; $wbRequire['Unsubscribe']['Moderate'][60] = 'wbValidInboxCode(%%)'; $wbRequire['Unsubscribe']['Reject'][10] = 'wbNotBlacklisted(%%)'; $wbRequire['Unsubscribe']['Reject'][20] = 'wbInboxPageExists(%%)'; $wbRequire['Unsubscribe']['Reject'][30] = 'wbValidInboxCode(%%)'; $wbRequire['Unsubscribe']['Reject'][40] = 'wbDeleteInbox(%%)'; $wbRequire['Blacklist']['Receive'][10] = 'wbNotBlacklisted(%%)'; $wbRequire['Blacklist']['Receive'][20] = 'wbSubscribed(%%)'; $wbRequire['Blacklist']['Receive'][30] = 'wbValidPasswd(%%)'; $wbRequire['Blacklist']['Receive'][40] = 'wbMkInboxPage(%%)'; $wbRequire['Blacklist']['UserConfirm'][10] = 'wbNotBlacklisted(%%)'; $wbRequire['Blacklist']['UserConfirm'][20] = 'wbSubscribed(%%)'; $wbRequire['Blacklist']['UserConfirm'][30] = 'wbInboxPageExists(%%)'; $wbRequire['Blacklist']['UserConfirm'][40] = 'wbValidInboxCode(%%)'; $wbRequire['Blacklist']['Moderate'][10] = 'wbNotBlacklisted(%%)'; $wbRequire['Blacklist']['Moderate'][20] = 'wbSubscribed(%%)'; $wbRequire['Blacklist']['Moderate'][30] = 'wbSenderIsModerator(%%)'; $wbRequire['Blacklist']['Moderate'][40] = 'wbValidPasswd(%%)'; $wbRequire['Blacklist']['Moderate'][50] = 'wbInboxPageExists(%%)'; $wbRequire['Blacklist']['Moderate'][60] = 'wbValidInboxCode(%%)'; $wbRequire['Blacklist']['Reject'][10] = 'wbNotBlacklisted(%%)'; $wbRequire['Blacklist']['Reject'][20] = 'wbInboxPageExists(%%)'; $wbRequire['Blacklist']['Reject'][30] = 'wbValidInboxCode(%%)'; $wbRequire['Blacklist']['Reject'][40] = 'wbDeleteInbox(%%)'; $wbRequire['Write']['Receive'][10] = 'wbNotBlacklisted(%%)'; $wbRequire['Write']['Receive'][20] = 'wbSubscribed(%%)'; $wbRequire['Write']['Receive'][30] = 'wbValidPasswd(%%)'; $wbRequire['Write']['Receive'][40] = 'wbStripPasswd(%%)'; $wbRequire['Write']['Receive'][50] = 'wbCanWritePage(%%)'; $wbRequire['Write']['Receive'][60] = 'wbMkInboxPage(%%)'; $wbRequire['Write']['UserConfirm'][10] = 'wbNotBlacklisted(%%)'; $wbRequire['Write']['UserConfirm'][20] = 'wbSubscribed(%%)'; $wbRequire['Write']['UserConfirm'][30] = 'wbInboxPageExists(%%)'; $wbRequire['Write']['UserConfirm'][40] = 'wbValidInboxCode(%%)'; $wbRequire['Write']['Moderate'][10] = 'wbNotBlacklisted(%%)'; $wbRequire['Write']['Moderate'][20] = 'wbSubscribed(%%)'; $wbRequire['Write']['Moderate'][30] = 'wbSenderIsModerator(%%)'; $wbRequire['Write']['Moderate'][40] = 'wbValidPasswd(%%)'; $wbRequire['Write']['Moderate'][50] = 'wbInboxPageExists(%%)'; $wbRequire['Write']['Moderate'][60] = 'wbValidInboxCode(%%)'; $wbRequire['Write']['Reject'][10] = 'wbNotBlacklisted(%%)'; $wbRequire['Write']['Reject'][20] = 'wbInboxPageExists(%%)'; $wbRequire['Write']['Reject'][30] = 'wbValidInboxCode(%%)'; $wbRequire['Write']['Reject'][40] = 'wbDeleteInbox(%%)'; $wbRequire['Read']['Receive'][10] = 'wbNotBlacklisted(%%)'; $wbRequire['Read']['Receive'][20] = 'wbSubscribed(%%)'; // optional? $wbRequire['Read']['Receive'][30] = 'wbValidPasswd(%%)';// optional? $wbRequire['Read']['Receive'][40] = 'wbStripPasswd(%%)';// use only if required $wbRequire['Read']['Receive'][50] = 'wbMkInboxPage(%%)'; # Probably the remaining 'Read' phases will be unused based on the value of # $wbControl['Read'] (who wants to userconfirm and moderate a read request!?) $wbRequire['Read']['UserConfirm'][10] = 'wbNotBlacklisted(%%)'; $wbRequire['Read']['UserConfirm'][20] = 'wbSubscribed(%%)'; $wbRequire['Read']['UserConfirm'][30] = 'wbInboxPageExists(%%)'; $wbRequire['Read']['UserConfirm'][40] = 'wbValidInboxCode(%%)'; $wbRequire['Read']['Moderate'][10] = 'wbNotBlacklisted(%%)'; $wbRequire['Read']['Moderate'][20] = 'wbSubscribed(%%)'; $wbRequire['Read']['Moderate'][30] = 'wbSenderIsModerator(%%)'; $wbRequire['Read']['Moderate'][40] = 'wbValidPasswd(%%)'; $wbRequire['Read']['Moderate'][50] = 'wbInboxPageExists(%%)'; $wbRequire['Read']['Moderate'][60] = 'wbValidInboxCode(%%)'; # These values determine the steps for preparing for the specified phase $wbPrepFor['Usage']['Complete'][10] = 'wbSend($pagename, $headers, $headhash, $bodytext, $mime, "Usage", "Complete")'; $wbPrepFor['Subscribe']['UserConfirm'][10] = 'wbSend($pagename, $headers, $headhash, $bodytext, $mime, "Subscribe", "UserConfirm", array("%PAGENAME%" => $subjvals["inboxpage"], "%CODE%" => PageTextVar($subjvals["inboxpage"], "Code")))'; $wbPrepFor['Subscribe']['Moderate'][10] = 'wbSend($pagename, $headers, $headhash, $bodytext, $mime, "Subscribe", "Moderate", array("%PAGENAME%" => $subjvals["inboxpage"], "%CODE%" => PageTextVar($subjvals["inboxpage"], "Code")), wbModeratorAddress())'; $wbPrepFor['Subscribe']['Moderate'][20] = 'wbSetExpectedSender(%%, wbModeratorAddress())'; $wbPrepFor['Subscribe']['Complete'][10] = 'wbReReadInbox(%%, "Subscribe", "Receive")'; $wbPrepFor['Subscribe']['Complete'][20] = 'wbMkEmailAuth(%%)'; $wbPrepFor['Unsubscribe']['UserConfirm'][10]='wbSend($pagename, $headers, $headhash, $bodytext, $mime, "Unsubscribe", "UserConfirm", array("%PAGENAME%" => $subjvals["inboxpage"], "%CODE%" => PageTextVar($subjvals["inboxpage"], "Code")))'; $wbPrepFor['Unsubscribe']['Moderate'][10] = 'wbSend($pagename, $headers, $headhash, $bodytext, $mime, "Unsubscribe", "Moderate", , array("%PAGENAME%" => $subjvals["inboxpage"], "%CODE%" => PageTextVar($subjvals["inboxpage"], "Code")), wbModeratorAddress())'; $wbPrepFor['Unsubscribe']['Moderate'][20] = 'wbSetExpectedSender(%%, wbModeratorAddress())'; $wbPrepFor['Unsubscribe']['Complete'][10] = 'wbReReadInbox(%%, "Unsubscribe", "Receive")'; $wbPrepFor['Unsubscribe']['Complete'][20] = 'wbDeactivateEmailAuth(%%)'; $wbPrepFor['Blacklist']['UserConfirm'][10] = 'wbSend($pagename, $headers, $headhash, $bodytext, $mime, "Blacklist", "UserConfirm", array("%PAGENAME%" => $subjvals["inboxpage"], "%CODE%" => PageTextVar($subjvals["inboxpage"], "Code")))'; $wbPrepFor['Blacklist']['Moderate'][10] = 'wbSend($pagename, $headers, $headhash, $bodytext, $mime, "Blacklist", "Moderate", array(), wbModeratorAddress())'; $wbPrepFor['Blacklist']['Moderate'][20] = 'wbSetExpectedSender(%%, wbModeratorAddress())'; $wbPrepFor['Blacklist']['Complete'][10] = 'wbBlacklistEmailAuth(%%)'; $wbPrepFor['Write']['UserConfirm'][10] = 'wbSend($pagename, $headers, $headhash, $bodytext, $mime, "Write", "UserConfirm", array("%PAGENAME%" => $subjvals["inboxpage"], "%CODE%" => PageTextVar($subjvals["inboxpage"], "Code")))'; $wbPrepFor['Write']['Moderate'][10] = 'wbSend($pagename, $headers, $headhash, $bodytext, $mime, "Write", "Moderate", array("%PAGENAME%" => $subjvals["inboxpage"], "%CODE%" => PageTextVar($subjvals["inboxpage"], "Code")), wbModeratorAddress())'; $wbPrepFor['Write']['Moderate'][20] = 'wbSetExpectedSender(%%, wbModeratorAddress())'; $wbPrepFor['Write']['Complete'][10] = 'wbReReadInbox(%%, "Write", "Receive")'; $wbPrepFor['Write']['Complete'][20] = 'wbCanWritePage(%%)'; $wbPrepFor['Write']['Complete'][30] = 'wbWriteToPage(%%)'; $wbPrepFor['Write']['Complete'][40] = 'wbUpload(%%)'; $wbPrepFor['Write']['Complete'][50] = 'wbSend($pagename, $headers, $headhash, $bodytext, $mime, "Misc", "Complete")'; $wbPrepFor['Read']['UserConfirm'][10] = 'wbSend($pagename, $headers, $headhash, $bodytext, $mime, "Read", "UserConfirm", array("%PAGENAME%" => $subjvals["inboxpage"]))'; $wbPrepFor['Read']['Moderate'][10] = 'wbSend($pagename, $headers, $headhash, $bodytext, $mime, "Read", "Moderate", array("%PAGENAME%" => $subjvals["inboxpage"]), wbModeratorAddress())'; $wbPrepFor['Read']['Moderate'][20] = 'wbSetExpectedSender(%%, wbModeratorAddress())'; $wbPrepFor['Read']['Complete'][10] = 'wbReReadInbox(%%, "Read", "Receive")'; $wbPrepFor['Read']['Complete'][20] = 'wbCanReadPage(%%)'; $wbPrepFor['Read']['Complete'][30] = 'wbSendPage(%%)'; # This variable defines the sets of markup rules that can be run over a given # page text (usually when the user requests a "read [[group.page]]") SDV($wbMarkupSet['source'], array()); SDV($wbMarkupSet['text'], array('include', 'comment', 'if')); SDV($wbMarkupSet['full'], true); # This is the name of the POP3 profile that wikimail will use. It must # be initialized in config.php by means of wmMkProfilePOP3() SDV($wbPOP3Profile, 'wikibox'); SDV($wbSMTP['From'], ''); $wbAuthFlds = array('email'=>0, 'id'=>1, 'author'=>2, 'active'=>3, 'blacklist'=>4, 'passwd'=>5, 'junk1'=>6, 'junk2'=>7, 'junk3'=>8, 'junk4'=>9, 'authid'=>10, 'authinfo'=>11); SDV($wbGroup, "WikiBox"); SDV($wbInboxPagePrefix, "Inbox-"); // for pages WikiBox.Inbox-TIMESTAMP SDV($wbMessagePagePrefix, "Msg-"); // for pages WikiBox.Msg-Subscribe-NoPass SDV($wbAuthor, 'WikiBox'); SDV($wbModerator, 'INVALID'); # Error log SDV($wbErrorLog, "$wbGroup.ErrorLog"); SDV($wbConfigPageAuth, "$SiteAdminGroup.WikiBoxPageAuth"); slParsePage($pagename, $wbConfigPageAuth, $wbPageAuthStore); # List of emails and authorizations (like /etc/passwd but for wikibox) SDV($wbConfigEmailAuth, "$SiteAdminGroup.WikiBoxEmailAuth"); # List of emails and pages written by that email on a given day - used to # enforce the max number of messages per n days SDV($wbConfigEmailHist, "$SiteAdminGroup.WikiBoxEmailHist"); SDV($wbMaxReadsPerSeconds, array(1*60*60*24 => 50, 7*60*60*24 => 200)); SDV($wbMaxWritesPerSeconds, array(1*60*60*24 => 10, 7*60*60*24 => 25)); SDV($wbMaxUniquePagesPerSeconds, array(1*60*60*24 => 5, 7*60*60*24 => 10)); # Number of messages per page in the form interface SDV($wbMessagesPerPage, 5); SDV($wbUploadPattern, "/(?:wikibox-upload|wikibox-attach)(?P!?):\\s*(?P[.\\w]*)/i"); # These patterns match subjects which are valid commands to WikiBox SDV($wbSubjectPattern['Usage']['Receive'], "/^\\s*usage\\s*$/i"); SDV($wbSubjectPattern['Subscribe']['Receive'], "/^\\s*subscribe\\s*$/i"); SDV($wbSubjectPattern['Subscribe']['UserConfirm'], "/\\bsubscribe:\\s*confirm\\s*\[\[(?P[^]]+)\]\]/i"); SDV($wbSubjectPattern['Subscribe']['Moderate'], "/\\bsubscribe:\\s*moderat(?:or|e|ed|er)\\s+confirm\\s*\[\[(?P[^]]+)\]\]/i"); SDV($wbSubjectPattern['Subscribe']['Reject'], "/\\bsubscribe:\\s*(?:moderat(?:or|e|ed|er)\\s*)?reject\\s*\[\[(?P[^]]+)\]\]/i"); SDV($wbSubjectPattern['Unsubscribe']['Receive'], "/^\\s*unsubscribe\\s*$/i"); SDV($wbSubjectPattern['Unsubscribe']['UserConfirm'], "/\\bunsubscribe:\\s*confirm\\s*\[\[(?P[^]]+)\]\]/i"); SDV($wbSubjectPattern['Unsubscribe']['Moderate'], "/\\bunsubscribe:\\s*moderat(?:or|e|ed|er)\\s+confirm\\s*\[\[(?P[^]]+)\]\]/i"); SDV($wbSubjectPattern['Unsubscribe']['Reject'], "/\\bunsubscribe:\\s*(?:moderat(?:or|e|ed|er)\\s*)?reject\\s*\[\[(?P[^]]+)\]\]/i"); SDV($wbSubjectPattern['Blacklist']['Receive'], "/^\\s*blacklist(?:\\s+me)?\\s*$/i"); SDV($wbSubjectPattern['Blacklist']['UserConfirm'], "/\\bblacklist:.*\\bconfirm\\s*\[\[(?P[^]]+)\]\]/i"); SDV($wbSubjectPattern['Blacklist']['Moderate'], "/\\bblacklist:\\s*moderat(?:or|e|ed|er)\\s+confirm\\s*\[\[(?P[^]]+)\]\]/i"); SDV($wbSubjectPattern['Blacklist']['Reject'], "/\\bblacklist:\\s*reject\\s*\[\[(?P[^]]+)\]\]/i"); SDV($wbSubjectPattern['Write']['Receive'], "/(?Pinsert|replace|write|overwrite|append|prepend)\s+(?P(?:in|into|on|to|at the (?:top|bottom) of)\s+)?\[\[(?P[\w.]+)\]\](?:\s+(?before|after|instead of|replacing)\s+(?\/.*?\/[msi]*))?/i"); SDV($wbSubjectPattern['Write']['UserConfirm'], "/write:\\s*confirm\\b.*\\s\[\[(?P[^]]+)\]\]\\s*$/i"); SDV($wbSubjectPattern['Write']['Moderate'], "/write:\\s*moderat(?:or|e|ed|er)\\s+confirm\\b.*\\s\[\[(?P[^]]+)\]\]\\s*$/i"); SDV($wbSubjectPattern['Write']['Reject'], "/write:\\s*(?:moderat(?:or|e|ed|er)\\s*)?reject\\b.*\\s\[\[(?P[^]]+)\]\]/i"); SDV($wbSubjectPattern['Read']['Receive'], "/(?Pget|retrieve|read)\s+(?P(?:from|page)\s+)?\[\[(?P[\w.\/#]+)\]\](?:\s+(?.*)?)?/i"); SDV($wbSubjectPattern['Read']['UserConfirm'], "/\\bead:\\s*confirm\\b.*\\s\[\[(?P[^]]+)\]\]/i"); SDV($wbSubjectPattern['Read']['Moderate'], "/\\bread:\\s*moderat(?:or|e|ed|er)\\s+confirm\\b.*\\s\[\[(?P[^]]+)\]\]/i"); SDV($wbSubjectPattern['Read']['Reject'], "/\\bread:\\s*(?:moderat(?:or|e|ed|er)\\s*)?reject\\b.*\\s\[\[(?P[^]]+)\]\]/i"); SDV($wbPasswdPrefix, "wikibox-password:"); SDV($wbPasswdPrefixPat, "wikibox-passw(?:or)?d:"); SDV($wbCodePrefix, "wikibox-code:"); SDV($wbCodePrefixPat, "wikibox-code:"); # The following are subjects and messages for various emails back to the user SDV($wbSubject['Usage']['Complete'], "Usage for WikiBox"); SDV($wbMessage['Usage']['Complete'], "WikiBox allows you to interract with PmWiki via email. The subject of your email is always the command while the body of the email provides the content. Here are some of the commands you may send in a subject:\n\n". "COMMANDS WHICH SIGN YOU UP OR REMOVE YOU FROM THE LIST OF VALID EMAIL USERS\n". "Usage\n\tYou will get this email in reply describing how to use the system\n\n". "Subscribe\n\tYour email address will be added to the list of valid \"email authors\" who are allowed to contribute content and interact with pmwiki via email\n". "Unsubscribe\n\tYour email address will be removed from the list of valid \"email authors\" and further emails from you will not be approved until you resubscribe\n". "Blacklist\n\tYour email address will be blacklisted which means (after appropriate confirmation) you will receive NO MORE messages from WikiBox without an administrator taking your name off the blacklist - use this if you do not want to ever get email from WikiBox again\n". "COMMANDS FOR POSTING TEXT TO PAGES\n". "Write to [[Group.Page]]\n\tThe body of your email will be used to either create the specified page or to overwrite any existing text on that page\n". "Append to [[Group.Page]]\n\tThe body of your email will be appended to the bottom of the specified page\n". "Prepend to [[Group.Page]]\n\tThe body of your email will be placed before any existing text on the specified page\n". "Insert into [[Group.Page]] before /pattern/\n\tThe body of your email will be inserted into the specified page immediate prior to the first occurrence of the specified pattern in the existing text\n". "Insert into [[Group.Page]] after /pattern/\n\tLike above, but after the pattern\n". "Insert into [[Group.Page]] replacing /pattern/\n\tLike above but whatever pattern is matched will be replaced by the text in the body of the email\n\n". "COMMANDS FOR RETRIEVING (READING) PAGES\n". "Read [[Group.Page]] FMT= RULESET=\n\t can be html, text, or both and indicates what format the email should be sent in.\n\t can be source, text, or full (or administrator specified) and indicates which set of markup rules will be run over the text before sending it back\n\n". "COMMANDS FOR CONFIRMING/REJECTING\n". "(Email is inherently insecure and so your administrator may have configured various requirements for confirming commands that appear to be from you -- the idea is to confirm that those commands actually did come from you.)". "CONFIRM\n\tRead the instructions carefully in the body of the email requesting confirmation and make sure any validation information is included, but when you send back a properly formed \"CONFIRM\" message you are agreeing that this message really came from you and that you really do want the command to be executed\n". "REJECT\n\t(Again, read the instructions carefully to properly validate the message). Sending back a \"REJECT\" command tells WikiBox that whatever command it thought you sent either was not sent by you or you do not want that command to be executed. In all probability the previous message which was being confirmed will be deleted\n"); SDV($wbSubject['Subscribe']['UserConfirm'], "Subscribe: CONFIRM [[%PAGENAME%]]"); SDV($wbMessage['Subscribe']['UserConfirm'], "The email below was sent for WikiBox to automatically process. Please confirm that you sent this message and wish to be subscribed to WikiBox on this server by replying to this message leaving the subject to read \n\t\"Subscribe: CONFIRM [[%PAGENAME%]]\"\n or reject the message by editing the subject to read \n\t\"Subscribe: REJECT [[%PAGENAME%]]\".\n\nAlso please type a password on the following line - this password must be included in all future WikiBox correspondence, so keep track of it. Note that this password will be sent through email and so should not be a valuable password.\n${wbPasswdPrefix}\n\nPlease specify the name you wish to be used in the \"Author\" field whenever you make changes to the wiki:\nAuthor:\n\nKeep this code unchanged in the body of your reply:\n${wbCodePrefix}%CODE%\n\nOriginal Message follows:\n\nSUBJECT: %SUBJECT%\n%BODY%\n"); SDV($wbSubject['Subscribe']['NoPasswd'], "Subscribe: No password specified [[%PAGENAME%]]"); SDV($wbMessage['Subscribe']['NoPasswd'], "The email below was sent for WikiBox to automatically process. No password was specified. Please re-send your confirmation (see previous message), specifying a valid password. \n\nOriginal Message follows:\n\nSUBJECT: %SUBJECT%\n%BODY%\n"); SDV($wbSubject['Subscribe']['NoAuthor'], "Subscribe: No Author specified [[%PAGENAME%]]"); SDV($wbMessage['Subscribe']['NoAuthor'], "The email below was sent for WikiBox to automatically process. No author was specified. Please re-send your confirmation (see previous message), specifying a valid password. \n\nOriginal Message follows:\n\nSUBJECT: %SUBJECT%\n%BODY%\n"); SDV($wbSubject['Subscribe']['Moderate'], "Subscribe: moderator CONFIRM [[%PAGENAME%]]"); SDV($wbMessage['Subscribe']['Moderate'], "The email below was sent for WikiBox to automatically process. Please moderate this subscription request by replying to this message leaving the subject above to read \n\t\"Subscribe: moderator CONFIRM [[%PAGENAME%]]\"\n or reject the message by editing the subject to read\n\t\"Subscribe: moderator REJECT [[%PAGENAME%]]\".\nAlso please provide your password on the line below:\n${wbPasswdPrefix}\n\nKeep this code unchanged in the body of your reply:\n${wbCodePrefix}%CODE%\n\nOriginal Message follows:\n\nFROM: %FROM%\nSUBJECT: %SUBJECT%\n%BODY%\n"); SDV($wbSubject['Unsubscribe']['UserConfirm'], "Unsubscribe: CONFIRM [[%PAGENAME%]]"); SDV($wbMessage['Unsubscribe']['UserConfirm'], "The email below was sent for WikiBox to automatically process. Please confirm that you sent this message and wish to be unsubscribed to WikiBox on this server by replying to this message leaving the subject to read \n\t\"Unsubscribe: CONFIRM [[%PAGENAME%]]\"\n or (if you did not send the message or for some other reason do not wish to be unsubscribed) edit the subject to read: \n\t\"Unsubscribe: REJECT [[%PAGENAME%]]\".\n\nKeep this code unchanged in the body of your reply:\n${wbCodePrefix}%CODE%\n\nOriginal Message follows:\n\nSUBJECT: %SUBJECT%\n%BODY%\n"); SDV($wbSubject['Unsubscribe']['Moderate'], "Unsubscribe: moderator CONFIRM [[%PAGENAME%]]"); SDV($wbMessage['Unsubscribe']['Moderate'], "The email below was sent for WikiBox to automatically process. Please moderate this unsubscription request by replying to this message leaving the subject above to read \n\t\"Unsubscribe: moderator CONFIRM [[%PAGENAME%]]\"\n to confirm or (to reject the message) by editing the subject to read:\n\t\"Unsubscribe: moderator REJECT [[%PAGENAME%]]\".\nAlso please provide your password on the line below:\n${wbPasswdPrefix}\n\nKeep this code unchanged in the body of your reply:\n${wbCodePrefix}%CODE%\n\nOriginal Message follows:\n\nFROM: %FROM%\nSUBJECT: %SUBJECT%\n%BODY%\n"); SDV($wbSubject['Blacklist']['UserConfirm'], "Blacklist: CONFIRM [[%PAGENAME%]]"); SDV($wbMessage['Blacklist']['UserConfirm'], "The email below was sent for WikiBox to automatically process. Please confirm that you sent this message and wish to be blacklisted from WikiBox on this server by replying to this message and leaving the subject to read \n\t\"Blacklist: CONFIRM [[%PAGENAME%]]\"\n or (if you do not wish to be blacklisted) edit the subject to read\n\t\"Blacklist: REJECT [[%PAGENAME%]]\".\n\nKeep this code unchanged in the body of your reply:\n${wbCodePrefix}%CODE%\n\nOriginal Message follows:\n\nSUBJECT: %SUBJECT%\n%BODY%\n"); SDV($wbSubject['Blacklist']['Moderate'], "Blacklist: moderator CONFIRM [[%PAGENAME%]]"); SDV($wbMessage['Blacklist']['Moderate'], "The email below was sent for WikiBox to automatically process. Please moderate this blacklist request by replying to this message. If you leave the subject to read \n\t\"Blacklist: moderator CONFIRM [[%PAGENAME%]]\"\n then the message will be confirmed. If you edit the subject to read \n\t\"Blacklist: moderator REJECT [[%PAGENAME%]]\".\nthen the message will be rejected.\n\nAlso please provide your password on the line below:\n${wbPasswdPrefix}\n\nKeep this code unchanged in the body of your reply:\n${wbCodePrefix}%CODE%\n\nOriginal Message follows:\n\nFROM: %FROM%\nSUBJECT: %SUBJECT%\n%BODY%\n"); SDV($wbSubject['Write']['UserConfirm'], "Write: CONFIRM [[%PAGENAME%]]"); SDV($wbMessage['Write']['UserConfirm'], "The email below was sent (apparently by you) for WikiBox to automatically process. Please confirm that you sent this message by replying to the message and leaving the subject to read \"Write: CONFIRM [[%PAGENAME%]]\". If you did not send the request or you do not want the request to be processed then reply after editing the subject to read \"Write: REJECT [[%PAGENAME%]]\".\n\nKeep this code unchanged in the body of your reply:\n${wbCodePrefix}%CODE%\n\nOriginal Message follows:\n\nSUBJECT: %SUBJECT%\n%BODY%\n"); SDV($wbSubject['Write']['Moderate'], "Write: moderator CONFIRM [[%PAGENAME%]]"); SDV($wbMessage['Write']['Moderate'], "The email below was sent for WikiBox to automatically process. Please confirm this message by replying to the message leaving the subject to read \"Write: moderator CONFIRM [[%PAGENAME%]]\" or else reject the message by editing the subject to read \"Write: moderator REJECT [[%PAGENAME%]]\". Also please provide your password on the line below:\n${wbPasswdPrefix}\n\nKeep this code unchanged in the body of your reply:\n${wbCodePrefix}%CODE%\n\nOriginal Message follows:\n\nSUBJECT: %SUBJECT%\n%BODY%\n"); SDV($wbSubject['Write']['NoAuth'], "No Authorization - Message Ignored"); SDV($wbMessage['Write']['NoAuth'], "This email (below) requests a write to a page for which you do not have authorization. If you need write authorization for this page please speak with an administrator. This message has been discarded.\n\nOriginal Message follows:\n\nSUBJECT: %SUBJECT%\n%BODY%\n"); SDV($wbSubject['Write']['Failed'], "Write to page failed - Message Ignored"); SDV($wbMessage['Write']['Failed'], "This email (below) requests a write to a page. For an unknown reason this write failed. This message has been discarded.\n\nOriginal Message follows:\n\nSUBJECT: %SUBJECT%\n%BODY%\n"); SDV($wbSubject['Read']['NoAuth'], "No Authorization to read - Message Ignored"); SDV($wbMessage['Read']['NoAuth'], "This email (below) requests a read of a page for which you do not have authorization. If you need read authorization for this page please speak with an administrator. This message has been discarded.\n\nOriginal Message follows:\n\nSUBJECT: %SUBJECT%\n%BODY%\n"); SDV($wbSubject['Misc']['UnexpectedSender'], "Not from expected sender - Message Ignored"); SDV($wbMessage['Misc']['UnexpectedSender'], "Your message was received, but the sender was not the expected email address. Please send it again from the expected email address.\n\nCurrent Message follows:\n\nSUBJECT: %SUBJECT%\n%BODY%\n"); SDV($wbSubject['Misc']['NoInbox'], "Temporary Inbox Page Missing - Message Ignored"); SDV($wbMessage['Misc']['NoInbox'], "Your message was received and processed, but somehow the temporary page holding the original message is no longer available.\n\nCurrent Message follows:\n\nSUBJECT: %SUBJECT%\n%BODY%\n"); SDV($wbSubject['Misc']['InboxAltered'], "Temporary Inbox Page Altered - Message Ignored"); SDV($wbMessage['Misc']['InboxAltered'], "Your message was received and processed, but somehow the temporary page holding the original message was altered and is no longer usable.\n\nCurrent Message follows:\n\nSUBJECT: %SUBJECT%\n%BODY%\n"); SDV($wbSubject['Misc']['NotValidated'], "Message Validation Failed - Message Ignored"); SDV($wbMessage['Misc']['NotValidated'], "This email did not validate correctly. If you were confirming a message please re-read the instructions in that email carefully AND THEN RE-SEND YOUR MESSAGE with the needed changes. If you were sending a new email try sending the email again with the word \"$wbPasswdPrefix\" followed by your specific code on a line all by itself somewhere in the body of your message. (That line will be automatically deleted later to protect your code.)\n\nOriginal Message follows:\n\nSUBJECT: %SUBJECT%\n%BODY%\n"); SDV($wbSubject['Misc']['EmailNotValid'], "Invalid Email - Message Ignored"); SDV($wbMessage['Misc']['EmailNotValid'], "This email (below) was sent from an email address which does not validate. Try sending an email with only the word \"subscribe\" in the subject.\n\nOriginal Message follows:\n\nSUBJECT: %SUBJECT%\n%BODY%\n"); SDV($wbSubject['Misc']['InvalidSubject'], "Invalid WikiBox Subject: %SUBJECT%"); SDV($wbMessage['Misc']['InvalidSubject'], "This message had an invalid subject. Please check it and re-send the message. If you are unsure what a valid subject looks like then send an email to the same address with a subject of just \"usage\".\n\nOriginal Message follows:\n\nSUBJECT: %SUBJECT%\n%BODY%\n"); SDV($wbSubject['Misc']['BadSender'], "Wrong Sender - Message Ignored"); SDV($wbMessage['Misc']['BadSender'], "This email did not validate correctly. The message came from %FROM% (another sender was expected).\n\nOriginal Message follows:\n\nSUBJECT: %SUBJECT%\n%BODY%\n"); SDV($wbSubject['Misc']['AlreadySubscribed'], "Already Subscribed - Message Ignored"); SDV($wbMessage['Misc']['AlreadySubscribed'], "You are already subscribed and can only be subscribed once. This message (below) has been ignored.\n\nOriginal Message follows:\n\nSUBJECT: %SUBJECT%\n%BODY%\n"); SDV($wbSubject['Misc']['Complete'], "Request Completed"); SDV($wbMessage['Misc']['Complete'], "The request from the email below has been completed.\n\nOriginal Message follows:\n\nSUBJECT: %SUBJECT%\n%BODY%\n"); Markup('wikibox', '<{$var}', '/\\(:wikibox(?:\\s+(\\S.*?))?\\s*:\\)/ie', "wbMaster(\$pagename, strtoupper('$1'))"); function wbMaster($pagename, $params) { $opt = ParseArgs($params); #echo "
OPT= " . print_r($opt, true) . "

\n"; if (in_array("SIGNUP", $opt['#'])) { return(wbSignup($pagename, $opt)); } if (in_array("PROCESS", $opt['#'])) { #echo "Calling EmailEngine()
\n"; return(wbEmailEngine($pagename, $opt)); } # If we're responding to submit button, go ahead and apply those actions #if ($_REQUEST['Submit'] || $opt['AUTO']) #WikiBox($pagename, $opt, true); # Now create the form as long as AUTO=n was not specified #if (!$opt['AUTO']) #return(WikiBox($pagename, $opt, false)); } # function wbEmailEngine() # For each email read # For each subject pattern # If match # Initialize all arguments # Do associated action from wbRequest & wbPrepFor # If no match # Do Invalid Subject action function wbEmailEngine($pagename, $opt) { global $Timeout, $wbSubjectPattern, $wbControl, $wbRequire, $wbPrepFor, $wbPOP3Profile, $WikiMailErr, $wbError, $EnablePostAuthorRequired; // $EnablePostAuthorRequired needed for eval $func = 'wbEmailEngine()'; $d = 1; $rtn = ''; SDV($EnablePostAuthorRequired, false); // is this the right default? dbg($d*4, "$func: Entering"); dbg($d*1, "$func: opt follows:"); dbg($d*1, $opt); if (!wmInitPOP3($wbPOP3Profile)) return("POP3 Initialization failed ($WikiMailErr)"); if ($opt['VERBOSE']) $rtn .= "\n'''WIKIBOX PROCESSING'''"; while (microtime(true)+5 < $Timeout) { // go to within 5 seconds of timeout dbg($d*2,"$func: Looping - attempting to retrieve message"); if (($msg = wmRetrievePOP3($wbPOP3Profile, true)) === false) { dbg($d*2,"$func: No more messages - exiting loop"); break; } list($headhash, $headers, $body) = $msg; $headers = implode("\n", $headers); dbg($d*4,"$func: Message retrieved. Subject=$headhash[subject]"); if ($opt['VERBOSE']) $rtn .= "\n*Retrieved message with Subject=$headhash[subject]"; $bodytext = implode("\n", $body); $mime = wmSimplifyMime($headers."\n\n".$bodytext); $processed = false; $mysavedsession = $_SESSION; foreach ($wbSubjectPattern as $Type => $Patterns) { dbg($d*2, "$func: Checking subjects for type: $Type"); foreach ($Patterns as $Phase => $pat) { dbg($d*1, "$func: Checking subject for phase: $Phase"); if (preg_match($pat, $headhash['subject'], $subjvals)) { $processed = true; dbg($d*3, "$func: MATCH SUBJECT: $Type-$Phase"); if ($opt['VERBOSE'] > 1) $rtn .= "\n** Subject matched on $Type-$Phase"; dbg($d*1, "$func: from $headhash[from]"); $EmailAuth = wbReadEmailAuth($pagename, $headhash['from']); if (@$subjvals['target']) $subjvals['target'] = MakePageName($pagename, $subjvals['target']); ksort($wbRequire[$Type][$Phase]); dbg($d*2, "$func: Looping through $Type-$Phase Requirements"); dbg($d*1, $wbRequire[$Type][$Phase]); if ($opt['VERBOSE'] > 1) $rtn .= "\n** Checking requirements for $Phase (" . count($wbRequire[$Type][$Phase]) . " steps)"; foreach ((array)$wbRequire[$Type][$Phase] as $k => $step) { $stepcode = 'return(' . str_replace('%%', '$pagename, $Type, $Phase, $headers, $headhash, $bodytext, $mime, $EmailAuth, $subjvals', $step) . ');'; dbg($d*1,"$func: require code=" . od($stepcode)); if (!eval($stepcode)) { if ($opt['VERBOSE']) { $rtn .= "\n* Requirements Failed ($k)"; if ($opt['VERBOSE'] > 1) $rtn .= "\n** Failure detail ($k=$step)"; } continue 4; } if ($wbError) $rtn .= "\n*%red% EXTERNAL ERROR: $wbError%%"; } $nextphase = wbNextPhase($Type, $Phase); if ($opt['VERBOSE'] > 1) $rtn .= "\n** Preparing for $nextphase (" . count($wbPrepFor[$Type][$nextphase]) . " steps)"; ksort($wbPrepFor[$Type][$nextphase]); dbg($d*2, "$func: Looping through $Type-$nextphase Preparations"); dbg($d*1, $wbPrepFor[$Type][$nextphase]); foreach ((array)$wbPrepFor[$Type][$nextphase] as $k=>$step) { $stepcode = 'return(' . str_replace('%%', '$pagename, $Type, $Phase, $headers, $headhash, $bodytext, $mime, $EmailAuth, $subjvals', $step) . ');'; dbg($d*1,"$func: prep4code=" . od($stepcode)); dbg($d*1, "$func: After $Type-$nextphase: body=$bodytext"); if (!eval($stepcode)) { if ($opt['VERBOSE']) { $rtn .= "\n* Preparation Failed ($k)"; if ($opt['VERBOSE'] > 1) $rtn .= "\n** Failure detail ($k=$step)"; } continue 4; } dbg($d*1,"POST: mime follows", $mime); if ($wbError) $rtn .= "\n*%red% EXTERNAL ERROR: $wbError%%"; } if ($opt['VERBOSE'] > 1) $rtn .= "\n** Completed successfully."; continue 3; // we matched - go on to the next email } } } $_SESSION = $mysavedsession; if (!$processed) { if ($opt['VERBOSE']>1) $rtn .= "\n**Invalid Subject"; dbg($d*3,"$func: INVALID SUBJECT"); wbSend($pagename, $headers, $headhash, $bodytext, $mime, 'Misc', 'InvalidSubject'); } } if ($opt['VERBOSE']) $rtn .= "\n'''WIKIBOX COMPLETE'''"; if (!wmClosePOP3($wbPOP3Profile)) { wbError($pagename, "ERROR: WikiBox: Unable to close POP3 handle"); } return($rtn); } # wbNextPhase() # Return the next phase that should be processed function wbNextPhase($type, $cur) { global $wbControl; $next = false; foreach ($wbControl[$type] as $i) if ($cur == $i) $next = true; elseif ($next) return($i); } # # wbIsBlacklisted() # Confirm that the email address passed is blacklisted # This is not a typical "templated" function but rather a utility function # function wbIsBlacklisted($pagename, $email) { $func='wbIsBlacklisted()'; $d=1; dbg($d*4, "$func: Entering"); $emailauth = wbReadEmailAuth($pagename, $email); if ($emailauth['blacklist']) { dbg($d*4,"$func: Success. Returning TRUE (is blacklisted)."); return(true); } else { dbg($d*4, "$func: Failure. Returning FALSE (is NOT blacklisted)"); return(false); // double negative - this address is blacklisted } } # # wbNotBlacklisted() # Confirm that the user in the headhash['from'] is not blacklisted function wbNotBlacklisted($pagename, $rtype, $rphase, $headers, $headhash, $bodytext, $mime, $emailauth, $cmdvals) { $func='wbNotBlacklisted()'; $d=1; dbg($d*4, "$func: Entering"); if ($emailauth['blacklist']) { wbError($pagename, "ERROR: $rtype-$rphase Attempt from blacklisted address \"$emailauth[email]\". Request ignored."); dbg($d*4, "$func: Failure. Returning FALSE"); return(false); // double negative - this address is blacklisted } else { dbg($d*4,"$func: Success. Returning TRUE."); return(true); } } # wbValidPasswd() # function wbValidPasswd($pagename, $rtype, $rphase, $headers, $headhash, $bodytext, $mime, $emailauth, $cmdvals) { global $wbPasswdPrefixPat; $func='wbValidPasswd()'; $d=1; dbg($d*4, "$func: Entering"); if (!$emailauth['passwd']) { dbg($d*4,"$func: No emailauth passwd. Success. Returning TRUE."); return(true); } $pat = $wbPasswdPrefixPat . "\s*" . preg_quote($emailauth['passwd']); if (preg_match("/$pat/i", $bodytext)) { dbg($d*4,"$func: Success. Returning TRUE."); return(true); } # Valid Passwd was NOT received. Log error, reply to message, return false. dbg($d*1, "$func: Pattern not found: " . od($pat)); wbError($pagename, "ERROR: Valid Passwd NOT included in $rtype-$rphase message. Message logged as [[" . wbLogMessage($pagename, $headers, $headhash, $bodytext, $mime) . "]] (expecting " . $emailauth['passwd'] . ": /$pat/)"); wbSend($pagename, $headers, $headhash, $bodytext, $mime, "Misc", "NotValidated"); dbg($d*4, "$func: Failure. Returning FALSE"); return(false); } # wbDeleteInbox() # function wbDeleteInbox($pagename, $rtype, $rphase, $headers, $headhash, $bodytext, $mime, $emailauth, $cmdvals) { global $wbPageAuthStore, $WikiDir; $func='wbDeleteInbox()'; $d=1; dbg($d*4, "$func: Entering"); if (!slAuthorized($cmdvals['inboxpage'], $wbPageAuthStore, 'delete')) { dbg($d*4, "$func: Not sl authorized. Returning FALSE"); wbError($pagename, "ERROR: Not (sl) authorized to delete $cmdvals[inboxpage] as specified in $rtype-$rphase action."); return(false); } if (!CondAuth($pagename, 'edit')) { dbg($d*4, "$func: CondAuth fails. Returning FALSE"); wbError($pagename, "ERROR: Not (pm) authorized to delete $cmdvals[inboxpage] as specified in $rtype-$rphase action."); return(false); } if ($WikiDir->delete($cmdvals['inboxpage'])) { dbg($d*4, "$func: Error deleting. Returning FALSE"); wbError($pagename, "ERROR: problem deleting $cmdvals[inboxpage] as specified in $rtype-$rphase action."); return(false); } dbg($d*4, "$func: Returning TRUE"); return(true); } # wbValidInboxCode() # function wbValidInboxCode($pagename, $rtype, $rphase, $headers, $headhash, $bodytext, $mime, $emailauth, $cmdvals) { global $wbCodePrefixPat; $func='wbValidInboxCode()'; $d=1; dbg($d*4, "$func: Entering"); dbg($d*1, "$func: looking for Code: in $cmdvals[inboxpage]"); $code = PageTextVar($cmdvals['inboxpage'], 'Code'); dbg($d*1, "$func: code found was $code"); if (!$code) wbError($pagename, "ERROR: $func: Inbox Page Code nonexistent in inbox-page [[$cmdvals[inboxpage]]]. Message logged as [[" . wbLogMessage($pagename, $headers, $headhash, $bodytext, $mime) . "]]"); $pat = $wbCodePrefixPat . "\s*" . preg_quote($code); if (preg_match("/$pat/i", $bodytext)) { dbg($d*4,"$func: Success. Returning TRUE."); return(true); } # Valid Code was NOT received. Log error, reply to message, return false. dbg($d*1, "$func: Pattern not found: " . od($pat)); wbError($pagename, "ERROR: Valid Inbox Page Code NOT included in $rtype-$rphase message. Message logged as [[" . wbLogMessage($pagename, $headers, $headhash, $bodytext, $mime) . "]]"); wbSend($pagename, $headers, $headhash, $bodytext, $mime, "Misc", "NotValidated"); dbg($d*4, "$func: Failure. Returning FALSE"); return(false); } # wbStripPasswd() # function wbStripPasswd($pagename, $rtype, $rphase, $headers, $headhash, &$bodytext, &$mime, $emailauth, $cmdvals) { global $wbPasswdPrefixPat; $func='wbStripPasswd()'; $d=1; dbg($d*4, "$func: Entering"); $obody = $bodytext; dbg($d*1, "$func: pre-replace: body=$bodytext"); $bodytext = preg_replace("/(?:^|([\\n>]))[^\\n<>]*${wbPasswdPrefixPat}\\s*" . preg_quote($emailauth['passwd']) . "[^\\n<]*(?:
)?(?:\\n|(<))/i", "$1$2", $bodytext); dbg($d*1, "$func: post-replace: body=$bodytext"); $mime = wmSimplifyMime($headers."\n\n".$bodytext); dbg($d*1, "$func: post-replace text body=".wmTextMessage($mime)); dbg($d*4,"$func: Success. Returning TRUE."); return(true); } # wbNotSubscribed() # function wbNotSubscribed($pagename, $rtype, $rphase, $headers, $headhash, $bodytext, $mime, $emailauth, $cmdvals) { $func='wbNotSubscribed()'; $d=1; dbg($d*4, "$func: Entering"); dbg($d*1, "$func: emailauth record follows"); dbg($d*1, $emailauth); if (!@$emailauth['active']) { dbg($d*4,"$func: Success. Returning TRUE."); return(true); } # User is already subscribed. Log error, reply to message, return false. wbError($pagename, "ERROR: This user ($headhash[from]) is already subscribed and sent a rtype-$rphase message. Message logged as [[" . wbLogMessage($pagename, $headers, $headhash, $bodytext, $mime) . "]]"); wbSend($pagename, $headers, $headhash, $bodytext, $mime, "Misc", "AlreadySubscribed"); dbg($d*4, "$func: Failure. Returning FALSE"); return(false); } # wbSubscribed() # function wbSubscribed($pagename, $rtype, $rphase, $headers, $headhash, $bodytext, $mime, $emailauth, $cmdvals) { $func='wbSubscribed()'; $d=1; dbg($d*4, "$func: Entering"); dbg($d*1, "$func: emailauth record follows"); dbg($d*1, $emailauth); if (@$emailauth['active']) { dbg($d*4,"$func: Success. Returning TRUE."); return(true); } # User is not subscribed. Log error, reply to message, return false. wbError($pagename, "ERROR: Unsubscribed user ($headhash[from]) sent $rtype-$rphase message. Message logged as [[" . wbLogMessage($pagename, $headers, $headhash, $bodytext, $mime) . "]]"); wbSend($pagename, $headers, $headhash, $bodytext, $mime, "Misc", "EmailNotValid"); dbg($d*4, "$func: Failure. Returning FALSE"); return(false); } # # wbMkInboxPage() # function wbMkInboxPage($pagename, $rtype, $rphase, $headers, $headhash, $bodytext, $mime, $emailauth, &$cmdvals) { global $wbInboxPagePrefix; $func='wbMkInboxPage()'; $d=1; dbg($d*4, "$func: Entering"); $code=md5(rand()); //This will be the validation code for this inbox $cmdvals['inboxpage'] = wbCreatePage($pagename, $wbInboxPagePrefix, $headers, $headhash, $bodytext, $mime, "(:ActionType:$rtype:)\n(:ActionPhase:$rphase:)\n(:Code:$code:)"); return($cmdvals['inboxpage']); } # # wbInboxPageExists() # function wbInboxPageExists($pagename, $rtype, $rphase, $headers, $headhash, $bodytext, $mime, $emailauth, $cmdvals) { $func='wbInboxPageExists()'; $d=1; dbg($d*4, "$func: Entering: $cmdvals[inboxpage]"); dbg($d*1, $cmdvals); if ($cmdvals['inboxpage'] || PageExists($cmdvals['inboxpage'])) { dbg($d*4,"$func: Success. Returning TRUE."); return(true); } # Inbox page does not exist. Log error, reply to message, return false. wbError($pagename, "ERROR: Inbox page [[$cmdvals[inboxpage]]] nonexistent in $rtype-$rphase message. Message logged as [[" . wbLogMessage($pagename, $headers, $headhash, $bodytext, $mime) . "]]"); wbSend($pagename, $headers, $headhash, $bodytext, $mime, "Misc", "EmailNotValid"); dbg($d*4, "$func: Failure. Returning FALSE"); return(false); } # wbSenderIsModerator() # function wbSenderIsModerator($pagename, $rtype, $rphase, $headers, $headhash, $bodytext, $mime, $emailauth, $cmdvals) { $func='wbSenderIsModerator()'; $d=1; dbg($d*4, "$func: Entering"); $sender = wmBoiledEmail($headhash['from']); $mods = wbModeratorAddress(); if (in_array($sender, (array)$mods)) { dbg($d*4,"$func: Success. Returning TRUE."); return(true); } dbg($d*1,"$func: $sender is not part of $mods"); # Sender is not moderator. Log error, reply to message, return false. wbError($pagename, "ERROR: Non-moderator attempted moderate in $rtype-$rphase message. Message logged as [[" . wbLogMessage($pagename, $headers, $headhash, $bodytext, $mime) . "]]"); wbSend($pagename, $headers, $headhash, $bodytext, $mime, "Misc", "EmailNotValid"); dbg($d*4, "$func: Failure. Returning FALSE"); return(false); } # wbCanReadPage() # Do we have authorization to read this page? function wbCanReadPage($pagename, $rtype, $rphase, $headers, $headhash, $bodytext, $mime, $emailauth, $cmdvals, $silent=false) { global $wbPageAuthStore; $func='wbCanReadPage()'; $d=1; dbg($d*4, "$func: Entering"); dbg($d*3, "$func: cmd=$cmdvals[cmd], target=$cmdvals[target]"); # This is not the purpose of this function, but more of a sanity check $cmdvals['target'] = MakePageName($pagename, $cmdvals['target']); $auth = 'read'; if (slAuthorized($cmdvals['target'], $wbPageAuthStore, $auth)) { dbg($d*4,"$func: Success. Returning TRUE."); return(true); } # No auth to write. Log error, reply to message, return false. if (!$silent) { wbError($pagename, "ERROR: Attempt to read unauthorized page ($cmdvals[target]) in $rtype-$rphase message. Message logged as [[" . wbLogMessage($pagename, $headers, $headhash, $bodytext, $mime) . "]]"); wbSend($pagename, $headers, $headhash, $bodytext, $mime, "Read", "NoAuth"); } dbg($d*4, "$func: Failure. Returning FALSE"); return(false); } # wbCanWritePage() # Do we have authorization to write to this page? function wbCanWritePage($pagename, $rtype, $rphase, $headers, $headhash, $bodytext, $mime, $emailauth, $cmdvals, $silent=false) { global $wbPageAuthStore; $func='wbCanWritePage()'; $d=1; dbg($d*4, "$func: Entering"); dbg($d*3, "$func: cmd=$cmdvals[cmd], target=$cmdvals[target]"); # This is not the purpose of this function, but more of a sanity check if (!$cmdvals['cmd']) { dbg($d*3, "$func: ERROR: Unspecified command"); if (!$silent) wbError($pagename, "ERROR: $func: cmd not specified. Message logged as [[" . wbLogMessage($pagename, $headers, $headhash, $bodytext, $mime) . "]]"); return(false); } $cmd = strtolower($cmdvals['cmd']); if ($cmd != 'insert' && $cmdvals['loc'] && $cmdvals['pat']) $cmd = 'insert'; $cmdvals['target'] = MakePageName($pagename, $cmdvals['target']); if (in_array($cmd, array('append', 'prepend', 'insert'))) $auth = 'insert'; elseif (in_array($cmd, array('write', 'replace', 'overwrite'))) $auth = 'overwrite'; if (!PageExists($cmdvals['target'])) $auth = 'create'; #echo "wikibox: auth=$auth, wikiboxauth follows
\n"; #print_r($wbPageAuthStore); #echo "
\n"; if (slAuthorized($cmdvals['target'], $wbPageAuthStore, $auth)) { dbg($d*4, "$func: Success. Returning TRUE"); return(true); } # No auth to write. Log error, reply to message, return false. if (!$silent) { wbError($pagename, "ERROR: Attempt to write ($auth) to unauthorized page ($cmdvals[target]) in $rtype-$rphase message. Message logged as [[" . wbLogMessage($pagename, $headers, $headhash, $bodytext, $mime) . "]]"); wbSend($pagename, $headers, $headhash, $bodytext, $mime, "Write", "NoAuth"); } dbg($d*4, "$func: Failure. Returning FALSE"); return(false); } # wbWriteToPage() # This function actually does the writing to a page based on the request the # user made. In other words, this is the heart of WikiBox. function wbWriteToPage($pagename, $rtype, $rphase, $headers, $headhash, $bodytext, $mime, $emailauth, $cmdvals) { global $Author, $wbAuthor; $func='wbWriteToPage()'; $d=1; dbg($d*4, "$func: Entering"); $textbody = wmTextMessage($mime); // Technically this is already handled in the normal Control and PrepFor // arrays, but we can't risk mis-administration on this one... if (!wbCanWritePage($pagename, $rtype, $rphase, $headers, $headhash, $bodytext, $mime, $emailauth, $cmdvals, true)) { wbError($pagename, "ERROR: wbCanWritePage() returned false for ($cmdvals[target]) in $rtype-$rphase message. Message logged as [[" . wbLogMessage($pagename, $headers, $headhash, $textbody, $mime) . "]]"); dbg($d*4, "$func: Failure. Returning FALSE"); return(false); } dbg($d*1, "$func: cmdvals (pre-massage) follows", $cmdvals); $cmdvals['cmd'] = strtolower($cmdvals['cmd']); if ($cmdvals['cmd'] != 'insert' && $cmdvals['loc'] && $cmdvals['pat']) $cmdvals['cmd'] = 'insert'; $cmdvals['target'] = MakePageName($pagename, $cmdvals['target']); if (!($page = RetrieveAuthPage($cmdvals['target'], 'edit', false))) { wbError($pagename, "ERROR: Attempt to write ($auth) to pmwiki-unauthorized page ($cmdvals[target]) in $rtype-$rphase message. Message logged as [[" . wbLogMessage($pagename, $headers, $headhash, $textbody, $mime) . "]]"); dbg($d*4, "$func: RetrieveAuthPage() Failure. Returning FALSE"); return(false); } $newpage = $page; #echo "Starting text: >>$newpage[text]<<
\n"; dbg($d*1, "$func: Before text alteration cmd=$cmdvals[cmd], existing text=>>$newpage[text]<< and textbody=>>$textbody<<"); switch ($cmdvals['cmd']) { case 'append': $newpage['text'] .= "\n" . $textbody; break; case 'prepend': $newpage['text'] = $textbody . "\n" . $newpage['text']; break; case 'insert': if (!$cmdvals['loc'] || !$cmdvals['pat']) { echo "ERROR: WikiBox: $header[subject]: location/pattern not specified correctly
\n"; continue; } if (!preg_match($cmdvals['pat'], $newpage['text'], $m1)) { echo "ERROR: WikiBox: $cmdvals[pat]: pattern not found
\n"; continue; } switch ($cmdvals['loc']) { case 'before': $newpage['text'] = str_replace($m1[0], $textbody.$m1[0], $newpage['text']); break; case 'after': $newpage['text'] = str_replace($m1[0], $m1[0].$textbody, $newpage['text']); break; case 'replacing': case 'instead of': $newpage['text'] = str_replace($m1[0], $textbody, $newpage['text']); break; } break; case 'write': case 'replace': case 'overwrite': dbg(1*$d, "$func: textbody=$textbody"); $newpage['text'] = $textbody; break; } dbg($d*1, "$func: emailauth follows", $emailauth); $Author = ($emailauth['author'] ? $emailauth['author'] : $wbAuthor); dbg($d*1, "$func: Setting Author to $Author"); $newpage['author'] = $Author; #echo "Writing >>$newpage[text]<< to $cmdvals[target]
\n"; if (!UpdatePage($cmdvals['target'], $page, $newpage)) { wbError($pagename, "ERROR: $func: Error writing to $cmdvals[target]. Message logged as [[" . wbLogMessage($pagename, $headers, $headhash, $textbody, $mime) . "]]"); wbSend($pagename, $headers, $headhash, $textbody, $mime, "Write", "Failed"); dbg($d*4, "$func: Failure. Returning FALSE"); return(false); } dbg(4*$d, "$func: Page written successfully. Returning TRUE"); return(true); } # wbReReadInbox() # This function re-reads the Inbox-TIMESTAMP file and replaces the body, # headhash, cmdvals, etc. with the original values function wbReReadInbox($pagename, $rtype, $rphase, &$headers, &$headhash, &$bodytext, &$mime, &$emailauth, &$cmdvals, $alttype, $altphase) { global $wbSubjectPattern, $PageTextVarPatterns; $func='wbReReadInbox()'; $d=1; dbg($d*4, "$func: Entering"); # Get the values from the inbox-page $inboxpn = MakePageName($pagename, $cmdvals['inboxpage']); $subject = PageTextVar($inboxpn, 'SUBJECT'); $inboxpage = ReadPage($inboxpn, READPAGE_CURRENT); if (!$inboxpage) { wbError($pagename, "ERROR: $func: Unable to read inbox page $inboxpn. Message logged as [[" . wbLogMessage($pagename, $headers, $headhash, $bodytext, $mime) . "]]"); wbSend($pagename, $headers, $headhash, $bodytext, $mime, "Misc", "NoInbox"); dbg($d*4, "$func: Failure. Returning FALSE"); return(false); } dbg($d*1, "body[text] follows", $inboxpage['text']); $bodytext = TextSection($inboxpage['text'], '#body'); dbg($d*1, "$func: bodytext follows", $bodytext); $headers = TextSection($inboxpage['text'], '#header'); $message_data = $headers . "\n\n" . $bodytext; $mime = wmSimplifyMime($message_data); dbg($d*1, "$func: mime follows", $mime); $headtext = TextSection($inboxpage['text'], '#headhash'); $headhash = unserialize($headtext); if ($emailauth = wbReadEmailAuth($pagename, $headhash['from'])) { dbg(1,"$func: EmailAuth follows:", $emailauth); #NOTE: I tried this and it didn't work... Maybe need $AuthPw #or $AuthId or $AuthList as well...? Meanwhile commenting out. $_SESSION = unserialize(base64_decode($emailauth['authinfo'])); #Note that just calling SessionAuth() is unsuccessful because of the #static variables preventing it being called more than once wbSessionAuth(); } if (!preg_match($wbSubjectPattern[$alttype][$altphase], $subject, $m)) { wbError($pagename, "ERROR: $func: Subject inexplicably no longer matches. Inbox page manually altered? Message logged as [[" . wbLogMessage($pagename, $headers, $headhash, $bodytext, $mime) . "]]"); wbSend($pagename, $headers, $headhash, $bodytext, $mime, "Misc", "InboxAltered"); dbg($d*4, "$func: Failure. Returning FALSE"); return(false); } $cmdvals = $m + $cmdvals; dbg($d*1, "$func: body=$bodytext, cmdvals follows:", $cmdvals); dbg($d*4,"$func: Success. Returning TRUE."); return(true); } # # wbSessionAuth() # # This is a copy of SessionAuth() from pmwiki.php with some alterations. # Basically I'm not interested in setting anything in $_SESSION from this # function so I'm getting rid of that. And I want to be able to call it # multiple times with multiple different "identities" as I change from one # user to another, so I've gotten rid of the static variables which # prevented this. Also I don't call session_start - this could be a problem # on certain systems? I'm not sure... function wbSessionAuth() { global $AuthId, $AuthList, $AuthPw, $SessionEncode, $SessionDecode, $EnableSessionPasswords, $VersionNum; if (!isset($AuthId)) $AuthId = @end($_SESSION['authid']); # Here's an attempt to keep it compatible both with pre-beta-67 and post-67 if ($VersionNum >= "2001967") $AuthPw = array_map($SessionDecode, array_keys((array)@$_SESSION['authpw'])); else $AuthPw = array_keys((array)@$_SESSION['authpw']); $AuthList = array_merge($AuthList, (array)@$_SESSION['authlist']); } # # wbMkEmailAuth() # function wbMkEmailAuth($pagename, $rtype, $rphase, $headers, $headhash, $bodytext, $mime, $emailauth, $cmdvals) { global $wbConfigEmailAuth, $wbAuthFlds, $Author, $wbAuthor; $func="wbMkEmailAuth($headhash[from])"; $d=1; dbg($d*4, "$func: Entering"); $email = wmBoiledEmail($headhash['from']); $passwd = PageTextVar($cmdvals['inboxpage'], 'Passwd'); $author = PageTextVar($cmdvals['inboxpage'], 'Author'); dbg($d*1, "$func: passwd=$passwd, author=$author, inboxpage=$cmdvals[inboxpage]"); dbg($d*1, "$func: cmdvals follows:", $cmdvals); $foo = MakePageName($pagename, $cmdvals['inboxpage']); dbg($d*1, "$func: new pagename=$foo"); $ap = FmtPagename($wbConfigEmailAuth, $pagename); $page = ReadPage($ap, READPAGE_CURRENT); $opage = $page; #dbg($d*2,"$func: AuthEmail contains >>$page[text]<<"); # If it exists then update active with 1 instead of 0 if (preg_match("/^" . preg_quote($email) . ":.*$/im", $page['text'], $m)) { $flds = split(":",$m[0],12); $flds[$wbAuthFlds['active']] = 1; if ($author) $flds[$wbAuthFlds['author']] = $author; if ($passwd) $flds[$wbAuthFlds['passwd']] = $passwd; $page['text'] = str_replace($m[0], implode(":", $flds), $page['text']); } else $page['text'] .= "\n$email::$author:1:0:$passwd::::::"; if (!$Author) $Author = $wbAuthor; if (!UpdatePage($ap, $opage, $page)) { wbError($pagename, "ERROR: $func: Unable to update the page. UpdatePage() failed."); dbg($d*4, "$func: Failure. Returning FALSE"); return(false); } dbg($d*4,"$func: Success. Returning TRUE."); return(true); } # # wbBlacklistEmailAuth() # function wbBlacklistEmailAuth($pagename, $rtype, $rphase, $headers, $headhash, $bodytext, $mime, $emailauth, $cmdvals) { global $wbConfigEmailAuth, $wbAuthFlds, $Author, $wbAuthor; $func="wbBlacklistEmailAuth($headhash[from])"; $d=1; dbg($d*4, "$func: Entering"); $email = wmBoiledEmail($headhash['from']); $ap = FmtPagename($wbConfigEmailAuth, $pagename); $page = ReadPage($ap, READPAGE_CURRENT); $opage = $page; #dbg(1,"$func: AuthEmail contains >>$page[text]<<"); # If it exists then update blacklist with 1 instead of 0 if (preg_match("/^" . preg_quote($email) . ":.*$/im", $page['text'], $m)) { $flds = split(":",$m[0],12); $flds[$wbAuthFlds['blacklist']] = 1; $page['text'] = str_replace($m[0], implode(":", $flds), $page['text']); if (!$Author) $Author = $wbAuthor; if (!UpdatePage($ap, $opage, $page)) { wbError($pagename, "ERROR: $func: Unable to update the page. UpdatePage() failed."); dbg($d*4, "$func: Failure. Returning FALSE"); return(false); } dbg($d*4,"$func: Success. Returning TRUE."); return(true); } wbError($pagename, "ERROR: $func: Unable to update the page. EmailAuth record ($email) inexplicably not found."); dbg($d*4, "$func: Failure. Returning FALSE"); return(false); } # # wbDeactivateEmailAuth() # function wbDeactivateEmailAuth($pagename, $rtype, $rphase, $headers, $headhash, $bodytext, $mime, $emailauth, $cmdvals) { global $wbConfigEmailAuth, $wbAuthFlds, $Author, $wbAuthor; $func="wbDeactivateEmailAuth($headhash[from])"; $d=1; dbg($d*4, "$func: Entering"); $email = wmBoiledEmail($headhash['from']); $ap = FmtPagename($wbConfigEmailAuth, $pagename); $page = ReadPage($ap, READPAGE_CURRENT); $opage = $page; dbg(1,"$func: AuthEmail contains >>$page[text]<<"); # If it exists then update active with 1 instead of 0 if (preg_match("/^" . preg_quote($email) . ":.*$/im", $page['text'], $m)) { $flds = split(":",$m[0],12); $flds[$wbAuthFlds['active']] = 0; $page['text'] = str_replace($m[0], implode(":", $flds), $page['text']); if (!$Author) $Author = $wbAuthor; if (!UpdatePage($ap, $opage, $page)) { wbError($pagename, "ERROR: $func: Unable to update the page. UpdatePage() failed."); dbg($d*4, "$func: Failure. Returning FALSE"); return(false); } dbg($d*4,"$func: Success. Returning TRUE."); return(true); } wbError($pagename, "ERROR: $func: Unable to update the page. EmailAuth record ($email) inexplicably not found."); dbg($d*4, "$func: Failure. Returning FALSE"); return(false); } # wbExpectedSender() # function wbExpectedSender($pagename, $rtype, $rphase, $headers, $headhash, $bodytext, $mime, $emailauth, $cmdvals) { $func='wbExpectedSender()'; $d=1; dbg($d*4, "$func: Entering"); $inboxpn = MakePageName($pagename, $cmdvals['inboxpage']); $expected = PageTextVar($inboxpn, 'ExpectedSender'); if (!$expected) $expected = PageTextVar($inboxpn, 'FROM'); $expected = wmBoiledEmail($expected); $actual = wmBoiledEmail($headhash['from']); if ($expected == $actual) { dbg($d*4,"$func: Success. Returning TRUE."); return(true); } # Sender was NOT expected. Log error, reply to message, return false. dbg($d*1, "$func: actual sender ($actual) is not expected ($expected)"); wbError($pagename, "ERROR: Actual sender ($actual) was NOT expected sender ($expected) in $rtype-$rphase message. Message logged as [[" . wbLogMessage($pagename, $headers, $headhash, $bodytext, $mime) . "]]"); wbSend($pagename, $headers, $headhash, $bodytext, $mime, "Misc", "UnexpectedSender"); dbg($d*4, "$func: Failure. Returning FALSE"); return(false); } # # wbSetExpectedsender() # function wbSetExpectedSender($pagename, $rtype, $rphase, $headers, $headhash, $bodytext, $mime, $emailauth, $cmdvals, $address) { $func='wbSetExpectedSender()'; $d=1; dbg($d*4, "$func: Entering"); dbg($d*2, "Writing expectedsender to inboxpage=$cmdvals[inboxpage]"); writeptv($pagename, $cmdvals['inboxpage'], 'ExpectedSender', $address); dbg($d*4,"$func: Success. Returning TRUE."); return(true); } # # wbSetPasswd() # function wbSetPasswd($pagename, $rtype, $rphase, $headers, $headhash, $bodytext, $mime, $emailauth, $cmdvals, $required = true) { global $wbPasswdPrefixPat, $Author, $wbAuthor; $func='wbSetPasswd()'; $d=1; dbg($d*4, "$func: Entering"); dbg($d*1, "$func: body=$bodytext"); if (preg_match("/${wbPasswdPrefixPat}\\s*(\\S+)/i", $bodytext, $m)) $passwd = $m[1]; else $passwd = ''; if ($passwd || !$required) { dbg($d*1, "$func: Setting passwd to $passwd"); dbg($d*1, "$func: pagename=$pagename, inboxpage=$cmdvals[inboxpage], passwd=$passwd"); if (!$Author) $Author = $wbAuthor; writeptv($pagename, $cmdvals['inboxpage'], 'Passwd', $passwd); dbg($d*4,"$func: Success. Returning TRUE."); return(true); } # No password specified. Log error, reply to message, return false. dbg($d*1, "$func: Password not specified"); wbError($pagename, "ERROR: User neglected to specify a password in $rtype-$rphase message. Message logged as [[" . wbLogMessage($pagename, $headers, $headhash, $bodytext, $mime) . "]]"); wbSend($pagename, $headers, $headhash, $bodytext, $mime, "Subscribe", "NoPasswd"); dbg($d*4, "$func: Failure. Returning FALSE"); return(false); } # # wbSetAuthor() # function wbSetAuthor($pagename, $rtype, $rphase, $headers, $headhash, $bodytext, $mime, $emailauth, $cmdvals, $required = true) { global $Author, $wbAuthor; $func='wbSetAuthor()'; $d=1; dbg($d*4, "$func: Entering"); dbg($d*1, "$func: bodytext follows:", $bodytext); if (preg_match("/Author:\\s*(\\w[^\n<]*)\\s*(?:<|$)/im", $bodytext, $m)) $author = $m[1]; else $author = ''; if ($author || !$required) { dbg($d*1, "$func: Setting author to $author"); if (!$Author) $Author = $wbAuthor; writeptv($pagename, $cmdvals['inboxpage'], 'Author', $author); dbg($d*4,"$func: Success. Returning TRUE."); return(true); } # No author specified. Log error, reply to message, return false. dbg($d*1, "$func: Author not specified"); wbError($pagename, "ERROR: User neglected to specify Author in $rtype-$rphase message. Message logged as [[" . wbLogMessage($pagename, $headers, $headhash, $bodytext, $mime) . "]]"); wbSend($pagename, $headers, $headhash, $bodytext, $mime, "Subscribe", "NoAuthor", array("%PAGENAME%" => $cmdvals["inboxpage"])); dbg($d*4, "$func: Failure. Returning FALSE"); return(false); } # wbSendPage() # Send a page back to the user (response to "read [[group.page]]") function wbSendPage($pagename, $rtype, $rphase, $headers, $headhash, $bodytext, $mime, $emailauth, $cmdvals, $to='') { global $wbMarkupSet, $wbSMTP, $wbError; $func='wbSendPage()'; $d=1; dbg($d*4, "$func: Entering"); if (!wbCanReadPage($pagename, $rtype, $rphase, $headhash, $bodytext, $emailauth, $cmdvals, true)) { wbError($pagename, "ERROR: wbCanReadPage() returned false for ($cmdvals[target]) in $rtype-$rphase message. Message logged as [[" . wbLogMessage($pagename, $headers, $headhash, $bodytext, $mime) . "]]"); dbg($d*4, "$func: Failure. Returning FALSE"); return(false); } $cmdvals['target'] = MakePageName($pagename, $cmdvals['target']); if (!($page = RetrieveAuthPage($cmdvals['target'], 'read', false))) { wbError($pagename, "ERROR: Attempt to read pmwiki-unauthorized page ($cmdvals[target]) in $rtype-$rphase message. Message logged as [[" . wbLogMessage($pagename, $headers, $headhash, $bodytext, $mime) . "]]"); dbg($d*4, "$func: Failure. Returning FALSE"); return(false); } $opt = ParseArgs($cmdvals['therest']); dbg(1,$opt); # fmt=html or fmt=both or fmt=text if ($opt['fmt']) $fmt = $opt['fmt']; else $fmt = NULL; if ($opt['ruleset']) $ruleset=$opt['ruleset']; else $ruleset='text'; $subject = "RE: " . $headhash['subject']; $message = $page['text']; if (!$to) $to = ($headhash['reply-to']?$headhash['reply-to']:$headhash['from']); dbg($d*1, "$func: Sending message fmt=$fmt, ruleset=$ruleset, to=$to"); $wbError = wmSendMail($pagename, $to, $subject, $message, '', '', $wbSMTP['From'], $fmt, $wbMarkupSet[$ruleset]); dbg($d*4,"$func: Success. Returning TRUE."); return(true); } # # wbUpload() # function wbUpload($pagename, $rtype, $rphase, $headers, $headhash, &$bodytext, &$mime, $emailauth, $cmdvals) { global $wbUploadPattern, $UploadFileFmt, $UploadVerifyFunction, $wbPageAuthStore, $EnableUpload, $EnableUploadOverwrite, $UploadExtSize, $EnableUploadVersions; $func='wbUpload()'; $d=1; dbg($d*4, "$func: Entering"); $msg=''; if (!$EnableUpload) $msg = "Uploads not enabled in PmWiki configuration."; elseif (!CondAuth($cmdvals['target'], 'upload')) $msg = "No PmWiki upload authorization for page=$cmdvals[target]."; elseif (!slAuthorized($cmdvals['target'], $wbPageAuthStore, 'upload')) $msg = "No SecLayer authorization for upload for page=$cmdvals[target]."; if ($msg) { dbg($d*4, "$func: $msg Returning FALSE"); echo "ERROR $func: $msg
\n"; return(false); } $UploadCnt=0; while (preg_match($wbUploadPattern, $bodytext, $m)) { $UploadCnt++; $bodytext = preg_replace("/".preg_quote($m[0])."[^\n<]*(?:
)?[^\n<]*(?:\n|(<))/", "$1", $bodytext); list($type, $content, $fn) = wmAttachment($mime, $m['filename']); dbg($d*1, "$func: type=$type, content=$content, fn=$fn"); $filepath = FmtPageName("$UploadFileFmt/$m[filename]", $cmdvals['target']); $msg = ''; if (file_exists($filepath)) { if (!$EnableUploadOverwrite) $msg = "PmWiki not configured to overwrite uploads. $filepath exists."; if (!$m['bang']) $msg = "WikiBox Upload directive did not include '!' for overwriting and $filepath exists."; } if (!$msg) { preg_match('/\\.([^.\\/]+)$/',$filepath,$match); $ext=@$match[1]; $maxsize = $UploadExtSize[$ext]; if ($maxsize<=0) $msg = "Bad file type. Extension=$ext."; elseif ($uploadfile['size']>$maxsize) $msg = "File too large. For extension=$ext the maximum size is $maxsize."; } if (!$msg) { $filedir = preg_replace('#/[^/]*$#','',$filepath); mkdirp($filedir); if (IsEnabled($EnableUploadVersions, 0)) @rename($filepath, "$filepath,$Now"); # Now write the file out if ($uploadfp = fopen($filepath, "wb")) { if (fwrite($uploadfp, $content)) { dbg($d*3,"$func: \"$filepath\" uploaded."); } else { $msg = "Unable to write to \"$filepath\"."; } fclose($uploadfp); } else { $msg = "Unable to open \"$filepath\"."; } fixperms($filepath,0444); } if ($msg) { dbg($d*4,"$func: $msg Returning FALSE."); echo "ERROR $func: $msg
\n"; return(false); } } # Since we updated $bodytext we need to update the $mime structure as well if ($UploadCnt) $mime = wmSimplifyMime($headers."\n\n".$bodytext); dbg($d*4,"$func: Uploaded $UploadCnt files. Returning TRUE."); return(true); } # wbTemplate() # function wbTemplate($pagename, $rtype, $rphase, $headers, $headhash, $bodytext, $mime, $emailauth, $cmdvals) { $func='wbTemplate()'; $d=1; dbg($d*4, "$func: Entering"); return(true); } # wbLogMessage() # This function logs a given email message function wbLogMessage($pagename, $headers, $headhash, $bodytext, $mime, $prefix='Logged-') { global $wbGroup; return(wbCreatePage($pagename, $prefix, $headers, $headhash, $bodytext, $mime, "")); } # wbSend() # Will "reply" unless the $to is specified # Subject & Message specified by type/phase in wbSubject/wbMessage arrays function wbSend($pagename, $headers, $headhash, $bodytext, $mime, $Type, $Phase, $extra=array(), $to=false) { global $wbSubject, $wbMessage, $wbGroup, $wbMessagePagePrefix, $wbSMTP; $func="wbSend()"; $d=1; dbg($d*4, "$func: Entering"); if (!($body = wmTextMessage($mime))) $body = $bodytext; dbg($d*1, "$func: text message=$body"); $subject = wbReplace($wbSubject[$Type][$Phase], $headhash['from'], $headhash['subject'], $body, $extra); $pn = "$wbGroup.$wbMessagePagePrefix-$Type-$Phase"; if (PageExists($pn)) $msg = "(:include $pn:)"; else $msg = $wbMessage[$Type][$Phase] . "\n\n(Message ID: $Type-$Phase)"; $message = wbReplace($msg, $headhash['from'], $headhash['subject'], $body, $extra); if (!$to) $to = ($headhash['reply-to']?$headhash['reply-to']:$headhash['from']); if (wbIsBlacklisted($pagename, $to)) { dbg($d*1, "$func: Attempt to send message to blacklisted address $to"); return(false); } wmSendMail($pagename, $to, $subject, $message, '', '', $wbSMTP['From']); return(true); } # wbModeratorAddress() # Return the moderator's address # (Later this may become a field in the AuthEmail file and thus allow more # than 1 email address. Hopefully it will be in a format acceptable to # wmSendMail()... Anyway, that's why it's a function and not a var.) function wbModeratorAddress() { global $wbModeratorAddress; return($wbModeratorAddress); } function wbError($pagename, $msg, $extra='') { global $wbErrorLog; $msg = strftime('%Y-%m-%d %H:%M:%S --> ') . $msg . ($extra ? " ($extra)" : ''); logit($pagename, $wbErrorLog, $msg); } # wbCreatePage() # Create a temporary page using the provided prefix and a timestamp function wbCreatePage($pagename, $prefix, $headers, $headhash, $bodytext, $mime, $extratext='') { global $wbGroup; static $PagesSoFar = array(); $func='wbCreatePage()'; $d=0; dbg($d*4, "$func: Entering"); $pn = $base = "$wbGroup.$prefix" . strftime('%Y-%m-%d-%H-%M-%S'); dbg($d*1, "$func: Initial Pagename=$pn"); if (PageExists($base) || in_array($base, $PagesSoFar)) { dbg($d*1, "$func: Initial Pagename already existed"); $i = 1; $pn = sprintf("$base-%03d", $i); while (PageExists($pn) || in_array($pn, $PagesSoFar)) { $pn = sprintf("$base-%03d", ++$i); dbg($d*1, "$func: Checking Pagename=$pn"); } dbg($d*1, "$func: Unique Pagename=$pn"); } dbg($d*1, "$func: Writing to Pagename=$pn"); $page['author'] = $wbAuthor; $page['csum'] = 'Email received and page automatically created'; $page['text'] = "(:linebreaks:)\n" . $extratext . "(:if false:)\n[[#headhash]]" . serialize($headhash). "\n[[#headhashend]]\n[[#header]]".$headers."\n[[#headerend]]\n(:ifend:)\n" . "FROM: $headhash[from]\n" . "DATE: $headhash[date]\n" . "TIMESTAMP: " . time() . "\n" . "SUBJECT: $headhash[subject]\n" . wmTextMessage($mime) . "\n" . "(:if false:)\n[[#body]]\n".$bodytext."\n[[#bodyend]]\n(:ifend:)"; $Author = $wbAuthor; WritePage($pn, $page); $PagesSoFar[] = $pn; return($pn); } function wbReplace($text, $from, $subject, $body, $more_rep=array()) { $func = 'wbReplace()'; dbg(3,"$func: Entering text=$text, from=$from, subject=$subject, body=$body"); $repl = array_merge(array('%SUBJECT%'=>$subject, '%FROM%'=>$from, '%BODY%'=>$body), $more_rep); $text = str_ireplace(array_keys($repl), array_values($repl), $text); return($text); } # wbReadEmailAuth() # Read the email authorization page and return the record function wbReadEmailAuth($pagename, $email) { global $wbConfigEmailAuth, $wbAuthFlds; $func = "wbReadEmailAuth($email)"; $email = wmBoiledEmail($email); dbg(4,"$func: Entering email=$email"); $ap = FmtPagename($wbConfigEmailAuth, $pagename); $page = ReadPage($ap, READPAGE_CURRENT); #dbg(2,"$func: AuthEmail contains >>$page[text]<<"); if (preg_match("/^" . preg_quote($email) . ":.*$/im", $page['text'], $m)) { $flds = split(":",$m[0],12); if (sizeof($flds) != sizeof($wbAuthFlds)) { wbError($pagename, "ERROR: EmailAuth record \"$email\" malformed (". sizeof($flds) .")"); return(false); } return(array_combine(array_keys($wbAuthFlds), $flds)); } else return(false); } # wbSignup is called in response to (:wikibox SIGNUP:) markup # It presents a form allowing the user to enter email & author and these # will be saved along with current authorizations (from $_SESSION) into # some SiteAdmin.* page. function wbSignup($pagename, $opt) { global $wbSignup, $wbConfigEmailAuth, $InputValues, $wbSignupForm, $wbAuthFlds, $wbSMTP, $Author; $rtn = ''; SDV($wbSignupForm, "|| (:input form method=POST:) (:input hidden n {*\$FullName}:)\n || border=1\n ||This form is used to sign up for wikibox access. Wikibox is a recipe which allows email access to the wiki. For more information send an email with the subject \"usage\" to the address @@$wbSMTP[From]@@. \\\\ \\\\ This form can be used either for initial sign-up or to update your subscription. Note that ALL fields will be updated EVERY time you press submit as long as the \"Email Address\" and \"Old Pass\" fields match the existing information. (If you are creating a new wikibox subscription then \"Old Pass\" is not required.)|||| || @@*@@Email Address:||(:input text name=emailaddr:) [-just a simple email @@name@domain.org@@-]||\n || @@*@@Author:||(:input text name=editauth:) [-this will be used to fill the \"author\" field for any changes you make via wikibox-]||\n || (Old Pass):||(:input text name=oldpass:) [-only needed if you are updating an existing record-] ||\n || @@*@@Email Pass:||(:input text name=emailpass:) [-this password must accompany any wikibox email (\"wikibox-passwd: PASSWORD\") to be validated as being really from you-]||\n (:input submit submit Submit:) (:input end:)"); if ($_REQUEST['emailaddr']) $InputValues['emailaddr'] = $_REQUEST['emailaddr']; if ($_REQUEST['editauth']) $InputValues['editauth'] = $_REQUEST['editauth']; if ($_REQUEST['oldpass']) $InputValues['oldpass'] = $_REQUEST['oldpass']; if ($_REQUEST['emailpass']) $InputValues['emailpass'] = $_REQUEST['emailpass']; if ($_REQUEST['submit']) { if (strpos($_REQUEST['editauth'], ':') === false && strpos($_REQUEST['emailaddr'], ':') === false && strpos($_REQUEST['emailpass'], ':') === false) { if (!$_REQUEST['editauth'] || !$_REQUEST['emailaddr'] || !$_REQUEST['emailpass']) { $rtn = "%red%Note required fields marked with @@*@@. You have left one or more required fields blank.%%\n"; } else { $ap = FmtPagename($wbConfigEmailAuth, $pagename); $page = ReadPage($ap, READPAGE_CURRENT); $npage = $page; $confirmcode = rand(100000,999999); $newline = "$_REQUEST[emailaddr]:$_SESSION[authid]:$_REQUEST[editauth]:1:0:$_REQUEST[emailpass]:::::$_SESSION[authid]:" . base64_encode(serialize($_SESSION)); if (preg_match("/^" . preg_quote($_REQUEST['emailaddr']) . ":.*$/m", $npage['text'], $m)) { $emailauth = split(":", $m[0], 12); $oldpass = $emailauth[$wbAuthFlds['passwd']]; if ($oldpass == $_REQUEST['oldpass'] || CondAuth($pagename, 'admin')) $npage['text'] = preg_replace("/^$_REQUEST[emailaddr]:.*$/m", $newline, $npage['text']); else { $rtn .= "\n%red%ERROR: Old Password did not match ($oldpass, $_REQUEST[oldpass]). Not saved%%\n"; $npage['text'] = ''; } } else $npage['text'] .= "\n$newline"; #echo "Updating with this text: >>$npage[text]<<
\n"; if ($npage['text']) { if (!$Author) $Author = $_REQUEST['editauth']; if (UpdatePage($ap, $page, $npage)) $rtn .= "Information saved.\n"; else $rtn .= "%red%'''Failure saving information'''%%\n"; } } } else $rtn = "%red%'''ERROR: No input field may contain a colon. NOT saved.'''%%\n"; } $rtn .= $wbSignupForm; return ($rtn); } # DEVELOPMENT ROADMAP # # Give ability to do MXes on pagename # # Give a default action if the command is invalid (write to timestamp, append # to X, something like that) # # Ability to log deleted messages with headers and what was done with them by # whom (one email per page? append to 1 long file? 1 file per month?) # $wbLog with strftime() replacements? MX processing? my own %from% # %month% %subject% etc replacement strings? # # See EditXSV.php for another idea for viewing/editing the EmailAuth, PageAuth, # and perhaps the EmailHist pages # # Implement some kind of logging using WritePage() instead of UpdatePage(). # Make sure that each action (including emails not being sent because of # blacklisting) gets logged. Maybe have a set number of lines or days (I # guess configurable) before you rename that page to a historical log and # then start again with the current log. # # Need to keep a count of the number of "bad subject" emails from a given email # address. Allow 2 or 3, but then blacklist them (warning them) or something # like that. Otherwise you could end up with vacation mails or something # causing an infinite loop...