diff --git a/ii-doc.txt b/ii-doc.txt index 868f6fb..84483fe 100644 --- a/ii-doc.txt +++ b/ii-doc.txt @@ -133,7 +133,7 @@ This algorithm must be implemented by every station to generate message IDs: 1. Calculate SHA256 of the message in the Node-to-Point format as binary data. 2. Calculate Base64 of the resulting binary hash sum. 3. Truncate to the first 20 characters. -4. Replace all occurrences of + or - with A, and / or _ with Z. +4. Replace all occurrences of + or - with A, and / or _ with z. 5. The result of these operations is your ii message ID. Implementation notes diff --git a/tiifetch.tcl b/tiifetch.tcl index b74e059..f46da62 100755 --- a/tiifetch.tcl +++ b/tiifetch.tcl @@ -15,6 +15,7 @@ package require http package require uri package require sqlite3 +package require sha256 # autodetect TclTLS support and enable HTTPS request support if detected set tls_support 0 @@ -190,6 +191,14 @@ proc listcomp {a b} { return $diff } +# generate ID from the Node-to-Point msg contents +# (exactly how it was transferred inside base64) +proc n2p_id {binmsg} { + set hash [::sha2::sha256 -bin -- $binmsg] + set trimbased [string range [binary encode base64 $hash] 0 19] + return [string map {+ A - A / z _ z} $trimbased] +} + # main logic proc proc fetchiidb {url echos dbfile dolog maxids} { if {$maxids < 12} {set maxids 12} @@ -200,8 +209,9 @@ proc fetchiidb {url echos dbfile dolog maxids} { # prepare starting script sqlite3 msgdb $dbfile msgdb eval { - CREATE TABLE IF NOT EXISTS `msg` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `msgid` VARCHAR(20), `timestamp` INT, `echoname` VARCHAR(120), - `repto` TEXT, `msgfrom` TEXT, `msgfromaddr` TEXT, `msgto` TEXT, `subj` TEXT, `body` TEXT); + CREATE TABLE IF NOT EXISTS `msg` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `msgid` VARCHAR(20) UNIQUE, + `timestamp` INT, `echoname` VARCHAR(120), `repto` TEXT, `msgfrom` TEXT, `msgfromaddr` TEXT, + `msgto` TEXT, `subj` TEXT, `body` TEXT, `content_id` VARCHAR(20)); } # attempt to fetch the echolist if echos are empty @@ -308,7 +318,10 @@ proc fetchiidb {url echos dbfile dolog maxids} { set parts [split $bline ":"] if {[llength $parts] > 1} { # valid message set mid [lindex $parts 0] - set mdata [encoding convertfrom utf-8 [binary decode base64 [lindex $parts 1]]] + set bdata [binary decode base64 [lindex $parts 1]] + # calculate ii Node-to-Point ID to verify the message integrity + set content_id [n2p_id $bdata] + set mdata [encoding convertfrom utf-8 $bdata] set msglines [split $mdata "\n"] set replyto "" set tags [split [lindex $msglines 0] "/"] @@ -322,8 +335,8 @@ proc fetchiidb {url echos dbfile dolog maxids} { set msgto [string trim [lindex $msglines 5]] set subj [string trim [lindex $msglines 6]] set msgbody [string trimright [lrange $msglines 8 end]] - msgdb eval {INSERT INTO `msg` (`msgid`, `timestamp`, `echoname`, `repto`, `msgfrom`, `msgfromaddr`, `msgto`, `subj`, `body`) - VALUES ($mid, $timestamp, $echoarea, $replyto, $msgfrom, $msgfromaddr, $msgto, $subj, $msgbody);} + msgdb eval {INSERT OR IGNORE INTO `msg` (`msgid`, `timestamp`, `echoname`, `repto`, `msgfrom`, `msgfromaddr`, `msgto`, `subj`, `body`, `content_id`) + VALUES ($mid, $timestamp, $echoarea, $replyto, $msgfrom, $msgfromaddr, $msgto, $subj, $msgbody, $content_id);} } } }