This commit is contained in:
maqp 2019-03-03 10:54:09 +02:00
parent 05d8ce0781
commit 3eb4f3671d
39 changed files with 935 additions and 501 deletions

View File

@ -145,6 +145,8 @@ Hardware<Br>
&nbsp;&nbsp;&nbsp;&nbsp;[Data diode (breadboard)](https://github.com/maqp/tfc/wiki/TTL-Data-Diode-(breadboard))<br>
&nbsp;&nbsp;&nbsp;&nbsp;[Data diode (perfboard)](https://github.com/maqp/tfc/wiki/TTL-Data-Diode-(perfboard))<br>
[Update log](https://github.com/maqp/tfc/wiki/Update-Log)<br>
Software<Br>
&nbsp;&nbsp;&nbsp;&nbsp;[Installation](https://github.com/maqp/tfc/wiki/Installation)<br>
&nbsp;&nbsp;&nbsp;&nbsp;[How to use](https://github.com/maqp/tfc/wiki/How-to-use)<br>
For the rest of the articles, see [TFC wiki](https://github.com/maqp/tfc/wiki).
[Update log](https://github.com/maqp/tfc/wiki/Update-Log)<br>

View File

@ -17,257 +17,179 @@
# along with TFC. If not, see <https://www.gnu.org/licenses/>.
dl_verify () {
# Download a TFC file from the GitHub repository and authenticate it
# by comparing its SHA512 hash against the hash pinned in this
# installer file.
torify wget https://raw.githubusercontent.com/maqp/tfc/master/$2$3 -q
# Check the SHA512 hash of the downloaded file
if sha512sum $3 | grep -Eo '^\w+' | cmp -s <(echo "$1"); then
if [[ ${sudo_pwd} ]]; then
echo ${sudo_pwd} | sudo -S mkdir --parents /opt/tfc/$2
echo ${sudo_pwd} | sudo -S mv $3 /opt/tfc/$2
echo ${sudo_pwd} | sudo -S chown root /opt/tfc/$2$3
echo ${sudo_pwd} | sudo -S chmod 644 /opt/tfc/$2$3
else
sudo mkdir --parents /opt/tfc/$2
sudo mv $3 /opt/tfc/$2
sudo chown root /opt/tfc/$2$3
sudo chmod 644 /opt/tfc/$2$3
fi
# Check the SHA512 hash of the moved file
if sha512sum /opt/tfc/$2$3 | grep -Eo '^\w+' | cmp -s <(echo "$1"); then
echo OK - Pinned SHA512 hash matched file /opt/tfc/$2$3
else
echo Error: /opt/tfc/$2$3 had invalid SHA512 hash
exit 1
fi
compare_digest () {
# Compare the SHA512 digest of TFC file against the digest pinned in this installer.
if sha512sum /opt/tfc/$2$3 | grep -Eo '^\w+' | cmp -s <(echo "$1"); then
echo OK - Pinned SHA512 hash matched file /opt/tfc/$2$3
else
echo Error: $3 had invalid SHA512 hash
echo Error: /opt/tfc/$2$3 had invalid SHA512 hash
exit 1
fi
}
download_common () {
dl_verify d361e5e8201481c6346ee6a886592c51265112be550d5224f1a7a6e116255c2f1ab8788df579d9b8372ed7bfd19bac4b6e70e00b472642966ab5b319b99a2686 '' LICENSE
dl_verify 04bc1b0bf748da3f3a69fda001a36b7e8ed36901fa976d6b9a4da0847bb0dcaf20cdeb884065ecb45b80bd520df9a4ebda2c69154696c63d9260a249219ae68a '' LICENSE-3RD-PARTY
dl_verify 6d93d5513f66389778262031cbba95e1e38138edaec66ced278db2c2897573247d1de749cf85362ec715355c5dfa5c276c8a07a394fd5cf9b45c7a7ae6249a66 '' tfc.png
verify_tcb_requirements_files () {
compare_digest a27d0a626f0963ee962a9bd9df98f157dcbb1fc7abf30322d8657f5db8b182f3ed7a3f2b736880e32121fb9bc6dce29cd7cb78cb77d5a82e42cadbacbe6b2651 '' requirements.txt
compare_digest d5e6ef9d3743cc81440d0f1024389ce0c10c23771f3aee95886731f1a7cbdf64fa5e0245d370382f8988d3c1758d0548e384e05635216ded3552dee80a03b16a '' requirements-venv.txt
}
dl_verify cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e src/ __init__.py
dl_verify cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e src/common/ __init__.py
dl_verify 003915a43670bbb3185e045de1d9cede67160d9da0a24a72650862e978106c451d94a2da4aa2e1d161315db7575251933b80881294f33f195531c75462bbcf9c src/common/ crypto.py
dl_verify 0dfae6aa49c399983a990ca672e24eef9aa3ed7782686dd6c78ab8041023650e195304a07d40b934ea6f73bb46189529983de4093144ffdef40e718263232365 src/common/ db_contacts.py
dl_verify 49ebf5dff5f34a373dccfaa0a8152e5bea11e6c3afc997d4c83d45b19351b62e0138555647c2ca796faf3cfc946f16d779af4ef9938b5ebffafa9ab155761696 src/common/ db_groups.py
dl_verify 157bc8b1cfea322118b880d9bcc76b695405668af718276246c334f76226781a55779da4adcea571472bfcc7ced2cdd908d49e181268707b16ef71ff4c8ff833 src/common/ db_keys.py
dl_verify 04cc3f2816b903d82e7baaa0bc9e406d7058c27537e8d07db67882a88deb4289fdff84150eb0dd1806721bf0ae1dd7f2757b916670eff6d1c122c660ac6d4ba2 src/common/ db_logs.py
dl_verify 8d53e7348abf71aa1e054e5e852e171e58ed409c394213d97edc392f016c38ce43ed67090d3623aaa5a3f335992fd5b0681cfb6b3170b639c2fa0e80a62af3a4 src/common/ db_masterkey.py
dl_verify 907c8997158a160b71bb964191848db42260a201e80b61133be1e7c7a650604792164499b85eaa4e84c58a7bc1598aff6ed10fda8442d60eb7f939d9de7f09c8 src/common/ db_onion.py
dl_verify 83b2a6d36de528106202eebccc50ca412fc4f0b6d0e5566c8f5e42e25dd18c67ae1b65cf4c19d3824123c59a23d6258e8af739c3d9147f2be04813c7ede3761d src/common/ db_settings.py
dl_verify 88f628cef1973cf0c9a9c8661a527570e01311efbbb6903760abec2b7ff6f4f42b3ff0e00c020d7b1912d66ac647b59b502942199334a83bb9d9dddc2a70c943 src/common/ encoding.py
dl_verify 0e3e6a40928ab781dbbca03f2378a14d6390444b13e85392ea4bdfb8e58ae63f25d6f55b2637f6749e463844784ea9242db5d18291e891ee88776d4c14498060 src/common/ exceptions.py
dl_verify 77b810f709739543dc40b1d1fbafb2a95d1c1772b929d3a4247c32e20b9bb40039c900ff4967c4b41118567463e59b7523fbbbf993b34251e46c60b8588f34ab src/common/ gateway.py
dl_verify 42742ab0e0f6f61bd6b8d7d32644a98e526fa7fd0fd7ed8e790c25e365874d77a6611849c168649160b84774059675a066dd0711db59ed41ffc449790fb5ffa0 src/common/ input.py
dl_verify 18efc508382167d3259c2eb2b8adcddda280c7dbc73e3b958a10cf4895c6eb8e7d4407bc4dc0ee1d0ab7cc974a609786649491874e72b4c31ad45b34d6e91be3 src/common/ misc.py
dl_verify f47308851d7f239237ed2ae82dd1e7cf92921c83bfb89ad44d976ebc0c78db722203c92a93b8b668c6fab6baeca8db207016ca401d4c548f505972d9aaa76b83 src/common/ output.py
dl_verify dc5fdd0f8262815386896e91e08324cda4aa27b5829d8f114e00128eb8e341c3d648ef2522f8eb5b413907975b1270771f60f9f6cdf0ddfaf01f288ba2768e14 src/common/ path.py
dl_verify f80a9906b7de273cec5ca32df80048a70ea95e7877cd093e50f9a8357c2459e5cffb9257c15bf0b44b5475cdd5aaf94eeec903cc72114210e19ac12f139e87f3 src/common/ reed_solomon.py
dl_verify 421fa2ec82f35a384baf5f5a4000afa4701e814ff28b4e8fa45478226cbf2f9272854ddf171def4ad7a489a77531457b9b6d62b68c4417b26b026e0ee6e521e8 src/common/ statics.py
verify_files () {
compare_digest dec90e113335d3274d87c3e12dda5a3205df57bd10c1e0532ecad34409520ce0596db21e989478836d4a0ea44da8c42902d2d8f05c9ad027a5560b4d0d5b9f13 '' dd.py
compare_digest d361e5e8201481c6346ee6a886592c51265112be550d5224f1a7a6e116255c2f1ab8788df579d9b8372ed7bfd19bac4b6e70e00b472642966ab5b319b99a2686 '' LICENSE
compare_digest 04bc1b0bf748da3f3a69fda001a36b7e8ed36901fa976d6b9a4da0847bb0dcaf20cdeb884065ecb45b80bd520df9a4ebda2c69154696c63d9260a249219ae68a '' LICENSE-3RD-PARTY
compare_digest 1dd17740ffb6bd4da5de8b00da8e0e1e79d9c81771bf62dee9d3e85e3fd6b1254ec1d011c217b0102f08384c03b63a002b6cddc691a2d03eaa3faddd8cef5a15 '' relay.py
compare_digest 2865708ab24c3ceeaf0a6ec382fb7c331fdee52af55a111c1afb862a336dd757d597f91b94267da009eb74bbc77d01bf78824474fa6f0aa820cd8c62ddb72138 '' requirements-dev.txt
compare_digest 6a27003e7feb81a2ef7a7ffb114d7130120cad53a2687f7ba7200eb3f65156ad0dc1dcb713234593df7dac9da047c4e1e7306f58ddbaae4751437c63c309c1e4 '' requirements-relay.txt
compare_digest 6d93d5513f66389778262031cbba95e1e38138edaec66ced278db2c2897573247d1de749cf85362ec715355c5dfa5c276c8a07a394fd5cf9b45c7a7ae6249a66 '' tfc.png
compare_digest cec2bc228cd3ef6190ea5637e95b0d65ea821fc159ebb2441f8420af0cdf440b964bdffd8e0791a77ab48081f5b6345a59134db4b8e2752062d7c7f4348a4f0f '' tfc.py
compare_digest 7a3d7b58081c0cd8981f9c7f058b7f35384e43b44879f242ebf43f94cec910bab0e40bd2f7fc1a2f7b87ebc8098357f43b5cede8948bd684be4c6d2deaf1a409 '' uninstall.sh
compare_digest 2f426d4d971d67ebf2f59b54fb31cff1a3e2567e343bfa1b3e638b8e0dffed5d0c3cac1f33229b98c302fee0cca3cc43567c2c615b5249a2db6d444e89e5fc70 launchers/ terminator-config-local-test
compare_digest 57110f77d5317cdebd38d478e6836ccea038ae17d6ea46e76e02358b367224468ee12e2a884bcf9f75fe1ae5d3aff5dcb6e7114032e54626ac18b53230b2949d launchers/ TFC-Local-test.desktop
compare_digest 7223cd66c5c9b5850a1c1c81d8751541ae3eb0b4e44b989ae6ec06618c167ee4f0c4e8ae374a1da654afa8eb751468cd06bd0f27638420b9f5befb7352c85ba9 launchers/ TFC-RP.desktop
compare_digest a72ce74903aafa47bbcced11b87396445916d53651aedc8fd1f0a03b87463673eed8b312e624bd559d5f382cc8f484c8e891932588e241c711bd082fda88f8ff launchers/ TFC-RP-Tails.desktop
compare_digest 0fc9b6e7ccbfe87ef39d2d1cd4434becd2070cdab72b3a215e9879fe060ce3c2a46251168ecc69e64c10d70210e50733f8e61abf6429ba6a811d91682683a8a8 launchers/ TFC-RxP.desktop
compare_digest 4c61d5f11da0f2b673a26f2070d8040df71fba9285f36880a718fa711c7cefbaf5d47fd506ae4ddb1f7a6a1d5afccfdbfe096a0204ad6a78fde9fcefa3c88908 launchers/ TFC-TxP.desktop
compare_digest cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e src/ __init__.py
compare_digest cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e src/common/ __init__.py
compare_digest 6a6434cdbb35c5dc0ebce6ee961da0d3afffe09b9cf0988cf08cc55d9cd9195462c1b986ec96e3521f88dea7c390daa7419446efd4bf3ed7383991e7f7347828 src/common/ crypto.py
compare_digest ce3a2b1890393801cad88162772a4d90799f95dc7d438c64856db92fa0a9b02431077e4c856a18c0953b242efc37e035fce96740b9379c966bd9fd76338889ef src/common/ db_contacts.py
compare_digest a071463fbc0e83237cc482ef709c0957f8774c325730c89a3deb7839d0997e47a3163c896df70e96e1c150f2f7dda7b096c808bba3dededddcb0036bfcc0f63c src/common/ db_groups.py
compare_digest 4855baf9d9bd48d210981e380ebc2d7ff65b7e13392606f386769e10ba918843e50ba6174e51a74f2d6841aa8b1f466e7f65a901143f484bdbe312ccbf9eb11e src/common/ db_keys.py
compare_digest 13138abd171b7b8db7b7443aa2cef5a5b000aa96a23a9169089c12b8ae6c4f23b5519b248a54be8767862adce03e98def314e471ffd74fdfc9bf1fa8f31c8e90 src/common/ db_logs.py
compare_digest 8d53e7348abf71aa1e054e5e852e171e58ed409c394213d97edc392f016c38ce43ed67090d3623aaa5a3f335992fd5b0681cfb6b3170b639c2fa0e80a62af3a4 src/common/ db_masterkey.py
compare_digest 516577100e4e03068cfcb0169975b86a258b8aafddddf995f434c98d0b2d81a2d96a45bca473ddeb6980dfd71420f489eee2d82a9053bf02c87d1acddf9b7ecf src/common/ db_onion.py
compare_digest 83b2a6d36de528106202eebccc50ca412fc4f0b6d0e5566c8f5e42e25dd18c67ae1b65cf4c19d3824123c59a23d6258e8af739c3d9147f2be04813c7ede3761d src/common/ db_settings.py
compare_digest 804e8124688e808440db585f6b1a05667666353684a4b31535100df7e54f0c5b91f5d61998a64717e710a62c7d8185b99b6012f713f3becaa7d73a39dcb5e774 src/common/ encoding.py
compare_digest 0e3e6a40928ab781dbbca03f2378a14d6390444b13e85392ea4bdfb8e58ae63f25d6f55b2637f6749e463844784ea9242db5d18291e891ee88776d4c14498060 src/common/ exceptions.py
compare_digest 77b810f709739543dc40b1d1fbafb2a95d1c1772b929d3a4247c32e20b9bb40039c900ff4967c4b41118567463e59b7523fbbbf993b34251e46c60b8588f34ab src/common/ gateway.py
compare_digest e27f950719760cc2f72db8e4a3c17389b2a52f34476c0ac4aeb17b050d27cb86209d49b83b049943c2bd97228de433834061dc0abffd61459502cd1303aca9c1 src/common/ input.py
compare_digest 18efc508382167d3259c2eb2b8adcddda280c7dbc73e3b958a10cf4895c6eb8e7d4407bc4dc0ee1d0ab7cc974a609786649491874e72b4c31ad45b34d6e91be3 src/common/ misc.py
compare_digest f47308851d7f239237ed2ae82dd1e7cf92921c83bfb89ad44d976ebc0c78db722203c92a93b8b668c6fab6baeca8db207016ca401d4c548f505972d9aaa76b83 src/common/ output.py
compare_digest dc5fdd0f8262815386896e91e08324cda4aa27b5829d8f114e00128eb8e341c3d648ef2522f8eb5b413907975b1270771f60f9f6cdf0ddfaf01f288ba2768e14 src/common/ path.py
compare_digest f80a9906b7de273cec5ca32df80048a70ea95e7877cd093e50f9a8357c2459e5cffb9257c15bf0b44b5475cdd5aaf94eeec903cc72114210e19ac12f139e87f3 src/common/ reed_solomon.py
compare_digest 0f58763f172daa457237f103146fb4c61b3cf8b06875f44ed934a2677c57041fa7902ac2730e6340c18a2b8ac5459ff1c2854fee325bd0d343885bb582c68c38 src/common/ statics.py
compare_digest cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e src/receiver/ __init__.py
compare_digest 35b035f2794b5d7618eeafd91781246a0100bac9ff6a1f643b16068d5b2dc2946c799e91beba77d94e4118f99d6d6653974ebd5d4008133131f3bf44a7a190fb src/receiver/ commands.py
compare_digest 09f921aaaeae96ee6e9ff787990864ba491d4f8b10c613ab2a01f74c00b62d570270323ea2f5dc08befd8aa7bf4be0c609f8dca1862e4465e521b8016dff14da src/receiver/ commands_g.py
compare_digest 7b1d45caf3faf28c484d7d8d0c96ff9ba6e840682b002e438eac620904d3ca39483009a079d300489d80e22025ba301fa483f235193de5b55a62e9dedb25967f src/receiver/ files.py
compare_digest 5dee12fdbb8bade16e2d7f97c8791a39f408ec7eaeee89c75beac799584f9ae4d6d3e9495693630d7cb2c8a167c3e542f0d28b78725821ff14f04eb706afbe71 src/receiver/ key_exchanges.py
compare_digest 2894c847fe3f69a829ed7d8e7933b4c5f97355a0d99df7125cee17fffdca9c8740b17aa512513ae02f8f70443d3143f26baea268ace7a197609f6b47b17360b7 src/receiver/ messages.py
compare_digest 57ebdf412723b5ab4f683afeda55f771ef6ef81fde5a18f05c470bca5262f9ff5eefd04a3648f12f749cec58a25fa62e6dfb1c35e3d03082c3ea464ef98168b1 src/receiver/ output_loop.py
compare_digest 3b84dbe9faffeab8b1d5953619e38aefc278ce4e603fd63beaee878af7b5daff46b8ed053ad56f11db164b1a3f5b694c6704c66588386b06db697281c9f81bbf src/receiver/ packet.py
compare_digest 1e5240d346a016b154faf877199227edf76e027d75e1e921f2024c5dd1d0a40c1de7e9197077786a21474a4bbf2c305d290214aacdea50f5abaeb39963ca08a6 src/receiver/ receiver_loop.py
compare_digest e84a92fa500492af0cc16038fd388c74c387334898b870e57bc599d1b95da85b579d50ba403cdfc82ce8d4d5765fc59e772796d54faa914d0b5874150428d762 src/receiver/ windows.py
compare_digest cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e src/relay/ __init__.py
compare_digest 62ac101830793c4bbf9b85f714b6d3609ae8f05aa7be36d32c54df1b27ec8c0b17e71de8ad3db4af9ebba6886d0ec4cf7990c36a13469fa316b4bc19b2fe7086 src/relay/ client.py
compare_digest 02c764d58ef8d02f95050cec41aa41fa90938ea08e0107ed49d3ae73357115b48f23f291dfc238ec3e45b12a705089b5c2ad3a1b30f27abb0a4c7498271161a3 src/relay/ commands.py
compare_digest d5cf0b3522490ca34b9171b036704fe0a2c79f338c8bbbaea6fcd4d186c4e30f6d9fe96634babfce3afa5c043eadb360d83bdf2c14d5c34616d4cab09eef29ce src/relay/ onion.py
compare_digest bc6d33d5e9439c1e7baf82c1eb43fbb21af6109db366082d124be2b3c70f90e6dda7f38f0e5cd55e3de0019ced0e0548f10fbe3792f0f621a4f2e31a0ef8496d src/relay/ server.py
compare_digest 380a78c8c0918e33fb6be39a4c51f51a93aa35b0cf320370d6fb892b5dade920e8ca4e4fe9d319c0a0cdc5b3a97f609fdee392b2b41175379200b1d793b75593 src/relay/ tcb.py
compare_digest cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e src/transmitter/ __init__.py
compare_digest f91c0f616555725e0d2a4d8e2ee2bf39e1ebc4cbdf0a2547f4e4b5e4f1ee88743273cffb422a43dff98ba42772b18ceb4c270628f933392e27fa5cd6cae991ce src/transmitter/ commands.py
compare_digest f7cf493506a19b9732ae9f780aeb131342a47644632fcf88f0df01f0bda88252fdbad37a4b80e87f97e57feb50079ac2e5194598d745163846e30fdd6d32fe60 src/transmitter/ commands_g.py
compare_digest a1b6af28645df531be3a670375ce3a3da1a48b279d646f04b3c14cfbdf7006060955f33595a2963f98a495ec16dfe969325842495d8fbfae5f93e1459ed047c4 src/transmitter/ contact.py
compare_digest 184c35a32a3858893c67622a21fc7fdbd88bc61f82d4b655ad26ef008563cdb31430a3b713b92c98ea8d983ebadd0db6f9de3f9b1c07ac3dce4cf405aedf21ae src/transmitter/ files.py
compare_digest 019c178982f89b93ba69d26e60625a868380ac102b10351ac42c4d1321a45dd7186694d86028371185a096cce2e2bbe2d68210552439e34c3d5166f67b3578ee src/transmitter/ input_loop.py
compare_digest 742fba91ebd67dca247d03df4cf1820fc6b07e6966449282d7c4019f48cc902dc8dfc4120be9fdd6e61a4f00dd7753a08565a1b04395bc347064631d957c9d82 src/transmitter/ key_exchanges.py
compare_digest a59619b239b747298cc676a53aa6f87a9ef6511f5e84ec9e8a8e323c65ab5e9234cb7878bd25d2e763d5f74b8ff9fe395035637b8340a5fd525c3dc5ccbf7223 src/transmitter/ packet.py
compare_digest c2f77f8d3ebf12c3816c5876cd748dc4d7e9cd11fe8305d247783df510685a9f7a6157762d8c80afda55572dcae5fe60c9f39d5ec599a64d40928a09dd789c35 src/transmitter/ sender_loop.py
compare_digest 5d42f94bf6a6a4b70c3059fd827449af5b0e169095d8c50b37a922d70955bf79058adc10da77ebb79fb565830168dccb774547b6af513b7c866faf786da7c324 src/transmitter/ traffic_masking.py
compare_digest 22e8ba63c1391233612155099f5f9017d33918180f35c2552e31213862c76e3048d552f193f9cd3e4e9a240c0ef9bef4eabefe70b37e911553afeceede1133ca src/transmitter/ user_input.py
compare_digest 39a7b3e4457d9aa6d53cb53d38c3ed9adbd9e3250008b4e79b5a174b9227fd0fac6dad30e6e9b8fe3d635b25b2d4dfc049804df48d04f5dfcc1016b2e0a42577 src/transmitter/ windows.py
}
download_relay () {
dl_verify 9ff2e54072e9cd9a87d167961bb5dd299caa035f634c08223262cda562faf9407ec09435c63e9cce7cb4121a6273ae0300835334e03f859df3e7f85b367d685c '' relay.py
dl_verify ddcefcf52d992f9027b530471a213e224382db5fbb516cc8dee73d519e40110f9fcca1de834a34e226c8621a96870f546b9a6b2f0e937b11fd8cd35198589e8b '' requirements-relay.txt
dl_verify f2b23d37a3753a906492fcb3e84df42b62bed660f568a0a5503b188f140fa91f86b6efa733b653fceff650168934e2f3f1174c892e7c28712eda7676b076dab8 launchers/ TFC-RP.desktop
dl_verify a86f3ac28bbd902dfec74451034c68c01e74bbe6b6ec609014329fba17cc1224dc34942b103620109ef19336daa72e50dae1a0b25a1a2720445863427724d544 launchers/ TFC-RP-Tails.desktop
dl_verify cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e src/relay/ __init__.py
dl_verify d009954abc9fa78350f721458071aeec78b6cd8773db588626a248f0756d1e39b32a8c8c58c370e87e9e4eb63f0ea150a427ad2b92b641c8fd71117933059db8 src/relay/ client.py
dl_verify 02c764d58ef8d02f95050cec41aa41fa90938ea08e0107ed49d3ae73357115b48f23f291dfc238ec3e45b12a705089b5c2ad3a1b30f27abb0a4c7498271161a3 src/relay/ commands.py
dl_verify fa7350a1dafe7e27638cb505a30e43815e157b08fc26b700f15633ab34f8ac3ad782a4396cc6b9aba3b59cd48d2e37b6f72befcafbd14772e135bc40fc080050 src/relay/ onion.py
dl_verify fe666032c2448d87355931bef235085039087b701b7b79a74b23f663d06b78264686c53800729f8a4197bf419076d76d1fe3ae74afa9141180035a6b807f0bb5 src/relay/ server.py
dl_verify 380a78c8c0918e33fb6be39a4c51f51a93aa35b0cf320370d6fb892b5dade920e8ca4e4fe9d319c0a0cdc5b3a97f609fdee392b2b41175379200b1d793b75593 src/relay/ tcb.py
}
# PIP dependency file names
ARGON2=argon2_cffi-19.1.0-cp34-abi3-manylinux1_x86_64.whl
ASN1CRYPTO=asn1crypto-0.24.0-py2.py3-none-any.whl
CERTIFI=certifi-2018.11.29-py2.py3-none-any.whl
CFFI=cffi-1.12.2-cp36-cp36m-manylinux1_x86_64.whl
CHARDET=chardet-3.0.4-py2.py3-none-any.whl
CLICK=Click-7.0-py2.py3-none-any.whl
CRYPTOGRAPHY=cryptography-2.6.1-cp34-abi3-manylinux1_x86_64.whl
FLASK=Flask-1.0.2-py2.py3-none-any.whl
IDNA=idna-2.8-py2.py3-none-any.whl
ITSDANGEROUS=itsdangerous-1.1.0-py2.py3-none-any.whl
JINJA2=Jinja2-2.10-py2.py3-none-any.whl
MARKUPSAFE=MarkupSafe-1.1.1-cp36-cp36m-manylinux1_x86_64.whl
PYCPARSER=pycparser-2.19.tar.gz
PYNACL=PyNaCl-1.3.0-cp34-abi3-manylinux1_x86_64.whl
PYSERIAL=pyserial-3.4-py2.py3-none-any.whl
PYSOCKS=PySocks-1.6.8.tar.gz
REQUESTS=requests-2.21.0-py2.py3-none-any.whl
SIX=six-1.12.0-py2.py3-none-any.whl
STEM=stem-1.7.1.tar.gz
URLLIB3=urllib3-1.24.1-py2.py3-none-any.whl
VIRTUALENV=virtualenv-16.4.3-py2.py3-none-any.whl
WERKZEUG=Werkzeug-0.14.1-py2.py3-none-any.whl
download_tcb () {
dl_verify cec2bc228cd3ef6190ea5637e95b0d65ea821fc159ebb2441f8420af0cdf440b964bdffd8e0791a77ab48081f5b6345a59134db4b8e2752062d7c7f4348a4f0f '' tfc.py
dl_verify 0711aabf9c0a60f6bd4afec9f272ab1dd7e85f1a92ee03b02395f65ed51f130d594d82565df98888dbf3e0bd6dfa30159f8bd1afed9b5ed3b9c6df2766b99793 '' requirements.txt
dl_verify cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e src/transmitter/ __init__.py
dl_verify f91c0f616555725e0d2a4d8e2ee2bf39e1ebc4cbdf0a2547f4e4b5e4f1ee88743273cffb422a43dff98ba42772b18ceb4c270628f933392e27fa5cd6cae991ce src/transmitter/ commands.py
dl_verify f7cf493506a19b9732ae9f780aeb131342a47644632fcf88f0df01f0bda88252fdbad37a4b80e87f97e57feb50079ac2e5194598d745163846e30fdd6d32fe60 src/transmitter/ commands_g.py
dl_verify a1b6af28645df531be3a670375ce3a3da1a48b279d646f04b3c14cfbdf7006060955f33595a2963f98a495ec16dfe969325842495d8fbfae5f93e1459ed047c4 src/transmitter/ contact.py
dl_verify 184c35a32a3858893c67622a21fc7fdbd88bc61f82d4b655ad26ef008563cdb31430a3b713b92c98ea8d983ebadd0db6f9de3f9b1c07ac3dce4cf405aedf21ae src/transmitter/ files.py
dl_verify 019c178982f89b93ba69d26e60625a868380ac102b10351ac42c4d1321a45dd7186694d86028371185a096cce2e2bbe2d68210552439e34c3d5166f67b3578ee src/transmitter/ input_loop.py
dl_verify 742fba91ebd67dca247d03df4cf1820fc6b07e6966449282d7c4019f48cc902dc8dfc4120be9fdd6e61a4f00dd7753a08565a1b04395bc347064631d957c9d82 src/transmitter/ key_exchanges.py
dl_verify a59619b239b747298cc676a53aa6f87a9ef6511f5e84ec9e8a8e323c65ab5e9234cb7878bd25d2e763d5f74b8ff9fe395035637b8340a5fd525c3dc5ccbf7223 src/transmitter/ packet.py
dl_verify c2f77f8d3ebf12c3816c5876cd748dc4d7e9cd11fe8305d247783df510685a9f7a6157762d8c80afda55572dcae5fe60c9f39d5ec599a64d40928a09dd789c35 src/transmitter/ sender_loop.py
dl_verify 5d42f94bf6a6a4b70c3059fd827449af5b0e169095d8c50b37a922d70955bf79058adc10da77ebb79fb565830168dccb774547b6af513b7c866faf786da7c324 src/transmitter/ traffic_masking.py
dl_verify 22e8ba63c1391233612155099f5f9017d33918180f35c2552e31213862c76e3048d552f193f9cd3e4e9a240c0ef9bef4eabefe70b37e911553afeceede1133ca src/transmitter/ user_input.py
dl_verify 39a7b3e4457d9aa6d53cb53d38c3ed9adbd9e3250008b4e79b5a174b9227fd0fac6dad30e6e9b8fe3d635b25b2d4dfc049804df48d04f5dfcc1016b2e0a42577 src/transmitter/ windows.py
dl_verify cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e src/receiver/ __init__.py
dl_verify 35b035f2794b5d7618eeafd91781246a0100bac9ff6a1f643b16068d5b2dc2946c799e91beba77d94e4118f99d6d6653974ebd5d4008133131f3bf44a7a190fb src/receiver/ commands.py
dl_verify 09f921aaaeae96ee6e9ff787990864ba491d4f8b10c613ab2a01f74c00b62d570270323ea2f5dc08befd8aa7bf4be0c609f8dca1862e4465e521b8016dff14da src/receiver/ commands_g.py
dl_verify 7b1d45caf3faf28c484d7d8d0c96ff9ba6e840682b002e438eac620904d3ca39483009a079d300489d80e22025ba301fa483f235193de5b55a62e9dedb25967f src/receiver/ files.py
dl_verify eab31c334f09930f1167b15fae4d0126711d6fb0efbe5b8ca9e6e49bdbf0a9ca90279be6d2cd0080d588cf15d83686ba895ee60dc6a2bb2cba0f8ed8005c99eb src/receiver/ key_exchanges.py
dl_verify 2894c847fe3f69a829ed7d8e7933b4c5f97355a0d99df7125cee17fffdca9c8740b17aa512513ae02f8f70443d3143f26baea268ace7a197609f6b47b17360b7 src/receiver/ messages.py
dl_verify 57ebdf412723b5ab4f683afeda55f771ef6ef81fde5a18f05c470bca5262f9ff5eefd04a3648f12f749cec58a25fa62e6dfb1c35e3d03082c3ea464ef98168b1 src/receiver/ output_loop.py
dl_verify 3b84dbe9faffeab8b1d5953619e38aefc278ce4e603fd63beaee878af7b5daff46b8ed053ad56f11db164b1a3f5b694c6704c66588386b06db697281c9f81bbf src/receiver/ packet.py
dl_verify 1e5240d346a016b154faf877199227edf76e027d75e1e921f2024c5dd1d0a40c1de7e9197077786a21474a4bbf2c305d290214aacdea50f5abaeb39963ca08a6 src/receiver/ receiver_loop.py
dl_verify e84a92fa500492af0cc16038fd388c74c387334898b870e57bc599d1b95da85b579d50ba403cdfc82ce8d4d5765fc59e772796d54faa914d0b5874150428d762 src/receiver/ windows.py
}
download_common_tests () {
dl_verify cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e tests/ __init__.py
dl_verify c20421e2293f058df4e03dee49e609b51fc1d39e69b4c44dd7580f88a5b2bf0729261167cb69fb0ff81b3838e3edca0e408c5c6410e4d43d06d6c0aa1ef6f805 tests/ mock_classes.py
dl_verify 2acdcd76d44caa417e9d1b3439816c4f07f763258b8240aa165a1dc0c948d68c4d4d5ac5e0ff7c02a0abc594e3d23883463a9578455749c92769fea8ee81490d tests/ utils.py
dl_verify cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e tests/common/ __init__.py
dl_verify b62eeed36733c4ddcbb657cf7b2b37737f2a1b0b5d11c7720cb13703f09a99ccb0ead2a379caeff073955a31a5ae123342c925d93bbdd3338cfc8e4efb83fa38 tests/common/ test_crypto.py
dl_verify 7c222cc89248f09992def8fa30c32a9c98a9188c0b30af5f352eeef7b1932bdbf070a87879b47fe09c5cb6f19ad69038f3f8e906479773987e3f47908119f444 tests/common/ test_db_contacts.py
dl_verify cb8e18ba393d05e89c635d9ee22f0a15bc3a2039c68c85cc0e3eafe6d5855601b0c00473d6284bb33c4f88184932f2413793e185e5478e6cb456976bc79ad790 tests/common/ test_db_groups.py
dl_verify b894e5719bbf666b2e86f911b422c857c8e3795b527e346e510ff636c8b9733607c8e4115168584fba3fd6144d64b53b85f65cbba18b21c7dd80ff6e0de2a271 tests/common/ test_db_keys.py
dl_verify ed68245632dcab1a0ff63aa18408514a8c902ffdaa509ee5f9ae6a4f4b57fc11d64d5a4b70cc2884b8f428afb2ee23a586ba0595ad9b921f66b735ae90f257a2 tests/common/ test_db_logs.py
dl_verify 4e7436d7316d56f50f604a900eddc6427bb2fe348073848b1d7845484f51739686c781935118a18bdc52d7848a46f24909ea630306c46f518ec9b72768c3f648 tests/common/ test_db_masterkey.py
dl_verify 9eb4af866f9e5f1561401a3b62f924e8133464dfc3bb06f5e17dc18f2c09b785133ad38cf45d6d218ef7c5eadad4207d53ad6492e82754753ed568884ba4d383 tests/common/ test_db_onion.py
dl_verify 58ed5e733ac373a6c3d69ff7218207a60b9e4138a549da1a9de158d770f5b2514d7042e4ec7feed86966388523ace278797535a77be926f34c406ac3bc4e96ce tests/common/ test_db_settings.py
dl_verify a2036517d264bbaf2db9683e573000fa222067c6a8e3e72337e5b31c6554c1c33259f885540aad73f2cc454f8d0ef289df9557106e43ca4504fbad447c7e4c04 tests/common/ test_encoding.py
dl_verify 3dea267fa9b4361890f374157b137c9f76946f3289f4faf4b293814f26f9769fb202ec98c6fd044891b2a51a3bb69f67fec46022210ebaf27f7270e9dfc779eb tests/common/ test_exceptions.py
dl_verify 3d2d5077bc946a1327c64598a3d7bb30786a6ccb089f5fc67330b05a3d867c46deb0d5cec593927782e1bfbf7efe74678f6aa4b62a3306ba33fa406537ee6499 tests/common/ test_gateway.py
dl_verify dad966ace979c486134dd3146a50eb2d26054984ca8fcad203d61bf9ae804db04664df21e8293e307fbfe9c331cb59a06a46626fb36f445f50ef0fba63b5d93d tests/common/ test_input.py
dl_verify 23d4ddd293defa5ac3dd4eada0e8e9263203c51d9d0260d370a362557f93bb74dbfff75620463e4c046db3350b54ee75889398c58be16df8dcffb928220815a9 tests/common/ test_misc.py
dl_verify d595d7b6c0e05f1c99a89f8dc2e662eff4127f0ad0b807156a4e6f42c9113e33302c00b311e9fdfcfce20e1fea331da02bbeb41a7c44d8e05795317711da8225 tests/common/ test_output.py
dl_verify 32da13fe8c0377257a5dd94d54c9a439b20308dbba7cbbd42798119f759c46d5948901eac78be9c2db984a3fc9791213c4913c49997a951b7458124d350c4ee4 tests/common/ test_path.py
dl_verify 1e320f69f236daed5f0fb2e6fda4b5b533dd628fff7db0ee8a6b405efe3c24138a43f24b45693017219cd885779f5ae57d3523d264e077ba9d3b9d2027b95d9c tests/common/ test_reed_solomon.py
dl_verify 223f66cbb3ff0567eba27b66c3be30bd292b6ab1405ea52af79e4adafc87901212998576665bfee5e40e9ece7cc0d369179945be903ae36e5016942cf8c7fd2b tests/common/ test_statics.py
}
download_relay_tests () {
dl_verify cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e tests/relay/ __init__.py
dl_verify 9d132ad47baca57c5ce8d7f07222b6c778aec697c190c48b82c86c4eb8588de1935f2309994c05bcdfd44fe2d8d85d20980520aa22771f3846e5ce89ac68a232 tests/relay/ test_client.py
dl_verify 2431fd853a9a0089a3837f1e20455c2d58d96722d5b803fe9e3dc9aa09a3e5fbffa3b0fa9e3e723d81a2aa2abd6b19275777ba6eb541ec1b403854260dd14591 tests/relay/ test_commands.py
dl_verify b64b8cef7f1c4699e34344b6c6ba255d6ead3e8f4765dfd5fb88d2a676962a7d8231d261f68d3399d9eb65196ea0cefb31e6800aa6cc6662dcf0fd927be8c1a4 tests/relay/ test_onion.py
dl_verify 42e494245869a5e652fe6bdcf5e21d1a0299c9ad7485d075fe7cf1d2d53118b444d8563bbea837316f00cbfea31117d569cf4e8694443ab5b50f606369aec987 tests/relay/ test_server.py
dl_verify 54c3026e797e75c46ca1d1493f6a396643948f707f1bc8ad377b7c625fda39d4e0fa6b0ec0fe39149ef0250568caf954e22ae8ebe7e7ac00ca8802ffbc6ae324 tests/relay/ test_tcb.py
}
download_tcb_tests () {
dl_verify cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e tests/transmitter/ __init__.py
dl_verify 3bdb8fd64bb2b4070da025e0187e434b5178b645fb08ec822bdd732bac3824316a8d13ded95e5e7bf754dddda5ea1f5805b6c2a3b46e8100509d3f5b32d18278 tests/transmitter/ test_commands.py
dl_verify c2429b5ffc32aa4a6377fef726553d7c731672367cb4eaa338c0a2099b3fe0455fa8a79c4b86afd9077a53422403649bc1fcf7540e4f996dc0890819c34d9135 tests/transmitter/ test_commands_g.py
dl_verify 3baaa1dc6dff7771f6167d699a81c6cb14f7b0ea307b83797d342a95b21f89d9f2c21e54feac0474f61174a1c708b3f02bc0e3a6b0b504bda8c03cdd16e5fefe tests/transmitter/ test_contact.py
dl_verify 3d86131dfd775aea2ea7c0500759befac8a5d7fe35f590974b2af56da42929db927c0bd86a352a38412fbb79c2bff09d33271b26ebd9aead1bf2b702918cc02a tests/transmitter/ test_files.py
dl_verify 3bc9c3275353f49516fdb2bc9d9a86286c121f085d5382980e118b0ea123da9b9829edeb172448416f30955c9a1c1c3704f36cfa4700ced86c33009e362d0b69 tests/transmitter/ test_input_loop.py
dl_verify 284fefc2a4986948a5ee4de1f935482b43011347b5454ab685f4a79a1036d1bf0518db536381dfddf706318bb44b584db37cfbf8fa07aac1b631a278dfe298d7 tests/transmitter/ test_key_exchanges.py
dl_verify 0c16f45ad9fda006b58a45a7c9a4b9777cf05d08f59c9207addbc27936c29a6aa2aa59146f0ef32fb883a5e24211c5dbdfbf5ad9cf9b72e999e599e9eda0d2ef tests/transmitter/ test_packet.py
dl_verify 49aa0e761771893e8bc057c8e305eb8b5e7103df9a31c80eba333db739f0b2c521eca59901f35bf2e319360902c8be12b112a29948461b73662554bdf55bf6d4 tests/transmitter/ test_sender_loop.py
dl_verify fd4d6cf68a4e555a60caf8efc6ebc6747990ed1c582036c6cc92012c5af82b49b32c42398bf822fda8257e84c822bdb8158260164a8774aea72723ddbe99e639 tests/transmitter/ test_traffic_masking.py
dl_verify b71f7d8e3ce943dca2516f730c9919633f40568af905ac32e05b126e06f2c968c9b0b795cfad81a696511cd07534a0593ef1c9b5d5299ab88b2aff32b9059b64 tests/transmitter/ test_user_input.py
dl_verify 5be56563cab2c9007b6be7ff767778e3fb0df1d3374174d6b6ef7dc6d66b0c692cd798a0a77f156c3eb1ad979a3b532b681db97c4d1948ff8f85cd4a1fa2d51d tests/transmitter/ test_windows.py
dl_verify cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e tests/receiver/ __init__.py
dl_verify d80af580f76c3c58d72828ab190a055a03f7e74ae17ccbaa2f70dd94e01b7efd85888ac51eefed94d6671027660a8080600f2e1e908bd77622c36ba258a8936e tests/receiver/ test_commands.py
dl_verify dce0fe6cd05915f1a0450259a08e9935b077f9b3af61f315812834811a5c82095b72bea5e4b283fd2b8285e86f8ee4897d43f42a99261767b77841deb471d980 tests/receiver/ test_commands_g.py
dl_verify eb86007ca9b0cfeb4d364b1fb53409443c8b9f95770979c471b8462c1c41205b96afd357670a9cd5949e8360b738d9284a9e726ee6ab89e09a0306b105f1a720 tests/receiver/ test_files.py
dl_verify 01bf3274c675b8cbe6379f8fb1883e0d4ed6c69d164b2c6a44794786d21f2604efc262b34372dfb581607655e6e1e73c178660d3e97f4f2c9bdfb11e4166b2fd tests/receiver/ test_key_exchanges.py
dl_verify 7b9d27497d5765739ee435c02a379e792ad510dd893ff0d3871a7d3f97d196274921a2d26fa656edb5e7974a390155e7c1914135d3e1b6a82ed8f94d46263b66 tests/receiver/ test_messages.py
dl_verify affbd5bccd0fcd87bb50e13b497b1ba3c29ccec954fa53f62bff1a28baa7b35376f614fb54c922ed4605a37f6aa1463efff43a6267619b04a605a2181222e873 tests/receiver/ test_output_loop.py
dl_verify da34f5bdcd8b108b45e955d545954de32c9d8959c26e9d2e3104106139fb2fec69aabd6d5d127beacef7a09ee4f16aab0a92ee7d76b0fa6cd199e56032c12257 tests/receiver/ test_packet.py
dl_verify 717722763a41267929b6038abe859eececee20e68497d0f3c04268b6b8274a04e39e3f8d37d0928c8459c7ef52478176c933d8ec8b2bd0b93ff952a9b92b86f4 tests/receiver/ test_receiver_loop.py
dl_verify e6df26dc7b829b8536e454b99c6c448330fc5cff3ff12a5ebc70103a5fb15ab4fcb8fcb785e27201228b6f50ec610ef214bee4f2d5ff35995b4f00ae23217bc0 tests/receiver/ test_windows.py
}
download_local_test_specific () {
dl_verify dec90e113335d3274d87c3e12dda5a3205df57bd10c1e0532ecad34409520ce0596db21e989478836d4a0ea44da8c42902d2d8f05c9ad027a5560b4d0d5b9f13 '' dd.py
dl_verify 2f426d4d971d67ebf2f59b54fb31cff1a3e2567e343bfa1b3e638b8e0dffed5d0c3cac1f33229b98c302fee0cca3cc43567c2c615b5249a2db6d444e89e5fc70 launchers/ config
dl_verify 5d5351dd24d7afd4dc717835cfffee718fca707133127d1826ae099c66b0bddd878d104c1ad43546c8157807c984bd26b562e455fe219c1a00cf49df6bb73009 launchers/ TFC-local-test.desktop
}
download_tcb_specific () {
dl_verify 883d8df82240d840a215a4a946ba3a15def11b9c50f659e84bdb3543e484fed3e520c471cc10301743d38a7560c2672f1cfd22efa99de495685a90b8559db4ee launchers/ TFC-TxP.desktop
dl_verify c10fb76486ada483cfdd9e351b6d9b89907ae6ccccb32cf4299bc4e67ba565aac7b05a2d62a89c0146a1783c9d0616ee3c9a9660173a98ca6b03f72c3fbe6202 launchers/ TFC-RxP.desktop
}
download_dev_specific () {
dl_verify 2865708ab24c3ceeaf0a6ec382fb7c331fdee52af55a111c1afb862a336dd757d597f91b94267da009eb74bbc77d01bf78824474fa6f0aa820cd8c62ddb72138 '' requirements-dev.txt
}
download_venv () {
dl_verify f74b9aeb3a17ef86782afb8c2f621709801631430423d13025310809e6d14ffecb3805ee600cd3740287105b7a0e0726f8ced202e7b55be7bf5b79240e34d35d '' requirements-venv.txt
process_tcb_dependencies () {
sudo $1 /opt/tfc/${SIX}
sudo $1 /opt/tfc/${PYCPARSER}
sudo $1 /opt/tfc/${CFFI}
sudo $1 /opt/tfc/${ARGON2}
sudo $1 /opt/tfc/${PYNACL}
sudo $1 /opt/tfc/${PYSERIAL}
sudo $1 /opt/tfc/${ASN1CRYPTO}
sudo $1 /opt/tfc/${CRYPTOGRAPHY}
}
install_tcb () {
create_install_dir
dpkg_check
check_rm_existing_installation
sudo torify apt update
sudo torify apt install libssl-dev python3-pip python3-setuptools python3-tk net-tools -y
sudo apt update
sudo torsocks apt install git libssl-dev python3-pip python3-setuptools python3-tk net-tools -y
sudo torsocks git clone https://github.com/maqp/tfc.git /opt/tfc
download_venv
download_common
download_tcb
download_tcb_specific
#download_common_tests
#download_tcb_tests
create_user_data_dir
cd $HOME/tfc/
torify pip3 download -r /opt/tfc/requirements-venv.txt --require-hashes
torify pip3 download -r /opt/tfc/requirements.txt --require-hashes
verify_tcb_requirements_files
sudo torsocks python3.6 -m pip download --no-cache-dir -r /opt/tfc/requirements-venv.txt --require-hashes -d /opt/tfc/
sudo torsocks python3.6 -m pip download --no-cache-dir -r /opt/tfc/requirements.txt --require-hashes -d /opt/tfc/
kill_network
pip3 install setuptools-40.6.3-py2.py3-none-any.whl
pip3 install virtualenv-16.2.0-py2.py3-none-any.whl
sudo python3 -m virtualenv /opt/tfc/venv_tcb --system-site-packages --never-download
create_user_data_dir
verify_files
sudo python3.6 -m pip install /opt/tfc/${VIRTUALENV}
sudo python3.6 -m virtualenv /opt/tfc/venv_tcb --system-site-packages --never-download
. /opt/tfc/venv_tcb/bin/activate
sudo pip3 install six-1.12.0-py2.py3-none-any.whl
sudo pip3 install pycparser-2.19.tar.gz
sudo pip3 install cffi-1.11.5-cp36-cp36m-manylinux1_x86_64.whl
sudo pip3 install argon2_cffi-19.1.0-cp34-abi3-manylinux1_x86_64.whl
sudo pip3 install PyNaCl-1.3.0-cp34-abi3-manylinux1_x86_64.whl
sudo pip3 install pyserial-3.4-py2.py3-none-any.whl
sudo pip3 install asn1crypto-0.24.0-py2.py3-none-any.whl
sudo pip3 install cryptography-2.5-cp34-abi3-manylinux1_x86_64.whl
process_tcb_dependencies "python3.6 -m pip install"
deactivate
sudo mv /opt/tfc/tfc.png /usr/share/pixmaps/
sudo mv /opt/tfc/launchers/TFC-TxP.desktop /usr/share/applications/
sudo mv /opt/tfc/launchers/TFC-RxP.desktop /usr/share/applications/
# Remove unnecessary files
sudo rm -r /opt/tfc/.git/
sudo rm -r /opt/tfc/launchers/
sudo rm -r /opt/tfc/src/relay/
sudo rm -r /opt/tfc/tests/
sudo rm /opt/tfc/install.sh
sudo rm /opt/tfc/install.sh.asc
sudo rm /opt/tfc/pubkey.asc
sudo rm /opt/tfc/README.md
sudo rm /opt/tfc/dd.py
sudo rm /opt/tfc/relay.py
sudo rm /opt/tfc/requirements.txt
sudo rm /opt/tfc/requirements-dev.txt
sudo rm /opt/tfc/requirements-relay.txt
sudo rm /opt/tfc/requirements-venv.txt
rm $HOME/tfc/setuptools-40.6.3-py2.py3-none-any.whl
rm $HOME/tfc/virtualenv-16.2.0-py2.py3-none-any.whl
rm $HOME/tfc/six-1.12.0-py2.py3-none-any.whl
rm $HOME/tfc/pycparser-2.19.tar.gz
rm $HOME/tfc/cffi-1.11.5-cp36-cp36m-manylinux1_x86_64.whl
rm $HOME/tfc/argon2_cffi-19.1.0-cp34-abi3-manylinux1_x86_64.whl
rm $HOME/tfc/PyNaCl-1.3.0-cp34-abi3-manylinux1_x86_64.whl
rm $HOME/tfc/pyserial-3.4-py2.py3-none-any.whl
rm $HOME/tfc/asn1crypto-0.24.0-py2.py3-none-any.whl
rm $HOME/tfc/cryptography-2.5-cp34-abi3-manylinux1_x86_64.whl
sudo rm /opt/tfc/${VIRTUALENV}
sudo rm /opt/install.sh
sudo rm /opt/install.sh.asc
sudo rm /opt/pubkey.asc
process_tcb_dependencies "rm"
add_serial_permissions
@ -276,39 +198,51 @@ install_tcb () {
install_local_test () {
create_install_dir
dpkg_check
check_rm_existing_installation
tor_dependencies
sudo torify apt update
sudo torify apt install libssl-dev python3-pip python3-setuptools python3-tk tor deb.torproject.org-keyring terminator -y
sudo apt update
sudo torsocks apt install git libssl-dev python3-pip python3-setuptools python3-tk net-tools -y
sudo torsocks git clone https://github.com/maqp/tfc.git /opt/tfc
download_venv
download_common
download_tcb
download_relay
download_local_test_specific
#download_common_tests
#download_tcb_tests
#download_relay_tests
verify_tcb_requirements_files
sudo torsocks python3.6 -m pip download --no-cache-dir -r /opt/tfc/requirements-venv.txt --require-hashes -d /opt/tfc/
sudo torsocks python3.6 -m pip download --no-cache-dir -r /opt/tfc/requirements.txt --require-hashes -d /opt/tfc/
torify pip3 install -r /opt/tfc/requirements-venv.txt --require-hashes
sudo python3 -m virtualenv /opt/tfc/venv_tfc --system-site-packages
upgrade_tor
sudo torsocks apt install terminator -y
torsocks python3.6 -m pip install -r /opt/tfc/requirements-venv.txt --require-hashes
sudo python3.6 -m virtualenv /opt/tfc/venv_tfc --system-site-packages
. /opt/tfc/venv_tfc/bin/activate
sudo torify pip3 install -r /opt/tfc/requirements.txt --require-hashes
sudo torify pip3 install -r /opt/tfc/requirements-relay.txt --require-hashes
sudo torsocks python3.6 -m pip install -r /opt/tfc/requirements.txt --require-hashes
sudo torsocks python3.6 -m pip install -r /opt/tfc/requirements-relay.txt --require-hashes
deactivate
sudo mv /opt/tfc/tfc.png /usr/share/pixmaps/
sudo mv /opt/tfc/launchers/TFC-local-test.desktop /usr/share/applications/
create_terminator_config "/opt/tfc/launchers/config"
sudo mv /opt/tfc/tfc.png /usr/share/pixmaps/
sudo mv /opt/tfc/launchers/TFC-Local-test.desktop /usr/share/applications/
sudo mv /opt/tfc/launchers/terminator-config-local-test /opt/tfc/
modify_terminator_font_size "sudo" "/opt/tfc/terminator-config-local-test"
# Remove unnecessary files
sudo rm -r /opt/tfc/.git/
sudo rm -r /opt/tfc/launchers/
sudo rm -r /opt/tfc/tests/
sudo rm /opt/tfc/install.sh
sudo rm /opt/tfc/install.sh.asc
sudo rm /opt/tfc/pubkey.asc
sudo rm /opt/tfc/README.md
sudo rm /opt/tfc/requirements.txt
sudo rm /opt/tfc/requirements-dev.txt
sudo rm /opt/tfc/requirements-relay.txt
sudo rm /opt/tfc/requirements-venv.txt
sudo rm /opt/tfc/${VIRTUALENV}
sudo rm /opt/install.sh
sudo rm /opt/install.sh.asc
sudo rm /opt/pubkey.asc
process_tcb_dependencies "rm"
install_complete "Installation of TFC for local testing is now complete."
}
@ -317,27 +251,27 @@ install_local_test () {
install_developer () {
dpkg_check
tor_dependencies
sudo torify apt update
sudo torify apt install git libssl-dev python3-pip python3-setuptools python3-tk tor deb.torproject.org-keyring terminator -y
upgrade_tor
sudo torsocks apt install git libssl-dev python3-pip python3-setuptools python3-tk terminator -y
cd $HOME
torify git clone https://github.com/maqp/tfc.git
torsocks git clone https://github.com/maqp/tfc.git
cd $HOME/tfc/
torify pip3 install -r requirements-venv.txt --require-hashes
torsocks python3.6 -m pip install -r requirements-venv.txt --require-hashes
python3.6 -m virtualenv venv_tfc --system-site-packages
. /$HOME/tfc/venv_tfc/bin/activate
torify pip3 install -r requirements.txt --require-hashes
torify pip3 install -r requirements-relay.txt --require-hashes
torify pip3 install -r requirements-dev.txt
torsocks python3.6 -m pip install -r requirements.txt --require-hashes
torsocks python3.6 -m pip install -r requirements-relay.txt --require-hashes
torsocks python3.6 -m pip install -r requirements-dev.txt
deactivate
sudo cp $HOME/tfc/launchers/TFC-local-test.desktop /usr/share/applications/
sudo cp $HOME/tfc/tfc.png /usr/share/pixmaps/
modify_terminator_font_size "" "${HOME}/tfc/launchers/terminator-config-dev"
create_terminator_config "$HOME/tfc/launchers/config"
sudo cp $HOME/tfc/tfc.png /usr/share/pixmaps/
sudo cp $HOME/tfc/launchers/TFC-Dev.desktop /usr/share/applications/
sudo sed -i "s|\$HOME|${HOME}|g" /usr/share/applications/TFC-Dev.desktop
chmod a+rwx -R $HOME/tfc/
@ -348,32 +282,50 @@ install_developer () {
install_relay_ubuntu () {
create_install_dir
dpkg_check
check_rm_existing_installation
tor_dependencies
sudo torify apt update
sudo torify apt install libssl-dev python3-pip python3-setuptools tor deb.torproject.org-keyring -y
sudo apt update
sudo torsocks apt install git libssl-dev python3-pip python3-setuptools python3-tk net-tools -y
sudo torsocks git clone https://github.com/maqp/tfc.git /opt/tfc
download_venv
download_common
download_relay
#download_common_tests
#download_relay_tests
verify_tcb_requirements_files
torify pip3 install -r /opt/tfc/requirements-venv.txt --require-hashes
sudo python3.6 -m virtualenv /opt/tfc/venv_relay --system-site-packages
sudo torsocks python3.6 -m pip download --no-cache-dir -r /opt/tfc/requirements-venv.txt --require-hashes -d /opt/tfc/
sudo torsocks python3.6 -m pip download --no-cache-dir -r /opt/tfc/requirements.txt --require-hashes -d /opt/tfc/
upgrade_tor
torsocks python3.6 -m pip install -r /opt/tfc/requirements-venv.txt --require-hashes
sudo python3.6 -m virtualenv /opt/tfc/venv_relay --system-site-packages
. /opt/tfc/venv_relay/bin/activate
sudo torify pip3 install -r /opt/tfc/requirements-relay.txt --require-hashes
sudo torsocks python3.6 -m pip install -r /opt/tfc/requirements-relay.txt --require-hashes
deactivate
sudo mv /opt/tfc/tfc.png /usr/share/pixmaps/
sudo mv /opt/tfc/launchers/TFC-RP.desktop /usr/share/applications/
sudo rm -r /opt/tfc/.git/
sudo rm -r /opt/tfc/launchers/
sudo rm /opt/tfc/requirements-venv.txt
sudo rm -r /opt/tfc/src/receiver/
sudo rm -r /opt/tfc/src/transmitter/
sudo rm -r /opt/tfc/tests/
sudo rm /opt/tfc/dd.py
sudo rm /opt/tfc/install.sh
sudo rm /opt/tfc/install.sh.asc
sudo rm /opt/tfc/pubkey.asc
sudo rm /opt/tfc/README.md
sudo rm /opt/tfc/requirements.txt
sudo rm /opt/tfc/requirements-dev.txt
sudo rm /opt/tfc/requirements-relay.txt
sudo rm /opt/tfc/requirements-venv.txt
sudo rm /opt/tfc/tfc.py
sudo rm /opt/tfc/${VIRTUALENV}
sudo rm /opt/install.sh
sudo rm /opt/install.sh.asc
sudo rm /opt/pubkey.asc
process_tcb_dependencies "rm"
add_serial_permissions
@ -387,64 +339,98 @@ install_relay_tails () {
# Cache password so that Debian doesn't keep asking
# for it during install (it won't be stored on disk).
read_sudo_pwd
create_install_dir
echo ${sudo_pwd} | sudo -S apt update
echo ${sudo_pwd} | sudo -S apt install libssl-dev python3-pip python3-setuptools -y
download_common
download_relay
#download_common_tests
#download_relay_tests
t_sudo apt update
t_sudo apt install git libssl-dev python3-pip python3-setuptools -y
t_sudo git clone https://github.com/maqp/tfc.git /opt/tfc
create_user_data_dir
cd $HOME/tfc/
torify pip3 download -r /opt/tfc/requirements-relay.txt --require-hashes
t_sudo python3.6 -m pip download --no-cache-dir -r /opt/tfc/requirements-relay.txt --require-hashes -d /opt/tfc/
# Pyserial
echo ${sudo_pwd} | sudo -S python3.6 -m pip install pyserial-3.4-py2.py3-none-any.whl
t_sudo python3.6 -m pip install /opt/tfc/${PYSERIAL}
# Stem
echo ${sudo_pwd} | sudo -S python3.6 -m pip install stem-1.7.1.tar.gz
t_sudo python3.6 -m pip install /opt/tfc/${STEM}
# PySocks
echo ${sudo_pwd} | sudo -S python3.6 -m pip install PySocks-1.6.8.tar.gz
t_sudo python3.6 -m pip install /opt/tfc/${PYSOCKS}
# Requests
echo ${sudo_pwd} | sudo -S python3.6 -m pip install urllib3-1.24.1-py2.py3-none-any.whl
echo ${sudo_pwd} | sudo -S python3.6 -m pip install idna-2.8-py2.py3-none-any.whl
echo ${sudo_pwd} | sudo -S python3.6 -m pip install chardet-3.0.4-py2.py3-none-any.whl
echo ${sudo_pwd} | sudo -S python3.6 -m pip install certifi-2018.11.29-py2.py3-none-any.whl
echo ${sudo_pwd} | sudo -S python3.6 -m pip install requests-2.21.0-py2.py3-none-any.whl
t_sudo python3.6 -m pip install /opt/tfc/${URLLIB3}
t_sudo python3.6 -m pip install /opt/tfc/${IDNA}
t_sudo python3.6 -m pip install /opt/tfc/${CHARDET}
t_sudo python3.6 -m pip install /opt/tfc/${CERTIFI}
t_sudo python3.6 -m pip install /opt/tfc/${REQUESTS}
# Flask
echo ${sudo_pwd} | sudo -S python3.6 -m pip install Werkzeug-0.14.1-py2.py3-none-any.whl
echo ${sudo_pwd} | sudo -S python3.6 -m pip install MarkupSafe-1.1.0-cp36-cp36m-manylinux1_x86_64.whl
echo ${sudo_pwd} | sudo -S python3.6 -m pip install Jinja2-2.10-py2.py3-none-any.whl
echo ${sudo_pwd} | sudo -S python3.6 -m pip install itsdangerous-1.1.0-py2.py3-none-any.whl
echo ${sudo_pwd} | sudo -S python3.6 -m pip install Click-7.0-py2.py3-none-any.whl
echo ${sudo_pwd} | sudo -S python3.6 -m pip install Flask-1.0.2-py2.py3-none-any.whl
t_sudo python3.6 -m pip install /opt/tfc/${WERKZEUG}
t_sudo python3.6 -m pip install /opt/tfc/${MARKUPSAFE}
t_sudo python3.6 -m pip install /opt/tfc/${JINJA2}
t_sudo python3.6 -m pip install /opt/tfc/${ITSDANGEROUS}
t_sudo python3.6 -m pip install /opt/tfc/${CLICK}
t_sudo python3.6 -m pip install /opt/tfc/${FLASK}
# Cryptography
echo ${sudo_pwd} | sudo -S python3.6 -m pip install six-1.12.0-py2.py3-none-any.whl
echo ${sudo_pwd} | sudo -S python3.6 -m pip install asn1crypto-0.24.0-py2.py3-none-any.whl
echo ${sudo_pwd} | sudo -S python3.6 -m pip install pycparser-2.19.tar.gz
echo ${sudo_pwd} | sudo -S python3.6 -m pip install cffi-1.11.5-cp36-cp36m-manylinux1_x86_64.whl
echo ${sudo_pwd} | sudo -S python3.6 -m pip install cryptography-2.5-cp34-abi3-manylinux1_x86_64.whl
t_sudo python3.6 -m pip install /opt/tfc/${SIX}
t_sudo python3.6 -m pip install /opt/tfc/${ASN1CRYPTO}
t_sudo python3.6 -m pip install /opt/tfc/${PYCPARSER}
t_sudo python3.6 -m pip install /opt/tfc/${CFFI}
t_sudo python3.6 -m pip install /opt/tfc/${CRYPTOGRAPHY}
cd $HOME
rm -r $HOME/tfc
echo ${sudo_pwd} | sudo -S mv /opt/tfc/tfc.png /usr/share/pixmaps/
echo ${sudo_pwd} | sudo -S mv /opt/tfc/launchers/TFC-RP-Tails.desktop /usr/share/applications/
t_sudo mv /opt/tfc/tfc.png /usr/share/pixmaps/
t_sudo mv /opt/tfc/launchers/TFC-RP-Tails.desktop /usr/share/applications/
echo ${sudo_pwd} | sudo -S rm -r /opt/tfc/launchers/
echo ${sudo_pwd} | sudo -S rm /opt/tfc/requirements-relay.txt
t_sudo rm -r /opt/tfc/.git/
t_sudo rm -r /opt/tfc/launchers/
t_sudo rm -r /opt/tfc/src/receiver/
t_sudo rm -r /opt/tfc/src/transmitter/
t_sudo rm -r /opt/tfc/tests/
t_sudo rm /opt/tfc/dd.py
t_sudo rm /opt/tfc/install.sh
t_sudo rm /opt/tfc/install.sh.asc
t_sudo rm /opt/tfc/pubkey.asc
t_sudo rm /opt/tfc/README.md
t_sudo rm /opt/tfc/requirements.txt
t_sudo rm /opt/tfc/requirements-dev.txt
t_sudo rm /opt/tfc/requirements-relay.txt
t_sudo rm /opt/tfc/requirements-venv.txt
t_sudo rm /opt/tfc/tfc.py
t_sudo rm /opt/tfc/${PYSERIAL}
t_sudo rm /opt/tfc/${STEM}
t_sudo rm /opt/tfc/${PYSOCKS}
t_sudo rm /opt/tfc/${URLLIB3}
t_sudo rm /opt/tfc/${IDNA}
t_sudo rm /opt/tfc/${CHARDET}
t_sudo rm /opt/tfc/${CERTIFI}
t_sudo rm /opt/tfc/${REQUESTS}
t_sudo rm /opt/tfc/${WERKZEUG}
t_sudo rm /opt/tfc/${MARKUPSAFE}
t_sudo rm /opt/tfc/${JINJA2}
t_sudo rm /opt/tfc/${ITSDANGEROUS}
t_sudo rm /opt/tfc/${CLICK}
t_sudo rm /opt/tfc/${FLASK}
t_sudo rm /opt/tfc/${SIX}
t_sudo rm /opt/tfc/${ASN1CRYPTO}
t_sudo rm /opt/tfc/${PYCPARSER}
t_sudo rm /opt/tfc/${CFFI}
t_sudo rm /opt/tfc/${CRYPTOGRAPHY}
t_sudo rm /opt/install.sh
t_sudo rm /opt/install.sh.asc
t_sudo rm /opt/pubkey.asc
install_complete "Installation of the TFC Relay configuration is now complete."
}
t_sudo () {
# Execute command as root on Tails
echo ${sudo_pwd} | sudo -S $@
}
install_relay () {
if [[ "$(lsb_release -a 2>/dev/null | grep Tails)" ]]; then
@ -457,7 +443,7 @@ install_relay () {
read_sudo_pwd () {
read -s -p "[sudo] password for ${USER}: " sudo_pwd
until (echo ${sudo_pwd} | sudo -S echo '' 2>/dev/null)
until (t_sudo echo '' 2>/dev/null)
do
echo -e '\nSorry, try again.'
read -s -p "[sudo] password for ${USER}: " sudo_pwd
@ -478,32 +464,46 @@ check_tails_tor_version () {
}
tor_dependencies () {
upgrade_tor () {
available=($(apt-cache policy tor |grep Candidate | awk '{print $2}' |head -c 5))
required="0.3.5"
# If OS repository does not provide 0.3.5, add Tor Project's repository
if ! [[ "$(printf '%s\n' "$required" "$available" | sort -V | head -n1)" = "$required" ]]; then
# If repository does not provide 0.3.5, default to 0.3.5 experimental.
sudo sudo rm /etc/apt/sources.list.d/torproject.list 2>/dev/null || true
if [[ -f /etc/upstream-release/lsb-release ]]; then
# Linux Mint etc.
codename=($(cat /etc/upstream-release/lsb-release |grep DISTRIB_CODENAME |cut -c 18-))
else
# *buntu
codename=($(lsb_release -a 2>/dev/null |grep Codename |awk '{print $2}'))
sudo torsocks apt install apt-transport-tor -y
# Remove .list-file
if [[ -f /etc/apt/sources.list.d/torproject.list ]]; then
sudo rm /etc/apt/sources.list.d/torproject.list
fi
url="https://deb.torproject.org/torproject.org"
# Set codename
if [[ -f /etc/upstream-release/lsb-release ]]; then
codename=($(cat /etc/upstream-release/lsb-release |grep DISTRIB_CODENAME |cut -c 18-)) # Linux Mint etc.
else
codename=($(lsb_release -a 2>/dev/null |grep Codename |awk '{print $2}')) # *buntu
fi
echo "deb ${url} ${codename} main" | sudo tee -a /etc/apt/sources.list.d/torproject.list
echo "deb-src ${url} ${codename} main" | sudo tee -a /etc/apt/sources.list.d/torproject.list
echo "deb ${url} ${codename} main" | sudo tee -a /etc/apt/sources.list.d/torproject.list
echo "deb-src ${url} ${codename} main" | sudo tee -a /etc/apt/sources.list.d/torproject.list
# Add .list-file
# The authenticity of the Onion URL for deb.torproject.org can be confirmed from https://www.torproject.org/docs/debian.html.en#apt-over-tor
echo "deb tor://sdscoq7snqtznauu.onion/torproject.org ${codename} main" | sudo tee -a /etc/apt/sources.list.d/torproject.list
sudo cp -f /etc/apt/sources.list.d/torproject.list /etc/apt/sources.list.d/torproject.list.save
# SKS Keyservers' Onion Service URL is verifiable via https://sks-keyservers.net/overview-of-pools.php
gpg --keyserver hkp://jirk5u4osbsr34t5.onion --recv-keys A3C4F0F979CAA22CDBA8F512EE8CBC9E886DDD89
# Import key
torsocks wget -O - -o /dev/null http://sdscoq7snqtznauu.onion/torproject.org/A3C4F0F979CAA22CDBA8F512EE8CBC9E886DDD89.asc | gpg --import
gpg --export A3C4F0F979CAA22CDBA8F512EE8CBC9E886DDD89 | sudo apt-key add -
sudo apt update
sudo apt install tor -y
else
if grep -q "tor://" -R /etc/apt/; then
sudo apt update
else
sudo torsocks apt update
fi
fi
}
@ -554,67 +554,41 @@ c_echo () {
}
create_install_dir () {
check_rm_existing_installation () {
if [[ ${sudo_pwd} ]]; then
# Tails
if [[ -d "/opt/tfc" ]]; then
echo ${sudo_pwd} | sudo -S rm -r /opt/tfc
t_sudo rm -r /opt/tfc
fi
echo ${sudo_pwd} | sudo -S mkdir -p /opt/tfc 2>/dev/null
else
# *buntu
if [[ -d "/opt/tfc" ]]; then
sudo rm -r /opt/tfc
fi
sudo mkdir -p /opt/tfc 2>/dev/null
fi
}
create_user_data_dir () {
if [[ -d "$HOME/tfc" ]]; then
mv $HOME/tfc tfc_backup_at_$(date +%Y-%m-%d_%H-%M-%S)
if [[ -d "$HOME/tfc" ]]; then # If directory exists
if ! [[ -z "$(ls -A $HOME/tfc/)" ]]; then # If directory is not empty
mv $HOME/tfc $HOME/tfc_userdata_backup_at_$(date +%Y-%m-%d_%H-%M-%S) # Move to timestamped directory
fi
fi
mkdir -p $HOME/tfc 2>/dev/null
}
create_terminator_config () {
mkdir -p $HOME/.config/terminator 2>/dev/null
if [[ -f $HOME/.config/terminator/config ]]; then
backup_file="$HOME/.config/terminator/config_backup_at_$(date +%Y-%m-%d_%H-%M-%S)"
mv $HOME/.config/terminator/config ${backup_file} 2>/dev/null
clear
c_echo ''
c_echo "NOTICE"
c_echo "An existing configuration file for the Terminator"
c_echo "application was found and backed up into"
c_echo ''
c_echo "${backup_file}"
c_echo ''
c_echo "Press any key to continue."
read -n 1 -s -p ''
echo ''
fi
cp $1 $HOME/.config/terminator/config
sudo chown ${USER} -R $HOME/.config/terminator/
modify_terminator_font_size
}
modify_terminator_font_size () {
width=$(get_screen_width)
# Defaults in terminator config file are for 1920 pixels wide screens
if (( $width < 1600 )); then
sed -i -e 's/font = Monospace 11/font = Monospace 8/g' $HOME/.config/terminator/config # Normal config
sed -i -e 's/font = Monospace 10.5/font = Monospace 7/g' $HOME/.config/terminator/config # Data Diode config
$1 sed -i -e 's/font = Monospace 11/font = Monospace 8/g' $2 # Normal config
$1 sed -i -e 's/font = Monospace 10.5/font = Monospace 7/g' $2 # Data Diode config
elif (( $width < 1920 )); then
sed -i -e 's/font = Monospace 11/font = Monospace 9/g' $HOME/.config/terminator/config # Normal config
sed -i -e 's/font = Monospace 10.5/font = Monospace 8.5/g' $HOME/.config/terminator/config # Data Diode config
$1 sed -i -e 's/font = Monospace 11/font = Monospace 9/g' $2 # Normal config
$1 sed -i -e 's/font = Monospace 10.5/font = Monospace 8.5/g' $2 # Data Diode config
fi
}

View File

@ -1,16 +1,16 @@
-----BEGIN PGP SIGNATURE-----
iQIzBAABCAAdFiEE6o84umdLJC6ZRIRcmBNw6XJaD7oFAlxJHPgACgkQmBNw6XJa
D7oLRg//UR6DA9whTWVQPw5etk1zop9Xduhe+jC5xrYtmXbh4LxP5TxrYbdh6xYn
Tx5Y5sfBPBRkvJj6DX82wCPeliUGqpErGp+8xKzlU7/amGXbcYi9O1+s+p6gbA2d
8erh7WIE06lZ+A9aeFBmbVJw0RkSIwNHY7bN69SnOjqjq4xe/V6Z5hrkwnNMw13z
oGZzsU8YNtGeZWwgzQRdJ+8i+PuqqXI2Qbl8Yuba4SeWaVHR3Q08nWExRoRLN95m
cYCOlSOaHQf2uSIsCQAveOVdu1CkMueYMQAhEKgiNFQF/NfDzBrkCMCh1ymY3zHr
IAEn4PPhVc4czNP0nUTL5qmf6i0MRQNn6xyJJuC1NAuG7DRxQZ3Ww9SlwCUH5+fQ
2C0k6Trq81/2dXPz+I28dtbQWgW70NQLvBaeukfsUoCG1RCPMZYHeSpEsO8lgNTA
qOATpV725n26kfL00smfYnCdtlsjIwmA8w1AOlbreCl92mqzFHHKd8/VkmPXjmYA
yolU3LPysF1Lw/QTPdd0ez7SgkydE9/mDoF5lsgCjoG6mNECnhTjVghoWykb0gKz
lbHrdAVOlIGF0/hMxj+rQGWkPy90X6n77zjAOrvUGDJ52jEXqtQe/KaJrT5YFrU0
J6VRv5FX3TlFhD9c49mc5baETDGXydxyNT5wPgaB1v2i+kRF2xI=
=I6uM
iQIzBAABCAAdFiEE6o84umdLJC6ZRIRcmBNw6XJaD7oFAlxJJdcACgkQmBNw6XJa
D7olYg//e/0wmfZEkZXbmC4/uf6NHtltlqG1hDzzYilDdSmMe8kJNIEji2pPcYMZ
n8k9lNASYyJWx4LikxM25XsgLKAdT/WaqeFSS8/Lh7akWfSJ6tZhMTj1e+6gWEaL
AsZlINROmNzgTVz+KLLgMiedmMFKzAa93D8jbPwbzOzRB2yjdI19VEIYaeotHj2y
z/Zx8XpmfLYIVIbGLY6v5H5CPOGjHKfRSOje806AFpEAA29n80D45ghmYvQFNj4a
HTnsc+yM181Tod8+l4RZ2p+QqbpjsDTZyVpJUlUF4dTaPKzCThvT0KZSaIUBGtoR
CM8NmuOCRjSsK7lUHEtTDZ8jjkb5C6B2wjZrKq12dVDLyDNKicitop6VzQZdcM4Y
KYRCS5Et4m7Y9g9GhdQf7DFljD8nkwF9cvF47JIeGcq4eVqw4jsqi0KuxY1UXhib
1/uKEqy6WZ50MaaIosq5uBPzXGJQJ0nod+OWkEfT3EBU0qFnOdebrWB+T3vWn3kN
GwItVroiK7NCTGtWvZx5jQ+Wd4BAsoh29zGhE1mm7bjd8VTB/QuE/uVtGOyoFPYL
85oFCGVrQoPLH/Htu2mbT1YLC0bliSYd+ORG8ZMU+ijaf+hDQO20Vp9UbAzlzFZw
uTh189Ln9i/E3i2sNtcGwQVhtx7IgjNplrLLMcOepfd6qxP6ylc=
=PV9K
-----END PGP SIGNATURE-----

25
launchers/TFC-Dev.desktop Executable file
View File

@ -0,0 +1,25 @@
[Desktop Entry]
Version=1.19.03
Name=TFC-Dev
Comment=Local testing
Exec=terminator -m -u -g $HOME/tfc/launchers/terminator-config-dev -p tfc -l tfc-lr
Icon=tfc.png
Terminal=false
Type=Application
Categories=Network;Messaging;Security;
Actions=TFC-RL;TFC-DD-LR;TFC-DD-RL
[Desktop Action TFC-RL]
Name=TFC-RL
Exec=terminator -m -u -g $HOME/tfc/launchers/terminator-config-dev -p tfc -l tfc-rl
OnlyShowIn=Unity;
[Desktop Action TFC-DD-LR]
Name=TFC-DD-LR
Exec=terminator -m -u -g $HOME/tfc/launchers/terminator-config-dev -p tfc-dd -l tfc-dd-lr
OnlyShowIn=Unity;
[Desktop Action TFC-DD-RL]
Name=TFC-DD-RL
Exec=terminator -m -u -g $HOME/tfc/launchers/terminator-config-dev -p tfc-dd -l tfc-dd-rl
OnlyShowIn=Unity;

View File

@ -0,0 +1,25 @@
[Desktop Entry]
Version=1.19.03
Name=TFC-LR
Comment=Local testing
Exec=terminator -m -u -g /opt/tfc/terminator-config-local-test -p tfc -l tfc-lr
Icon=tfc.png
Terminal=false
Type=Application
Categories=Network;Messaging;Security;
Actions=TFC-RL;TFC-DD-LR;TFC-DD-RL
[Desktop Action TFC-RL]
Name=TFC-RL
Exec=terminator -m -u -g /opt/tfc/terminator-config-local-test -p tfc -l tfc-rl
OnlyShowIn=Unity;
[Desktop Action TFC-DD-LR]
Name=TFC-DD-LR
Exec=terminator -m -u -g /opt/tfc/terminator-config-local-test -p tfc-dd -l tfc-dd-lr
OnlyShowIn=Unity;
[Desktop Action TFC-DD-RL]
Name=TFC-DD-RL
Exec=terminator -m -u -g /opt/tfc/terminator-config-local-test -p tfc-dd -l tfc-dd-rl
OnlyShowIn=Unity;

View File

@ -1,5 +1,5 @@
[Desktop Entry]
Version=1.19.01
Version=1.19.03
Name=TFC-Relay
Exec=gnome-terminal -x bash -c "cd /opt/tfc && python3.5 'relay.py' || bash"
Icon=tfc.png

View File

@ -1,5 +1,5 @@
[Desktop Entry]
Version=1.19.01
Version=1.19.03
Name=TFC-Relay
Exec=gnome-terminal --disable-factory -x bash -c "cd /opt/tfc && source venv_relay/bin/activate && python3.6 'relay.py' && deactivate || bash"
Icon=tfc.png

View File

@ -1,5 +1,5 @@
[Desktop Entry]
Version=1.19.01
Version=1.19.03
Name=TFC-Receiver
Exec=gnome-terminal --disable-factory --maximize -x bash -c "cd /opt/tfc && source venv_tcb/bin/activate && python3.6 'tfc.py' -r && deactivate || bash"
Icon=tfc.png

View File

@ -1,5 +1,5 @@
[Desktop Entry]
Version=1.19.01
Version=1.19.03
Name=TFC-Transmitter
Exec=gnome-terminal --disable-factory --maximize -x bash -c "cd /opt/tfc && source venv_tcb/bin/activate && python3.6 'tfc.py' && deactivate || bash"
Icon=tfc.png

View File

@ -1,25 +0,0 @@
[Desktop Entry]
Version=1.19.01
Name=TFC-LR
Comment=Local testing
Exec=terminator -m -u -p tfc -l tfc-lr
Icon=tfc.png
Terminal=false
Type=Application
Categories=Network;Messaging;Security;
Actions=TFC-RL;TFC-DD-LR;TFC-DD-RL
[Desktop Action TFC-RL]
Name=TFC-RL
Exec=terminator -m -u -p tfc -l tfc-rl
OnlyShowIn=Unity;
[Desktop Action TFC-DD-LR]
Name=TFC-DD-LR
Exec=terminator -m -u -p tfc-dd -l tfc-dd-lr
OnlyShowIn=Unity;
[Desktop Action TFC-DD-RL]
Name=TFC-DD-RL
Exec=terminator -m -u -p tfc-dd -l tfc-dd-rl
OnlyShowIn=Unity;

View File

@ -0,0 +1,264 @@
[global_config]
geometry_hinting = False
suppress_multiple_term_dialog = True
[keybindings]
[layouts]
[[default]]
[[[child1]]]
parent = window0
type = Terminal
[[[window0]]]
parent = ""
type = Window
[[tfc-lr]]
[[[root]]]
fullscreen = False
maximised = True
order = 0
parent = ""
position = 0:0
title = TFC
type = Window
[[[child1]]]
order = 0
parent = root
ratio = 0.585
type = HPaned
[[[child2]]]
order = 0
parent = child1
ratio = 0.5
type = VPaned
[[[source_computer_emulator]]]
command = cd $HOME/tfc/ && source venv_tfc/bin/activate && python3.6 tfc.py -l && deactivate || bash
directory = ""
order = 1
parent = child2
profile = tfc
type = Terminal
[[[destination_computer_emulator]]]
command = cd $HOME/tfc/ && source venv_tfc/bin/activate && python3.6 tfc.py -l -r && deactivate || bash
directory = ""
order = 0
parent = child2
profile = tfc
type = Terminal
[[[networked_computer_emulator]]]
command = cd $HOME/tfc/ && source venv_tfc/bin/activate && python3.6 relay.py -l && deactivate || bash
directory = ""
order = 1
parent = child1
profile = tfc
type = Terminal
[[tfc-rl]]
[[[root]]]
fullscreen = False
maximised = True
order = 0
parent = ""
position = 0:0
title = TFC
type = Window
[[[child1]]]
order = 0
parent = root
ratio = 0.415
type = HPaned
[[[child2]]]
order = 1
parent = child1
ratio = 0.5
type = VPaned
[[[source_computer_emulator]]]
command = cd $HOME/tfc/ && source venv_tfc/bin/activate && python3.6 tfc.py -l && deactivate || bash
directory = ""
order = 1
parent = child2
profile = tfc
type = Terminal
[[[destination_computer_emulator]]]
command = cd $HOME/tfc/ && source venv_tfc/bin/activate && python3.6 tfc.py -l -r && deactivate || bash
directory = ""
order = 0
parent = child2
profile = tfc
type = Terminal
[[[networked_computer_emulator]]]
command = cd $HOME/tfc/ && source venv_tfc/bin/activate && python3.6 relay.py -l && deactivate || bash
directory = ""
order = 0
parent = child1
profile = tfc
type = Terminal
[[tfc-dd-lr]]
[[[root]]]
fullscreen = False
maximised = True
order = 0
parent = ""
position = 0:0
title = TFC
type = Window
[[[child1]]]
order = 0
parent = root
ratio = 0.545
type = HPaned
[[[child2]]]
order = 0
parent = child1
ratio = 0.5
type = VPaned
[[[child3]]]
order = 1
parent = child1
ratio = 0.14
type = HPaned
[[[child4]]]
order = 0
parent = child3
ratio = 0.5
type = VPaned
[[[source_computer_emulator]]]
command = cd $HOME/tfc/ && source venv_tfc/bin/activate && python3.6 tfc.py -l -d && deactivate || bash
directory = ""
order = 1
parent = child2
profile = tfc-dd
type = Terminal
[[[destination_computer_emulator]]]
command = cd $HOME/tfc/ && source venv_tfc/bin/activate && python3.6 tfc.py -l -r && deactivate || bash
directory = ""
order = 0
parent = child2
profile = tfc-dd
type = Terminal
[[[networked_computer_emulator]]]
command = cd $HOME/tfc/ && source venv_tfc/bin/activate && python3.6 relay.py -l -d && deactivate || bash
directory = ""
order = 1
parent = child3
profile = tfc-dd
type = Terminal
[[[source_computer_dd_emulator]]]
command = cd $HOME/tfc/ && python3.6 dd.py scnclr
directory = ""
order = 1
parent = child4
profile = tfc-dd
type = Terminal
[[[destination_computer_dd_emulator]]]
command = cd $HOME/tfc/ && python3.6 dd.py ncdclr
directory = ""
order = 0
parent = child4
profile = tfc-dd
type = Terminal
[[tfc-dd-rl]]
[[[root]]]
fullscreen = False
maximised = True
order = 0
parent = ""
position = 0:0
title = TFC
type = Window
[[[child1]]]
order = 0
parent = root
ratio = 0.451
type = HPaned
[[[child2]]]
order = 0
parent = child1
ratio = 0.867
type = HPaned
[[[child3]]]
order = 1
parent = child2
ratio = 0.5
type = VPaned
[[[child4]]]
order = 1
parent = child1
ratio = 0.5
type = VPaned
[[[source_computer_emulator]]]
command = cd $HOME/tfc/ && source venv_tfc/bin/activate && python3.6 tfc.py -l -d && deactivate || bash
directory = ""
order = 1
parent = child4
profile = tfc-dd
type = Terminal
[[[destination_computer_emulator]]]
command = cd $HOME/tfc/ && source venv_tfc/bin/activate && python3.6 tfc.py -l -r && deactivate || bash
directory = ""
order = 0
parent = child4
profile = tfc-dd
type = Terminal
[[[networked_computer_emulator]]]
command = cd $HOME/tfc/ && source venv_tfc/bin/activate && python3.6 relay.py -l -d && deactivate || bash
directory = ""
order = 0
parent = child2
profile = tfc-dd
type = Terminal
[[[source_computer_dd_emulator]]]
command = cd $HOME/tfc/ && python3.6 dd.py scncrl
directory = ""
order = 1
parent = child3
profile = tfc-dd
type = Terminal
[[[destination_computer_dd_emulator]]]
command = cd $HOME/tfc/ && python3.6 dd.py ncdcrl
directory = ""
order = 0
parent = child3
profile = tfc-dd
type = Terminal
[plugins]
[profiles]
[[default]]
background_color = "#3c3f41"
background_image = None
foreground_color = "#a1b6bd"
scrollback_infinite = True
show_titlebar = False
[[tfc]]
background_color = "#3c3f41"
background_image = None
use_system_font = False
font = Monospace 11
foreground_color = "#a1b6bd"
scrollback_infinite = True
show_titlebar = False
scrollbar_position = hidden
[[tfc-dd]]
background_color = "#3c3f41"
background_image = None
use_system_font = False
font = Monospace 10.5
foreground_color = "#a1b6bd"
scrollback_infinite = True
show_titlebar = False
scrollbar_position = hidden

29
pubkey.asc Normal file
View File

@ -0,0 +1,29 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
mQINBFxI9IABEADGN00o+hqjq0wp+Nt4TfkuP7+yj5kHbqnc2nGWXoWrdPMxATDf
5MRdhD9dc+pf/6McfcN7od3U6AyJFW1Tzs6yFzSFJI0EGdZsqfco87Za0VpiVn0i
XaoHZgtklgwK47pcJZe5+TeXWkBGB02OC0UZu3THdjL8JrqhtdSR7jxShHxpZcR1
4PCsPLcA7wJiWM6Xu8KYpjuDFkGSbpk4msuLN9E5M6DFspcTlrD2ZT2F2l/BnzVt
XARg+2PAnAddmmK7NXBTe1MWN2UJc8eer1RaWlovi5m3ziS+hvTtCkjgTrVDyZHc
Xi35XRRX+Zn1uijTBwOqPFDyUwo4VGnaOTkKyS5awYrAL0pCTQbKr119mKcv5bPp
pCm8Ld59/W/0XP8Fwpdyll1E3Nft6cPa3esyVaN1zdsmvxDo7rHp/C8I1bgEdAlj
VFFaOKpXXHiQ78Ey3JTzXfGq7LduHhKohOFQsBTsWlm1hYspaDVqxRLsIirQgHkW
5CYWYg0V+e7EsY4UzCQCA2KkaVon9hR8gYcbv/DzCDYds+RkyJY6dFC+hSyVuPtx
fUoH6K8fMhuYArBQU9mzz2qKlzT7Q5Z5xisOquFaCdorsoUxUpQ8Jzt1sqASyrZx
uI2de0QYQzC5E0ySdfgtQmEXwF+rjsT1zhD33/UbjBUuk0moNrXyLWFH4QARAQAB
tDhNYXJrdXMgT3R0ZWxhIChURkMgc2lnbmluZyBrZXkpIDxvb3R0ZWxhQGNzLmhl
bHNpbmtpLmZpPokCVAQTAQgAPhYhBOqPOLpnSyQumUSEXJgTcOlyWg+6BQJcSPSA
AhsDBQkB4TOABQsJCAcCBhUICQoLAgQWAgMBAh4BAheAAAoJEJgTcOlyWg+6L34P
/0c+32+Je9Sgt87a88CiND7oRCMznSSfNG0vaNu7+L2KxgHyM1WZ3QgCJdZdtqDX
CIATMpEAUXT+DPf/zmpSVn0TCY3/7LhRdxT7DuF6diyXVjGkiBLI66sqFv3mB19K
alc3GJmCq6AD63ubNofVcwfs1gH7aPI0a1szTN0eB1vxV/vRjiCbtD7W6QNcWuup
EjJCdZu4PEJyiFOIMucqGmYla9vVmFt/2t5cPGSwxYqEzFhmE100QcRHmzoOAztl
5rNnDHwte9/9MBYVKaR3Xg3id6zmAJrTzopjYNND2ULoXiOn9iwwGe6cmT2Hi9VR
bFK1rh7P8x9d/ZxojSG7QfNmrgJORSLUIczJlIECBoUmMJlb63H3TMgUQh5ui8mH
Z1YfAwodcO54ShmrNh1rRgtXvcrwwwlXf2IhYirZmophw9gIo6Rvo533m/RwGxuR
iRhteVRg9G5fCZtZhbrpmgaoKom+PyxX+a2IeN9DcnPYy2qYBER1DXdNenuo4S8W
DWgrs4T6Zc8AbSNroV2QKBY69LGMBR4LjRhtbdeJkv5f9BMzWM/cHbJfGOcFpxfD
FQ9S1Dj/eW4rGgmazljlQgdwr7wDj0rbzAR3Gs6bDBMn4UEXeqKADm6UMuFnXisq
ioBl7i5Wxnv66C5I4KgQtdOb5XszP9xU1hLuBKsIjFJa
=efYt
-----END PGP PUBLIC KEY BLOCK-----

View File

@ -33,7 +33,7 @@ from src.common.misc import ensure_dir, monitor_processes, process_arguments
from src.common.output import print_title
from src.common.statics import *
from src.relay.client import c_req_manager, client_manager, g_msg_manager
from src.relay.client import c_req_manager, client_scheduler, g_msg_manager
from src.relay.commands import relay_command
from src.relay.onion import onion_service
from src.relay.server import flask_server
@ -87,24 +87,24 @@ def main() -> None:
| commands) (Outgoing msg/file/public key)
|
Source |( gateway_loop > src_incoming > flask_server <
Computer | | |
| | |
| (Local keys, commands | |
| and copies of messages)| |
| |
Destination <|( dst_outgoing |
Computer | |
> g_msg_manager |
| |
| (Group (Incoming (URL token)|
| management messages) |
messages) |
|
client_mgr |
> client
flask_server on
Computer | | |
| | |
| (Local keys, commands | |
| and copies of messages)| |
| |
Destination <|( dst_outgoing |
Computer | |
> g_msg_manager |
| |
| (Group (Incoming (URL token)|
| management messages) |
messages) |
|
client_scheduler |
> client
flask_server on
contact's Networked
(Incoming message/file/public key/group management message) Computer
@ -162,15 +162,15 @@ def main() -> None:
EXIT_QUEUE: Queue() # EXIT/WIPE signal from `relay_command` to `main`
} # type: Dict[bytes, Queue]
process_list = [Process(target=gateway_loop, args=(queues, gateway )),
Process(target=src_incoming, args=(queues, gateway )),
Process(target=dst_outgoing, args=(queues, gateway )),
Process(target=client_manager, args=(queues, gateway, url_token_private_key)),
Process(target=g_msg_manager, args=(queues, )),
Process(target=c_req_manager, args=(queues, )),
Process(target=flask_server, args=(queues, url_token_public_key)),
Process(target=onion_service, args=(queues, )),
Process(target=relay_command, args=(queues, gateway, sys.stdin.fileno()) )]
process_list = [Process(target=gateway_loop, args=(queues, gateway )),
Process(target=src_incoming, args=(queues, gateway )),
Process(target=dst_outgoing, args=(queues, gateway )),
Process(target=client_scheduler, args=(queues, gateway, url_token_private_key)),
Process(target=g_msg_manager, args=(queues, )),
Process(target=c_req_manager, args=(queues, )),
Process(target=flask_server, args=(queues, url_token_public_key)),
Process(target=onion_service, args=(queues, )),
Process(target=relay_command, args=(queues, gateway, sys.stdin.fileno()) )]
for p in process_list:
p.start()

View File

@ -21,12 +21,12 @@ flask==1.0.2 --hash=sha512:0cca42400dc1019eb8c9fae32460967f64880f05627bdc
click==7.0 --hash=sha512:6b30987349df7c45c5f41cff9076ed45b178b444fca1ab1965f4ae33d1631522ce0a2868392c736666e83672b8b20e9503ae9ce5016dce3fa8f77bc8a3674130
itsdangerous==1.1.0 --hash=sha512:891c294867f705eb9c66274bd04ac5d93140d6e9beea6cbf9a44e7f9c13c0e2efa3554bdf56620712759a5cd579e112a782d25f3f91ba9419d60b2b4d2bc5b7c
jinja2==2.10 --hash=sha512:672c1a112f76f399600a069c5ee882d5fdf065ff25f6b729ec12a266d7ef6f638c26d5cc680db7b3a375d9e1ae7323aed3c2a49eb03fc39dd1a1ca8b0d658b63
markupsafe==1.1.0 --hash=sha512:103e80f9307ebb46178aad44d8d0fe36cfc019656ecb0249767d2cd249e8fbfc48ee9b2a5d7f25845312662ccf8b09dbee0a93f5ff573883eb40ec4511c89959
markupsafe==1.1.1 --hash=sha512:a82f797400b692e39efcb76f680c6988651381da7afdd764816a312d0e65cdc999a4bf97b474e89b03941d914ff1b73e8e8e8cd5b210bab157ce2c93a8a92ff2
werkzeug==0.14.1 --hash=sha512:0fa694cd71fa83d4a178e9f831fa9784c26e42feb5987e390ed88eb60ea2f829da5795206983236e3442ee1479dd4ca587d26dcb074a881d6d1b055bfc493c56
# Cryptography (Handles URL token derivation)
cryptography==2.5 --hash=sha512:820b591f3c838f86ee59e027986511abd3eb537bf8f5f4d2d499ab950a128bd2960c138616f0a6c36408fc72d6eefc27a14fddab9c5a6f4118e6bbad5e9d9d7f
cryptography==2.6.1 --hash=sha512:fcddaf49d784e91fab8437cf9a110a4c01f44d686154814c4d488198f61cb732b5db6b63ca66ec2955fe26aed70b5276f282efb0eed17684811a2092b9c7095a
asn1crypto==0.24.0 --hash=sha512:8d9bc344981079ac6c00e71e161c34b6f403e575bbfe1ad06e30a3bcb33e0db317bdcb7aed2d18d510cb1b3ee340a649f7f77a00d271fcf3cc388e6655b67533
cffi==1.11.5 --hash=sha512:32631c8a407f77c4580e75122a79d2f14fbc90ea958ecd9ff0a01c83280aec8b48ac202fc55c1d4aaf09975c9d1b8c21858666076ab554a71577c7a89236e87f
cffi==1.12.2 --hash=sha512:9b188b05fc0de50ac3cdeeb89c0dbc1c71cff9992906f8a7275efb7807f5c61c026d7c49aec9144f1ae4e6e1ea8e90241b71e0b4486a4059fcf24361c26e06e8
pycparser==2.19 --hash=sha512:7f830e1c9066ee2d297a55e2bf6db4bf6447b6d9da0145d11a88c3bb98505755fb7986eafa6e06ae0b7680838f5e5d6a6d188245ca5ad45c2a727587bac93ab5
six==1.12.0 --hash=sha512:326574c7542110d2cd8071136a36a6cffc7637ba948b55e0abb7f30f3821843073223301ecbec1d48b8361b0d7ccb338725eeb0424696efedc3f6bd2a23331d3

View File

@ -1,5 +1,2 @@
# Sub-dependencies are listed below dependencies
# Virtual environment (Used to create an isolated Python environment for TFC dependencies)
virtualenv==16.2.0 --hash=sha512:d08800652cf3c2a695971b54be32ded4bccd6b0223b8586c6e2348b8f60be2df7f47aed693f20e106fba11267819c81b7f7a5c3a75f89e36740c6639274a9a50
setuptools==40.6.3 --hash=sha512:bdbd2079d053409838690709389fa09cb498ee055c829e622d57c0b07069b0ec5065c64f5f76994c27fc8563ad47cd08eef843240539744223f5371b4d2daf1a
virtualenv==16.4.3 --hash=sha512:e0c132ae6b226845be2cd3d0c4fc2a59d98cdeaf668d4cb60484bbcff337a1ea28db85b832bf6fb4614fe21e08c55ebbb8c879f7069e5822ddefa324c2dde5f5

View File

@ -5,21 +5,21 @@ pyserial==3.4 --hash=sha512:8333ac2843fd136d5d0d63b527b37866f7d18afc3bb33c
# Argon2 (Derives keys that protect persistent user data)
argon2_cffi==19.1.0 --hash=sha512:77b17303a5d22fc35ac4771be5c710627c80ed7d6bf6705f70015197dbbc2b699ad6af0604b4517d1afd2f6d153058150a5d2933d38e4b4ca741e4ac560ddf72
cffi==1.11.5 --hash=sha512:32631c8a407f77c4580e75122a79d2f14fbc90ea958ecd9ff0a01c83280aec8b48ac202fc55c1d4aaf09975c9d1b8c21858666076ab554a71577c7a89236e87f
cffi==1.12.2 --hash=sha512:9b188b05fc0de50ac3cdeeb89c0dbc1c71cff9992906f8a7275efb7807f5c61c026d7c49aec9144f1ae4e6e1ea8e90241b71e0b4486a4059fcf24361c26e06e8
pycparser==2.19 --hash=sha512:7f830e1c9066ee2d297a55e2bf6db4bf6447b6d9da0145d11a88c3bb98505755fb7986eafa6e06ae0b7680838f5e5d6a6d188245ca5ad45c2a727587bac93ab5
six==1.12.0 --hash=sha512:326574c7542110d2cd8071136a36a6cffc7637ba948b55e0abb7f30f3821843073223301ecbec1d48b8361b0d7ccb338725eeb0424696efedc3f6bd2a23331d3
# PyNaCl (Handles TCB-side XChaCha20-Poly1305 symmetric encryption)
PyNaCl==1.3.0 --hash=sha512:c4017c38b026a5c531b15839b8d61d1fae9907ba1960c2f97f4cd67fe0827729346d5186a6d6927ba84f64b4cbfdece12b287aa7750a039f4160831be871cea3
# Duplicate sub-dependencies
# cffi==1.11.5 --hash=sha512:32631c8a407f77c4580e75122a79d2f14fbc90ea958ecd9ff0a01c83280aec8b48ac202fc55c1d4aaf09975c9d1b8c21858666076ab554a71577c7a89236e87f
# cffi==1.12.2 --hash=sha512:9b188b05fc0de50ac3cdeeb89c0dbc1c71cff9992906f8a7275efb7807f5c61c026d7c49aec9144f1ae4e6e1ea8e90241b71e0b4486a4059fcf24361c26e06e8
# pycparser==2.19 --hash=sha512:7f830e1c9066ee2d297a55e2bf6db4bf6447b6d9da0145d11a88c3bb98505755fb7986eafa6e06ae0b7680838f5e5d6a6d188245ca5ad45c2a727587bac93ab5
# six==1.12.0 --hash=sha512:326574c7542110d2cd8071136a36a6cffc7637ba948b55e0abb7f30f3821843073223301ecbec1d48b8361b0d7ccb338725eeb0424696efedc3f6bd2a23331d3
# Cryptography (Handles TCB-side X448 key exchange)
cryptography==2.5 --hash=sha512:820b591f3c838f86ee59e027986511abd3eb537bf8f5f4d2d499ab950a128bd2960c138616f0a6c36408fc72d6eefc27a14fddab9c5a6f4118e6bbad5e9d9d7f
cryptography==2.6.1 --hash=sha512:fcddaf49d784e91fab8437cf9a110a4c01f44d686154814c4d488198f61cb732b5db6b63ca66ec2955fe26aed70b5276f282efb0eed17684811a2092b9c7095a
asn1crypto==0.24.0 --hash=sha512:8d9bc344981079ac6c00e71e161c34b6f403e575bbfe1ad06e30a3bcb33e0db317bdcb7aed2d18d510cb1b3ee340a649f7f77a00d271fcf3cc388e6655b67533
# Duplicate sub-dependencies
# cffi==1.11.5 --hash=sha512:32631c8a407f77c4580e75122a79d2f14fbc90ea958ecd9ff0a01c83280aec8b48ac202fc55c1d4aaf09975c9d1b8c21858666076ab554a71577c7a89236e87f
# cffi==1.12.2 --hash=sha512:9b188b05fc0de50ac3cdeeb89c0dbc1c71cff9992906f8a7275efb7807f5c61c026d7c49aec9144f1ae4e6e1ea8e90241b71e0b4486a4059fcf24361c26e06e8
# pycparser==2.19 --hash=sha512:7f830e1c9066ee2d297a55e2bf6db4bf6447b6d9da0145d11a88c3bb98505755fb7986eafa6e06ae0b7680838f5e5d6a6d188245ca5ad45c2a727587bac93ab5
# six==1.12.0 --hash=sha512:326574c7542110d2cd8071136a36a6cffc7637ba948b55e0abb7f30f3821843073223301ecbec1d48b8361b0d7ccb338725eeb0424696efedc3f6bd2a23331d3

View File

@ -153,7 +153,8 @@ def argon2_kdf(password: str, # Password to derive the k
* https://github.com/P-H-C/phc-winner-argon2
https://github.com/hynek/argon2_cffi
"""
assert len(salt) == ARGON2_SALT_LENGTH
if len(salt) != ARGON2_SALT_LENGTH:
raise CriticalError("Invalid salt length.")
key = argon2.low_level.hash_secret_raw(secret=password.encode(),
salt=salt,
@ -214,7 +215,7 @@ class X448(object):
"""Derive the X448 shared key.
Since the shared secret is zero if contact's public key is zero,
this function asserts the public key is a valid non-zero
this function checks the public key is a valid non-zero
bytestring.
Because the raw bits of the X448 shared secret might not be
@ -222,8 +223,11 @@ class X448(object):
towards 0 or 1), the raw shared secret is passed through BLAKE2b
CSPRF to ensure uniformly random shared key.
"""
assert len(public_key) == TFC_PUBLIC_KEY_LENGTH
assert public_key != bytes(TFC_PUBLIC_KEY_LENGTH)
if len(public_key) != TFC_PUBLIC_KEY_LENGTH:
raise CriticalError("Invalid public key length.")
if public_key == bytes(TFC_PUBLIC_KEY_LENGTH):
raise CriticalError("Received zero public key.")
shared_secret = private_key.exchange(X448PublicKey.from_public_bytes(public_key))
return blake2b(shared_secret, digest_size=SYMMETRIC_KEY_LENGTH)
@ -286,7 +290,8 @@ def encrypt_and_sign(plaintext: bytes, # Plaintext to encrypt
* https://github.com/jedisct1/libsodium/tree/master/src/libsodium/crypto_aead/xchacha20poly1305/sodium
https://github.com/pyca/pynacl/blob/master/src/nacl/bindings/crypto_aead.py
"""
assert len(key) == SYMMETRIC_KEY_LENGTH
if len(key) != SYMMETRIC_KEY_LENGTH:
raise CriticalError("Invalid key length.")
nonce = csprng(XCHACHA20_NONCE_LENGTH)
ct_tag = nacl.bindings.crypto_aead_xchacha20poly1305_ietf_encrypt(plaintext, ad, nonce, key) # type: bytes
@ -317,7 +322,8 @@ def auth_and_decrypt(nonce_ct_tag: bytes, # Nonce + ciphertext + tag
processing the unsafe data and warn the user in which database the
issue was detected.
"""
assert len(key) == SYMMETRIC_KEY_LENGTH
if len(key) != SYMMETRIC_KEY_LENGTH:
raise CriticalError("Invalid key length.")
nonce, ct_tag = separate_header(nonce_ct_tag, XCHACHA20_NONCE_LENGTH)
@ -356,7 +362,8 @@ def byte_padding(bytestring: bytes # Bytestring to be padded
padding_len = PADDING_LENGTH - (len(bytestring) % PADDING_LENGTH)
bytestring += padding_len * bytes([padding_len])
assert len(bytestring) % PADDING_LENGTH == 0
if len(bytestring) % PADDING_LENGTH != 0: # pragma: no cover
raise CriticalError("Invalid padding length.")
return bytestring
@ -410,7 +417,7 @@ def csprng(key_length: int = SYMMETRIC_KEY_LENGTH) -> bytes:
Since the largest key generated in TFC is the 56-byte X448 private
key, GETRANDOM is guaranteed to always work. As a good practice
however, TFC asserts that the length of the obtained entropy is
however, TFC checks that the length of the obtained entropy is
correct.
The output of GETRANDOM is further compressed with BLAKE2b. The
@ -424,13 +431,18 @@ def csprng(key_length: int = SYMMETRIC_KEY_LENGTH) -> bytes:
size of the key to 64 bytes. This is not a problem for TFC because
again, the largest key it generates is the 56-byte X448 private key.
"""
assert key_length <= BLAKE2_DIGEST_LENGTH_MAX
if key_length > BLAKE2_DIGEST_LENGTH_MAX:
raise CriticalError("Invalid key size.")
entropy = os.getrandom(key_length, flags=0)
assert len(entropy) == key_length
if len(entropy) != key_length:
raise CriticalError("GETRANDOM returned invalid amount of entropy.")
compressed = blake2b(entropy, digest_size=key_length)
assert len(compressed) == key_length
if len(compressed) != key_length:
raise CriticalError("Invalid final key size.")
return compressed

View File

@ -24,12 +24,13 @@ import typing
from typing import Generator, Iterable, List, Optional, Sized
from src.common.crypto import auth_and_decrypt, encrypt_and_sign
from src.common.encoding import bool_to_bytes, pub_key_to_onion_address, str_to_bytes, pub_key_to_short_address
from src.common.encoding import bytes_to_bool, onion_address_to_pub_key, bytes_to_str
from src.common.misc import ensure_dir, get_terminal_width, separate_headers, split_byte_string
from src.common.output import clear_screen
from src.common.statics import *
from src.common.crypto import auth_and_decrypt, encrypt_and_sign
from src.common.encoding import bool_to_bytes, pub_key_to_onion_address, str_to_bytes, pub_key_to_short_address
from src.common.encoding import bytes_to_bool, onion_address_to_pub_key, bytes_to_str
from src.common.exceptions import CriticalError
from src.common.misc import ensure_dir, get_terminal_width, separate_headers, split_byte_string
from src.common.output import clear_screen
from src.common.statics import *
if typing.TYPE_CHECKING:
from src.common.db_masterkey import MasterKey
@ -273,7 +274,8 @@ class ContactList(Iterable, Sized):
df_blocks = [b for b in blocks if not b.startswith(self.dummy_contact.onion_pub_key)]
for block in df_blocks:
assert len(block) == CONTACT_LENGTH
if len(block) != CONTACT_LENGTH:
raise CriticalError("Invalid data in contact database.")
(onion_pub_key, tx_fingerprint, rx_fingerprint, kex_status_byte,
log_messages_byte, file_reception_byte, notifications_byte,

View File

@ -25,12 +25,13 @@ import typing
from typing import Callable, Generator, Iterable, List, Sized
from src.common.crypto import auth_and_decrypt, encrypt_and_sign
from src.common.encoding import bool_to_bytes, int_to_bytes, str_to_bytes, onion_address_to_pub_key, b58encode
from src.common.encoding import bytes_to_bool, bytes_to_int, bytes_to_str
from src.common.misc import ensure_dir, get_terminal_width, round_up, separate_header, separate_headers
from src.common.misc import split_byte_string
from src.common.statics import *
from src.common.crypto import auth_and_decrypt, encrypt_and_sign
from src.common.encoding import bool_to_bytes, int_to_bytes, str_to_bytes, onion_address_to_pub_key, b58encode
from src.common.encoding import bytes_to_bool, bytes_to_int, bytes_to_str
from src.common.exceptions import CriticalError
from src.common.misc import ensure_dir, get_terminal_width, round_up, separate_header, separate_headers
from src.common.misc import split_byte_string
from src.common.statics import *
if typing.TYPE_CHECKING:
from src.common.db_contacts import Contact, ContactList
@ -241,7 +242,7 @@ class GroupList(Iterable, Sized):
members. In addition, the group database stores the header that
contains four 8-byte values. The database plaintext length with
50 groups, each with 50 members is
4*8 + 50*( 1024 + 4 + 2*1 + 50*32)
4*8 + 50*(1024 + 4 + 2*1 + 50*32)
= 32 + 50*2630
= 131532 bytes.
@ -292,7 +293,8 @@ class GroupList(Iterable, Sized):
# Deserialize group objects
for block in blocks:
assert len(block) == bytes_per_group
if len(block) != bytes_per_group:
raise CriticalError("Invalid data in group database.")
name_bytes, group_id, log_messages_byte, notification_byte, ser_pub_keys \
= separate_headers(block, [PADDED_UTF32_STR_LENGTH, GROUP_ID_LENGTH] + 2*[ENCODED_BOOLEAN_LENGTH])

View File

@ -228,7 +228,8 @@ class KeyList(object):
df_blocks = [b for b in blocks if not b.startswith(self.dummy_id)]
for block in df_blocks:
assert len(block) == KEYSET_LENGTH
if len(block) != KEYSET_LENGTH:
raise CriticalError("Invalid data in key database.")
onion_pub_key, tx_mk, rx_mk, tx_hk, rx_hk, tx_harac_bytes, rx_harac_bytes \
= separate_headers(block, [ONION_SERVICE_PUBLIC_KEY_LENGTH] + 4*[SYMMETRIC_KEY_LENGTH] + [HARAC_LENGTH])

View File

@ -31,7 +31,7 @@ from typing import Dict, IO, List, Tuple, Union
from src.common.crypto import auth_and_decrypt, encrypt_and_sign
from src.common.encoding import b58encode, bytes_to_bool, bytes_to_timestamp, pub_key_to_short_address
from src.common.exceptions import FunctionReturn
from src.common.exceptions import CriticalError, FunctionReturn
from src.common.misc import ensure_dir, get_terminal_width, ignored, separate_header, separate_headers
from src.common.output import clear_screen
from src.common.statics import *
@ -169,7 +169,8 @@ def write_log_entry(assembly_packet: bytes, # Assembly pack
pt_bytes = onion_pub_key + timestamp + origin + assembly_packet
ct_bytes = encrypt_and_sign(pt_bytes, key=master_key.master_key)
assert len(ct_bytes) == LOG_ENTRY_LENGTH
if len(ct_bytes) != LOG_ENTRY_LENGTH:
raise CriticalError("Invalid log entry ciphertext length.")
ensure_dir(DIR_USER_DATA)
file_name = f'{DIR_USER_DATA}{settings.software_operation}_logs'

View File

@ -24,11 +24,12 @@ import typing
import nacl.signing
from src.common.crypto import auth_and_decrypt, csprng, encrypt_and_sign
from src.common.encoding import pub_key_to_onion_address, pub_key_to_short_address
from src.common.misc import ensure_dir
from src.common.output import phase
from src.common.statics import *
from src.common.crypto import auth_and_decrypt, csprng, encrypt_and_sign
from src.common.encoding import pub_key_to_onion_address, pub_key_to_short_address
from src.common.exceptions import CriticalError
from src.common.misc import ensure_dir
from src.common.output import phase
from src.common.statics import *
if typing.TYPE_CHECKING:
from src.common.db_masterkey import MasterKey
@ -65,8 +66,6 @@ class OnionService(object):
self.onion_private_key = self.new_onion_service_private_key()
self.store_onion_service_private_key()
assert len(self.onion_private_key) == ONION_SERVICE_PRIVATE_KEY_LENGTH
self.public_key = bytes(nacl.signing.SigningKey(seed=self.onion_private_key).verify_key)
self.user_onion_address = pub_key_to_onion_address(self.public_key)
@ -95,6 +94,9 @@ class OnionService(object):
onion_private_key = auth_and_decrypt(ct_bytes, self.master_key.master_key, database=self.file_name)
if len(onion_private_key) != ONION_SERVICE_PRIVATE_KEY_LENGTH:
raise CriticalError("Invalid Onion Service private key length.")
return onion_private_key
def new_confirmation_code(self) -> None:

View File

@ -147,12 +147,16 @@ def unicode_padding(string: str) -> str:
Database fields are padded with Unicode chars and then encoded
with UTF-32 to hide the metadata about plaintext field length.
"""
assert len(string) < PADDING_LENGTH
from src.common.exceptions import CriticalError
if len(string) >= PADDING_LENGTH:
raise CriticalError("Invalid input size.")
length = PADDING_LENGTH - (len(string) % PADDING_LENGTH)
string += length * chr(length)
assert len(string) == PADDING_LENGTH
if len(string) != PADDING_LENGTH: # pragma: no cover
raise CriticalError("Invalid padded string size.")
return string

View File

@ -73,7 +73,7 @@ def box_input(message: str, # Input prompt messag
validator: Optional[Callable] = None, # Input validator function
validator_args: Optional[Any] = None # Arguments required by the validator
) -> str: # Input from user
"""Display boxed input prompt with the title."""
"""Display boxed input prompt with a message."""
print_spacing(head)
terminal_width = get_terminal_width()
@ -129,7 +129,7 @@ def box_input(message: str, # Input prompt messag
def get_b58_key(key_type: str, # The type of Base58 key to be entered
settings: 'Settings', # Settings object
short_address: str = '' # The contact's short Onion address
) -> bytes: # The B58 decoded key
) -> bytes: # The Base58 decoded key
"""Ask the user to input a Base58 encoded key."""
if key_type == B58_PUBLIC_KEY:
clear_screen()

View File

@ -24,7 +24,7 @@ TFC = 'TFC'
TXP = 'Transmitter'
RXP = 'Receiver'
RP = 'Relay'
VERSION = '1.19.01'
VERSION = '1.19.03'
"""Identifiers

View File

@ -309,14 +309,14 @@ def key_ex_psk_rx(packet: bytes,
if any(k == bytes(SYMMETRIC_KEY_LENGTH) for k in [rx_mk, rx_hk]):
raise FunctionReturn("Error: Received invalid keys from contact.", head_clear=True)
contact.kex_status = KEX_STATUS_HAS_RX_PSK
contact_list.store_contacts()
keyset = key_list.get_keyset(onion_pub_key)
keyset.rx_mk = rx_mk
keyset.rx_hk = rx_hk
key_list.store_keys()
contact.kex_status = KEX_STATUS_HAS_RX_PSK
contact_list.store_contacts()
# Pipes protects against shell injection. Source of command's parameter is
# the program itself, and therefore trusted, but it's still good practice.
subprocess.Popen(f"shred -n 3 -z -u {pipes.quote(psk_file)}", shell=True).wait()

View File

@ -44,11 +44,11 @@ if typing.TYPE_CHECKING:
QueueDict = Dict[bytes, Queue]
def client_manager(queues: 'QueueDict',
gateway: 'Gateway',
url_token_private_key: X448PrivateKey,
unittest: bool = False
) -> None:
def client_scheduler(queues: 'QueueDict',
gateway: 'Gateway',
url_token_private_key: X448PrivateKey,
unittest: bool = False
) -> None:
"""Manage `client` processes."""
proc_dict = dict() # type: Dict[bytes, Process]
@ -155,12 +155,13 @@ def client(onion_pub_key: bytes,
if url_token_public_key_hex != cached_pk:
try:
public_key = bytes.fromhex(url_token_public_key_hex)
assert len(public_key) == TFC_PUBLIC_KEY_LENGTH
assert public_key != bytes(TFC_PUBLIC_KEY_LENGTH)
if len(public_key) != TFC_PUBLIC_KEY_LENGTH or public_key == bytes(TFC_PUBLIC_KEY_LENGTH):
raise ValueError
shared_secret = url_token_private_key.exchange(X448PublicKey.from_public_bytes(public_key))
url_token = hashlib.blake2b(shared_secret, digest_size=SYMMETRIC_KEY_LENGTH).hexdigest()
except (AssertionError, TypeError, ValueError):
except (TypeError, ValueError):
continue
cached_pk = url_token_public_key_hex # Update client's URL token public key

View File

@ -146,9 +146,12 @@ def stem_compatible_ed25519_key_from_private_key(private_key: bytes) -> str:
h = hashlib.sha512(sk).digest()
a = 2 ** (b - 2) + sum(2 ** i * bit(h, i) for i in range(3, b - 2))
k = b''.join([bytes([h[i]]) for i in range(b // 8, b // 4)])
assert len(k) == ONION_SERVICE_PRIVATE_KEY_LENGTH
return encode_int(a) + k
if len(private_key) != ONION_SERVICE_PRIVATE_KEY_LENGTH:
raise CriticalError("Onion Service private key had invalid length.")
expanded_private_key = expand_private_key(private_key)
return base64.b64encode(expanded_private_key).decode()
@ -213,7 +216,10 @@ def onion_service(queues: Dict[bytes, 'Queue']) -> None:
time.sleep(0.1)
if queues[ONION_KEY_QUEUE].qsize() > 0:
queues[ONION_KEY_QUEUE].get() # Discard re-sent private keys
_, c_code = queues[ONION_KEY_QUEUE].get()
m_print(["Onion Service is already running.", '',
f"Onion Service confirmation code (to Transmitter): {c_code.hex()}"], box=True)
if queues[ONION_CLOSE_QUEUE].qsize() > 0:
command = queues[ONION_CLOSE_QUEUE].get()

View File

@ -110,7 +110,7 @@ def flask_server(queues: 'QueueDict',
for url_token in pub_key_dict:
valid_url_token |= hmac.compare_digest(purp_url_token, url_token)
return valid_url_token
return valid_url_token
@app.route('/')
def index() -> str:

View File

@ -103,9 +103,9 @@ class TestArgon2KDF(unittest.TestCase):
self.assertIsInstance(key, bytes)
self.assertEqual(len(key), SYMMETRIC_KEY_LENGTH)
def test_invalid_salt_length_raises_assertion_error(self):
def test_invalid_salt_length_raises_critical_error(self):
for salt_length in [v for v in range(1000) if v != ARGON2_SALT_LENGTH]:
with self.assertRaises(AssertionError):
with self.assertRaises(SystemExit):
argon2_kdf('password', salt_length * b'a')
@ -137,7 +137,17 @@ class TestX448(unittest.TestCase):
def test_private_key_generation(self):
self.assertIsInstance(X448.generate_private_key(), X448PrivateKey)
def test_x448(self):
def test_incorrect_public_key_length_raises_critical_error(self):
sk = X448PrivateKey.generate()
for key in [key_len * b'a' for key_len in range(1, 100) if key_len != TFC_PUBLIC_KEY_LENGTH]:
with self.assertRaises(SystemExit):
X448.shared_key(sk, key)
def test_zero_public_key_raises_critical_error(self):
with self.assertRaises(SystemExit):
X448.shared_key(X448PrivateKey.generate(), bytes(TFC_PUBLIC_KEY_LENGTH))
def test_with_test_vectors(self):
sk_alice_ = X448PrivateKey.from_private_bytes(TestX448.sk_alice)
sk_bob_ = X448PrivateKey.from_private_bytes(TestX448.sk_bob)
@ -238,6 +248,13 @@ class TestXChaCha20Poly1305(unittest.TestCase):
self.assertEqual(auth_and_decrypt(self.ietf_nonce_ct_tag, self.key, ad=self.ad),
self.plaintext)
def test_invalid_key_size_raises_critical_error(self):
with self.assertRaises(SystemExit):
encrypt_and_sign(self.plaintext, self.key + b'a')
with self.assertRaises(SystemExit):
auth_and_decrypt(self.nonce_ct_tag, self.key + b'a')
def test_database_decryption_error_raises_critical_error(self):
with self.assertRaises(SystemExit):
auth_and_decrypt(self.nonce_ct_tag, key=bytes(SYMMETRIC_KEY_LENGTH), database='path/database_filename')
@ -291,10 +308,23 @@ class TestCSPRNG(unittest.TestCase):
key = csprng(key_size)
self.assertEqual(len(key), key_size)
def test_exceeding_hash_function_max_digest_size_raises_assertion_error(self):
with self.assertRaises(AssertionError):
def test_exceeding_hash_function_max_digest_size_raises_critical_error(self):
with self.assertRaises(SystemExit):
csprng(BLAKE2_DIGEST_LENGTH_MAX + 1)
@mock.patch('os.getrandom', side_effect=[(SYMMETRIC_KEY_LENGTH-1) * b'a',
(SYMMETRIC_KEY_LENGTH+1) * b'a'])
def test_invalid_entropy_raises_critical_error(self, _):
with self.assertRaises(SystemExit):
csprng()
csprng()
@mock.patch('src.common.crypto.blake2b', side_effect=[(SYMMETRIC_KEY_LENGTH-1) * b'a',
(SYMMETRIC_KEY_LENGTH+1) * b'a'])
def test_invalid_blake2b_digest_raises_critical_error(self, _):
with self.assertRaises(SystemExit):
csprng()
csprng()
class TestCheckKernelEntropy(unittest.TestCase):

View File

@ -22,7 +22,9 @@ along with TFC. If not, see <https://www.gnu.org/licenses/>.
import os
import unittest
from src.common.crypto import encrypt_and_sign
from src.common.db_contacts import Contact, ContactList
from src.common.misc import ensure_dir
from src.common.statics import *
from tests.mock_classes import create_contact, MasterKey, Settings
@ -96,6 +98,20 @@ class TestContactList(TFCTestCase):
for c in contact_list2:
self.assertIsInstance(c, Contact)
def test_invalid_content_raises_critical_error(self):
# Setup
invalid_data = b'a'
pt_bytes = b''.join([c.serialize_c() for c in self.contact_list.contacts + self.contact_list._dummy_contacts()])
ct_bytes = encrypt_and_sign(pt_bytes + invalid_data, self.master_key.master_key)
ensure_dir(DIR_USER_DATA)
with open(self.file_name, 'wb+') as f:
f.write(ct_bytes)
# Test
with self.assertRaises(SystemExit):
ContactList(self.master_key, self.settings)
def test_load_of_modified_database_raises_critical_error(self):
self.contact_list.store_contacts()

View File

@ -22,6 +22,7 @@ along with TFC. If not, see <https://www.gnu.org/licenses/>.
import os
import unittest
from src.common.crypto import encrypt_and_sign
from src.common.db_contacts import Contact, ContactList
from src.common.db_groups import Group, GroupList
from src.common.encoding import b58encode
@ -180,6 +181,21 @@ class TestGroupList(TFCTestCase):
group_list3 = GroupList(self.master_key, self.settings, self.contact_list)
self.assertEqual(len(group_list3.get_group('test_group_1').members), 10)
def test_invalid_content_raises_critical_error(self):
# Setup
invalid_data = b'a'
pt_bytes = self.group_list._generate_group_db_header()
pt_bytes += b''.join([g.serialize_g() for g in (self.group_list.groups + self.group_list._dummy_groups())])
ct_bytes = encrypt_and_sign(pt_bytes + invalid_data, self.master_key.master_key)
ensure_dir(DIR_USER_DATA)
with open(self.file_name, 'wb+') as f:
f.write(ct_bytes)
# Test
with self.assertRaises(SystemExit):
GroupList(self.master_key, self.settings, self.contact_list)
def test_load_of_modified_database_raises_critical_error(self):
self.group_list.store_groups()

View File

@ -22,9 +22,10 @@ along with TFC. If not, see <https://www.gnu.org/licenses/>.
import os.path
import unittest
from src.common.crypto import blake2b
from src.common.crypto import blake2b, encrypt_and_sign
from src.common.db_keys import KeyList, KeySet
from src.common.encoding import int_to_bytes
from src.common.misc import ensure_dir
from src.common.statics import *
from tests.mock_classes import create_keyset, MasterKey, nick_to_pub_key, Settings
@ -119,6 +120,20 @@ class TestKeyList(unittest.TestCase):
with self.assertRaises(SystemExit):
KeyList(self.master_key, self.settings)
def test_invalid_content_raises_critical_error(self):
# Setup
invalid_data = b'a'
pt_bytes = b''.join([k.serialize_k() for k in self.keylist.keysets + self.keylist._dummy_keysets()])
ct_bytes = encrypt_and_sign(pt_bytes + invalid_data, self.master_key.master_key)
ensure_dir(DIR_USER_DATA)
with open(self.file_name, 'wb+') as f:
f.write(ct_bytes)
# Test
with self.assertRaises(SystemExit):
KeyList(self.master_key, self.settings)
def test_generate_dummy_keyset(self):
dummy_keyset = self.keylist.generate_dummy_keyset()
self.assertEqual(len(dummy_keyset.serialize_k()), KEYSET_LENGTH)

View File

@ -202,6 +202,14 @@ class TestWriteLogEntry(unittest.TestCase):
def tearDown(self):
cleanup(self.unittest_dir)
def test_oversize_packet_raises_critical_error(self):
# Setup
assembly_p = F_S_HEADER + bytes(PADDING_LENGTH) + b'a'
# Test
with self.assertRaises(SystemExit):
write_log_entry(assembly_p, nick_to_pub_key('Alice'), self.settings, self.master_key)
def test_log_entry_is_concatenated(self):
for i in range(5):
assembly_p = F_S_HEADER + bytes(PADDING_LENGTH)

View File

@ -24,8 +24,9 @@ import unittest
from unittest import mock
from src.common.crypto import encrypt_and_sign
from src.common.db_onion import OnionService
from src.common.misc import validate_onion_addr
from src.common.misc import ensure_dir, validate_onion_addr
from src.common.statics import *
from tests.mock_classes import MasterKey
@ -63,6 +64,19 @@ class TestOnionService(unittest.TestCase):
self.assertIsInstance(onion_service2.onion_private_key, bytes)
self.assertEqual(onion_service.onion_private_key, onion_service2.onion_private_key)
@mock.patch('time.sleep', return_value=None)
def test_loading_invalid_onion_key_raises_critical_error(self, _):
# Setup
ct_bytes = encrypt_and_sign((ONION_SERVICE_PRIVATE_KEY_LENGTH +1) * b'a', self.master_key.master_key)
ensure_dir(DIR_USER_DATA)
with open(f'{DIR_USER_DATA}{TX}_onion_db', 'wb+') as f:
f.write(ct_bytes)
# Test
with self.assertRaises(SystemExit):
OnionService(self.master_key)
@mock.patch('time.sleep', return_value=None)
def test_load_of_modified_database_raises_critical_error(self, _):
# Write data to file

View File

@ -106,9 +106,9 @@ class TestUnicodePadding(unittest.TestCase):
# Verify removal of padding doesn't alter the string
self.assertEqual(string, padded[:-ord(padded[-1:])])
def test_oversize_msg_raises_assertion_error(self):
for s in range(PADDING_LENGTH, 260):
with self.assertRaises(AssertionError):
def test_oversize_msg_raises_critical_error(self):
for s in range(PADDING_LENGTH, 500):
with self.assertRaises(SystemExit):
unicode_padding(s * 'm')

View File

@ -33,7 +33,7 @@ from src.common.crypto import X448
from src.common.db_onion import pub_key_to_onion_address, pub_key_to_short_address
from src.common.statics import *
from src.relay.client import c_req_manager, client, client_manager, g_msg_manager, get_data_loop
from src.relay.client import c_req_manager, client, client_scheduler, g_msg_manager, get_data_loop
from tests.mock_classes import Gateway
from tests.utils import gen_queue_dict, nick_to_onion_address, nick_to_pub_key, tear_queues
@ -320,9 +320,9 @@ class TestGroupManager(unittest.TestCase):
tear_queues(queues)
class TestClientManager(unittest.TestCase):
class TestClientScheduler(unittest.TestCase):
def test_client_manager(self):
def test_client_scheduler(self):
queues = gen_queue_dict()
gateway = Gateway()
server_private_key = X448.generate_private_key()
@ -344,7 +344,7 @@ class TestClientManager(unittest.TestCase):
threading.Thread(target=queue_delayer).start()
self.assertIsNone(client_manager(queues, gateway, server_private_key, unittest=True))
self.assertIsNone(client_scheduler(queues, gateway, server_private_key, unittest=True))
tear_queues(queues)

View File

@ -19,6 +19,7 @@ You should have received a copy of the GNU General Public License
along with TFC. If not, see <https://www.gnu.org/licenses/>.
"""
import os
import threading
import time
import unittest
@ -31,7 +32,7 @@ import stem.control
from src.common.misc import validate_onion_addr
from src.common.statics import *
from src.relay.onion import get_available_port, onion_service, Tor
from src.relay.onion import get_available_port, onion_service, stem_compatible_ed25519_key_from_private_key, Tor
from tests.utils import gen_queue_dict
@ -75,6 +76,18 @@ class TestTor(unittest.TestCase):
tor.stop()
class TestTorKeyExpansion(unittest.TestCase):
def test_invalid_key_size_raises_critical_error(self):
for ks in [ks for ks in range(64) if ks != ONION_SERVICE_PRIVATE_KEY_LENGTH]:
with self.assertRaises(SystemExit):
stem_compatible_ed25519_key_from_private_key(os.urandom(ks))
def test_valid_key_size(self):
self.assertEqual(stem_compatible_ed25519_key_from_private_key(bytes(ONION_SERVICE_PRIVATE_KEY_LENGTH)),
'UEatwduoOIZ7K7v90MNCPli1eXC1JnqQ9XlgkkqH8VYKaoXqpkLayDVCS118jWN8AECMenPaZyt/SYUhQgtt0w==')
class TestOnionService(unittest.TestCase):
@mock.patch('shlex.split', return_value=['NOTICE', 'BOOTSTRAP', 'PROGRESS=100',