From 285792acfc12280228f8034f319a6db19d67b87a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois?= Date: Tue, 27 Dec 2022 10:14:47 +0100 Subject: [PATCH] fix curl filter / fix BOTH --- src/bash/filter.sh | 36 +++++-- src/bash/filterTest.sh | 79 ++++++++++------ src/cpp/MainAttachment.cpp | 168 ++++++++++++++++++++++++--------- src/cpp/eMailShrinker.cpp | 4 +- src/cpp/kazMisc.cpp | 13 +++ src/include/MainAttachment.hpp | 9 ++ src/include/kazMisc.hpp | 3 + src/mainpage.md | 16 ++++ 8 files changed, 243 insertions(+), 85 deletions(-) mode change 100644 => 100755 src/bash/filter.sh diff --git a/src/bash/filter.sh b/src/bash/filter.sh old mode 100644 new mode 100755 index 95c538d..dce2de3 --- a/src/bash/filter.sh +++ b/src/bash/filter.sh @@ -40,6 +40,8 @@ # proriétaire du script # - shrinkEMail et jirafeau.sh doivent être accessible en execution pour # le roriétaire du script +# - il faut que root fasse avant : +# mkdir -p "${DIR_LOG}/pb/" ; chmod a+rwx "${DIR_LOG}/pb/" ########################################################################## DEFAULT_MODE="footer" @@ -99,10 +101,28 @@ quitFilter () { keepFailed () { [ -z "${KEEP_FAILED}" ] && return - mkdir -p "${DIR_LOG}/pb/" cp "$1" "${DIR_LOG}/pb/" } +######################################## +# curl Jirafeau +curlJirafeauUpdate () { + # $1: periode + # $2: jirafeauItemRef + LOG_FIC " - ${CYAN}curl -X POST -d \"u=$1\" -d \"h=$2\" \"${JIRAFEAU_LOCAL}/a.php}\"" + curl -X POST -d "u=$1" -d "h=$2" "${JIRAFEAU_LOCAL}/a.php" +} + +curlJirafeauSend () { + # $1: periode + # $2: filename + # $3: content-type + # $4: name + # $5: password + LOG_FIC " - curl -X POST -F \"time=$1\" -F \"key=$5\" -F \"file=@$2;type=$3;filename=$4\" \"${JIRAFEAU_LOCAL}/a.php\"" + curl -X POST -F "time=$1" -F "key=$5" -F "file=@$2;type=$3;filename=$4" "${JIRAFEAU_LOCAL}/a.php" +} + #################### MAIN ################################################# echo "${NL}${BLUE}$(date +%d-%m-%Y-%H-%M-%S)${NC} : ${GREEN}######################################## filter start (log in ${TMP_LOG})${NC}" >> "${FIC_LOG}" LOG_FIC "${GREEN}######################################## ${TMP_LOG} ${NC}" @@ -154,7 +174,7 @@ dos2unix "${INSPECT_DIR}/in.$$" 2> /dev/null 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") +[ -z "${DEBUG}" ] || (cp "${INSPECT_DIR}/in.$$" "${DIR_LOG}/pb/in.$$.orig") mkdir -p "${REP_PIECE_JOINTE}/" >"${OLD_LINKS}" @@ -178,8 +198,7 @@ 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 \"${PERIOD}\" update \"${REMOTE_REF}\" 2>&1 >> \"${TMP_LOG}\"${NC}" - "${JIRAFEAU_CMD}" -f "${JIRAFEAU_LOCAL}" -t "${PERIOD}" update "${REMOTE_REF}" 2>&1 >> "${TMP_LOG}" + curlJirafeauUpdate "${PERIOD}" "${REMOTE_REF}" 2>&1 >> "${TMP_LOG}" echo "old: ${REMOTE_REF} ${REMOTE_KEY}" >> "${ARCHIVE_CONTENT}" done LOG_FIC " - archive starts with: ${NL}${YELLOW}$(cat ${ARCHIVE_CONTENT})${NC}" @@ -200,8 +219,7 @@ LOG_FIC "${CYAN}${SHRINK_CMD} -s \"${MAX_KEEP_IN_MAIL}\" -d \"${REP_PIECE_JOINTE # 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 \"${PERIOD}\" -s \"${MAX_UPLOAD_SIZE}\" -c \"${ATTACH_CONTENT_TYPE}\" -n \"${ATTACH_NAME}\" send \"${ATTACH_MEDIA}\" \"${PASSWORD}\" 2>> \"${TMP_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>> "${TMP_LOG}" > "${ONE_LINK}" + curlJirafeauSend "${PERIOD}" "${ATTACH_MEDIA}" "${ATTACH_CONTENT_TYPE}" "${ATTACH_NAME}" "${PASSWORD}" 2>> "${TMP_LOG}" > "${ONE_LINK}" cat "${ONE_LINK}" | { read JIR_TOKEN read JIR_CODE @@ -227,8 +245,8 @@ LOG_FIC "${CYAN}${SHRINK_CMD} -s \"${MAX_KEEP_IN_MAIL}\" -d \"${REP_PIECE_JOINTE 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 \"${PERIOD}\" -s \"${MAX_UPLOAD_SIZE}\" -c \"${ARCHIVE_MIME}\" -n \"${ARCHIVE_TITLE}\" send \"${ARCHIVE_CONTENT}\" \"${PASSWORD}\" 2>> \"${TMP_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>> "${TMP_LOG}" > "${ONE_LINK}" + + curlJirafeauSend "${PERIOD}" "${ARCHIVE_CONTENT}" "${ARCHIVE_MIME}" "${ARCHIVE_TITLE}" "${PASSWORD}" 2>> "${TMP_LOG}" > "${ONE_LINK}" fi LOG_FIC " - final archive content: ${NL}${YELLOW}$(cat ${ARCHIVE_CONTENT})${NC}" if [ "${NB_ATTACH}" -gt 1 ]; then @@ -257,7 +275,7 @@ LOG_FIC "${CYAN}${SHRINK_CMD} -s \"${MAX_KEEP_IN_MAIL}\" -d \"${REP_PIECE_JOINTE LOG_FIC "${CYAN}${SHRINK_CMD} -m \"${MODE}\" -s \"${MAX_KEEP_IN_MAIL}\" \"${INSPECT_DIR}/in.$$\" \"${INSPECT_DIR}/in.$$.altered\" 2>> \"${TMP_LOG}\"${NC}" } | "${SHRINK_CMD}" -m "${MODE}" -s "${MAX_KEEP_IN_MAIL}" "${INSPECT_DIR}/in.$$" "${INSPECT_DIR}/in.$$.altered" 2>> "${TMP_LOG}" -[ -n "${DEBUG}" ] && (mkdir -p "${DIR_LOG}/pb/" ; cp "${INSPECT_DIR}/in.$$.altered" "${DIR_LOG}/pb/in.$$.altered") +[ -z "${DEBUG}" ] || (cp "${INSPECT_DIR}/in.$$.altered" "${DIR_LOG}/pb/in.$$.altered") if [ -s "${JIRAFEAU_ERROR}" ]; then LOG_FIC " - ${RED}upload fail${NC}" diff --git a/src/bash/filterTest.sh b/src/bash/filterTest.sh index 1a4c05c..f6fd624 100755 --- a/src/bash/filterTest.sh +++ b/src/bash/filterTest.sh @@ -35,7 +35,7 @@ PRG=$(basename $0) -ATTACH_MODE="-m FOOTER" +ATTACH_MODE="FOOTER" BOLD='' RED='' @@ -60,9 +60,33 @@ usage () { } ######################################## -mbox=$(realpath $1) -dos2unix "${mbox}" +# recherche des binaires cd $(dirname $0) +eMailShrinker="$(realpath "./eMailShrinker")" +[ -x "${eMailShrinker}" ] || eMailShrinker="$(realpath "../../build/out/eMailShrinker")" +[ -x "${eMailShrinker}" ] || ( echo "${RED}eMailShrinker not found${NC}" ; exit) + +while : ; do + case "$1" in + -h*) usage;; + -v*) "${eMailShrinker}" -v; exit;; + -g) DEBUG="-g"; shift;; + -m) shift; ATTACH_MODE="$1"; shift;; + *) break;; + esac +done +case "${ATTACH_MODE}" in + ""|NONE|FOOTER|ATTACHMENT|BOTH);; + *) usage;; +esac + +[ -z "${ATTACH_MODE}" ] || ATTACH_MODE="-m ${ATTACH_MODE}" + +[ "$#" -eq 1 ] || usage + +######################################## +mbox=$(realpath "$1") +dos2unix "${mbox}" DOMAINNAME="$(cat domainname)" JIRAFEAU_URL="https://depot.${DOMAINNAME}" JIRAFEAU_LOCAL="${JIRAFEAU_URL}" @@ -70,30 +94,25 @@ JIRAFEAU_LOCAL="${JIRAFEAU_URL}" TMP_DIR="$(mktemp)" ######################################## -# recherche des binaires -eMailShrinker="$(realpath "./eMailShrinker")" -[ -x "${eMailShrinker}" ] || eMailShrinker="$(realpath "../../build/out/eMailShrinker")" -[ -x "${eMailShrinker}" ] || ( echo "${RED}eMailShrinker not found${NC}" ; exit) +# curl Jirafeau +curlJirafeauUpdate () { + # $1: periode + # $2: jirafeauItemRef -jirafeauAPI="$(realpath "./jirafeauAPI")" -[ -x "${jirafeauAPI}" ] || jirafeauAPI="$(realpath "../../build/out/jirafeauAPI")" -[ -x "${jirafeauAPI}" ] || ( echo "${RED}jirafeauAPI not found${NC}" ; exit) + curl -X POST -d "u=$1" -d "h=$2" "${JIRAFEAU_LOCAL}/a.php" + #"${jirafeauAPI}" -f "${JIRAFEAU_LOCAL}" -t "$1" update "$2" +} -for ARG in $*; do - case "$1" in - -h*) usage;; - -v*) "${eMailShrinker}" -v; exit;; - -g) DEBUG="-g"; shift;; - -m) shift; ATTACH_MODE="-m $1"; shift;; # XXX test option - *) break;; - esac -done -case "${ATTACH_MODE}" in - NONE|FOOTER|ATTACHMENT|BOTH);; - *) usage;; -esac +curlJirafeauSend () { + # $1: periode + # $2: filename + # $3: content-type + # $4: name + # $5: password -[ "$#" -eq 1 ] || usage + curl -X POST -F "time=$1" -F "key=$5" -F "file=@$2;type=$3;filename=$4" "${JIRAFEAU_LOCAL}/a.php" + #"${jirafeauAPI}" -f "${JIRAFEAU_LOCAL}" -t "$1" -s "1Gi" -c "$3" -n "$4" send "$2" "$5" +} ######################################## # nettoyage @@ -110,19 +129,19 @@ LOG ######################################## # recherche des prolongations des délais de grace -"${eMailShrinker}" -u "${mbox}" > "${TMP_DIR}/url-to-refresh.txt" 2>> "${TTY}" +"${eMailShrinker}" ${DEBUG} -u "${mbox}" > "${TMP_DIR}/url-to-refresh.txt" 2>> "${TTY}" cat "${TMP_DIR}/url-to-refresh.txt" | grep "${JIRAFEAU_URL}" | while read REMOTE_LINK; do REMOTE_REF=$(echo "${REMOTE_LINK}" | sed -e 's/.*h=\([^&]*\).*/\1/' -e 's/.*http.*//') [ -z "${REMOTE_REF}" ] && continue LOG " - ${BLUE}update ${REMOTE_REF}${NC}" - "${jirafeauAPI}" -f "${JIRAFEAU_LOCAL}" -t "month" update "${REMOTE_REF}" 2>> "${TTY}" + curlJirafeauUpdate "month" "${REMOTE_REF}" 2>> "${TTY}" LOG echo "old: ${REMOTE_REF} ${REMOTE_KEY}" >> "${TMP_DIR}/archive-content.txt" done ######################################## # extraction des pièces jointes -"${eMailShrinker}" -s "5ki" -d "${TMP_DIR}/PJ" "${mbox}" > "${TMP_DIR}/PJ-name.txt" +"${eMailShrinker}" ${DEBUG} -s "5ki" -d "${TMP_DIR}/PJ" "${mbox}" > "${TMP_DIR}/PJ-name.txt" LOG " - ${BLUE}PJ-name: ${NC}" cat "${TMP_DIR}/PJ-name.txt" @@ -145,7 +164,7 @@ cat "${TMP_DIR}/PJ-name.txt" | { LOG " - ${BLUE}find ${ATTACH_NAME} / (${ATTACH_CONTENT_TYPE}) / ${ATTACH_MEDIA} ${NC}" PASSWORD=$(apg -n 1 -m 12) PASSWORD_MD5=$(echo -n ${PASSWORD} | ${MD5_CMD} | cut -d \ -f 1) - "${jirafeauAPI}" -f "${JIRAFEAU_LOCAL}" -t "month" -s "1Gi" -c "${ATTACH_CONTENT_TYPE}" -n "${ATTACH_NAME}" send "${ATTACH_MEDIA}" "${PASSWORD}" 2>> "${TTY}" > "${TMP_DIR}/one.txt" + curlJirafeauSend "month" "${ATTACH_MEDIA}" "${ATTACH_CONTENT_TYPE}" "${ATTACH_NAME}" "${PASSWORD}" 2>> "${TTY}" > "${TMP_DIR}/one.txt" cat "${TMP_DIR}/one.txt" | { read JIR_TOKEN @@ -168,7 +187,7 @@ cat "${TMP_DIR}/PJ-name.txt" | { if [ "${NB_ATTACH}" -gt 1 ]; then PASSWORD=$(apg -n 1 -m 12) PASSWORD_MD5=$(echo -n ${PASSWORD} | ${MD5_CMD} | cut -d \ -f 1) - "${jirafeauAPI}" -f "${JIRAFEAU_LOCAL}" -t "month" -s "1Gi" -c "text/kaz_email_archive" -n "archive_content" send "${TMP_DIR}/archive-content.txt" "${PASSWORD}" > "${TMP_DIR}/one.txt" 2>> "${TTY}" + curlJirafeauSend "month" "${TMP_DIR}/archive-content.txt" "text/kaz_email_archive" "archive_content" "${PASSWORD}" 2>> "${TTY}" > "${TMP_DIR}/one.txt" cat "${TMP_DIR}/one.txt" | { read JIR_TOKEN read JIR_CODE @@ -197,7 +216,7 @@ LOG " - ${GREEN}ATTACH_MODE: ${ATTACH_MODE}${NC}" ######################################## # substitution des pièces jointes par les codes fournis par jirafeau -cat "${TMP_DIR}/PJ-Keys.txt" | "${eMailShrinker}" ${ATTACH_MODE} -s "5ki" "${mbox}" "${TMP_DIR}/new-mbox" 2>> "${TTY}" +cat "${TMP_DIR}/PJ-Keys.txt" | "${eMailShrinker}" ${DEBUG} ${ATTACH_MODE} -s "5ki" "${mbox}" "${TMP_DIR}/new-mbox" 2>> "${TTY}" ######################################## # affichage de la structure à la fin diff --git a/src/cpp/MainAttachment.cpp b/src/cpp/MainAttachment.cpp index 665c354..a91c931 100644 --- a/src/cpp/MainAttachment.cpp +++ b/src/cpp/MainAttachment.cpp @@ -157,6 +157,35 @@ kaz::operator >> (istream &in, AttachMode &attachMode) { return in; } +// ================================================================================ +const string +kaz::headerTypeLabels[] = { + "Same", "Multi", "MainPlain", "AttachHtml" +}; +const map +kaz::headerTypeMap = boost::assign::map_list_of + ("same", SAME) + ("multi", MULTI) + ("mainplain", MAIN_PLAIN) + ("attachhtml", ATTACH_HTML) + ; +ostream & +kaz::operator << (ostream &out, const HeaderType &headerType) { + //BOOST_ASSERT (treeType >= MIN && treeType <= ALPHA); + return out << headerTypeLabels [headerType]; +} +istream & +kaz::operator >> (istream &in, HeaderType &headerType) { + string token; + in >> token; + auto pos = headerTypeMap.find (boost::algorithm::to_lower_copy (token)); + if (pos == headerTypeMap.end ()) + in.setstate (ios_base::failbit); + else + headerType = pos->second; + return in; +} + // ================================================================================ void MainAttachment::copy (ifstream &mbox, ofstream &outbox, const streamoff &begin, const streamoff &end) { @@ -420,6 +449,7 @@ MainAttachment::extractPreviousKAZ (ifstream &mbox) { void MainAttachment::removePreviousArchive () { + DEF_LOG ("MainAttachment::removePreviousArchive", ""); vector toRemove; for (map ::const_iterator it = previousLinks.begin (); it != previousLinks.end (); ++it) { const string key (it->first); @@ -430,6 +460,41 @@ MainAttachment::removePreviousArchive () { previousLinks.erase (old); } +// ================================================================================ +void MainAttachment::rewriteHeaders (ifstream &mbox, ofstream &outbox, const HeaderType &headerType) { + DEF_LOG ("MainAttachment::rewriteHeaders", "headerType: " << headerType); + if (SAME == headerType) { + copy (mbox, outbox, 0, contentPos); + return; + } + string mime (getMime (mbox)); + string::size_type startPos = (0); + for (string token : {string ("content-transfer-encoding"), Attachment::contentTypeToken}) { + startPos = caseInsensitiveFind (mime, token); + for (string::size_type stopPos (startPos); + (stopPos = mime.find ("\n", stopPos)) != string::npos; + ) { + if (string (" \t").find (mime [stopPos+1]) == string::npos) { + mime.erase (startPos, stopPos-startPos); + break; + } + } + } + string contentType (KAZ_EMPTY_TEXT_PLAIN); + switch (headerType) { + case SAME: /* no way */; + case MAIN_PLAIN: contentType = KAZ_EMPTY_TEXT_PLAIN; break; + case ATTACH_HTML: contentType = KAZ_ATTACHMENT_TEXT_HTML; break; + case MULTI: + boundary = "__KAZ__"+boundaryGen (40); + contentType = "Content-Type: multipart/mixed; boundary=\""+boundary+"\""; + boundary = "--"+boundary+"--"; + boundaryMiddleSize = boundary.length () - 2; + } + mime.insert (startPos, contentType); + outbox << mime << flush; +} + // ================================================================================ MainAttachment::MainAttachment (ifstream &mbox) : Attachment (mbox, initTmpLevel (), 0, initTmpPos ()), @@ -566,6 +631,15 @@ MainAttachment::extract (ifstream &mbox, const SizeArg &minSize) const { } // ================================================================================ +/*! + Régle à appliquer dans le cas où Kaz ajoute son cartouche et que le corps principale n'est pas multipart : + + + + + +
srcFOOTERBOTHATTCH
text/plainOKmute multimute multi
empty mailmute plainmute multimute html
+ */ void MainAttachment::substitute (ifstream &mbox, ofstream &outbox, const SizeArg &minSize, AttachMode attachMode) { DEF_LOG ("MainAttachment::substitute", "minSize: " << minSize << " AttachMode: " << attachMode); @@ -600,53 +674,55 @@ MainAttachment::substitute (ifstream &mbox, ofstream &outbox, const SizeArg &min string plainDisclaim, htmlDisclaim; getDisclaim (plainDisclaim, htmlDisclaim); + HeaderType headerType (SAME); // copy email - if (!boundary.size () && plainDisclaim.size ()) { - if (attachMode & ATTACHMENT) - attachMode = FOOTER; - if (emptyEMail) { - // only one attachment must be replace - cerr << "eMailShrinker: force one attachment" << endl; - string mime (getMime (mbox)); - string::size_type startPos = (0); - for (string token : {string ("Content-Transfer-Encoding"), Attachment::contentTypeToken}) { - startPos = caseInsensitiveFind (mime, "Content-Transfer-Encoding"); - for (string::size_type stopPos (startPos); - (stopPos = mime.find ("\n", stopPos)) != string::npos; - ) { - if (string (" \t").find (mime [stopPos+1]) == string::npos) { - mime.erase (startPos, stopPos-startPos); - break; - } - } - } - mime.insert (startPos, KAZ_EMPTY_TEXT_PLAIN); - string content (plainDisclaim); - base64Encode (content); - outbox << mime - << content << endl; - outbox.flush (); - outbox.close (); - return; + if (!boundary.size () && plainDisclaim.size ()) + switch (attachMode) { + case NONE: LOG_BUG (true, /* */, "eMailShrinker: bug M12: nothing to do"); break; + case FOOTER: headerType = (emptyEMail ? MAIN_PLAIN : SAME); break; + case BOTH: headerType = MULTI; break; + case ATTACHMENT: headerType = ATTACH_HTML; break; } - } - streamoff curPos = 0; - copy (mbox, outbox, curPos, contentPos); - curPos = contentPos; + rewriteHeaders (mbox, outbox, headerType); + streamoff curPos = contentPos; - if (plainDisclaim.size ()) { - if (emptyEMail && (attachMode & FOOTER)) { - // check no main text - LOG ("Force main text"); - cerr << "eMailShrinker: force footer" << endl; + if (MAIN_PLAIN == headerType) { + LOG ("Replace old content with plain"); string content (plainDisclaim); base64Encode (content); - outbox << boundary.substr (0, boundary.length () -2) << endl - << KAZ_EMPTY_TEXT_PLAIN << endl - << content << endl; + outbox << content << endl; outbox.flush (); - } + return; } + if (ATTACH_HTML == headerType) { + LOG ("Replace old content with html"); + string content (plainDisclaim); + base64Encode (content); + outbox << content << endl; + outbox.flush (); + return; + } + + if (plainDisclaim.size () && emptyEMail && (attachMode & FOOTER)) { + // case : multi + LOG ("Force main text"); + cerr << "eMailShrinker: force main text" << endl; + string content (plainDisclaim); + base64Encode (content); + outbox << boundary.substr (0, boundary.length () -2) << endl + << KAZ_EMPTY_TEXT_PLAIN << endl + << content << endl; + outbox.flush (); + } + + if (MULTI == headerType) { + LOG ("New boundary"); + map::const_iterator it (env.find (contentTypeToken)); + LOG_BUG (it == env.end (), /* */, "eMailShrinker: bug M13: no content-type"); + outbox << boundary.substr (0, boundary.length () -2) << endl + << Attachment::contentTypeToken << ": " << it->second << endl; + } + for (Attachment *attachP : allMarkedPtrs) { copy (mbox, outbox, curPos, attachP->beginInParent); LOG_BUG (attachP->toUpdate && attachP->toExtract, /**/, "eMailShrinker: bug M5: update and extract. pos: " << attachP->beginPos); @@ -727,12 +803,15 @@ MainAttachment::substitute (ifstream &mbox, ofstream &outbox, const SizeArg &min outbox.flush (); curPos = attachP->endPos; } + if (plainDisclaim.size () && (attachMode & ATTACHMENT)) { LOG ("Add kaz attachment"); cerr << "eMailShrinker: force attachment" << endl; - streamoff lastPos = subAttachements.back ().endPos; - copy (mbox, outbox, curPos, lastPos); - curPos = lastPos; + if (subAttachements.size ()) { + streamoff lastPos = subAttachements.back ().endPos; + copy (mbox, outbox, curPos, lastPos); + curPos = lastPos; + } string content (KAZ_HTML_CONTENT+htmlDisclaim+BODY_END+HTML_END); base64Encode (content); @@ -742,7 +821,8 @@ MainAttachment::substitute (ifstream &mbox, ofstream &outbox, const SizeArg &min outbox.flush (); } copy (mbox, outbox, curPos, endPos); - //outbox << endl; + if (MULTI == headerType) + outbox << boundary.substr (0, boundary.length ()) << endl; outbox.close (); } diff --git a/src/cpp/eMailShrinker.cpp b/src/cpp/eMailShrinker.cpp index 87bad68..0c04973 100644 --- a/src/cpp/eMailShrinker.cpp +++ b/src/cpp/eMailShrinker.cpp @@ -33,8 +33,8 @@ //////////////////////////////////////////////////////////////////////////// #include "version.hpp" -const std::string kaz::LAST_VERSION_NUM ("2.9"); -const std::string kaz::LAST_VERSION_DATE ("2022-12-24"); +const std::string kaz::LAST_VERSION_NUM ("2.10"); +const std::string kaz::LAST_VERSION_DATE ("2022-12-27"); const std::string kaz::LAST_VERSION (LAST_VERSION_NUM+" "+LAST_VERSION_DATE+" eMailShrinker"); #include diff --git a/src/cpp/kazMisc.cpp b/src/cpp/kazMisc.cpp index b2907c8..ff9cbfb 100644 --- a/src/cpp/kazMisc.cpp +++ b/src/cpp/kazMisc.cpp @@ -175,6 +175,19 @@ kaz::caseInsensitiveRFind (const string& s, const string& pattern, const string: return s.rend () - it - pattern.length (); } +string +kaz::boundaryGen (const int &size) { + static const char alphanum[] = + "0123456789" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz"; + string result; + result.reserve (size); + for (int i = 0; i < size; ++i) + result += alphanum[rand() % (sizeof (alphanum) - 1)]; + return result; +} + // ================================================================================ template void diff --git a/src/include/MainAttachment.hpp b/src/include/MainAttachment.hpp index 04b16a2..edc95c4 100644 --- a/src/include/MainAttachment.hpp +++ b/src/include/MainAttachment.hpp @@ -51,6 +51,12 @@ namespace kaz { ostream &operator << (ostream &out, const AttachMode &attachMode); istream &operator >> (istream &in, AttachMode &attachMode); + enum HeaderType { SAME, MULTI, MAIN_PLAIN, ATTACH_HTML }; + extern const string headerTypeLabels[]; + extern const map headerTypeMap; + ostream &operator << (ostream &out, const HeaderType &headerType); + istream &operator >> (istream &in, HeaderType &headerType); + /*! root level of e-mail structure */ class MainAttachment : public Attachment { public: @@ -113,6 +119,9 @@ namespace kaz { /*! remove previous links to archive. Used by substitute */ void removePreviousArchive (); + /*! rewrite main headers */ + void rewriteHeaders (ifstream &mbox, ofstream &outbox, const HeaderType &headerType); + public: /*! the main attachment in mbox */ MainAttachment (ifstream &mbox); diff --git a/src/include/kazMisc.hpp b/src/include/kazMisc.hpp index e636687..03ca6a4 100644 --- a/src/include/kazMisc.hpp +++ b/src/include/kazMisc.hpp @@ -74,6 +74,9 @@ namespace kaz { string::size_type caseInsensitiveFind (const string& s, const string& p, const string::size_type &pos = 0); /*! reverse find upper case of p in upper case of s */ string::size_type caseInsensitiveRFind (const string& s, const string& p, const string::size_type &pos = 0); + + string boundaryGen (const int &size); + /*! side effect to repplace =XX by the char with de haxe value XX. It could be %XX in rfc2184 */ template void quotedDecode (string &content); diff --git a/src/mainpage.md b/src/mainpage.md index 82378e6..de42aec 100644 --- a/src/mainpage.md +++ b/src/mainpage.md @@ -1,5 +1,21 @@ **Dépollueur** +Le dépollueur consiste à extraire les pièces jointes pour les remplacer par des liens de téléchargement temporaire. + +Le logiciel est donc très fortement lié à un logiciel de dépôt de fichier. +Le système de dépôt de proposé par Jirafeau à l'avantage de gérer les liens interne en fonction de la signature du contenu (hash). +Cela offre plusieurs avantages. les fichiers de même contenu sont factorisés sans que les utilisateurs en aient consciences. +L'intégrité des données est inhérente à ce mécanisme, puisque un lien ne va pas faire référence à un autre contenu dans le dépôt. + +A partir du moment où notre dépollueur à une action sur les messages, cela à des conséquences sur l’utilisation d'outils cryptographiques. +Le chiffrement de pièces jointes a peu d'incidence. L'information chiffrée se trouve stocké sur un serveur au lieu d'un ordinateur personnel (voir pire un serveur des GAFAM). +Ici, l'avantage est que l'information sera détruite au bout d'un temps spécifié. + +La signature, empêche le dépollueur d'intervenir. +Dans le cas où l'on souhaite signer ses messages, il faut au préalable déposer ses pièces jointes (hors GAFAM) et faire référence dans le message aux liens de téléchargement. + + + Main Programmes: * [eMailShrinker](eMailShrinker_8cpp.html) * [jirafeauAPI](jirafeauAPI_8cpp.html)