From 5ec61c7634d868ec9c410ee030f00e813cb34270 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois?= Date: Fri, 11 Feb 2022 01:01:24 +0100 Subject: [PATCH] fix links --- src/Jirafeau/a.php | 326 +++++++++++++++++++++++++++---------- src/cpp/MainAttachment.cpp | 15 +- 2 files changed, 247 insertions(+), 94 deletions(-) diff --git a/src/Jirafeau/a.php b/src/Jirafeau/a.php index 3a5b24b..ea6a0f8 100644 --- a/src/Jirafeau/a.php +++ b/src/Jirafeau/a.php @@ -7,13 +7,53 @@ a.php?g=l~k => zip a.php?s=mel@domain.org => send status e-mail */ +use PHPMailer\PHPMailer\PHPMailer; +use PHPMailer\PHPMailer\SMTP; +use PHPMailer\PHPMailer\Exception; +require 'vendor/autoload.php'; +define ('JIRAFEAU_ROOT', dirname (__FILE__) . '/'); -define('JIRAFEAU_ROOT', dirname(__FILE__) . '/'); +require (JIRAFEAU_ROOT . 'lib/settings.php'); +require (JIRAFEAU_ROOT . 'lib/functions.php'); +require (JIRAFEAU_ROOT . 'lib/lang.php'); + +define ('A_GET', 'g'); +define ('A_HASH', 'h'); +define ('A_SENDER', 's'); +define ('A_UPDATE', 'u'); +define ('A_OPEN_TOKEN', 'o'); +define ('E_BAD_SENDER_NAME', 'mèl incorrect : '); +define ('E_BAD_ARCHIVE_NAME', 'bad archive name format : '); +define ('E_CREATE_ZIP', "Impossible de créer l'archive."); +define ('E_OPEN_ZIP', "Impossible d'ouvrir l'archive."); +define ('M_BAD_KEY', "Mauvaise clef pour "); +define ('M_FILE', " fichier."); +define ('M_FILES', " fichiers."); +define ('M_FILES_NOT_FOUND', " fichiers sont expirés."); +define ('M_FILES_RENAMED', " fichiers renommés."); +define ('M_FILE_NOT_FOUND', " fichier est expiré."); +define ('M_FILE_RENAMED', " fichier renommé."); +define ('M_NO_FILENAME', 'SansNom'); +define ('M_NO_SENDER', 'kaz'); +define ('M_OLD_ATTACHEMENT_DIRNAME', "RappelHistorique"); +define ('M_INTRO_FORM', "Où sont les dernières pièces jointe que j'ai envoyé ?"); +define ('M_SEND_TOKEN', "Vous allez recevoir un lien d'accès temporaire à vos données."); +define ('T_BAD_PASW', 'bad_psw'); +define ('T_CRYPTED', 'crypted'); +define ('T_CRYPT_KEY', 'crypt_key'); +define ('T_ENTRIES', 'entries'); +define ('T_FILENAME', 'file_name'); +define ('T_HASH', 'hash'); +define ('T_NEW', 'new'); +define ('T_NOT_FOUND', 'not_found'); +define ('T_OLD', 'old'); +define ('T_RENAME', 'rename'); +define ('T_SENDER', 'sender'); +define ('T_TIMESTAMP', 'timestamp'); +define ('T_WARNING_FILENAME', "-Avertissement.txt"); +define ('T_ZIP_EXT', ".zip"); -require(JIRAFEAU_ROOT . 'lib/settings.php'); -require(JIRAFEAU_ROOT . 'lib/functions.php'); -require(JIRAFEAU_ROOT . 'lib/lang.php'); /* Operations may take a long time. * Be sure PHP's safe mode is off. @@ -23,12 +63,12 @@ require(JIRAFEAU_ROOT . 'lib/lang.php'); @error_reporting (0); $do_update = false; -if (isset ($_REQUEST['u']) && !empty ($_REQUEST['u'])) { +if (isset ($_REQUEST[A_UPDATE]) && !empty ($_REQUEST[A_UPDATE])) { $do_update = true; } $do_download = false; -if (isset ($_REQUEST['g']) && !empty ($_REQUEST['g'])) { +if (isset ($_REQUEST[A_GET]) && !empty ($_REQUEST[A_GET])) { $do_download = true; } @@ -52,14 +92,14 @@ function jirafeau_update_link ($link_name, $link, $update_period) { if ($time_max < 0 || $time_up < $time_max) return $time_max; $link ['time'] = $time_more; - $link_tmp_name = VAR_LINKS . $link['hash'] . rand (0, 10000) . '.tmp'; + $link_tmp_name = VAR_LINKS . $link ['hash'] . rand (0, 10000) . '.tmp'; $handle = fopen ($link_tmp_name, 'w'); fwrite ($handle, - $link['file_name'] .NL. $link['mime_type'] .NL. $link['file_size'] .NL. $link['key'] .NL. $link['time'] .NL. - $link['hash'] .NL. $link['onetime'] .' '.JIRAFEAU_MONTH . ' '. JIRAFEAU_DAY .NL. $link['upload_date'] .NL. - $link['ip'] .NL. $link['link_code'] .NL. $link['crypted']); + $link ['file_name'] .NL. $link ['mime_type'] .NL. $link ['file_size'] .NL. $link ['key'] .NL. $link ['time'] .NL. + $link ['hash'] .NL. $link ['onetime'] .' '.JIRAFEAU_MONTH . ' '. JIRAFEAU_DAY .NL. $link ['upload_date'] .NL. + $link ['ip'] .NL. $link ['link_code'] .NL. $link ['crypted']); fclose ($handle); - $link_file = VAR_LINKS . s2p("$link_name") . $link_name; + $link_file = VAR_LINKS . s2p ("$link_name") . $link_name; rename ($link_tmp_name, $link_file); return $time_more; } @@ -69,19 +109,19 @@ function read_archive_info ($link) { $p = s2p ($link ['hash']); // read archive info $result=[]; - foreach (file (VAR_FILES . $p . $link['hash']) as $line) { + foreach (file (VAR_FILES . $p . $link ['hash']) as $line) { switch (true) { case preg_match ("/^\s*src:\s*(([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9\-]+\.)+[a-z]{2,6})\s*$/i", $line, $matches): - $result['sender'] = $matches[1]; + $result[T_SENDER] = $matches[1]; break; case preg_match ("/^\s*time:\s*(\d{4}([:-]\d{2}){5})\s*$/i", $line, $matches): - $result['timestamp'] = $matches[1]; + $result[T_TIMESTAMP] = $matches[1]; break; case preg_match ("/^\s*old:\s*([0-9a-zA-Z_-]+)\s+([0-9a-zA-Z_-]+)\s*$/", $line, $matches): - $result['old'][] = [$matches[1], $matches[2]]; + $result[T_OLD][] = [$matches[1], $matches[2]]; break; case preg_match ("/^\s*new:\s*([0-9a-zA-Z_-]+)\s+([0-9a-zA-Z_-]+)\s*$/", $line, $matches): - $result['new'][] = [$matches[1], $matches[2]]; + $result[T_NEW][] = [$matches[1], $matches[2]]; break; default: break; @@ -90,11 +130,40 @@ function read_archive_info ($link) { return $result; } +// ======================================== +function send_email($receiver, $receiver_name, $subject, $body_string){ + // SERVER SETTINGS + $mail = new PHPMailer (true); + $mail->isSMTP (); + $mail->Host = 'smtp'; + $mail->SMTPAuth = false; + $mail->SMTPAutoTLS = false; + $mail->SMTPSecure = "none"; + $mail->Port = 25; + + //Recipients (change this for every project) + $mail->setFrom ('no-reply@kaz.local', ''); + $mail->addAddress ($receiver, $receiver_name); + + //Content + $mail->isHTML (false); + $mail->Subject = $subject; + $mail->Body = $body_string; + + //send the message, check for errors + if (!$mail->send ()) { + //echo 'Mailer Error: ' . $mail->ErrorInfo; + return 0; + } else { + //echo 'Message sent!'; + return 1; + } +} // ======================================== if ($do_update) { $update_period = JIRAFEAU_MONTH; - switch ($_REQUEST['u']) { + switch ($_REQUEST[A_UPDATE]) { case 'minute': $update_period = JIRAFEAU_MINUTE; break; @@ -117,19 +186,19 @@ if ($do_update) { $update_period = JIRAFEAU_YEAR; break; default: - return_error (t('ERR_OCC') . ' (update_period)'); + return_error (t ('ERR_OCC') . ' (update_period)'); } - $link_name = $_GET['h']; - if (!preg_match('/[0-9a-zA-Z_-]+$/', $link_name)) - return_error (t('FILE_404')); - $link = jirafeau_get_link($link_name); - if (count($link) == 0) - return_error (t('FILE_404')); - $time = jirafeau_update_link($link_name, $link, $update_period); + $link_name = $_REQUEST[A_HASH]; + if (!preg_match ('/[0-9a-zA-Z_-]+$/', $link_name)) + return_error (t ('FILE_404')); + $link = jirafeau_get_link ($link_name); + if (count ($link) == 0) + return_error (t ('FILE_404')); + $time = jirafeau_update_link ($link_name, $link, $update_period); $content = '' . $time . NL; - header('HTTP/1.0 200 OK'); - header('Content-Length: ' . strlen ($content)); - header('Content-Type: text/plain'); + header ('HTTP/1.0 200 OK'); + header ('Content-Length: ' . strlen ($content)); + header ('Content-Type: text/plain'); echo $content; exit; } @@ -137,17 +206,17 @@ if ($do_update) { // ======================================== if ($do_download) { // check archive exist - $couple = explode ("~", $_REQUEST['g'], 2); + $couple = explode ("~", $_REQUEST[A_GET], 2); if (count ($couple) == 0) - return_error ("bad archive name format : ".$_REQUEST['g']); + return_error (E_BAD_ARCHIVE_NAME.$_REQUEST [A_GET]); $link_name = $couple [0]; if (!$link_name || !preg_match ('/[0-9a-zA-Z_-]+$/', $link_name)) - return_error ("bad archive name format : ".$_REQUEST['g']); + return_error (E_BAD_ARCHIVE_NAME.$_REQUEST [A_GET]); $crypt_key = count ($couple) == 2 ? $couple [1] : ""; $link = jirafeau_get_link ($link_name); if (count ($link) == 0) return_error (t ('FILE_404')); - $key = $link['key']; + $key = $link ['key']; if ($key && (empty ($crypt_key) || $key != $crypt_key)) return_error (t ('BAD_PSW')); @@ -156,80 +225,79 @@ if ($do_download) { // check entries $archive_content = []; $modif = false; - foreach (["old", "new"] as $cat) { - $single_name = []; + $single_name = []; + foreach ([T_OLD, T_NEW] as $cat) if (isset ($archive_info[$cat])) foreach ($archive_info[$cat] as [$link_name, $crypt_key]) { $link = jirafeau_get_link ($link_name); if (count ($link) == 0) { - ++$archive_content[$cat]['not_found']; + if (isset ($archive_content[T_NOT_FOUND])) + ++$archive_content[T_NOT_FOUND]; + else + $archive_content[T_NOT_FOUND] = 1; $modif = true; continue; } - $key = $link['key']; + $key = $link ['key']; if ($key && (empty ($crypt_key) || $key != $crypt_key)) { - ++$archive_content[$cat]['bad_pass']; + if (isset ($archive_content[T_BAD_PASW])) + ++$archive_content[T_BAD_PASW]; + else + $archive_content[T_BAD_PASW] = 1; $modif = true; continue; } - $src_name = $dst_name = $link['file_name']; + $src_name = $dst_name = ($link ['file_name'] ? $link ['file_name'] : M_NO_FILENAME); if (in_array ($src_name, $single_name)) for ($i = 0; $i < 10000; ++$i) { $dst_name = sprintf ("%s-%2d", $src_name, $i); if (!in_array ($dst_name, $single_name)) { - ++$archive_content[$cat]['rename']; + if (isset ($archive_content[T_RENAME])) + ++$archive_content[T_RENAME]; + else + $archive_content[T_RENAME] = 1; $modif = true; break; } } $single_name [] = $dst_name; - $archive_content[$cat]['entries'][] = ['hash' => $link['hash'], 'file_name' => $dst_name, 'crypt_key' => $crypt_key, 'crypted' => $link['crypted']]; + $archive_content[$cat][T_ENTRIES][] = [T_HASH => $link ['hash'], T_FILENAME => $dst_name, T_CRYPT_KEY => $crypt_key, T_CRYPTED => $link['crypted']]; } - } // build zip - $dirname = (isset ($archive_info['sender']) && !empty ($archive_info['sender'])) - ? $archive_info['sender'] : "kaz"; - $dirname .= "-" . (isset ($archive_info['timestamp']) && !empty ($archive_info['timestamp'])) - ? $archive_info['timestamp'] : date ("Ymd-His"); + $dirname = (isset ($archive_info[T_SENDER]) && !empty ($archive_info[T_SENDER])) + ? $archive_info[T_SENDER] : M_NO_SENDER; + $dirname .= "-" . (isset ($archive_info[T_TIMESTAMP]) && !empty ($archive_info[T_TIMESTAMP])) + ? $archive_info[T_TIMESTAMP] : date ("Ymd-His"); $tmpFileName = tempnam (sys_get_temp_dir (), $dirname."-"); $zip = new ZipArchive; if (!$zip) - return_error ("can't create zip"); - if ($zip->open ($tmpFileName.".zip", ZipArchive::CREATE) !== TRUE) - return_error ("can't open zip"); + return_error (E_CREATE_ZIP); + if ($zip->open ($tmpFileName.T_ZIP_EXT, ZipArchive::CREATE) !== TRUE) + return_error (E_OPEN_ZIP); // create info XXX if ($modif) { $info = ''; - $not_found = $bad_pass = $rename = 0; - foreach (["old", "new"] as $cat) { - if (isset ($archive_info[$cat]['not_found'])) - $not_found += $archive_info[$cat]['not_found']; - if (isset ($archive_info[$cat]['bad_pass'])) - $bad_pass += $archive_info[$cat]['bad_pass']; - if (isset ($archive_info[$cat]['rename'])) - $rename += $archive_info[$cat]['rename']; - } - if ($not_found) - $info .= $not_found. ($not_found ? " fichier est expiré." : " fichiers sont expirés.").NL; - if ($bad_pass) - $info .= "Mauvaise clef pour ". $bad_pass. ($bad_pass ? " fichier" : " fichiers.").NL; - if ($rename) - $info .= $rename. ($rename ? " fichier renommé." : " fichiers sont renommés.").NL; - $zip->addFromString ($dirname."-Avertissement.txt", $info); + if (isset ($archive_info[T_NOT_FOUND])) + $info .= $archive_info[T_NOT_FOUND]. ($archive_info[T_NOT_FOUND] ? M_FILE_NOT_FOUND : M_FILES_NOT_FOUND).NL; + if (isset ($archive_info[T_BAD_PASW])) + $info .= M_BAD_KEY. $archive_info[T_BAD_PASW]. ($archive_info[T_BAD_PASW] ? M_FILE : M_FILES).NL; + if (isset ($archive_info[$cat][T_RENAME])) + $info .= $archive_info[$cat][T_RENAME]. ($archive_info[$cat][T_RENAME] ? M_FILE_RENAMED : M_FILES_RENAMED).NL; + $zip->addFromString ($dirname.T_WARNING_FILENAME, $info); } - foreach (["old", "new"] as $cat) + foreach ([T_OLD, T_NEW] as $cat) if (isset ($archive_info [$cat])) { - $subdir = $dirname . ($cat == "new" ? "" : "/origine"); - foreach ($archive_content [$cat]['entries'] as $entry) { - $p = s2p ($entry ['hash']); - if ($entry['crypted']) { + $subdir = $dirname . ($cat == T_NEW ? "" : "/".M_OLD_ATTACHEMENT_DIRNAME); + foreach ($archive_content [$cat][T_ENTRIES] as $entry) { + $p = s2p ($entry [T_HASH]); + if ($entry [T_CRYPTED]) { $m = mcrypt_module_open ('rijndael-256', '', 'ofb', ''); - $md5_key = md5 ($entry['crypt_key']); + $md5_key = md5 ($entry [T_CRYPT_KEY]); $iv = jirafeau_crypt_create_iv ($md5_key, mcrypt_enc_get_iv_size ($m)); mcrypt_generic_init ($m, $md5_key, $iv); - $r = fopen (VAR_FILES . $p . $entry['hash'], 'r'); + $r = fopen (VAR_FILES . $p . $entry [T_HASH], 'r'); $content = ""; while (!feof ($r)) { $dec = mdecrypt_generic ($m, fread ($r, 1024)); @@ -237,35 +305,35 @@ if ($do_download) { ob_flush (); } fclose ($r); - $zip->addFromString ($subdir."/".$entry['file_name'], $content); + $zip->addFromString ($subdir."/".$entry [T_FILENAME], $content); mcrypt_generic_deinit ($m); mcrypt_module_close ($m); continue; } - $zip->addFile (VAR_FILES.$p.$entry['hash'], $subdir."/".$entry['file_name']); + $zip->addFile (VAR_FILES.$p.$entry [T_HASH], $subdir."/".$entry [T_FILENAME]); } } $zip->close (); - if (!is_file ($tmpFileName.".zip")) - return_error ("can't retreive tmp"); + if (!is_file ($tmpFileName.T_ZIP_EXT,)) + return_error (E_OPEN_ZIP); if (false) { // log $content = print_r ($archive_info, 1); $content .= print_r ($archive_content, 1); - header('HTTP/1.0 200 OK'); - header('Content-Length: ' . strlen ($content)); - header('Content-Type: text/plain'); + header ('HTTP/1.0 200 OK'); + header ('Content-Length: ' . strlen ($content)); + header ('Content-Type: text/plain'); echo $content; exit; } header ("Content-Type: application/zip"); header ('Content-Disposition: filename="'.$dirname.'.zip"'); - $r = fopen($tmpFileName.".zip", 'r'); + $r = fopen ($tmpFileName.".zip", 'r'); while (!feof ($r)) { print fread ($r, 1024); ob_flush (); @@ -281,14 +349,98 @@ if ($do_download) { // XXX form send $content = "TODO send form".NL; -if (isset ($_REQUEST['s']) && !empty ($_REQUEST['s'])) { - $sender=$_REQUEST ['s']; - if (!preg_match("/^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9\-]+\.)+[a-z]{2,6}$/ix", $sender)) - return_error ("bad dir name format : ".$sender); - +$sender = ''; +if (isset ($_REQUEST [A_SENDER]) && !empty ($_REQUEST [A_SENDER])) { + $sender=$_REQUEST [A_SENDER]; + if (!preg_match ("/^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9\-]+\.)+[a-z]{2,6}$/ix", $sender)) + return_error (E_BAD_SENDER_NAME.$sender); $content = "${sender}".NL; } +if (!$sender) { + require (JIRAFEAU_ROOT . 'lib/template/header.php'); + echo M_INTRO_FORM; + ?> +
+
+ + + + + + + + + + +
+
+
+
+
+ $crypt_key) + $content .= $link_name . " - " . $crypt_key . NL; // XXX find // add link : name / time / download / delete @@ -301,8 +453,8 @@ if (isset ($_REQUEST['s']) && !empty ($_REQUEST['s'])) { // fwrite ($fd, $content); // fclose ($fd); -header('HTTP/1.0 200 OK'); -header('Content-Length: ' . strlen ($content)); -header('Content-Type: text/plain'); +header ('HTTP/1.0 200 OK'); +header ('Content-Length: ' . strlen ($content)); +header ('Content-Type: text/plain'); echo $content; ?> diff --git a/src/cpp/MainAttachment.cpp b/src/cpp/MainAttachment.cpp index 5251409..2e49f75 100644 --- a/src/cpp/MainAttachment.cpp +++ b/src/cpp/MainAttachment.cpp @@ -163,7 +163,7 @@ void MainAttachment::addLink (string &plain, string &html, const string &url, const string &name) const { string plainNewOneLink (templatePlainAddLink); replaceAll (plainNewOneLink, TMPL_DOWNLOAD, url); - replaceAll (plainNewOneLink, TMPL_FILENAME, name); + replaceAll (plainNewOneLink, TMPL_FILENAME, "\""+name+"\""); plain += plainNewOneLink; string htmlNewOneLink (templateHtmlAddLink); string codedUrl (url); @@ -211,7 +211,7 @@ MainAttachment::getDisclaim (string &plain, string &html) const { plain = "\r\n"+KAZ_PLAIN_START+"\r\n"+KAZ_PLAIN_HR+"\r\n"+KAZ_PLAIN_DONT_TOUCH+"\r\n\r\n"+KAZ_PLAIN_WARNING+"\r\n\r\n"+KAZ_PLAIN_DOWLOAD_ONE+"\r\n"+plainNewLinks; html = templateHtmlHeader+htmlNewLinks; if (previousLinks.size ()) { - plain += KAZ_PLAIN_DOWLOAD_OTHER+"\r\n"+plainOldLinks; + plain += "\r\n"+KAZ_PLAIN_DOWLOAD_OTHER+"\r\n"+plainOldLinks; html += templateHtmlOtherLink+htmlOldLinks; } if (linkCount > 1 && archiveDownloadURL.length ()) { @@ -239,7 +239,7 @@ MainAttachment::addPrevious (const string &href, const string &name, const bool if (oldVal.length () && name.length () && !trust) return; previousLinks.erase (href); - previousLinks [href] = name; + previousLinks [href] = regex_replace (name, regex (R"([\t\r\n\"]+|(\\\")|(>\s*))"), ""); LOG ("inserted: " << href << ": " << previousLinks[href]); } @@ -255,7 +255,7 @@ MainAttachment::extractLinks (const string &extractedPlainKAZ) { const string href (extractedPlainKAZ.substr (startPos, stopPos-startPos)); LOG ("plain href: " << href); - if (extractedPlainKAZ [stopPos] && extractedPlainKAZ [stopPos] != '\n') + if (extractedPlainKAZ [stopPos]) ++stopPos; startPos = stopPos; // get all href but KAZ_WEB_SITE @@ -266,11 +266,11 @@ MainAttachment::extractLinks (const string &extractedPlainKAZ) { string::size_type nextPos = extractedPlainKAZ.find ("http", startPos); string name (extractedPlainKAZ, startPos, (nextPos == string::npos ? extractedPlainKAZ.length () : nextPos) - startPos); // skip [> \r\n\t] - nextPos = name.find_first_not_of ("[> \t\r\n]"); + nextPos = name.find_first_not_of ("[> \t\r\n\"]"); if (nextPos != string::npos) name.erase (0, nextPos); // stop before [>\r\n\t] - nextPos = name.find_first_of ("[>\t\r\n]"); + nextPos = name.find_first_of ("[\"]"); if (nextPos != string::npos) name.erase (nextPos); LOG ("plain name: " << name); @@ -354,7 +354,8 @@ void MainAttachment::removePreviousArchive () { vector toRemove; for (map ::const_iterator it = previousLinks.begin (); it != previousLinks.end (); ++it) - if (it->first.find ("&l=/") != string::npos) + if (it->first.find ("&g=") != string::npos || + it->first.find ("&l=/") != string::npos) // v1 compatibility toRemove.push_back (it->first); for (string old : toRemove) previousLinks.erase (old);