Browse Source

fix curl filter / fix BOTH

test-skip
François 1 year ago
parent
commit
285792acfc
  1. 36
      src/bash/filter.sh
  2. 67
      src/bash/filterTest.sh
  3. 168
      src/cpp/MainAttachment.cpp
  4. 4
      src/cpp/eMailShrinker.cpp
  5. 13
      src/cpp/kazMisc.cpp
  6. 9
      src/include/MainAttachment.hpp
  7. 3
      src/include/kazMisc.hpp
  8. 16
      src/mainpage.md

36
src/bash/filter.sh

@ -40,6 +40,8 @@
# proriétaire du script # proriétaire du script
# - shrinkEMail et jirafeau.sh doivent être accessible en execution pour # - shrinkEMail et jirafeau.sh doivent être accessible en execution pour
# le roriétaire du script # 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" DEFAULT_MODE="footer"
@ -99,10 +101,28 @@ quitFilter () {
keepFailed () { keepFailed () {
[ -z "${KEEP_FAILED}" ] && return [ -z "${KEEP_FAILED}" ] && return
mkdir -p "${DIR_LOG}/pb/"
cp "$1" "${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 ################################################# #################### MAIN #################################################
echo "${NL}${BLUE}$(date +%d-%m-%Y-%H-%M-%S)${NC} : ${GREEN}######################################## filter start (log in ${TMP_LOG})${NC}" >> "${FIC_LOG}" 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}" LOG_FIC "${GREEN}######################################## ${TMP_LOG} ${NC}"
@ -154,7 +174,7 @@ dos2unix "${INSPECT_DIR}/in.$$" 2> /dev/null
LOG_FIC "${NL}" \ LOG_FIC "${NL}" \
" size: ${YELLOW}$(wc -c < "${INSPECT_DIR}/in.$$")${NC}" " 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}/" mkdir -p "${REP_PIECE_JOINTE}/"
>"${OLD_LINKS}" >"${OLD_LINKS}"
@ -178,8 +198,7 @@ cat "${OLD_LINKS}" | grep "${JIRAFEAU_URL}" | while read REMOTE_LINK; do
[ -z "${REMOTE_REF}" ] && continue [ -z "${REMOTE_REF}" ] && continue
REMOTE_KEY=$(echo "${REMOTE_LINK}" | grep "k=" | sed 's%.*k=\([^&]*\).*%\1%') REMOTE_KEY=$(echo "${REMOTE_LINK}" | grep "k=" | sed 's%.*k=\([^&]*\).*%\1%')
# update periode for download # update periode for download
LOG_FIC " - ${CYAN}\"${JIRAFEAU_CMD}\" -f \"${JIRAFEAU_LOCAL}\" -t \"${PERIOD}\" update \"${REMOTE_REF}\" 2>&1 >> \"${TMP_LOG}\"${NC}" curlJirafeauUpdate "${PERIOD}" "${REMOTE_REF}" 2>&1 >> "${TMP_LOG}"
"${JIRAFEAU_CMD}" -f "${JIRAFEAU_LOCAL}" -t "${PERIOD}" update "${REMOTE_REF}" 2>&1 >> "${TMP_LOG}"
echo "old: ${REMOTE_REF} ${REMOTE_KEY}" >> "${ARCHIVE_CONTENT}" echo "old: ${REMOTE_REF} ${REMOTE_KEY}" >> "${ARCHIVE_CONTENT}"
done done
LOG_FIC " - archive starts with: ${NL}${YELLOW}$(cat ${ARCHIVE_CONTENT})${NC}" 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 # Etape de televersement des pieces jointes
PASSWORD=$(apg -n 1 -m 12) PASSWORD=$(apg -n 1 -m 12)
PASSWORD_MD5=$(echo -n ${PASSWORD} | ${MD5_CMD} | cut -d \ -f 1) 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}" curlJirafeauSend "${PERIOD}" "${ATTACH_MEDIA}" "${ATTACH_CONTENT_TYPE}" "${ATTACH_NAME}" "${PASSWORD}" 2>> "${TMP_LOG}" > "${ONE_LINK}"
"${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}"
cat "${ONE_LINK}" | { cat "${ONE_LINK}" | {
read JIR_TOKEN read JIR_TOKEN
read JIR_CODE 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=$(apg -n 1 -m 12)
PASSWORD_MD5=$(echo -n ${PASSWORD} | ${MD5_CMD} | cut -d \ -f 1) PASSWORD_MD5=$(echo -n ${PASSWORD} | ${MD5_CMD} | cut -d \ -f 1)
LOG_FIC " - ${MAGENTA}upload archive${NC}" 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 fi
LOG_FIC " - final archive content: ${NL}${YELLOW}$(cat ${ARCHIVE_CONTENT})${NC}" LOG_FIC " - final archive content: ${NL}${YELLOW}$(cat ${ARCHIVE_CONTENT})${NC}"
if [ "${NB_ATTACH}" -gt 1 ]; then 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}" 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}" } | "${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 if [ -s "${JIRAFEAU_ERROR}" ]; then
LOG_FIC " - ${RED}upload fail${NC}" LOG_FIC " - ${RED}upload fail${NC}"

67
src/bash/filterTest.sh

@ -35,7 +35,7 @@
PRG=$(basename $0) PRG=$(basename $0)
ATTACH_MODE="-m FOOTER" ATTACH_MODE="FOOTER"
BOLD='' BOLD=''
RED='' RED=''
@ -59,42 +59,61 @@ usage () {
exit 1 exit 1
} }
########################################
mbox=$(realpath $1)
dos2unix "${mbox}"
cd $(dirname $0)
DOMAINNAME="$(cat domainname)"
JIRAFEAU_URL="https://depot.${DOMAINNAME}"
JIRAFEAU_LOCAL="${JIRAFEAU_URL}"
TMP_DIR="$(mktemp)"
######################################## ########################################
# recherche des binaires # recherche des binaires
cd $(dirname $0)
eMailShrinker="$(realpath "./eMailShrinker")" eMailShrinker="$(realpath "./eMailShrinker")"
[ -x "${eMailShrinker}" ] || eMailShrinker="$(realpath "../../build/out/eMailShrinker")" [ -x "${eMailShrinker}" ] || eMailShrinker="$(realpath "../../build/out/eMailShrinker")"
[ -x "${eMailShrinker}" ] || ( echo "${RED}eMailShrinker not found${NC}" ; exit) [ -x "${eMailShrinker}" ] || ( echo "${RED}eMailShrinker not found${NC}" ; exit)
jirafeauAPI="$(realpath "./jirafeauAPI")" while : ; do
[ -x "${jirafeauAPI}" ] || jirafeauAPI="$(realpath "../../build/out/jirafeauAPI")"
[ -x "${jirafeauAPI}" ] || ( echo "${RED}jirafeauAPI not found${NC}" ; exit)
for ARG in $*; do
case "$1" in case "$1" in
-h*) usage;; -h*) usage;;
-v*) "${eMailShrinker}" -v; exit;; -v*) "${eMailShrinker}" -v; exit;;
-g) DEBUG="-g"; shift;; -g) DEBUG="-g"; shift;;
-m) shift; ATTACH_MODE="-m $1"; shift;; # XXX test option -m) shift; ATTACH_MODE="$1"; shift;;
*) break;; *) break;;
esac esac
done done
case "${ATTACH_MODE}" in case "${ATTACH_MODE}" in
NONE|FOOTER|ATTACHMENT|BOTH);; ""|NONE|FOOTER|ATTACHMENT|BOTH);;
*) usage;; *) usage;;
esac esac
[ -z "${ATTACH_MODE}" ] || ATTACH_MODE="-m ${ATTACH_MODE}"
[ "$#" -eq 1 ] || usage [ "$#" -eq 1 ] || usage
########################################
mbox=$(realpath "$1")
dos2unix "${mbox}"
DOMAINNAME="$(cat domainname)"
JIRAFEAU_URL="https://depot.${DOMAINNAME}"
JIRAFEAU_LOCAL="${JIRAFEAU_URL}"
TMP_DIR="$(mktemp)"
########################################
# curl Jirafeau
curlJirafeauUpdate () {
# $1: periode
# $2: jirafeauItemRef
curl -X POST -d "u=$1" -d "h=$2" "${JIRAFEAU_LOCAL}/a.php"
#"${jirafeauAPI}" -f "${JIRAFEAU_LOCAL}" -t "$1" update "$2"
}
curlJirafeauSend () {
# $1: periode
# $2: filename
# $3: content-type
# $4: name
# $5: password
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 # nettoyage
rm -f "${TMP_DIR}" ; mkdir -p "${TMP_DIR}" rm -f "${TMP_DIR}" ; mkdir -p "${TMP_DIR}"
@ -110,19 +129,19 @@ LOG
######################################## ########################################
# recherche des prolongations des délais de grace # 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 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.*//') REMOTE_REF=$(echo "${REMOTE_LINK}" | sed -e 's/.*h=\([^&]*\).*/\1/' -e 's/.*http.*//')
[ -z "${REMOTE_REF}" ] && continue [ -z "${REMOTE_REF}" ] && continue
LOG " - ${BLUE}update ${REMOTE_REF}${NC}" LOG " - ${BLUE}update ${REMOTE_REF}${NC}"
"${jirafeauAPI}" -f "${JIRAFEAU_LOCAL}" -t "month" update "${REMOTE_REF}" 2>> "${TTY}" curlJirafeauUpdate "month" "${REMOTE_REF}" 2>> "${TTY}"
LOG LOG
echo "old: ${REMOTE_REF} ${REMOTE_KEY}" >> "${TMP_DIR}/archive-content.txt" echo "old: ${REMOTE_REF} ${REMOTE_KEY}" >> "${TMP_DIR}/archive-content.txt"
done done
######################################## ########################################
# extraction des pièces jointes # 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}" LOG " - ${BLUE}PJ-name: ${NC}"
cat "${TMP_DIR}/PJ-name.txt" 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}" LOG " - ${BLUE}find ${ATTACH_NAME} / (${ATTACH_CONTENT_TYPE}) / ${ATTACH_MEDIA} ${NC}"
PASSWORD=$(apg -n 1 -m 12) PASSWORD=$(apg -n 1 -m 12)
PASSWORD_MD5=$(echo -n ${PASSWORD} | ${MD5_CMD} | cut -d \ -f 1) 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" | { cat "${TMP_DIR}/one.txt" | {
read JIR_TOKEN read JIR_TOKEN
@ -168,7 +187,7 @@ cat "${TMP_DIR}/PJ-name.txt" | {
if [ "${NB_ATTACH}" -gt 1 ]; then if [ "${NB_ATTACH}" -gt 1 ]; then
PASSWORD=$(apg -n 1 -m 12) PASSWORD=$(apg -n 1 -m 12)
PASSWORD_MD5=$(echo -n ${PASSWORD} | ${MD5_CMD} | cut -d \ -f 1) 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" | { cat "${TMP_DIR}/one.txt" | {
read JIR_TOKEN read JIR_TOKEN
read JIR_CODE 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 # 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 # affichage de la structure à la fin

168
src/cpp/MainAttachment.cpp

@ -157,6 +157,35 @@ kaz::operator >> (istream &in, AttachMode &attachMode) {
return in; return in;
} }
// ================================================================================
const string
kaz::headerTypeLabels[] = {
"Same", "Multi", "MainPlain", "AttachHtml"
};
const map<string, HeaderType>
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 void
MainAttachment::copy (ifstream &mbox, ofstream &outbox, const streamoff &begin, const streamoff &end) { MainAttachment::copy (ifstream &mbox, ofstream &outbox, const streamoff &begin, const streamoff &end) {
@ -420,6 +449,7 @@ MainAttachment::extractPreviousKAZ (ifstream &mbox) {
void void
MainAttachment::removePreviousArchive () { MainAttachment::removePreviousArchive () {
DEF_LOG ("MainAttachment::removePreviousArchive", "");
vector<string> toRemove; vector<string> toRemove;
for (map <string, string>::const_iterator it = previousLinks.begin (); it != previousLinks.end (); ++it) { for (map <string, string>::const_iterator it = previousLinks.begin (); it != previousLinks.end (); ++it) {
const string key (it->first); const string key (it->first);
@ -430,6 +460,41 @@ MainAttachment::removePreviousArchive () {
previousLinks.erase (old); 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) MainAttachment::MainAttachment (ifstream &mbox)
: Attachment (mbox, initTmpLevel (), 0, initTmpPos ()), : Attachment (mbox, initTmpLevel (), 0, initTmpPos ()),
@ -566,6 +631,15 @@ MainAttachment::extract (ifstream &mbox, const SizeArg &minSize) const {
} }
// ================================================================================ // ================================================================================
/*!
Régle à appliquer dans le cas Kaz ajoute son cartouche et que le corps principale n'est pas multipart :
<table>
<tr><th>src</th><th>FOOTER</th><th>BOTH</th><th>ATTCH</th></tr>
<tr><th>text/plain</th><td>OK</td><td>mute multi</td><td>mute multi</td></tr>
<tr><th>empty mail</th><td>mute plain</td><td>mute multi</td><td>mute html</td></tr>
</table>
*/
void void
MainAttachment::substitute (ifstream &mbox, ofstream &outbox, const SizeArg &minSize, AttachMode attachMode) { MainAttachment::substitute (ifstream &mbox, ofstream &outbox, const SizeArg &minSize, AttachMode attachMode) {
DEF_LOG ("MainAttachment::substitute", "minSize: " << 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; string plainDisclaim, htmlDisclaim;
getDisclaim (plainDisclaim, htmlDisclaim); getDisclaim (plainDisclaim, htmlDisclaim);
HeaderType headerType (SAME);
// copy email // copy email
if (!boundary.size () && plainDisclaim.size ()) { if (!boundary.size () && plainDisclaim.size ())
if (attachMode & ATTACHMENT) switch (attachMode) {
attachMode = FOOTER; case NONE: LOG_BUG (true, /* */, "eMailShrinker: bug M12: nothing to do"); break;
if (emptyEMail) { case FOOTER: headerType = (emptyEMail ? MAIN_PLAIN : SAME); break;
// only one attachment must be replace case BOTH: headerType = MULTI; break;
cerr << "eMailShrinker: force one attachment" << endl; case ATTACHMENT: headerType = ATTACH_HTML; break;
string mime (getMime (mbox)); }
string::size_type startPos = (0); rewriteHeaders (mbox, outbox, headerType);
for (string token : {string ("Content-Transfer-Encoding"), Attachment::contentTypeToken}) { streamoff curPos = contentPos;
startPos = caseInsensitiveFind (mime, "Content-Transfer-Encoding");
for (string::size_type stopPos (startPos); if (MAIN_PLAIN == headerType) {
(stopPos = mime.find ("\n", stopPos)) != string::npos; LOG ("Replace old content with plain");
) {
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); string content (plainDisclaim);
base64Encode (content); base64Encode (content);
outbox << mime outbox << content << endl;
<< content << endl;
outbox.flush (); outbox.flush ();
outbox.close ();
return; return;
}
} }
streamoff curPos = 0; if (ATTACH_HTML == headerType) {
copy (mbox, outbox, curPos, contentPos); LOG ("Replace old content with html");
curPos = contentPos; string content (plainDisclaim);
base64Encode (content);
if (plainDisclaim.size ()) { outbox << content << endl;
if (emptyEMail && (attachMode & FOOTER)) { outbox.flush ();
// check no main text return;
LOG ("Force main text");
cerr << "eMailShrinker: force footer" << endl;
string content (plainDisclaim);
base64Encode (content);
outbox << boundary.substr (0, boundary.length () -2) << endl
<< KAZ_EMPTY_TEXT_PLAIN << endl
<< content << endl;
outbox.flush ();
}
} }
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<string, string>::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) { for (Attachment *attachP : allMarkedPtrs) {
copy (mbox, outbox, curPos, attachP->beginInParent); copy (mbox, outbox, curPos, attachP->beginInParent);
LOG_BUG (attachP->toUpdate && attachP->toExtract, /**/, "eMailShrinker: bug M5: update and extract. pos: " << attachP->beginPos); 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 (); outbox.flush ();
curPos = attachP->endPos; curPos = attachP->endPos;
} }
if (plainDisclaim.size () && (attachMode & ATTACHMENT)) { if (plainDisclaim.size () && (attachMode & ATTACHMENT)) {
LOG ("Add kaz attachment"); LOG ("Add kaz attachment");
cerr << "eMailShrinker: force attachment" << endl; cerr << "eMailShrinker: force attachment" << endl;
streamoff lastPos = subAttachements.back ().endPos; if (subAttachements.size ()) {
copy (mbox, outbox, curPos, lastPos); streamoff lastPos = subAttachements.back ().endPos;
curPos = lastPos; copy (mbox, outbox, curPos, lastPos);
curPos = lastPos;
}
string content (KAZ_HTML_CONTENT+htmlDisclaim+BODY_END+HTML_END); string content (KAZ_HTML_CONTENT+htmlDisclaim+BODY_END+HTML_END);
base64Encode (content); base64Encode (content);
@ -742,7 +821,8 @@ MainAttachment::substitute (ifstream &mbox, ofstream &outbox, const SizeArg &min
outbox.flush (); outbox.flush ();
} }
copy (mbox, outbox, curPos, endPos); copy (mbox, outbox, curPos, endPos);
//outbox << endl; if (MULTI == headerType)
outbox << boundary.substr (0, boundary.length ()) << endl;
outbox.close (); outbox.close ();
} }

4
src/cpp/eMailShrinker.cpp

@ -33,8 +33,8 @@
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
#include "version.hpp" #include "version.hpp"
const std::string kaz::LAST_VERSION_NUM ("2.9"); const std::string kaz::LAST_VERSION_NUM ("2.10");
const std::string kaz::LAST_VERSION_DATE ("2022-12-24"); const std::string kaz::LAST_VERSION_DATE ("2022-12-27");
const std::string kaz::LAST_VERSION (LAST_VERSION_NUM+" "+LAST_VERSION_DATE+" eMailShrinker"); const std::string kaz::LAST_VERSION (LAST_VERSION_NUM+" "+LAST_VERSION_DATE+" eMailShrinker");
#include <iostream> #include <iostream>

13
src/cpp/kazMisc.cpp

@ -175,6 +175,19 @@ kaz::caseInsensitiveRFind (const string& s, const string& pattern, const string:
return s.rend () - it - pattern.length (); 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<char delim> template<char delim>
void void

9
src/include/MainAttachment.hpp

@ -51,6 +51,12 @@ namespace kaz {
ostream &operator << (ostream &out, const AttachMode &attachMode); ostream &operator << (ostream &out, const AttachMode &attachMode);
istream &operator >> (istream &in, AttachMode &attachMode); istream &operator >> (istream &in, AttachMode &attachMode);
enum HeaderType { SAME, MULTI, MAIN_PLAIN, ATTACH_HTML };
extern const string headerTypeLabels[];
extern const map<string, HeaderType> headerTypeMap;
ostream &operator << (ostream &out, const HeaderType &headerType);
istream &operator >> (istream &in, HeaderType &headerType);
/*! root level of e-mail structure */ /*! root level of e-mail structure */
class MainAttachment : public Attachment { class MainAttachment : public Attachment {
public: public:
@ -113,6 +119,9 @@ namespace kaz {
/*! remove previous links to archive. Used by substitute */ /*! remove previous links to archive. Used by substitute */
void removePreviousArchive (); void removePreviousArchive ();
/*! rewrite main headers */
void rewriteHeaders (ifstream &mbox, ofstream &outbox, const HeaderType &headerType);
public: public:
/*! the main attachment in mbox */ /*! the main attachment in mbox */
MainAttachment (ifstream &mbox); MainAttachment (ifstream &mbox);

3
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); 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 */ /*! 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::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 */ /*! side effect to repplace =XX by the char with de haxe value XX. It could be %XX in rfc2184 */
template<char delim='='> template<char delim='='>
void quotedDecode (string &content); void quotedDecode (string &content);

16
src/mainpage.md

@ -1,5 +1,21 @@
**Dépollueur** **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: Main Programmes:
* [eMailShrinker](eMailShrinker_8cpp.html) * [eMailShrinker](eMailShrinker_8cpp.html)
* [jirafeauAPI](jirafeauAPI_8cpp.html) * [jirafeauAPI](jirafeauAPI_8cpp.html)

Loading…
Cancel
Save