diff --git a/src/Jirafeau/a.php b/src/Jirafeau/a.php index 6dac4ca..75570c3 100644 --- a/src/Jirafeau/a.php +++ b/src/Jirafeau/a.php @@ -77,7 +77,7 @@ define ('M_WELCOME', "
Informations concernant le compte : ___SENDER___
define ('M_INCONSISTENT_DATES',
" (dates incohéantes avec ___FILENAME___ : ___DIRTIME___ != ___FILETIME___)");
-define ('A_ACTION', 'a'); // action : T_LOGIN, T_LOGOUT, A_MODE(footer|attachment|both), A_RECORD+(on|off), A_PERIOD(minute|hour|day|week|month|quarter), A_LANG(fr|en|br)
+define ('A_ACTION', 'a'); // action : T_LOGIN, T_LOGOUT, A_MODE(none|footer|attachment|both), A_RECORD+(on|off), A_PERIOD(minute|hour|day|week|month|quarter), A_LANG(fr|en|br)
define ('A_GET', 'g'); // get archive
define ('A_HASH', 'h'); // file to update or delete
define ('A_OPEN_TOKEN', 'o'); // ask token
@@ -114,7 +114,7 @@ define ('T_ARCHIVE_TITLE', "archive_content");
define ('T_ARCHIVE_MIME', "text/kaz_email_archive");
-$modeText = ['footer' => "pied de page", 'attachment' => "pièce jointe", 'both' => "les deux"];
+$modeText = ['none' => "sans", 'footer' => "pied de page", 'attachment' => "pièce jointe", 'both' => "les deux"];
$trackText = ['on' => "oui", 'off' => "non"];
$periodText = ['minute' => "minute", 'hour' => "heure", 'day' => "jour", 'week' => "semaine", 'month' => "mois"];
// XXX , 'quarter' => "trimestre"];
diff --git a/src/bash/filter.sh b/src/bash/filter.sh
index 8150880..6233085 100644
--- a/src/bash/filter.sh
+++ b/src/bash/filter.sh
@@ -53,7 +53,7 @@ EX_UNAVAILABLE=69
EX_TOO_LARGE=552
INSPECT_DIR=/var/spool/filter
DIR_LOG=/var/log/mail
-FIC_LOG=${DIR_LOG}/filter.log
+FIC_LOG="${DIR_LOG}/filter.log"
SENDMAIL="/usr/sbin/sendmail -G -i"
MAILS=/tmp/FILTER
MAX_KEEP_IN_MAIL=5ki
@@ -62,7 +62,6 @@ SHRINK_CMD=/home/filter/eMailShrinker
JIRAFEAU_CMD=/home/filter/jirafeauAPI
JIRAFEAU_URL=https://depot.${DOMAINNAME:-"kaz.bzh"}
JIRAFEAU_LOCAL=http://depot
-JIRAFEAU_TIME=month
MD5_CMD=/usr/bin/md5sum
DISCLAMER_CMD=altermime
MAX_FINAL_SIZE=2097152 # 2Mi
@@ -113,22 +112,18 @@ DATE_TEMPS=$(date "+%Y-%m-%d-%H:%M:%S")
REP_PIECE_JOINTE="${MAILS}/${DATE_TEMPS}_${MAIL_SOURCE}_$$"
MODE=$(curl "${JIRAFEAU_LOCAL}/a.php?m=${MAIL_SOURCE}" 2>/dev/null )
-[[ "${MODE}" =~ ^(footer|attachment|both)$ ]] || MODE="${DEFAULT_MODE}"
+[[ "${MODE}" =~ ^(none|footer|attachment|both)$ ]] || MODE="${DEFAULT_MODE}"
TRACK=$(curl "${JIRAFEAU_LOCAL}/a.php?r=${MAIL_SOURCE}" 2>/dev/null )
[[ "${TRACK}" =~ ^(|0|1|false|true|FALSE|TRUE|on|off)$ ]] || TRACK="${DEFAULT_TRACK}"
PERIOD=$(curl "${JIRAFEAU_LOCAL}/a.php?p=${MAIL_SOURCE}" 2>/dev/null )
[[ "${PERIOD}" =~ ^(minute|hour|day|week|month|quarter)$ ]] || PERIOD="${DEFAULT_PERIOD}"
-if [ -n "$(echo "${PERIOD}" | grep -e minute -e hour -e day -e week -e month -e quarter 2>/dev/null)" ]; then
- JIRAFEAU_TIME="${PERIOD}"
-fi
-
-LOG_FIC "\n" \
- " MAIL_SOURCE : ${YELLOW}${MAIL_SOURCE}${NC}\n" \
- " DATE_TEMPS : ${YELLOW}${DATE_TEMPS=}${NC}\n" \
- " TRACK : ${YELLOW}${TRACK}${NC}\n" \
- " PERIOD : ${YELLOW}${PERIOD}${NC}\n" \
- " JIRAFEAU_TIME: ${YELLOW}${JIRAFEAU_TIME}${NC}"
+LOG_FIC "${NL}" \
+ " MAIL_SOURCE : ${YELLOW}${MAIL_SOURCE}${NC}${NL}" \
+ " DATE_TEMPS : ${YELLOW}${DATE_TEMPS=}${NC}${NL}" \
+ " MODE : ${YELLOW}${MODE}${NC}${NL}" \
+ " TRACK : ${YELLOW}${TRACK}${NC}${NL}" \
+ " PERIOD : ${YELLOW}${PERIOD}${NC}${NL}"
if ! cd "${INSPECT_DIR}"; then
echo "${INSPECT_DIR} does not exist"
@@ -145,13 +140,13 @@ ARCHIVE_CONTENT="${REP_PIECE_JOINTE}/archive-content.txt"
JIRAFEAU_ERROR="${REP_PIECE_JOINTE}/jirafeau-error.txt"
# Clean up when done or when aborting.
-[ -z "${DEBUG}" ] && trap "rm -rf in.$$ in.$$.altered ${REP_PIECE_JOINTE}" 0 1 2 3 15
+[ -z "${DEBUG}" ] && trap "cd ${INSPECT_DIR}; rm -rf in.$$ in.$$.altered ${REP_PIECE_JOINTE}" 0 1 2 3 15
-if ! cat > "in.$$"; then
+if ! cat > "${INSPECT_DIR}/in.$$"; then
LOG_FIC "${RED}Cannot save mail to file${NC}"
quitFilter "${EX_TEMPFAIL}"
fi
-LOG_FIC "\n" \
+LOG_FIC "${NL}" \
" size: ${YELLOW}$(wc -c < "${INSPECT_DIR}/in.$$")${NC}"
[ -n "${DEBUG}" ] && (mkdir -p "${DIR_LOG}/pb/" ; cp "${INSPECT_DIR}/in.$$" "${DIR_LOG}/pb/in.$$.orig")
@@ -159,8 +154,14 @@ mkdir -p "${REP_PIECE_JOINTE}/"
>"${OLD_LINKS}"
>"${ARCHIVE_CONTENT}"
+if [ "${MODE}" = "none" ]; then
+ LOG_FIC " - ${GREEN}send without change (MODE=none)${NC}"
+ ${SENDMAIL} "$@" < "${INSPECT_DIR}/in.$$"
+ quitFilter 0
+fi
+
# Etape de rafraichissement des anciens fichiers inclus
-echo "time: ${DATE_TEMPS}\nid: $(date +%s)" > "${ARCHIVE_CONTENT}"
+echo "time: ${DATE_TEMPS}${NL}id: $(date +%s)" > "${ARCHIVE_CONTENT}"
[ -n "${TRACK}" ] && echo "sender: ${MAIL_SOURCE}" >> "${ARCHIVE_CONTENT}"
LOG_FIC "${CYAN}${SHRINK_CMD} -u \"${INSPECT_DIR}/in.$$\" 2>> \"${FIC_LOG}\" > \"${OLD_LINKS}\"${NC}"
@@ -171,14 +172,14 @@ cat "${OLD_LINKS}" | grep "${JIRAFEAU_URL}" | while read REMOTE_LINK; do
[ -z "${REMOTE_REF}" ] && continue
REMOTE_KEY=$(echo "${REMOTE_LINK}" | grep "k=" | sed 's%.*k=\([^&]*\).*%\1%')
# update periode for download
- LOG_FIC " - ${CYAN}\"${JIRAFEAU_CMD}\" -f \"${JIRAFEAU_LOCAL}\" -t \"${JIRAFEAU_TIME}\" update \"${REMOTE_REF}\" 2>&1 >> \"${FIC_LOG}\"${NC}"
- "${JIRAFEAU_CMD}" -f "${JIRAFEAU_LOCAL}" -t "${JIRAFEAU_TIME}" update "${REMOTE_REF}" 2>&1 >> "${FIC_LOG}"
+ LOG_FIC " - ${CYAN}\"${JIRAFEAU_CMD}\" -f \"${JIRAFEAU_LOCAL}\" -t \"${PERIOD}\" update \"${REMOTE_REF}\" 2>&1 >> \"${FIC_LOG}\"${NC}"
+ "${JIRAFEAU_CMD}" -f "${JIRAFEAU_LOCAL}" -t "${PERIOD}" update "${REMOTE_REF}" 2>&1 >> "${FIC_LOG}"
echo "old: ${REMOTE_REF} ${REMOTE_KEY}" >> "${ARCHIVE_CONTENT}"
done
LOG_FIC " - archive starts with: ${NL}${YELLOW}$(cat ${ARCHIVE_CONTENT})${NC}"
# Etape extraction des pieces jointes
-LOG_FIC "${CYAN}${SHRINK_CMD} -s ${MAX_KEEP_IN_MAIL} -d ${REP_PIECE_JOINTE} ${INSPECT_DIR}/in.$$ ${NC}"
+LOG_FIC "${CYAN}${SHRINK_CMD} -s \"${MAX_KEEP_IN_MAIL}\" -d \"${REP_PIECE_JOINTE}\" \"${INSPECT_DIR}/in.$$\"${NC}"
"${SHRINK_CMD}" -s "${MAX_KEEP_IN_MAIL}" -d "${REP_PIECE_JOINTE}" "${INSPECT_DIR}/in.$$" 2>> "${FIC_LOG}" | {
while read ATTACH_TMP_NAME; do
if [ -d "${ATTACH_TMP_NAME}" ]; then
@@ -193,8 +194,8 @@ LOG_FIC "${CYAN}${SHRINK_CMD} -s ${MAX_KEEP_IN_MAIL} -d ${REP_PIECE_JOINTE} ${IN
# Etape de televersement des pieces jointes
PASSWORD=$(apg -n 1 -m 12)
PASSWORD_MD5=$(echo -n ${PASSWORD} | ${MD5_CMD} | cut -d \ -f 1)
- LOG_FIC " - ${CYAN}\"${JIRAFEAU_CMD}\" -f \"${JIRAFEAU_LOCAL}\" -t \"${JIRAFEAU_TIME}\" -s \"${MAX_UPLOAD_SIZE}\" -c \"${ATTACH_CONTENT_TYPE}\" -n \"${ATTACH_NAME}\" send \"${ATTACH_MEDIA}\" \"${PASSWORD}\" 2>> \"${FIC_LOG}\" > \"${ONE_LINK}\"${NC}"
- "${JIRAFEAU_CMD}" -f "${JIRAFEAU_LOCAL}" -t "${JIRAFEAU_TIME}" -s "${MAX_UPLOAD_SIZE}" -c "${ATTACH_CONTENT_TYPE}" -n "${ATTACH_NAME}" send "${ATTACH_MEDIA}" "${PASSWORD}" 2>> "${FIC_LOG}" > "${ONE_LINK}"
+ LOG_FIC " - ${CYAN}\"${JIRAFEAU_CMD}\" -f \"${JIRAFEAU_LOCAL}\" -t \"${PERIOD}\" -s \"${MAX_UPLOAD_SIZE}\" -c \"${ATTACH_CONTENT_TYPE}\" -n \"${ATTACH_NAME}\" send \"${ATTACH_MEDIA}\" \"${PASSWORD}\" 2>> \"${FIC_LOG}\" > \"${ONE_LINK}\"${NC}"
+ "${JIRAFEAU_CMD}" -f "${JIRAFEAU_LOCAL}" -t "${PERIOD}" -s "${MAX_UPLOAD_SIZE}" -c "${ATTACH_CONTENT_TYPE}" -n "${ATTACH_NAME}" send "${ATTACH_MEDIA}" "${PASSWORD}" 2>> "${FIC_LOG}" > "${ONE_LINK}"
cat "${ONE_LINK}" | {
read JIR_TOKEN
read JIR_CODE
@@ -207,8 +208,8 @@ LOG_FIC "${CYAN}${SHRINK_CMD} -s ${MAX_KEEP_IN_MAIL} -d ${REP_PIECE_JOINTE} ${IN
echo "UPLOAD_FAIL" >> "${JIRAFEAU_ERROR}"
;;
* )
- LOG_FIC " - change by link ${YELLOW}${JIRAFEAU_URL}/f.php?d=1&h=${JIR_TOKEN}&k=${PASSWORD_MD5}${NC}"
- echo "url: ${JIRAFEAU_URL}/f.php?d=1&h=${JIR_TOKEN}&k=${PASSWORD_MD5}"
+ LOG_FIC " - change by link ${YELLOW}${JIRAFEAU_URL}/f.php?d=0&h=${JIR_TOKEN}&k=${PASSWORD_MD5}${NC}"
+ echo "url: ${JIRAFEAU_URL}/f.php?d=0&h=${JIR_TOKEN}&k=${PASSWORD_MD5}"
echo "new: ${JIR_TOKEN} ${PASSWORD_MD5}" >> "${ARCHIVE_CONTENT}"
;;
esac
@@ -220,8 +221,8 @@ LOG_FIC "${CYAN}${SHRINK_CMD} -s ${MAX_KEEP_IN_MAIL} -d ${REP_PIECE_JOINTE} ${IN
PASSWORD=$(apg -n 1 -m 12)
PASSWORD_MD5=$(echo -n ${PASSWORD} | ${MD5_CMD} | cut -d \ -f 1)
LOG_FIC " - ${MAGENTA}upload archive${NC}"
- LOG_FIC " - ${CYAN}\"${JIRAFEAU_CMD}\" -f \"${JIRAFEAU_LOCAL}\" -t \"${JIRAFEAU_TIME}\" -s \"${MAX_UPLOAD_SIZE}\" -c \"${ARCHIVE_MIME}\" -n \"${ARCHIVE_TITLE}\" send \"${ARCHIVE_CONTENT}\" \"${PASSWORD}\" 2>> \"${FIC_LOG}\" > \"${ONE_LINK}\"${NC}"
- "${JIRAFEAU_CMD}" -f "${JIRAFEAU_LOCAL}" -t "${JIRAFEAU_TIME}" -s "${MAX_UPLOAD_SIZE}" -c "${ARCHIVE_MIME}" -n "${ARCHIVE_TITLE}" send "${ARCHIVE_CONTENT}" "${PASSWORD}" 2>> "${FIC_LOG}" > "${ONE_LINK}"
+ LOG_FIC " - ${CYAN}\"${JIRAFEAU_CMD}\" -f \"${JIRAFEAU_LOCAL}\" -t \"${PERIOD}\" -s \"${MAX_UPLOAD_SIZE}\" -c \"${ARCHIVE_MIME}\" -n \"${ARCHIVE_TITLE}\" send \"${ARCHIVE_CONTENT}\" \"${PASSWORD}\" 2>> \"${FIC_LOG}\" > \"${ONE_LINK}\"${NC}"
+ "${JIRAFEAU_CMD}" -f "${JIRAFEAU_LOCAL}" -t "${PERIOD}" -s "${MAX_UPLOAD_SIZE}" -c "${ARCHIVE_MIME}" -n "${ARCHIVE_TITLE}" send "${ARCHIVE_CONTENT}" "${PASSWORD}" 2>> "${FIC_LOG}" > "${ONE_LINK}"
fi
LOG_FIC " - final archive content: ${NL}${YELLOW}$(cat ${ARCHIVE_CONTENT})${NC}"
if [ "${NB_ATTACH}" -gt 1 ]; then
@@ -261,7 +262,7 @@ fi
if [ "$(wc -l < "${ARCHIVE_CONTENT}")" -ge 3 ]; then
# verification de taille finale
actualSize=$(wc -c < "${INSPECT_DIR}/in.$$.altered")
- if [ ${actualSize} -ge $MAX_FINAL_SIZE ]; then
+ if [ "${actualSize}" -ge "${MAX_FINAL_SIZE}" ]; then
LOG_FIC " - ${RED}too big even after diet ${INSPECT_DIR}/in.$$.altered (${actualSize})${NC}"
keepFailed "${INSPECT_DIR}/in.$$"
quitFilter "${EX_TOO_LARGE}"
@@ -271,13 +272,13 @@ if [ "$(wc -l < "${ARCHIVE_CONTENT}")" -ge 3 ]; then
else
# verification de taille finale
actualSize=$(wc -c < "${INSPECT_DIR}/in.$$")
- if [ ${actualSize} -ge $MAX_FINAL_SIZE ]; then
+ if [ "${actualSize}" -ge "${MAX_FINAL_SIZE}" ]; then
LOG_FIC " - ${RED}too big without diet ${INSPECT_DIR}/in.$$ (${actualSize}) ${NC}"
keepFailed "${INSPECT_DIR}/in.$$"
quitFilter "${EX_TOO_LARGE}"
fi
LOG_FIC " - ${GREEN}send without attach file${NC}"
- ${SENDMAIL} "$@" < "in.$$"
+ ${SENDMAIL} "$@" < "${INSPECT_DIR}/in.$$"
fi
quitFilter 0
diff --git a/src/cpp/Attachment.cpp b/src/cpp/Attachment.cpp
index dbb0905..dba811e 100644
--- a/src/cpp/Attachment.cpp
+++ b/src/cpp/Attachment.cpp
@@ -64,8 +64,8 @@ const string Attachment::ALTERNATIVE ("alternative");
const string Attachment::KAZ_ATTACH_NAME (".---KazAttachment---.html");
-const regex Attachment::nameCharsetRegEx (".*name\\*=(.*)");
-const regex Attachment::nameRegEx (".*name=\\s*\"?(.*)\"?\\s*;?\\s*");
+const regex Attachment::nameCharsetRegEx (".*name\\*=[ \t]*(.*)");
+const regex Attachment::nameRegEx (".*name=[ \t]*((\"(\\\\.|[^\\\\\r])*\")|[^\r; ]*);?.*");
// boundary="----=_Part_796779_1154936629.1668080348646"
// boundary="------------040709000505010508040808"
// boundary="----------=_1668606031-941125-91"
@@ -73,7 +73,7 @@ const regex Attachment::nameRegEx (".*name=\\s*\"?(.*)\"?\\s*;?\\s*");
// boundary="_000_PAVPR10MB6792713B313048E3A259B215B2079PAVPR10MB6792EURP_"
// boundary=--boundary_1351_64006126-2b0e-4a3b-98ac-4797d1634188
// boundary=--boundary_1352_7e294c9a-cfab-44a0-bfb3-7310380ac7cb;
-const regex Attachment::boundaryRegEx (".*boundary=\"?([^\"; ]*)\"?;?.*");
+const regex Attachment::boundaryRegEx (".*boundary=[ \t]*((\"(\\\\.|[^\\\\\r])*\")|[^\r; ]*);?.*");
const regex Attachment::cidDefRegEx (".*<([^>]*)>.*");
const regex Attachment::textRegEx (".*text/("+PLAIN+"|"+HTML+").*");
const regex Attachment::multiRegEx ("\\s*multipart/(mixed|"+RELATED+"|"+ALTERNATIVE+").*");
@@ -184,12 +184,14 @@ const string
Attachment::getAttachName () const {
DEF_LOG ("Attachment::getAttachName", "");
string result = getProp (contentTypeToken, nameRegEx);
+ removeQuote (result);
if (result.length ()) {
LOG ("name=: " << result);
encodedWord (result);
return result;
}
result = getProp (contentTypeToken, nameCharsetRegEx);
+ removeQuote (result);
if (result.length ()) {
LOG ("name*=: " << result);
charsetValue (result);
@@ -197,13 +199,15 @@ Attachment::getAttachName () const {
}
// XXX il faut composer s'il y a plusieurs ligne filename*x=
result = getProp (contentDispositionToken, nameRegEx);
+ removeQuote (result);
if (result.length ()) {
LOG ("filename=: " << result);
encodedWord (result);
return result;
}
// XXX il faut composer s'il y a plusieurs ligne filename*x*=
- result = getProp (contentDispositionToken, nameRegEx);
+ result = getProp (contentDispositionToken, nameCharsetRegEx);
+ removeQuote (result);
if (result.length ()) {
LOG ("filename*=: " << result);
charsetValue (result);
@@ -282,6 +286,13 @@ Attachment::Attachment (ifstream &mbox, const int &level, const streamoff beginI
}
// ================================================================================
+inline string
+cleanString (const string &line) {
+ if (!line.empty () && line[line.size() - 1] == '\r')
+ return line.substr (0, line.size () - 1);
+ return line;
+}
+
void
Attachment::readMime (ifstream &mbox, streamoff &curPos) {
DEF_LOG ("Attachment::readMime", "curPos: " << curPos);
@@ -290,7 +301,7 @@ Attachment::readMime (ifstream &mbox, streamoff &curPos) {
for (; getline (mbox, line); ) {
LOG ("pos: " << curPos << " line: " << line);
curPos += line.length () + 1;
- if (line.empty ())
+ if (line.empty () || "\r" == line)
break;
if (line[0] == ' ' || line[0] == '\t') {
if (lastVar.empty ()) {
@@ -298,8 +309,8 @@ Attachment::readMime (ifstream &mbox, streamoff &curPos) {
LOG_BUG (true, /**/, "eMailShrinker: bug A5: not compliant MIME. pos: " << (curPos - (line.length () + 1)) << " line: " << line);
} else {
LOG ("add line to var: " << line);
- env.find (lastVar)->second += line;
- LOG ("new val: " << env.find (lastVar)->second);
+ env.find (lastVar)->second += cleanString (line);
+ LOG ("new val: <" << lastVar << " <=> " << env.find (lastVar)->second << ">");
}
continue;
}
@@ -308,8 +319,8 @@ Attachment::readMime (ifstream &mbox, streamoff &curPos) {
lastVar = line.substr (0, colonPos);
toLower (lastVar);
LOG ("find var: " << lastVar);
- string val (line.length () >= colonPos+2 ? line.substr (colonPos+2) : ""); // XXX check RFC " " after ": "
- LOG ("new var: " << lastVar << " <=> " << val);
+ string val (cleanString (line.length () >= colonPos+2 ? line.substr (colonPos+2) : "")); // XXX check RFC " " after ": "
+ LOG ("new var: <" << lastVar << " <=> " << val << ">");
env [lastVar] = val;
}
}
@@ -318,6 +329,7 @@ Attachment::readMime (ifstream &mbox, streamoff &curPos) {
contentPos = curPos;
cid = getProp (contentIDToken, cidDefRegEx);
boundary = getProp (contentTypeToken, boundaryRegEx);
+ removeQuote (boundary);
LOG ("boundary: " << boundary);
if (boundary.length ()) {
boundary = "--"+boundary+"--";
diff --git a/src/cpp/MainAttachment.cpp b/src/cpp/MainAttachment.cpp
index d52b809..1e9680e 100644
--- a/src/cpp/MainAttachment.cpp
+++ b/src/cpp/MainAttachment.cpp
@@ -177,8 +177,8 @@ MainAttachment::readArchiveUrl () {
archiveDownloadURL.clear ();
string line;
getline (cin, line);
- LOG_BUG (line.rfind ("arch: ", 0) != 0, return, "eMailShrinker: bug ZZ: no archive link. (line: " << line << ")");
- LOG_BUG (line.rfind ("arch: bad", 0) == 0, return, "eMailShrinker: bug ZZ: bad archive link. (line: " << line << ")");
+ LOG_BUG (line.rfind ("arch: ", 0) != 0, return, "eMailShrinker: bug 9: no archive link. (line: " << line << ")");
+ LOG_BUG (line.rfind ("arch: bad", 0) == 0, return, "eMailShrinker: bug 10: bad archive link. (line: " << line << ")");
if (line.rfind ("arch: none", 0) == 0)
return;
archiveDownloadURL = line.substr (6);
@@ -192,7 +192,7 @@ MainAttachment::readDownloadUrl (string &url) {
string line;
getline (cin, line);
LOG ("get URL: " << line);
- LOG_BUG (line.rfind ("url: ", 0) != 0, return, "eMailShrinker: bug ZZ: no download link. (line: " << line << ")");
+ LOG_BUG (line.rfind ("url: ", 0) != 0, return, "eMailShrinker: bug 11: no download link. (line: " << line << ")");
url = line.substr (5);
}
@@ -371,30 +371,39 @@ MainAttachment::extractLinks (const vector