1.19.04
This commit is contained in:
parent
6ab753565e
commit
d2b170c558
|
@ -1,7 +1,7 @@
|
|||
language: python
|
||||
|
||||
python:
|
||||
- '3.6'
|
||||
- '3.7'
|
||||
|
||||
dist: xenial
|
||||
sudo: required
|
||||
|
|
13
README.md
13
README.md
|
@ -47,7 +47,8 @@ Encryption and decryption are separated on two isolated computers. The split
|
|||
[TCB](https://en.wikipedia.org/wiki/Trusted_computing_base)
|
||||
interacts with a third, Networked Computer, through unidirectional
|
||||
[serial](https://en.wikipedia.org/wiki/Universal_asynchronous_receiver/transmitter)
|
||||
interfaces. The direction of data flow is enforced with free hardware design
|
||||
interfaces. The direction of data flow between the computers is enforced with free
|
||||
hardware design
|
||||
[data diodes](https://en.wikipedia.org/wiki/Unidirectional_network),
|
||||
technology the certified implementations of which are typically found in
|
||||
critical infrastructure protection and government networks where classification
|
||||
|
@ -129,11 +130,11 @@ fundamental laws of physics.
|
|||
### Supported Operating Systems
|
||||
|
||||
#### Source/Destination Computer
|
||||
- *buntu 18.04 (or newer)
|
||||
- *buntu 19.04 (or newer)
|
||||
|
||||
#### Networked Computer
|
||||
- Tails (Debian Buster or newer)
|
||||
- *buntu 18.04 (or newer)
|
||||
- *buntu 19.04 (or newer)
|
||||
|
||||
|
||||
### More information
|
||||
|
@ -145,8 +146,6 @@ Hardware<Br>
|
|||
[Data diode (breadboard)](https://github.com/maqp/tfc/wiki/TTL-Data-Diode-(breadboard))<br>
|
||||
[Data diode (perfboard)](https://github.com/maqp/tfc/wiki/TTL-Data-Diode-(perfboard))<br>
|
||||
|
||||
Software<Br>
|
||||
[Installation](https://github.com/maqp/tfc/wiki/Installation)<br>
|
||||
[How to use](https://github.com/maqp/tfc/wiki/How-to-use)<br>
|
||||
|
||||
[Update log](https://github.com/maqp/tfc/wiki/Update-Log)<br>
|
||||
|
||||
For the rest of the articles, see [TFC wiki](https://github.com/maqp/tfc/wiki).
|
4
dd.py
4
dd.py
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
@ -123,7 +123,7 @@ def process_arguments() -> Tuple[str, int, int]:
|
|||
|
||||
except (IndexError, KeyError):
|
||||
clear_screen()
|
||||
print("\nUsage: python3.6 dd.py [OPTION]\n\n"
|
||||
print("\nUsage: python3.7 dd.py [OPTION]\n\n"
|
||||
"\nMandatory arguments"
|
||||
"\n Argument Simulate data diodes between..."
|
||||
"\n scnclr Source Computer and Networked Computer (left to right)"
|
||||
|
|
262
install.sh
262
install.sh
|
@ -29,94 +29,94 @@ compare_digest () {
|
|||
|
||||
|
||||
verify_tcb_requirements_files () {
|
||||
compare_digest a27d0a626f0963ee962a9bd9df98f157dcbb1fc7abf30322d8657f5db8b182f3ed7a3f2b736880e32121fb9bc6dce29cd7cb78cb77d5a82e42cadbacbe6b2651 '' requirements.txt
|
||||
compare_digest 2191cd9f1bb40dee172ad885edb1402d3e2a961ee5ae3eda607fb84d4b60995687cb3eededb6db326ca64919077481c26f3516e9c1153c069df5ee7307aa58a7 '' requirements.txt
|
||||
compare_digest d5e6ef9d3743cc81440d0f1024389ce0c10c23771f3aee95886731f1a7cbdf64fa5e0245d370382f8988d3c1758d0548e384e05635216ded3552dee80a03b16a '' requirements-venv.txt
|
||||
}
|
||||
|
||||
verify_files () {
|
||||
compare_digest dec90e113335d3274d87c3e12dda5a3205df57bd10c1e0532ecad34409520ce0596db21e989478836d4a0ea44da8c42902d2d8f05c9ad027a5560b4d0d5b9f13 '' dd.py
|
||||
compare_digest f7b8c252517ec7f59d636c1290fa6083b6b90e771f3e40fc961c289bd3bae0a32497eebe4fef9f8e4cae2998bf4aa32f0022e216ce5bcfb322485143617f7b65 '' dd.py
|
||||
compare_digest d361e5e8201481c6346ee6a886592c51265112be550d5224f1a7a6e116255c2f1ab8788df579d9b8372ed7bfd19bac4b6e70e00b472642966ab5b319b99a2686 '' LICENSE
|
||||
compare_digest 04bc1b0bf748da3f3a69fda001a36b7e8ed36901fa976d6b9a4da0847bb0dcaf20cdeb884065ecb45b80bd520df9a4ebda2c69154696c63d9260a249219ae68a '' LICENSE-3RD-PARTY
|
||||
compare_digest 1dd17740ffb6bd4da5de8b00da8e0e1e79d9c81771bf62dee9d3e85e3fd6b1254ec1d011c217b0102f08384c03b63a002b6cddc691a2d03eaa3faddd8cef5a15 '' relay.py
|
||||
compare_digest f8b574dd16eb867dd43b468ac96b7fdee699dc642ad8b412b89d1e4538cc3ec46b49dc3fd6cd8e6d30d838e0f7f1955651d42d82a44450a8567053bda7b523d0 '' relay.py
|
||||
compare_digest 2865708ab24c3ceeaf0a6ec382fb7c331fdee52af55a111c1afb862a336dd757d597f91b94267da009eb74bbc77d01bf78824474fa6f0aa820cd8c62ddb72138 '' requirements-dev.txt
|
||||
compare_digest 6a27003e7feb81a2ef7a7ffb114d7130120cad53a2687f7ba7200eb3f65156ad0dc1dcb713234593df7dac9da047c4e1e7306f58ddbaae4751437c63c309c1e4 '' requirements-relay.txt
|
||||
compare_digest 54bac0d6a9198d57a2e08c012dee46af5d34ccc6577ab834900941dcbeba36c0b3e1222acfcc76a68b3480c173dbf82267ea77b54f432e1e8bfd72d22a898f0d '' requirements-relay.txt
|
||||
compare_digest 6d93d5513f66389778262031cbba95e1e38138edaec66ced278db2c2897573247d1de749cf85362ec715355c5dfa5c276c8a07a394fd5cf9b45c7a7ae6249a66 '' tfc.png
|
||||
compare_digest cec2bc228cd3ef6190ea5637e95b0d65ea821fc159ebb2441f8420af0cdf440b964bdffd8e0791a77ab48081f5b6345a59134db4b8e2752062d7c7f4348a4f0f '' tfc.py
|
||||
compare_digest d30e4ea7758a2fa3b704f61b0bec3c78af7830f5b1518473bf629660de4c5138df043a2542f174d790b4bda282edb1f8b536913bb9d9f62fb0c6faf87f255ee0 '' 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 d4f503df2186db02641f54a545739d90974b6d9d920f76ad7e93fe1a38a68a85c167da6c19f7574d11fbb69e57d563845d174d420c55691bc2cd75a1a72806dc launchers/ terminator-config-local-test
|
||||
compare_digest 6fac0ac5a90783a6a57bb1819c026935fb1fc830c92fc77df9cec2cd3aff4c7ff30d6cd798a2ce055cf682f3199248ec687f3a500182e2de4e8ea18706e46d00 launchers/ TFC-Local-test.desktop
|
||||
compare_digest 03a205361c7b9521fd8cb08daed455ccd6793609e9896cdd9079379558f642d44c2d3e69415ac7f403ac7e8008eaf6367aeadb44b9be591624e7992518939af5 launchers/ TFC-RP.desktop
|
||||
compare_digest de9bd3e7dfe911f39630853244ae82ac1ea6fc52524a6e2ad85eba1bd4f84f74177d622117adcb6db696af48c9e2fe099f0a59a2284f8e5a2b5defd9084be1f3 launchers/ TFC-RP-Tails.desktop
|
||||
compare_digest 9a9fe7a8020669cc89e71dc8404868d51ad81af278840e117319f156c55f9b6f11c9590e9b3d2764809e2b7b207d44ef80c3b2e89c227764524db903d1726c35 launchers/ TFC-RxP.desktop
|
||||
compare_digest a128edbaba75155697ebc54af922d2f200a8aa2eee9d1acb039d39b18908deb3bea417abd058049ea8e1e7a217f838ce80204eda73ca74e545fa5cab3a47c09e 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 10f94d1eb194a1137e9099ff77b936f4935cab7ab5307e38d9bb5dde183fa431356cffaa8f04772df51e9f8b1becb5d46254a35b4d1550ec368bd2d68043db18 src/common/ crypto.py
|
||||
compare_digest c1e4b2a8266876ccbbb63f8008725a3a14aa841b70b4309c5b23153c963cc5ede855174c7ba92d3968e284ce0538ddc85e81de16c2d9a225b70708aa1753243d src/common/ db_contacts.py
|
||||
compare_digest 2cd737ece390a5d4f5d5579d49c4afaeebd7e9d40309f8dd08340c881c1e014fc350190520e6e00a2794c1d91df5e77fcead527f804c3e8a7cfd810e6c5f7dde src/common/ db_groups.py
|
||||
compare_digest a71345dea4e9fcbe7131e3692ec5687e706e069f7aada56856837675fec7b2ee393ae4221fe8fd08f5c359a5f506dbced04586f9b908a27d2f81c99fa42d3b23 src/common/ db_keys.py
|
||||
compare_digest dee2bcd41c4999890ea4643c4661fabd4fd35bcf04f165faf6409b60071736290a331ef1834292e08290ccf6c6bce980842f6abbf9b52300e15613a18f4efaca src/common/ db_logs.py
|
||||
compare_digest a29077738fce281fd540df3812307c02b5b8af62cb62234b9f0c20033775fb834f26d00f47cb71e0fc68656375cfa7e66eb7e510e0e2ed1a56ea3e651c7b680e src/common/ db_masterkey.py
|
||||
compare_digest 5befbe864e2b09125be2b04cdfee8d13e7616715fc20a0fa06da270e34b555602b2df825fd429059056b2beb1497c50dafdc682d59a43a483837445861647e9d src/common/ db_onion.py
|
||||
compare_digest 404aa061de5a33b910cce126ff55ff28999ea981a971cbd2d198cfb3cf6d186646cc02727ddd8312bfedf5662b2302d46af92175682891f288b06d7c18f1819f src/common/ db_settings.py
|
||||
compare_digest 13c203b565880ab83f8b54fa2474c17c9b5cea890a1839666515600f876bdf749132b63e48e56d3d43a7042e29acb7d14fd2aa0f5f448622f5eaf8bd933c6b01 src/common/ encoding.py
|
||||
compare_digest 043a5518a6afb2f3e5c445d26d7f0a3bbcd80cc26679b17fc3342671759cfc9e3f23ba68e4479c795c7455cec73fe7b332febde29944c1e1f69455780ca1f036 src/common/ exceptions.py
|
||||
compare_digest bcf070f6bc6a6dce043df981e799b05d676607a218544391653c4b1e50f94a548106b5e564d79fc9567a404e305cd0e209bc5690aec30e200b143e7078a4ea07 src/common/ gateway.py
|
||||
compare_digest 56639c5be9e89abb3305bda4d96fddd74490f125a68ae5cf1de2e0d4dee7bf04b114ce1e52b540484b89493aca772122cbb253ea15a78381a56c29c6a50edff9 src/common/ input.py
|
||||
compare_digest 55c7ae84935b2ad7f80277cd30fe5297fa9404f3ecd0e8c9fa76f640f4277e38bdd1e61094a2b4eb1b787f0adfdb76d13c06799380e72513ef4ff22bba95d98b src/common/ misc.py
|
||||
compare_digest c06045121eeb8a4210f153cdbecd83544e00796a704498f6381be2d02be422e013fe98e01f2821e06a35d281423c9cf4dc9c551c8b3a14578b7ba27b031d83eb src/common/ output.py
|
||||
compare_digest a62724cb2e2ac0f63371fc0dc4be5541c9d9eaf1c8441c69001485f9057bbea16f31b9093ad6f9f6b4d1ed5a70136b8881bb7c09c63b2631a6ce052b2e914253 src/common/ path.py
|
||||
compare_digest 9c05675ecd3a8a436d24469adbb5ce821632e4fae95452d06ffad92b692a9950d1a0bf4e5875b2f0f6e6fa592fd25f11382ff2354b78d19a84a720aa324005ef src/common/ reed_solomon.py
|
||||
compare_digest af7b79b7f7f5b677d9804bc222c3109f911286bb4ee79cc66ec75a9115f9439a8b959dbb6bd51f14e59c65b500827edf431a41ff5bece33ea6b75ff39dbfe5b9 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 908f0083b503251baf38997a603efb04987c4ebb74bb3caffb6d9fbe77efff0e177626d5e639f8564a417c7a8c4164a76fecdd414f96a0f89af3cd09bac3472b src/receiver/ commands.py
|
||||
compare_digest 760edaa44ff6175612b02f95b02b291ae369733a18cc5f87d525b46bcebc35c8a2d169a47962417eab434cf26ea6d5bfcd8894153fae668bb4a8cf2ceb8871f0 src/receiver/ commands_g.py
|
||||
compare_digest 5a728d57c954a1616848fa4839058f28de8960686efa2670549fe98b0b08b28fb99dcc1d15c5fe405615ea69f708845005cd596cfca5345bdde3a33aead2be8c src/receiver/ files.py
|
||||
compare_digest ed73dece8ccd6f71874ffb8d1e2bdae13621ff7bc44f656b84053dcc199773c9c0533ef12d87f17b7b16551fafef6356cb237b9771487ddceed5763b63059eae src/receiver/ key_exchanges.py
|
||||
compare_digest 65307a0ea2c9ae69859cc8ef62a5d7e45c27bdf5a4ec44db704df143ce3630fdc077fafc7fd4cfc0cd922f350f49f0aa0a880192c40c614b6d3117804ea683ae src/receiver/ messages.py
|
||||
compare_digest e1b568104da0f3c3cfa53d379a7b68d8e89718e24db51f0e1deade5e2183523bca4eb673885820721d561e538eb75df1df289fd7d7a25b3c9fce1074b5e14106 src/receiver/ output_loop.py
|
||||
compare_digest 9e5a15e46b39d39afabac1d8facbf542afdb201084e319e8a098ee5b46a0fe42e59767a5ae9281ad4cd5d9bb9d7ffb87f7c4c77777796631d9736f3f9f181f68 src/receiver/ packet.py
|
||||
compare_digest 6bdcef60acfc7725488fbe21e74b5d6490b0d9918903231a611aa41cca185153a3f507ee2fa06a91cb657aea15eb1c2131526e56014383e8c5f76a29749b3077 src/receiver/ receiver_loop.py
|
||||
compare_digest 27cc4f8048b1f7d5e5dee0216d279701258eb468b8452fddfd3402c2eed4bb78673d8f1320412bf2bac43a5a23af07517a90fcca5446621773f8c54cefdfe3e3 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 ba56c76a825bef2b64ce09b6b6a8215451f9da7747e321ec50e2c03af00e896fee67d8a087b6287e892457054a624c85c232df085f73da472c4c3d82ec043589 src/relay/ client.py
|
||||
compare_digest 48f36d5dccb3e8b06cd4ab8c6bc0c06ae73e63c290a36f0f2e1c756392cd39c78a61db3ee13386f6b888c65d0273533998f65dad46a02bcea4efe2f8c24f2738 src/relay/ commands.py
|
||||
compare_digest 9e1364e05c7ba9acc65cf7926c94ece8e440e65f21f40affeeade9541c82a15cee47c962bc5478babcc9147dfbaf89276cfeb53547512883cb7fcb14d0f5e496 src/relay/ onion.py
|
||||
compare_digest 5771ec48e4f1aecc2b9beeb906b4779850fe9069a95023439d7dcc57721e152d0bcba8a39526c6a5c53d7691566c31986e5539c0ae82939ddd36992727061a0b src/relay/ server.py
|
||||
compare_digest 4c5b5cbce1ba79eca1f17d34d91e7f21aeded9c12d4ad2e1992ccccd41dd24d31722f023fed52bd02df53170777fa3f3273897529160853ae75877438d9317d9 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
|
||||
compare_digest d69ef890aeb43f2ddae1d55ffc8304bec3168beabc647905fc1084288fdfc2bb2d87deb2a9f819f2671a029be1174ca8b74244d19f4280b4e80cf2f9000c92aa src/transmitter/ commands.py
|
||||
compare_digest c912deb82fa99bcab1a0b07a57a9168a926dcc09d8ead3a36a6d7064bea96f3773e136992dfa9c94028f8803183a3db0cd6e0c2ca9d2b6edc4f680dbc83ee560 src/transmitter/ commands_g.py
|
||||
compare_digest 1fe99e684ca629c6c081979393bb17fc644bd13a8a33e3a3b09001da5f37dc054f3e5d0ca7ed9b8420c5b1a97ded512ea71a328c65547e8097d5bff29ed02ce8 src/transmitter/ contact.py
|
||||
compare_digest dffc059fc25cbfb17beb9f83fc2d52ce043e9b923580ccf655933cf66fefcf6e18bcb923d7cb42a7d547126f938ff867a7638ffd13c14953b4a2d700f8f0d5c4 src/transmitter/ files.py
|
||||
compare_digest 319a6f33ca0571768b78008c9c746b84df1aeeb9dd13fe663e4143c4af524dafc6ae83923b84430b08f4b598dffa09c1a1a5095e7571a25c0fd811428772ff26 src/transmitter/ input_loop.py
|
||||
compare_digest cb02629de416059ae56fcbcfe943bc5ea0ebed108f296d13a06693f466e2fa4b4bfb0cb25fe47132a2f3d47dae2b5675aca0f4c44ac36141c75815280f66a027 src/transmitter/ key_exchanges.py
|
||||
compare_digest bb86d9314bed916a45c36812f419aa9fe663a904ceeaddc4516ad8055fccce3526e9bdac3be8df9e09bcbae1be5fafeed068643b1972d480b3cb13af8c97e69a src/transmitter/ packet.py
|
||||
compare_digest ca0088c5e7e45f719d3fa813034de07099650c8c8564d8e4aa77e1778f7a58bb9f3d4dc1de4323ffc483b82867984b3cd3eb79461bf47062dc52d838f10630f2 src/transmitter/ sender_loop.py
|
||||
compare_digest 3e8408b891e446a8b99488703b94ca7e6767bdc29c6218e8b4ab7844a0fb687863620ff3dced5c20e71c11b93238b1bd9f08a9791443f20745e39facaf37f50b src/transmitter/ traffic_masking.py
|
||||
compare_digest ccbda8415c23b23cc10cda57fb6b32df71e6510f3cb94c7f932b40adcf5f0abdd9842c48a992d56c95755e3024aebd7ecb05f69eb18f3c41656d94cfeabb38fa src/transmitter/ user_input.py
|
||||
compare_digest a22b4eb71fa2b56d61a27193987b5755bc5eeec8011d99ea7813c830a4cb38f8934fb70acf4b1dd0980dbb4a30e0ec5945cfb869fb40e74c4f0ecd12f129b040 src/transmitter/ windows.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
|
||||
CERTIFI=certifi-2019.3.9-py2.py3-none-any.whl
|
||||
CFFI=cffi-1.12.3-cp37-cp37m-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
|
||||
JINJA2=Jinja2-2.10.1-py2.py3-none-any.whl
|
||||
MARKUPSAFE=MarkupSafe-1.1.1-cp37-cp37m-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
|
||||
|
@ -124,9 +124,9 @@ 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
|
||||
URLLIB3=urllib3-1.24.2-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
|
||||
WERKZEUG=Werkzeug-0.15.2-py2.py3-none-any.whl
|
||||
|
||||
|
||||
process_tcb_dependencies () {
|
||||
|
@ -145,13 +145,13 @@ install_tcb () {
|
|||
dpkg_check
|
||||
check_rm_existing_installation
|
||||
|
||||
sudo apt update
|
||||
sudo torsocks 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
|
||||
|
||||
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/
|
||||
sudo torsocks python3.7 -m pip download --no-cache-dir -r /opt/tfc/requirements-venv.txt --require-hashes -d /opt/tfc/
|
||||
sudo torsocks python3.7 -m pip download --no-cache-dir -r /opt/tfc/requirements.txt --require-hashes -d /opt/tfc/
|
||||
|
||||
kill_network
|
||||
|
||||
|
@ -159,11 +159,11 @@ install_tcb () {
|
|||
|
||||
create_user_data_dir
|
||||
|
||||
sudo python3.6 -m pip install /opt/tfc/${VIRTUALENV}
|
||||
sudo python3.6 -m virtualenv /opt/tfc/venv_tcb --system-site-packages --never-download
|
||||
sudo python3.7 -m pip install /opt/tfc/${VIRTUALENV}
|
||||
sudo python3.7 -m virtualenv /opt/tfc/venv_tcb --system-site-packages --never-download
|
||||
|
||||
. /opt/tfc/venv_tcb/bin/activate
|
||||
process_tcb_dependencies "python3.6 -m pip install"
|
||||
process_tcb_dependencies "python3.7 -m pip install"
|
||||
deactivate
|
||||
|
||||
sudo mv /opt/tfc/tfc.png /usr/share/pixmaps/
|
||||
|
@ -201,27 +201,25 @@ install_local_test () {
|
|||
dpkg_check
|
||||
check_rm_existing_installation
|
||||
|
||||
sudo apt update
|
||||
sudo torsocks 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
|
||||
|
||||
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/
|
||||
sudo torsocks python3.7 -m pip download --no-cache-dir -r /opt/tfc/requirements-venv.txt --require-hashes -d /opt/tfc/
|
||||
sudo torsocks python3.7 -m pip download --no-cache-dir -r /opt/tfc/requirements.txt --require-hashes -d /opt/tfc/
|
||||
|
||||
verify_files
|
||||
|
||||
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
|
||||
torsocks python3.7 -m pip install -r /opt/tfc/requirements-venv.txt --require-hashes
|
||||
sudo python3.7 -m virtualenv /opt/tfc/venv_tfc --system-site-packages
|
||||
|
||||
. /opt/tfc/venv_tfc/bin/activate
|
||||
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
|
||||
sudo torsocks python3.7 -m pip install -r /opt/tfc/requirements.txt --require-hashes
|
||||
sudo torsocks python3.7 -m pip install -r /opt/tfc/requirements-relay.txt --require-hashes
|
||||
deactivate
|
||||
|
||||
sudo mv /opt/tfc/tfc.png /usr/share/pixmaps/
|
||||
|
@ -258,20 +256,19 @@ install_developer () {
|
|||
sudo rm -r $HOME/tfc/
|
||||
fi
|
||||
|
||||
upgrade_tor
|
||||
sudo torsocks apt install git libssl-dev python3-pip python3-setuptools python3-tk terminator -y
|
||||
|
||||
cd $HOME
|
||||
torsocks git clone https://github.com/maqp/tfc.git
|
||||
cd $HOME/tfc/
|
||||
|
||||
torsocks python3.6 -m pip install -r requirements-venv.txt --require-hashes
|
||||
python3.6 -m virtualenv venv_tfc --system-site-packages
|
||||
torsocks python3.7 -m pip install -r requirements-venv.txt --require-hashes
|
||||
python3.7 -m virtualenv venv_tfc --system-site-packages
|
||||
|
||||
. /$HOME/tfc/venv_tfc/bin/activate
|
||||
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
|
||||
torsocks python3.7 -m pip install -r requirements.txt --require-hashes
|
||||
torsocks python3.7 -m pip install -r requirements-relay.txt --require-hashes
|
||||
torsocks python3.7 -m pip install -r requirements-dev.txt
|
||||
deactivate
|
||||
|
||||
modify_terminator_font_size "" "${HOME}/tfc/launchers/terminator-config-dev"
|
||||
|
@ -296,24 +293,22 @@ install_relay_ubuntu () {
|
|||
dpkg_check
|
||||
check_rm_existing_installation
|
||||
|
||||
sudo apt update
|
||||
sudo torsocks 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
|
||||
|
||||
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/
|
||||
sudo torsocks python3.7 -m pip download --no-cache-dir -r /opt/tfc/requirements-venv.txt --require-hashes -d /opt/tfc/
|
||||
sudo torsocks python3.7 -m pip download --no-cache-dir -r /opt/tfc/requirements.txt --require-hashes -d /opt/tfc/
|
||||
|
||||
verify_files
|
||||
|
||||
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
|
||||
torsocks python3.7 -m pip install -r /opt/tfc/requirements-venv.txt --require-hashes
|
||||
sudo python3.7 -m virtualenv /opt/tfc/venv_relay --system-site-packages
|
||||
|
||||
. /opt/tfc/venv_relay/bin/activate
|
||||
sudo torsocks python3.6 -m pip install -r /opt/tfc/requirements-relay.txt --require-hashes
|
||||
sudo torsocks python3.7 -m pip install -r /opt/tfc/requirements-relay.txt --require-hashes
|
||||
deactivate
|
||||
|
||||
sudo mv /opt/tfc/tfc.png /usr/share/pixmaps/
|
||||
|
@ -362,38 +357,38 @@ install_relay_tails () {
|
|||
|
||||
create_user_data_dir
|
||||
|
||||
t_sudo python3.6 -m pip download --no-cache-dir -r /opt/tfc/requirements-relay.txt --require-hashes -d /opt/tfc/
|
||||
t_sudo python3.7 -m pip download --no-cache-dir -r /opt/tfc/requirements-relay.txt --require-hashes -d /opt/tfc/
|
||||
|
||||
# Pyserial
|
||||
t_sudo python3.6 -m pip install /opt/tfc/${PYSERIAL}
|
||||
t_sudo python3.7 -m pip install /opt/tfc/${PYSERIAL}
|
||||
|
||||
# Stem
|
||||
t_sudo python3.6 -m pip install /opt/tfc/${STEM}
|
||||
t_sudo python3.7 -m pip install /opt/tfc/${STEM}
|
||||
|
||||
# PySocks
|
||||
t_sudo python3.6 -m pip install /opt/tfc/${PYSOCKS}
|
||||
t_sudo python3.7 -m pip install /opt/tfc/${PYSOCKS}
|
||||
|
||||
# Requests
|
||||
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}
|
||||
t_sudo python3.7 -m pip install /opt/tfc/${URLLIB3}
|
||||
t_sudo python3.7 -m pip install /opt/tfc/${IDNA}
|
||||
t_sudo python3.7 -m pip install /opt/tfc/${CHARDET}
|
||||
t_sudo python3.7 -m pip install /opt/tfc/${CERTIFI}
|
||||
t_sudo python3.7 -m pip install /opt/tfc/${REQUESTS}
|
||||
|
||||
# Flask
|
||||
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}
|
||||
t_sudo python3.7 -m pip install /opt/tfc/${WERKZEUG}
|
||||
t_sudo python3.7 -m pip install /opt/tfc/${MARKUPSAFE}
|
||||
t_sudo python3.7 -m pip install /opt/tfc/${JINJA2}
|
||||
t_sudo python3.7 -m pip install /opt/tfc/${ITSDANGEROUS}
|
||||
t_sudo python3.7 -m pip install /opt/tfc/${CLICK}
|
||||
t_sudo python3.7 -m pip install /opt/tfc/${FLASK}
|
||||
|
||||
# Cryptography
|
||||
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}
|
||||
t_sudo python3.7 -m pip install /opt/tfc/${SIX}
|
||||
t_sudo python3.7 -m pip install /opt/tfc/${ASN1CRYPTO}
|
||||
t_sudo python3.7 -m pip install /opt/tfc/${PYCPARSER}
|
||||
t_sudo python3.7 -m pip install /opt/tfc/${CFFI}
|
||||
t_sudo python3.7 -m pip install /opt/tfc/${CRYPTOGRAPHY}
|
||||
|
||||
cd $HOME
|
||||
rm -r $HOME/tfc
|
||||
|
@ -480,53 +475,14 @@ check_tails_tor_version () {
|
|||
}
|
||||
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
# 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
|
||||
|
||||
# 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
|
||||
|
||||
# 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
|
||||
}
|
||||
|
||||
|
||||
kill_network () {
|
||||
for interface in /sys/class/net/*; do
|
||||
sudo ifconfig `basename ${interface}` down
|
||||
name=`basename ${interface}`
|
||||
if [[ $name != "lo" ]]
|
||||
then
|
||||
echo "Closing network interace ${name}"
|
||||
sudo ifconfig ${name} down
|
||||
fi
|
||||
done
|
||||
|
||||
clear
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
-----BEGIN PGP SIGNATURE-----
|
||||
|
||||
iQIzBAABCAAdFiEE6o84umdLJC6ZRIRcmBNw6XJaD7oFAlxJJgEACgkQmBNw6XJa
|
||||
D7oMsxAAvs+LMPzFX1YAqnzIv1b487fwwlzu0mUqG0kWJ5mZzeTY9J3awaQ7KZmo
|
||||
VvhxvUG0ccKw37TP8KG/QrMZuF0Svgr4WunDRFvKE/Bo72C8XOg5IMYfa1Nq2mRb
|
||||
ROMTXR7AUQHD9htajjXUCH4emF7aHsQSZo5RintNUqNBUD8j1fzGYRYdeA4y8a9M
|
||||
9spGgC6CUBFKhzIWCBDCQ0K/tKwufQVvcDuz8furc/hLbg2hzUg6R+F+HfzGRa9S
|
||||
S3c0/R89n2rvoF3wJ/A6jf/ulqSIFgqBFV9DaptzdTq3Gi9BNSlIFkg2K176OSj4
|
||||
+LMba7Q6XzpBRCTwyj8nBy8hAHAAQByrJY/mWF5nH5DTIpjE91MUkckPhZyyZFqj
|
||||
QCP/3IaLV4iJ4otATUCglCwtFVO/twLTcMRhnCHgGsHjas+TTmm/N5Q0OYrvGNpK
|
||||
fUHUnxYNKrr8RaLy3Rt7y+UuidX1SigEvPsWNlTv0Syt85QARRVJHYF56cjaktdL
|
||||
oB4eYR+3cwlKvR+v4B71npz21CmFahUSYAGI1adEEQRsEfKLVPqb9XAg54QDJzUr
|
||||
xgbfZTpEPd9PxfBQNHlXhQVuo0CukOI66bx7nnPZKfBbq0wiV17rnIgex+8gvLXQ
|
||||
k/R96kWWYkTEfydXWDX5yFPAGRzXHPp0Eb5Kc4lVgHIuRLycB7w=
|
||||
=GmPi
|
||||
iQIzBAABCAAdFiEE6o84umdLJC6ZRIRcmBNw6XJaD7oFAlxJJY4ACgkQmBNw6XJa
|
||||
D7rUvQ//Sn+n0F3AsZYhiJMQgwn53NshlEAQXyJNermQSuEC9flx1B9Kqtx1Vffy
|
||||
1P5VCKin09GcJB9eujpAgcGhHJfk+eOmthDE+o5UsEC+83MqxB30UVLBT2AM2cmW
|
||||
CfxSYbJNmuwWhCy5CyrnbWAyVjTb/XP5R7YrlICLKkO2XESwLJdZLUnZB7ht7pS9
|
||||
nBe4qW7p/Qxt7P6DL0MKj3v+Tx8JDgUl8wYZdv9GN3x9A1aLSkhWsr+fnfmH2D9K
|
||||
N0gPhKaG5bgDi+Fu2bEERgfjzK2zIRdKMR1sY0aytp0DL5lJhCqFWoFTVflU0+1s
|
||||
TZ+FZJzrc9jBKC79AGsiS1q9l79qUSzrnQujCUkFQWJVln5mzKLISP64wYVnwfQ5
|
||||
xS41YYmeqALA2E3kv4q+s0aj7igpyKDLiM4tLnxC3G8xVSQs0bjeyaPo+rdu1mmI
|
||||
tefKXbfcfUUOANIMbpUbuqhm3bUQYGGou9FG/XBpcCcY8YgVpeSHuKZrjgMc1u30
|
||||
quibZAflWBJh2tA98HTT7JGyrWIlAsPUvIdCf6uPNcgfohcViNbtnuoYTDz15WQO
|
||||
g2z9IQs3F5VRg6pHgcrY4hWZZ+uyvXQnbzo0GdTgRT70pRlbwYOgud0oRsVEEA6x
|
||||
rrolz+lVYXzMifAYX/EVccV5ifK8/6G4QSc1hpglc/qEqkpcfuY=
|
||||
=l5BI
|
||||
-----END PGP SIGNATURE-----
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
[Desktop Entry]
|
||||
Version=1.19.03
|
||||
Version=1.19.04
|
||||
Name=TFC-Dev
|
||||
Comment=Local testing
|
||||
Exec=terminator -m -u -g $HOME/tfc/launchers/terminator-config-dev -p tfc -l tfc-lr
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
[Desktop Entry]
|
||||
Version=1.19.03
|
||||
Version=1.19.04
|
||||
Name=TFC-LR
|
||||
Comment=Local testing
|
||||
Exec=terminator -m -u -g /opt/tfc/terminator-config-local-test -p tfc -l tfc-lr
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
[Desktop Entry]
|
||||
Version=1.19.03
|
||||
Version=1.19.04
|
||||
Name=TFC-Relay
|
||||
Exec=gnome-terminal -x bash -c "cd /opt/tfc && python3.5 'relay.py' || bash"
|
||||
Exec=gnome-terminal -x bash -c "cd /opt/tfc && python3.7 'relay.py' || bash"
|
||||
Icon=tfc.png
|
||||
Terminal=false
|
||||
Type=Application
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
[Desktop Entry]
|
||||
Version=1.19.03
|
||||
Version=1.19.04
|
||||
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"
|
||||
Exec=gnome-terminal --disable-factory -x bash -c "cd /opt/tfc && source venv_relay/bin/activate && python3.7 'relay.py' && deactivate || bash"
|
||||
Icon=tfc.png
|
||||
Terminal=false
|
||||
Type=Application
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
[Desktop Entry]
|
||||
Version=1.19.03
|
||||
Version=1.19.04
|
||||
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"
|
||||
Exec=gnome-terminal --disable-factory --maximize -x bash -c "cd /opt/tfc && source venv_tcb/bin/activate && python3.7 'tfc.py' -r && deactivate || bash"
|
||||
Icon=tfc.png
|
||||
Terminal=false
|
||||
Type=Application
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
[Desktop Entry]
|
||||
Version=1.19.03
|
||||
Version=1.19.04
|
||||
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"
|
||||
Exec=gnome-terminal --disable-factory --maximize -x bash -c "cd /opt/tfc && source venv_tcb/bin/activate && python3.7 'tfc.py' && deactivate || bash"
|
||||
Icon=tfc.png
|
||||
Terminal=false
|
||||
Type=Application
|
||||
|
|
|
@ -33,21 +33,21 @@
|
|||
type = VPaned
|
||||
|
||||
[[[source_computer_emulator]]]
|
||||
command = cd $HOME/tfc/ && source venv_tfc/bin/activate && python3.6 tfc.py -l && deactivate || bash
|
||||
command = cd $HOME/tfc/ && source venv_tfc/bin/activate && python3.7 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
|
||||
command = cd $HOME/tfc/ && source venv_tfc/bin/activate && python3.7 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
|
||||
command = cd $HOME/tfc/ && source venv_tfc/bin/activate && python3.7 relay.py -l && deactivate || bash
|
||||
directory = ""
|
||||
order = 1
|
||||
parent = child1
|
||||
|
@ -76,21 +76,21 @@
|
|||
type = VPaned
|
||||
|
||||
[[[source_computer_emulator]]]
|
||||
command = cd $HOME/tfc/ && source venv_tfc/bin/activate && python3.6 tfc.py -l && deactivate || bash
|
||||
command = cd $HOME/tfc/ && source venv_tfc/bin/activate && python3.7 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
|
||||
command = cd $HOME/tfc/ && source venv_tfc/bin/activate && python3.7 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
|
||||
command = cd $HOME/tfc/ && source venv_tfc/bin/activate && python3.7 relay.py -l && deactivate || bash
|
||||
directory = ""
|
||||
order = 0
|
||||
parent = child1
|
||||
|
@ -129,21 +129,21 @@
|
|||
type = VPaned
|
||||
|
||||
[[[source_computer_emulator]]]
|
||||
command = cd $HOME/tfc/ && source venv_tfc/bin/activate && python3.6 tfc.py -l -d && deactivate || bash
|
||||
command = cd $HOME/tfc/ && source venv_tfc/bin/activate && python3.7 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
|
||||
command = cd $HOME/tfc/ && source venv_tfc/bin/activate && python3.7 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
|
||||
command = cd $HOME/tfc/ && source venv_tfc/bin/activate && python3.7 relay.py -l -d && deactivate || bash
|
||||
directory = ""
|
||||
order = 1
|
||||
parent = child3
|
||||
|
@ -151,14 +151,14 @@
|
|||
type = Terminal
|
||||
|
||||
[[[source_computer_dd_emulator]]]
|
||||
command = cd $HOME/tfc/ && python3.6 dd.py scnclr
|
||||
command = cd $HOME/tfc/ && python3.7 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
|
||||
command = cd $HOME/tfc/ && python3.7 dd.py ncdclr
|
||||
directory = ""
|
||||
order = 0
|
||||
parent = child4
|
||||
|
@ -197,21 +197,21 @@
|
|||
type = VPaned
|
||||
|
||||
[[[source_computer_emulator]]]
|
||||
command = cd $HOME/tfc/ && source venv_tfc/bin/activate && python3.6 tfc.py -l -d && deactivate || bash
|
||||
command = cd $HOME/tfc/ && source venv_tfc/bin/activate && python3.7 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
|
||||
command = cd $HOME/tfc/ && source venv_tfc/bin/activate && python3.7 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
|
||||
command = cd $HOME/tfc/ && source venv_tfc/bin/activate && python3.7 relay.py -l -d && deactivate || bash
|
||||
directory = ""
|
||||
order = 0
|
||||
parent = child2
|
||||
|
@ -219,14 +219,14 @@
|
|||
type = Terminal
|
||||
|
||||
[[[source_computer_dd_emulator]]]
|
||||
command = cd $HOME/tfc/ && python3.6 dd.py scncrl
|
||||
command = cd $HOME/tfc/ && python3.7 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
|
||||
command = cd $HOME/tfc/ && python3.7 dd.py ncdcrl
|
||||
directory = ""
|
||||
order = 0
|
||||
parent = child3
|
||||
|
|
|
@ -33,21 +33,21 @@
|
|||
type = VPaned
|
||||
|
||||
[[[source_computer_emulator]]]
|
||||
command = cd /opt/tfc/ && source venv_tfc/bin/activate && python3.6 tfc.py -l && deactivate || bash
|
||||
command = cd /opt/tfc/ && source venv_tfc/bin/activate && python3.7 tfc.py -l && deactivate || bash
|
||||
directory = ""
|
||||
order = 1
|
||||
parent = child2
|
||||
profile = tfc
|
||||
type = Terminal
|
||||
[[[destination_computer_emulator]]]
|
||||
command = cd /opt/tfc/ && source venv_tfc/bin/activate && python3.6 tfc.py -l -r && deactivate || bash
|
||||
command = cd /opt/tfc/ && source venv_tfc/bin/activate && python3.7 tfc.py -l -r && deactivate || bash
|
||||
directory = ""
|
||||
order = 0
|
||||
parent = child2
|
||||
profile = tfc
|
||||
type = Terminal
|
||||
[[[networked_computer_emulator]]]
|
||||
command = cd /opt/tfc/ && source venv_tfc/bin/activate && python3.6 relay.py -l && deactivate || bash
|
||||
command = cd /opt/tfc/ && source venv_tfc/bin/activate && python3.7 relay.py -l && deactivate || bash
|
||||
directory = ""
|
||||
order = 1
|
||||
parent = child1
|
||||
|
@ -76,21 +76,21 @@
|
|||
type = VPaned
|
||||
|
||||
[[[source_computer_emulator]]]
|
||||
command = cd /opt/tfc/ && source venv_tfc/bin/activate && python3.6 tfc.py -l && deactivate || bash
|
||||
command = cd /opt/tfc/ && source venv_tfc/bin/activate && python3.7 tfc.py -l && deactivate || bash
|
||||
directory = ""
|
||||
order = 1
|
||||
parent = child2
|
||||
profile = tfc
|
||||
type = Terminal
|
||||
[[[destination_computer_emulator]]]
|
||||
command = cd /opt/tfc/ && source venv_tfc/bin/activate && python3.6 tfc.py -l -r && deactivate || bash
|
||||
command = cd /opt/tfc/ && source venv_tfc/bin/activate && python3.7 tfc.py -l -r && deactivate || bash
|
||||
directory = ""
|
||||
order = 0
|
||||
parent = child2
|
||||
profile = tfc
|
||||
type = Terminal
|
||||
[[[networked_computer_emulator]]]
|
||||
command = cd /opt/tfc/ && source venv_tfc/bin/activate && python3.6 relay.py -l && deactivate || bash
|
||||
command = cd /opt/tfc/ && source venv_tfc/bin/activate && python3.7 relay.py -l && deactivate || bash
|
||||
directory = ""
|
||||
order = 0
|
||||
parent = child1
|
||||
|
@ -129,21 +129,21 @@
|
|||
type = VPaned
|
||||
|
||||
[[[source_computer_emulator]]]
|
||||
command = cd /opt/tfc/ && source venv_tfc/bin/activate && python3.6 tfc.py -l -d && deactivate || bash
|
||||
command = cd /opt/tfc/ && source venv_tfc/bin/activate && python3.7 tfc.py -l -d && deactivate || bash
|
||||
directory = ""
|
||||
order = 1
|
||||
parent = child2
|
||||
profile = tfc-dd
|
||||
type = Terminal
|
||||
[[[destination_computer_emulator]]]
|
||||
command = cd /opt/tfc/ && source venv_tfc/bin/activate && python3.6 tfc.py -l -r && deactivate || bash
|
||||
command = cd /opt/tfc/ && source venv_tfc/bin/activate && python3.7 tfc.py -l -r && deactivate || bash
|
||||
directory = ""
|
||||
order = 0
|
||||
parent = child2
|
||||
profile = tfc-dd
|
||||
type = Terminal
|
||||
[[[networked_computer_emulator]]]
|
||||
command = cd /opt/tfc/ && source venv_tfc/bin/activate && python3.6 relay.py -l -d && deactivate || bash
|
||||
command = cd /opt/tfc/ && source venv_tfc/bin/activate && python3.7 relay.py -l -d && deactivate || bash
|
||||
directory = ""
|
||||
order = 1
|
||||
parent = child3
|
||||
|
@ -151,14 +151,14 @@
|
|||
type = Terminal
|
||||
|
||||
[[[source_computer_dd_emulator]]]
|
||||
command = cd /opt/tfc/ && python3.6 dd.py scnclr
|
||||
command = cd /opt/tfc/ && python3.7 dd.py scnclr
|
||||
directory = ""
|
||||
order = 1
|
||||
parent = child4
|
||||
profile = tfc-dd
|
||||
type = Terminal
|
||||
[[[destination_computer_dd_emulator]]]
|
||||
command = cd /opt/tfc/ && python3.6 dd.py ncdclr
|
||||
command = cd /opt/tfc/ && python3.7 dd.py ncdclr
|
||||
directory = ""
|
||||
order = 0
|
||||
parent = child4
|
||||
|
@ -197,21 +197,21 @@
|
|||
type = VPaned
|
||||
|
||||
[[[source_computer_emulator]]]
|
||||
command = cd /opt/tfc/ && source venv_tfc/bin/activate && python3.6 tfc.py -l -d && deactivate || bash
|
||||
command = cd /opt/tfc/ && source venv_tfc/bin/activate && python3.7 tfc.py -l -d && deactivate || bash
|
||||
directory = ""
|
||||
order = 1
|
||||
parent = child4
|
||||
profile = tfc-dd
|
||||
type = Terminal
|
||||
[[[destination_computer_emulator]]]
|
||||
command = cd /opt/tfc/ && source venv_tfc/bin/activate && python3.6 tfc.py -l -r && deactivate || bash
|
||||
command = cd /opt/tfc/ && source venv_tfc/bin/activate && python3.7 tfc.py -l -r && deactivate || bash
|
||||
directory = ""
|
||||
order = 0
|
||||
parent = child4
|
||||
profile = tfc-dd
|
||||
type = Terminal
|
||||
[[[networked_computer_emulator]]]
|
||||
command = cd /opt/tfc/ && source venv_tfc/bin/activate && python3.6 relay.py -l -d && deactivate || bash
|
||||
command = cd /opt/tfc/ && source venv_tfc/bin/activate && python3.7 relay.py -l -d && deactivate || bash
|
||||
directory = ""
|
||||
order = 0
|
||||
parent = child2
|
||||
|
@ -219,14 +219,14 @@
|
|||
type = Terminal
|
||||
|
||||
[[[source_computer_dd_emulator]]]
|
||||
command = cd /opt/tfc/ && python3.6 dd.py scncrl
|
||||
command = cd /opt/tfc/ && python3.7 dd.py scncrl
|
||||
directory = ""
|
||||
order = 1
|
||||
parent = child3
|
||||
profile = tfc-dd
|
||||
type = Terminal
|
||||
[[[destination_computer_dd_emulator]]]
|
||||
command = cd /opt/tfc/ && python3.6 dd.py ncdcrl
|
||||
command = cd /opt/tfc/ && python3.7 dd.py ncdcrl
|
||||
directory = ""
|
||||
order = 0
|
||||
parent = child3
|
||||
|
|
2
relay.py
2
relay.py
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
|
|
@ -11,22 +11,22 @@ pysocks==1.6.8 --hash=sha512:9b544cf11464142a5f347cd5688b48422249363a425ccf
|
|||
|
||||
# Requests (Connects to the contact's Tor Onion Service)
|
||||
requests==2.21.0 --hash=sha512:f5db1cc049948a8cc38d1c3c2de9f997bc99b65b88bd2e052be62a8c2934773d33f471ce86d8cdcacc2e651b1545d88cc571ace62154a6ccb285a19c83836483
|
||||
certifi==2018.11.29 --hash=sha512:6f6cb73ec56d85ffc62eddd506c44fa597dfd3a7b74bad7f301482cad47c79d0ab7a3a390905ae46fe2a49f1007f6a1c33c41987ce769f9b5a1ea5fa773ea4eb
|
||||
certifi==2019.3.9 --hash=sha512:db7302a3017bb621e69027ec8e95e5d9610d53d1fdaad5d7c1bbb6c3e875f08c7d58058d6622964e07c2f01803d36575f22f2cccaf8af0c5e8361e35be60b513
|
||||
chardet==3.0.4 --hash=sha512:bfae58c8ea19c87cc9c9bf3d0b6146bfdb3630346bd954fe8e9f7da1f09da1fc0d6943ff04802798a665ea3b610ee2d65658ce84fe5a89f9e93625ea396a17f4
|
||||
idna==2.8 --hash=sha512:fb07dbec1de86efbad82a4f73d98123c59b083c1f1277445204bef75de99ca200377ad2f1db8924ae79b31b3dd984891c87d0a6344ec4d07a0ddbbbc655821a3
|
||||
urllib3==1.24.1 --hash=sha512:fdba3d58539eb31dff22cdfad91536587db3ce575af4f4c803758211dbec46944e6cf9d5459d22da620c49a36fe3ca1ae2067c741bb3f643e7b548c4abfb0d7f
|
||||
urllib3==1.24.2 --hash=sha512:c6182596b373e07bf06a7cb6cff0279830586493a360e628ba07e452abe0d8fe50da87b11d07dfec9895a9eff5c584ad348ca68b99298d39006e412d13526001
|
||||
|
||||
# Flask (Onion Service web server that serves TFC public keys and ciphertexts to contacts)
|
||||
flask==1.0.2 --hash=sha512:0cca42400dc1019eb8c9fae32460967f64880f05627bdcb06c8df0ef0f7cc2d791c2a96ab6313bca10120a6f785aa0ccdad093e6ab3d7e997ed354fd432257e7
|
||||
click==7.0 --hash=sha512:6b30987349df7c45c5f41cff9076ed45b178b444fca1ab1965f4ae33d1631522ce0a2868392c736666e83672b8b20e9503ae9ce5016dce3fa8f77bc8a3674130
|
||||
itsdangerous==1.1.0 --hash=sha512:891c294867f705eb9c66274bd04ac5d93140d6e9beea6cbf9a44e7f9c13c0e2efa3554bdf56620712759a5cd579e112a782d25f3f91ba9419d60b2b4d2bc5b7c
|
||||
jinja2==2.10 --hash=sha512:672c1a112f76f399600a069c5ee882d5fdf065ff25f6b729ec12a266d7ef6f638c26d5cc680db7b3a375d9e1ae7323aed3c2a49eb03fc39dd1a1ca8b0d658b63
|
||||
markupsafe==1.1.1 --hash=sha512:a82f797400b692e39efcb76f680c6988651381da7afdd764816a312d0e65cdc999a4bf97b474e89b03941d914ff1b73e8e8e8cd5b210bab157ce2c93a8a92ff2
|
||||
werkzeug==0.14.1 --hash=sha512:0fa694cd71fa83d4a178e9f831fa9784c26e42feb5987e390ed88eb60ea2f829da5795206983236e3442ee1479dd4ca587d26dcb074a881d6d1b055bfc493c56
|
||||
jinja2==2.10.1 --hash=sha512:04860c7ff7086f051368787289f75198eec3357c7da7565dc5045353122650a887e063b1a5297578ddefcc77bfdfe3d9a23c868cb3e7f18a0b5f1c475e29339e
|
||||
markupsafe==1.1.1 --hash=sha512:69e9b9c9ac4fdf3cfa1a3de23d14964b843989128f8cc6ea58617fc5d6ef937bcc3eae9cb32b5164b5f54b06f96bdff9bc249529f20671cc26adc9e6ce8f6bec
|
||||
werkzeug==0.15.2 --hash=sha512:4b5d1631153117674c21fdd3dc3fc064cfea8add5f4669bfef243ec2d67f498bf3525d41b7e858de460a775a044cb02dd7d5a904cda23b24f2eb34b3d9d50d31
|
||||
|
||||
# Cryptography (Handles URL token derivation)
|
||||
cryptography==2.6.1 --hash=sha512:fcddaf49d784e91fab8437cf9a110a4c01f44d686154814c4d488198f61cb732b5db6b63ca66ec2955fe26aed70b5276f282efb0eed17684811a2092b9c7095a
|
||||
asn1crypto==0.24.0 --hash=sha512:8d9bc344981079ac6c00e71e161c34b6f403e575bbfe1ad06e30a3bcb33e0db317bdcb7aed2d18d510cb1b3ee340a649f7f77a00d271fcf3cc388e6655b67533
|
||||
cffi==1.12.2 --hash=sha512:9b188b05fc0de50ac3cdeeb89c0dbc1c71cff9992906f8a7275efb7807f5c61c026d7c49aec9144f1ae4e6e1ea8e90241b71e0b4486a4059fcf24361c26e06e8
|
||||
cffi==1.12.3 --hash=sha512:69a2d725395a1a3585556cb44b62c49bd7f88f41ff194b60d4b9b591c4878a907c0770ef4052b588eaa9d420a53cbeb6b13237fff4054bf26ba5deaa84e25afa
|
||||
pycparser==2.19 --hash=sha512:7f830e1c9066ee2d297a55e2bf6db4bf6447b6d9da0145d11a88c3bb98505755fb7986eafa6e06ae0b7680838f5e5d6a6d188245ca5ad45c2a727587bac93ab5
|
||||
six==1.12.0 --hash=sha512:326574c7542110d2cd8071136a36a6cffc7637ba948b55e0abb7f30f3821843073223301ecbec1d48b8361b0d7ccb338725eeb0424696efedc3f6bd2a23331d3
|
||||
|
|
|
@ -5,14 +5,14 @@ pyserial==3.4 --hash=sha512:8333ac2843fd136d5d0d63b527b37866f7d18afc3bb33c
|
|||
|
||||
# Argon2 (Derives keys that protect persistent user data)
|
||||
argon2_cffi==19.1.0 --hash=sha512:77b17303a5d22fc35ac4771be5c710627c80ed7d6bf6705f70015197dbbc2b699ad6af0604b4517d1afd2f6d153058150a5d2933d38e4b4ca741e4ac560ddf72
|
||||
cffi==1.12.2 --hash=sha512:9b188b05fc0de50ac3cdeeb89c0dbc1c71cff9992906f8a7275efb7807f5c61c026d7c49aec9144f1ae4e6e1ea8e90241b71e0b4486a4059fcf24361c26e06e8
|
||||
cffi==1.12.3 --hash=sha512:69a2d725395a1a3585556cb44b62c49bd7f88f41ff194b60d4b9b591c4878a907c0770ef4052b588eaa9d420a53cbeb6b13237fff4054bf26ba5deaa84e25afa
|
||||
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.12.2 --hash=sha512:9b188b05fc0de50ac3cdeeb89c0dbc1c71cff9992906f8a7275efb7807f5c61c026d7c49aec9144f1ae4e6e1ea8e90241b71e0b4486a4059fcf24361c26e06e8
|
||||
# cffi==1.12.3 --hash=sha512:69a2d725395a1a3585556cb44b62c49bd7f88f41ff194b60d4b9b591c4878a907c0770ef4052b588eaa9d420a53cbeb6b13237fff4054bf26ba5deaa84e25afa
|
||||
# pycparser==2.19 --hash=sha512:7f830e1c9066ee2d297a55e2bf6db4bf6447b6d9da0145d11a88c3bb98505755fb7986eafa6e06ae0b7680838f5e5d6a6d188245ca5ad45c2a727587bac93ab5
|
||||
# six==1.12.0 --hash=sha512:326574c7542110d2cd8071136a36a6cffc7637ba948b55e0abb7f30f3821843073223301ecbec1d48b8361b0d7ccb338725eeb0424696efedc3f6bd2a23331d3
|
||||
|
||||
|
@ -20,6 +20,6 @@ PyNaCl==1.3.0 --hash=sha512:c4017c38b026a5c531b15839b8d61d1fae9907ba1960c2
|
|||
cryptography==2.6.1 --hash=sha512:fcddaf49d784e91fab8437cf9a110a4c01f44d686154814c4d488198f61cb732b5db6b63ca66ec2955fe26aed70b5276f282efb0eed17684811a2092b9c7095a
|
||||
asn1crypto==0.24.0 --hash=sha512:8d9bc344981079ac6c00e71e161c34b6f403e575bbfe1ad06e30a3bcb33e0db317bdcb7aed2d18d510cb1b3ee340a649f7f77a00d271fcf3cc388e6655b67533
|
||||
# Duplicate sub-dependencies
|
||||
# cffi==1.12.2 --hash=sha512:9b188b05fc0de50ac3cdeeb89c0dbc1c71cff9992906f8a7275efb7807f5c61c026d7c49aec9144f1ae4e6e1ea8e90241b71e0b4486a4059fcf24361c26e06e8
|
||||
# cffi==1.12.3 --hash=sha512:69a2d725395a1a3585556cb44b62c49bd7f88f41ff194b60d4b9b591c4878a907c0770ef4052b588eaa9d420a53cbeb6b13237fff4054bf26ba5deaa84e25afa
|
||||
# pycparser==2.19 --hash=sha512:7f830e1c9066ee2d297a55e2bf6db4bf6447b6d9da0145d11a88c3bb98505755fb7986eafa6e06ae0b7680838f5e5d6a6d188245ca5ad45c2a727587bac93ab5
|
||||
# six==1.12.0 --hash=sha512:326574c7542110d2cd8071136a36a6cffc7637ba948b55e0abb7f30f3821843073223301ecbec1d48b8361b0d7ccb338725eeb0424696efedc3f6bd2a23331d3
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
@ -40,6 +40,7 @@ import nacl.exceptions
|
|||
import nacl.secret
|
||||
import nacl.utils
|
||||
|
||||
from cryptography.hazmat.primitives import padding
|
||||
from cryptography.hazmat.primitives.asymmetric.x448 import X448PrivateKey, X448PublicKey
|
||||
from cryptography.hazmat.primitives.serialization import Encoding, PublicFormat
|
||||
|
||||
|
@ -87,7 +88,7 @@ def blake2b(message: bytes, # Message to hash
|
|||
o 128-bit collision/preimage/second-preimage resistance against
|
||||
Grover's algorithm running on a quantum Turing machine.
|
||||
|
||||
o The algorithm is bundled in Python3.6's hashlib.
|
||||
o The algorithm is bundled in Python3.7's hashlib.
|
||||
|
||||
o Compared to SHA3-256, the algorithm runs faster on CPUs which
|
||||
means better hash ratchet performance.
|
||||
|
@ -102,18 +103,18 @@ def blake2b(message: bytes, # Message to hash
|
|||
The correctness of the BLAKE2b implementation* is tested by TFC unit
|
||||
tests. The testing is done in limited scope by using an official KAT.
|
||||
|
||||
* https://github.com/python/cpython/tree/3.6/Modules/_blake2
|
||||
https://github.com/python/cpython/blob/3.6/Lib/hashlib.py
|
||||
* https://github.com/python/cpython/tree/3.7/Modules/_blake2
|
||||
https://github.com/python/cpython/blob/3.7/Lib/hashlib.py
|
||||
"""
|
||||
return hashlib.blake2b(message, digest_size=digest_size, key=key, salt=salt, person=person).digest()
|
||||
|
||||
|
||||
def argon2_kdf(password: str, # Password to derive the key from
|
||||
salt: bytes, # Salt to derive the key from
|
||||
rounds: int = ARGON2_ROUNDS, # Number of iterations
|
||||
memory: int = ARGON2_MIN_MEMORY, # Amount of memory to use (in bytes)
|
||||
parallelism: int = 1 # Number of threads to use
|
||||
) -> bytes: # The derived key
|
||||
def argon2_kdf(password: str, # Password to derive the key from
|
||||
salt: bytes, # Salt to derive the key from
|
||||
time_cost: int = ARGON2_PSK_TIME_COST, # Number of iterations
|
||||
memory_cost: int = ARGON2_PSK_MEMORY_COST, # Amount of memory to use (in bytes)
|
||||
parallelism: int = 2 # Number of threads to use
|
||||
) -> bytes: # The derived key
|
||||
"""Derive an encryption key from password and salt using Argon2d.
|
||||
|
||||
Argon2 is a key derivation function (KDF) designed by Alex Biryukov,
|
||||
|
@ -158,8 +159,8 @@ def argon2_kdf(password: str, # Password to derive the k
|
|||
|
||||
key = argon2.low_level.hash_secret_raw(secret=password.encode(),
|
||||
salt=salt,
|
||||
time_cost=rounds,
|
||||
memory_cost=memory,
|
||||
time_cost=time_cost,
|
||||
memory_cost=memory_cost,
|
||||
parallelism=parallelism,
|
||||
hash_len=SYMMETRIC_KEY_LENGTH,
|
||||
type=argon2.Type.D) # type: bytes
|
||||
|
@ -359,8 +360,9 @@ def byte_padding(bytestring: bytes # Bytestring to be padded
|
|||
For a better explanation, see
|
||||
https://en.wikipedia.org/wiki/Padding_(cryptography)#PKCS#5_and_PKCS#7
|
||||
"""
|
||||
padding_len = PADDING_LENGTH - (len(bytestring) % PADDING_LENGTH)
|
||||
bytestring += padding_len * bytes([padding_len])
|
||||
padder = padding.PKCS7(PADDING_LENGTH * BITS_PER_BYTE).padder()
|
||||
bytestring = padder.update(bytestring)
|
||||
bytestring += padder.finalize()
|
||||
|
||||
if len(bytestring) % PADDING_LENGTH != 0: # pragma: no cover
|
||||
raise CriticalError("Invalid padding length.")
|
||||
|
@ -375,8 +377,11 @@ def rm_padding_bytes(bytestring: bytes # Bytestring from which padding is remov
|
|||
The length of padding is determined by the ord-value of the last
|
||||
byte that is always part of the padding.
|
||||
"""
|
||||
length = ord(bytestring[-1:])
|
||||
return bytestring[:-length]
|
||||
unpadder = padding.PKCS7(PADDING_LENGTH * BITS_PER_BYTE).unpadder()
|
||||
bytestring = unpadder.update(bytestring)
|
||||
bytestring += unpadder.finalize()
|
||||
|
||||
return bytestring
|
||||
|
||||
|
||||
def csprng(key_length: int = SYMMETRIC_KEY_LENGTH) -> bytes:
|
||||
|
@ -389,7 +394,7 @@ def csprng(key_length: int = SYMMETRIC_KEY_LENGTH) -> bytes:
|
|||
|
||||
Since Python 3.6.0, `os.urandom` is a wrapper for best available
|
||||
CSPRNG. The 3.17 and earlier versions of Linux kernel do not support
|
||||
the GETRANDOM call, and Python 3.6's `os.urandom` will in those
|
||||
the GETRANDOM call, and Python 3.7's `os.urandom` will in those
|
||||
cases fall back to non-blocking `/dev/urandom` that is not secure on
|
||||
live distros as they have low entropy at the start of the session.
|
||||
|
||||
|
@ -437,12 +442,12 @@ def csprng(key_length: int = SYMMETRIC_KEY_LENGTH) -> bytes:
|
|||
entropy = os.getrandom(key_length, flags=0)
|
||||
|
||||
if len(entropy) != key_length:
|
||||
raise CriticalError("GETRANDOM returned invalid amount of entropy.")
|
||||
raise CriticalError(f"GETRANDOM returned invalid amount of entropy ({len(entropy)} bytes).")
|
||||
|
||||
compressed = blake2b(entropy, digest_size=key_length)
|
||||
|
||||
if len(compressed) != key_length:
|
||||
raise CriticalError("Invalid final key size.")
|
||||
raise CriticalError(f"Invalid final key size ({len(compressed)} bytes).")
|
||||
|
||||
return compressed
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
@ -23,6 +23,8 @@ import multiprocessing
|
|||
import os.path
|
||||
import time
|
||||
|
||||
from typing import Tuple
|
||||
|
||||
from src.common.crypto import argon2_kdf, blake2b, csprng
|
||||
from src.common.encoding import bytes_to_int, int_to_bytes
|
||||
from src.common.exceptions import CriticalError, graceful_exit
|
||||
|
@ -52,60 +54,157 @@ class MasterKey(object):
|
|||
except (EOFError, KeyboardInterrupt):
|
||||
graceful_exit()
|
||||
|
||||
@staticmethod
|
||||
def timed_key_derivation(password: str,
|
||||
salt: bytes,
|
||||
time_cost: int,
|
||||
memory_cost: int,
|
||||
parallelism: int
|
||||
) -> Tuple[bytes, float]:
|
||||
"""Derive key and measure its derivation time."""
|
||||
time_start = time.monotonic()
|
||||
master_key = argon2_kdf(password, salt, time_cost, memory_cost, parallelism)
|
||||
kd_time = time.monotonic() - time_start
|
||||
|
||||
return master_key, kd_time
|
||||
|
||||
@staticmethod
|
||||
def get_free_memory() -> int:
|
||||
"""Return the amount of free memory in the system."""
|
||||
fields = os.popen("cat /proc/meminfo").read().splitlines()
|
||||
field = [f for f in fields if f.startswith('MemFree')][0]
|
||||
mem_free = int(field.split()[1])
|
||||
|
||||
return mem_free
|
||||
|
||||
def new_master_key(self) -> bytes:
|
||||
"""Create a new master key from password and salt.
|
||||
|
||||
The generated master key depends on a 256-bit salt and the
|
||||
password entered by the user. Additional computational strength
|
||||
is added by the slow hash function (Argon2d). This method
|
||||
automatically tweaks the Argon2 memory parameter so that key
|
||||
derivation on used hardware takes at least three seconds. The
|
||||
more cores and the faster each core is, the more security a
|
||||
given password provides.
|
||||
is added by the slow hash function (Argon2d). The more cores and
|
||||
the faster each core is, and the more memory the system has, the
|
||||
more secure TFC data is under the same password.
|
||||
|
||||
The preimage resistance of BLAKE2b prevents derivation of master
|
||||
This method automatically tweaks the Argon2 time and memory cost
|
||||
parameters according to best practices as determined in
|
||||
|
||||
https://tools.ietf.org/html/draft-irtf-cfrg-argon2-04#section-4
|
||||
|
||||
1) For Argon 2 type (y), Argon2d has is selected because the
|
||||
adversary does not have side channel access to the
|
||||
data-diode separated devices that run the algorithm.
|
||||
|
||||
2) The maximum number of threads (h) is determined by the number
|
||||
available in the system. However, during local testing this
|
||||
number is reduced to half to allow simultaneous login to
|
||||
Transmitter and Receiver Program.
|
||||
|
||||
3) The maximum amount of memory (m) is what the system has to
|
||||
offer. For hard-drive encryption purposes, the recommendation
|
||||
is 6GB. TFC will use that amount (or even more) if available.
|
||||
However, on less powerful systems, it will settle for less.
|
||||
|
||||
4) For key derivation time (x), the value is set to at least 3
|
||||
seconds, with the maximum being 4 seconds. The minimum value
|
||||
is the same as the recommendation for hard-drive encryption.
|
||||
|
||||
5) The salt length is set to 256-bits which is double the recommended
|
||||
length. The salt size ensures that even in a group of 4.8*10^29
|
||||
users, the probability that two users share the same salt is just
|
||||
10^(-18).*
|
||||
* https://en.wikipedia.org/wiki/Birthday_attack
|
||||
|
||||
The salt does not need additional protection as the security it
|
||||
provides depends on the salt space in relation to the number of
|
||||
attacked targets (i.e. if two or more physically compromised
|
||||
systems happen to share the same salt, the attacker can speed up
|
||||
the attack against those systems with time-memory-trade-off
|
||||
attack).
|
||||
|
||||
6) The tag length isn't utilized. The result of the key derivation is
|
||||
the master encryption key itself, which is set to 32 bytes for
|
||||
use in XChaCha20-Poly1305.
|
||||
|
||||
7) Memory wiping feature is not provided by argon2_cffi.
|
||||
|
||||
To recognize the password is correct, the BLAKE2b hash of the master
|
||||
key is stored together with key derivation parameters into the
|
||||
login database.
|
||||
The preimage resistance of BLAKE2b prevents derivation of master
|
||||
key from the stored hash, and Argon2d ensures brute force and
|
||||
dictionary attacks against the master password are painfully
|
||||
slow even with GPUs/ASICs/FPGAs, as long as the password is
|
||||
sufficiently strong.
|
||||
|
||||
The salt does not need additional protection as the security it
|
||||
provides depends on the salt space in relation to the number of
|
||||
attacked targets (i.e. if two or more physically compromised
|
||||
systems happen to share the same salt, the attacker can speed up
|
||||
the attack against those systems with time-memory-trade-off
|
||||
attack).
|
||||
|
||||
A 256-bit salt ensures that even in a group of 4.8*10^29 users,
|
||||
the probability that two users share the same salt is just
|
||||
10^(-18).*
|
||||
* https://en.wikipedia.org/wiki/Birthday_attack
|
||||
"""
|
||||
password = MasterKey.new_password()
|
||||
salt = csprng(ARGON2_SALT_LENGTH)
|
||||
memory = ARGON2_MIN_MEMORY
|
||||
password = MasterKey.new_password()
|
||||
salt = csprng(ARGON2_SALT_LENGTH)
|
||||
time_cost = 1
|
||||
|
||||
# Determine the amount of memory used from the amount of free RAM in the system.
|
||||
memory_cost = self.get_free_memory()
|
||||
if self.local_test:
|
||||
memory_cost //= 2
|
||||
|
||||
# Determine the amount of threads to use
|
||||
parallelism = multiprocessing.cpu_count()
|
||||
if self.local_test:
|
||||
parallelism = max(1, parallelism // 2)
|
||||
|
||||
phase("Deriving master key", head=2)
|
||||
while True:
|
||||
time_start = time.monotonic()
|
||||
master_key = argon2_kdf(password, salt, ARGON2_ROUNDS, memory, parallelism)
|
||||
kd_time = time.monotonic() - time_start
|
||||
|
||||
if kd_time < MIN_KEY_DERIVATION_TIME:
|
||||
memory *= 2
|
||||
else:
|
||||
ensure_dir(DIR_USER_DATA)
|
||||
with open(self.file_name, 'wb+') as f:
|
||||
f.write(salt
|
||||
+ blake2b(master_key)
|
||||
+ int_to_bytes(memory)
|
||||
+ int_to_bytes(parallelism))
|
||||
phase(DONE)
|
||||
return master_key
|
||||
# Initial key derivation
|
||||
master_key, kd_time = self.timed_key_derivation(password, salt, time_cost, memory_cost, parallelism)
|
||||
|
||||
# If derivation was too fast, increase time_cost
|
||||
while kd_time < MIN_KEY_DERIVATION_TIME:
|
||||
time_cost += 1
|
||||
master_key, kd_time = self.timed_key_derivation(password, salt, time_cost, memory_cost, parallelism)
|
||||
|
||||
# At this point time_cost may have value of 1 or it may have increased to e.g. 3, which might make it take
|
||||
# longer than MAX_KEY_DERIVATION_TIME. If that's the case, it makes no sense to lower it back to 2 because even
|
||||
# with all memory, time_cost=2 will still be too fast. We therefore accept the time_cost whatever it is.
|
||||
|
||||
# If the key derivation time is too long, we do a binary search on the amount
|
||||
# of memory to use until we hit the desired key derivation time range.
|
||||
if kd_time > MAX_KEY_DERIVATION_TIME:
|
||||
|
||||
lower_bound = ARGON_2_MIN_MEMORY_COST
|
||||
upper_bound = memory_cost
|
||||
|
||||
while kd_time < MIN_KEY_DERIVATION_TIME or kd_time > MAX_KEY_DERIVATION_TIME:
|
||||
|
||||
middle = (lower_bound + upper_bound) // 2
|
||||
master_key, kd_time = self.timed_key_derivation(password, salt, time_cost, middle, parallelism)
|
||||
|
||||
# End of search might happen e.g. if external CPU load causes delay in key derivation, which causes
|
||||
# the search to continue into wrong branch. In such situation the search is restarted. The binary search
|
||||
# is problematic with tight key derivation time target ranges, so if the search keeps restarting,
|
||||
# increasing MAX_KEY_DERIVATION_TIME (and thus expanding the range) will help finding suitable
|
||||
# memory_cost value faster. Increasing MAX_KEY_DERIVATION_TIME slightly affects security (positively)
|
||||
# and user experience (negatively).
|
||||
if middle == lower_bound or middle == upper_bound:
|
||||
lower_bound = ARGON_2_MIN_MEMORY_COST
|
||||
upper_bound = memory_cost
|
||||
continue
|
||||
|
||||
if kd_time < MIN_KEY_DERIVATION_TIME:
|
||||
lower_bound = middle
|
||||
|
||||
elif kd_time > MAX_KEY_DERIVATION_TIME:
|
||||
upper_bound = middle
|
||||
|
||||
# Store values to database
|
||||
ensure_dir(DIR_USER_DATA)
|
||||
with open(self.file_name, 'wb+') as f:
|
||||
f.write(salt
|
||||
+ blake2b(master_key)
|
||||
+ int_to_bytes(time_cost)
|
||||
+ int_to_bytes(memory_cost)
|
||||
+ int_to_bytes(parallelism))
|
||||
phase(DONE)
|
||||
|
||||
return master_key
|
||||
|
||||
def load_master_key(self) -> bytes:
|
||||
"""Derive the master key from password and salt.
|
||||
|
@ -122,16 +221,18 @@ class MasterKey(object):
|
|||
if len(data) != MASTERKEY_DB_SIZE:
|
||||
raise CriticalError(f"Invalid {self.file_name} database size.")
|
||||
|
||||
salt, key_hash, memory_bytes, parallelism_bytes \
|
||||
= separate_headers(data, [ARGON2_SALT_LENGTH, BLAKE2_DIGEST_LENGTH, ENCODED_INTEGER_LENGTH])
|
||||
salt, key_hash, time_bytes, memory_bytes, parallelism_bytes \
|
||||
= separate_headers(data, [ARGON2_SALT_LENGTH, BLAKE2_DIGEST_LENGTH,
|
||||
ENCODED_INTEGER_LENGTH, ENCODED_INTEGER_LENGTH])
|
||||
|
||||
memory = bytes_to_int(memory_bytes)
|
||||
time_cost = bytes_to_int(time_bytes)
|
||||
memory_cost = bytes_to_int(memory_bytes)
|
||||
parallelism = bytes_to_int(parallelism_bytes)
|
||||
|
||||
while True:
|
||||
password = MasterKey.get_password()
|
||||
phase("Deriving master key", head=2, offset=len("Password correct"))
|
||||
purp_key = argon2_kdf(password, salt, ARGON2_ROUNDS, memory, parallelism)
|
||||
purp_key = argon2_kdf(password, salt, time_cost, memory_cost, parallelism)
|
||||
|
||||
if blake2b(purp_key) == key_hash:
|
||||
phase("Password correct", done=True, delay=1)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
@ -179,6 +179,7 @@ def monitor_processes(process_list: List[Process],
|
|||
while True:
|
||||
with ignored(EOFError, KeyboardInterrupt):
|
||||
time.sleep(0.1)
|
||||
|
||||
if not all([p.is_alive() for p in process_list]):
|
||||
for p in process_list:
|
||||
p.terminate()
|
||||
|
@ -205,6 +206,7 @@ def monitor_processes(process_list: List[Process],
|
|||
for d in [DIR_USER_DATA, DIR_RECV_FILES]:
|
||||
with ignored(FileNotFoundError):
|
||||
shutil.rmtree(d)
|
||||
|
||||
os.system(POWEROFF)
|
||||
|
||||
|
||||
|
@ -215,7 +217,7 @@ def process_arguments() -> Tuple[str, bool, bool]:
|
|||
Terminator configuration file for local testing. The descriptions
|
||||
here are provided for the sake of completeness.
|
||||
"""
|
||||
parser = argparse.ArgumentParser(f'python3.6 {sys.argv[0]}',
|
||||
parser = argparse.ArgumentParser(f'python3.7 {sys.argv[0]}',
|
||||
usage='%(prog)s [OPTION]',
|
||||
epilog='Full documentation at: <https://github.com/maqp/tfc/wiki>')
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
@ -24,7 +24,7 @@ TFC = 'TFC'
|
|||
TXP = 'Transmitter'
|
||||
RXP = 'Receiver'
|
||||
RP = 'Relay'
|
||||
VERSION = '1.19.03'
|
||||
VERSION = '1.19.04'
|
||||
|
||||
|
||||
"""Identifiers
|
||||
|
@ -379,7 +379,7 @@ STATIC = 'static'
|
|||
TRAFFIC_MASKING = 'traffic_masking'
|
||||
|
||||
|
||||
"""Default folders"""
|
||||
"""Default directories"""
|
||||
DIR_USER_DATA = 'user_data/'
|
||||
DIR_RECV_FILES = 'received_files/'
|
||||
DIR_TFC = 'tfc/'
|
||||
|
@ -448,7 +448,6 @@ WIPE = 'WIPE'
|
|||
|
||||
|
||||
"""Static values"""
|
||||
|
||||
# Serial interface
|
||||
BAUDS_PER_BYTE = 10
|
||||
SERIAL_RX_MIN_TIMEOUT = 0.05
|
||||
|
@ -493,15 +492,18 @@ ONION_ADDRESS_CHECKSUM_LENGTH = 2
|
|||
ONION_ADDRESS_LENGTH = 56
|
||||
|
||||
# Misc
|
||||
BITS_PER_BYTE = 8
|
||||
MAX_INT = 2 ** 64 - 1
|
||||
B58_CHECKSUM_LENGTH = 4
|
||||
TRUNC_ADDRESS_LENGTH = 5
|
||||
|
||||
# Key derivation
|
||||
ARGON_2_MIN_MEMORY_COST = 8
|
||||
ARGON2_SALT_LENGTH = 32
|
||||
ARGON2_ROUNDS = 25
|
||||
ARGON2_MIN_MEMORY = 64000 # bytes
|
||||
MIN_KEY_DERIVATION_TIME = 3.0 # seconds
|
||||
ARGON2_PSK_TIME_COST = 25
|
||||
ARGON2_PSK_MEMORY_COST = 512 * 1024 # kibibytes
|
||||
MIN_KEY_DERIVATION_TIME = 3.0 # seconds
|
||||
MAX_KEY_DERIVATION_TIME = 4.0 # seconds
|
||||
|
||||
# Cryptographic field sizes
|
||||
TFC_PRIVATE_KEY_LENGTH = 56
|
||||
|
@ -572,7 +574,7 @@ LOG_ENTRY_LENGTH = (XCHACHA20_NONCE_LENGTH
|
|||
|
||||
MASTERKEY_DB_SIZE = (ARGON2_SALT_LENGTH
|
||||
+ BLAKE2_DIGEST_LENGTH
|
||||
+ 2 * ENCODED_INTEGER_LENGTH)
|
||||
+ 3 * ENCODED_INTEGER_LENGTH)
|
||||
|
||||
SETTING_LENGTH = (XCHACHA20_NONCE_LENGTH
|
||||
+ 4 * ENCODED_INTEGER_LENGTH
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
@ -111,7 +111,7 @@ def process_assembled_file(ts: 'datetime', # Timestamp last receiv
|
|||
window.add_new(ts, message, onion_pub_key, output=True, event_msg=True)
|
||||
|
||||
|
||||
def new_file(ts: 'datetime',
|
||||
def new_file(ts: 'datetime', # Timestamp of received_packet
|
||||
packet: bytes, # Sender of file and file ciphertext
|
||||
file_keys: Dict[bytes, bytes], # Dictionary for file decryption keys
|
||||
file_buf: Dict[bytes, Tuple['datetime', bytes]], # Dictionary for cached file ciphertexts
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
@ -64,6 +64,8 @@ def process_local_key(ts: 'datetime',
|
|||
) -> None:
|
||||
"""Decrypt local key packet and add local contact/keyset."""
|
||||
bootstrap = not key_list.has_local_keyset()
|
||||
plaintext = None
|
||||
|
||||
try:
|
||||
packet_hash = blake2b(packet)
|
||||
|
||||
|
@ -112,6 +114,10 @@ def process_local_key(ts: 'datetime',
|
|||
|
||||
break
|
||||
|
||||
# This catches PyCharm's weird claim that plaintext might be referenced before assignment
|
||||
if plaintext is None: # pragma: no cover
|
||||
raise FunctionReturn("Error: Could not decrypt local key.")
|
||||
|
||||
# Add local contact to contact list database
|
||||
contact_list.add_contact(LOCAL_PUBKEY,
|
||||
LOCAL_NICK,
|
||||
|
@ -292,7 +298,7 @@ def key_ex_psk_rx(packet: bytes,
|
|||
try:
|
||||
password = MasterKey.get_password("PSK password")
|
||||
phase("Deriving the key decryption key", head=2)
|
||||
kdk = argon2_kdf(password, salt, rounds=ARGON2_ROUNDS, memory=ARGON2_MIN_MEMORY)
|
||||
kdk = argon2_kdf(password, salt, time_cost=ARGON2_PSK_TIME_COST, memory_cost=ARGON2_PSK_MEMORY_COST)
|
||||
psk = auth_and_decrypt(ct_tag, kdk)
|
||||
phase(DONE)
|
||||
break
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
@ -137,13 +137,13 @@ def process_message(ts: 'datetime',
|
|||
packet.clear_assembly_packets()
|
||||
|
||||
|
||||
def process_group_message(assembled: bytes,
|
||||
ts: 'datetime',
|
||||
onion_pub_key: bytes,
|
||||
origin: bytes,
|
||||
whisper: bool,
|
||||
group_list: 'GroupList',
|
||||
window_list: 'WindowList'
|
||||
def process_group_message(assembled: bytes, # Group message and its headers
|
||||
ts: 'datetime', # Timestamp of group message
|
||||
onion_pub_key: bytes, # Onion address of associated contact
|
||||
origin: bytes, # Origin of group message (user / contact)
|
||||
whisper: bool, # When True, message is not logged.
|
||||
group_list: 'GroupList', # GroupList object
|
||||
window_list: 'WindowList' # WindowList object
|
||||
) -> bool:
|
||||
"""Process a group message."""
|
||||
group_id, assembled = separate_header(assembled, GROUP_ID_LENGTH)
|
||||
|
@ -177,11 +177,11 @@ def process_group_message(assembled: bytes,
|
|||
return group.log_messages
|
||||
|
||||
|
||||
def process_file_key_message(assembled: bytes,
|
||||
onion_pub_key: bytes,
|
||||
origin: bytes,
|
||||
contact_list: 'ContactList',
|
||||
file_keys: Dict[bytes, bytes]
|
||||
def process_file_key_message(assembled: bytes, # File decryption key
|
||||
onion_pub_key: bytes, # Onion address of associated contact
|
||||
origin: bytes, # Origin of file key packet (user / contact)
|
||||
contact_list: 'ContactList', # ContactList object
|
||||
file_keys: Dict[bytes, bytes] # Dictionary of file identifiers and decryption keys
|
||||
) -> str:
|
||||
"""Process received file key delivery message."""
|
||||
if origin == ORIGIN_USER_HEADER:
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
@ -223,8 +223,6 @@ class Packet(object):
|
|||
|
||||
if self.type == FILE:
|
||||
self.new_file_packet()
|
||||
sh, _, packet = separate_headers(packet, [ASSEMBLY_PACKET_HEADER_LENGTH] + [2*ENCODED_INTEGER_LENGTH])
|
||||
packet = sh + packet
|
||||
|
||||
self.assembly_pt_list = [packet]
|
||||
self.long_active = False
|
||||
|
@ -244,14 +242,13 @@ class Packet(object):
|
|||
if self.type == FILE:
|
||||
self.new_file_packet()
|
||||
try:
|
||||
lh, no_p_bytes, time_bytes, size_bytes, packet \
|
||||
lh, no_p_bytes, time_bytes, size_bytes, _ \
|
||||
= separate_headers(packet, [ASSEMBLY_PACKET_HEADER_LENGTH] + 3*[ENCODED_INTEGER_LENGTH])
|
||||
|
||||
self.packets = bytes_to_int(no_p_bytes) # added by transmitter.packet.split_to_assembly_packets
|
||||
self.time = str(timedelta(seconds=bytes_to_int(time_bytes)))
|
||||
self.size = readable_size(bytes_to_int(size_bytes))
|
||||
self.name = packet.split(US_BYTE)[0].decode()
|
||||
packet = lh + packet
|
||||
|
||||
m_print([f'Receiving file from {self.contact.nick}:',
|
||||
f'{self.name} ({self.size})',
|
||||
|
@ -358,6 +355,9 @@ class Packet(object):
|
|||
padded = b''.join([p[ASSEMBLY_PACKET_HEADER_LENGTH:] for p in self.assembly_pt_list])
|
||||
payload = rm_padding_bytes(padded)
|
||||
|
||||
no_fields = 3 if len(self.assembly_pt_list) > 1 else 2
|
||||
*_, payload = separate_headers(payload, no_fields * [ENCODED_INTEGER_LENGTH])
|
||||
|
||||
process_assembled_file(ts, payload, onion_pub_key, self.contact.nick, self.settings, window_list)
|
||||
|
||||
def assemble_command_packet(self) -> bytes:
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
@ -25,7 +25,6 @@ import os
|
|||
import random
|
||||
import shlex
|
||||
import socket
|
||||
import subprocess
|
||||
import tempfile
|
||||
import time
|
||||
|
||||
|
@ -157,24 +156,8 @@ def stem_compatible_ed25519_key_from_private_key(private_key: bytes) -> str:
|
|||
return base64.b64encode(expanded_private_key).decode()
|
||||
|
||||
|
||||
def kill_background_tor() -> None:
|
||||
"""Kill any open TFC-related Tor instances left open.
|
||||
|
||||
Copies of Tor might stay open in cases where the user has closed the
|
||||
application from Terminator's close window ((x) button).
|
||||
"""
|
||||
try:
|
||||
pids = subprocess.check_output("ps aux |grep '[t]fc/tor' | awk '{print $2}' 2>/dev/null", shell=True)
|
||||
for pid in pids.split(b'\n'):
|
||||
subprocess.Popen("kill {}".format(int(pid)), shell=True).wait()
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
|
||||
def onion_service(queues: Dict[bytes, 'Queue']) -> None:
|
||||
"""Manage the Tor Onion Service and control Tor via stem."""
|
||||
kill_background_tor()
|
||||
|
||||
rp_print("Setup 0% - Waiting for Onion Service configuration...", bold=True)
|
||||
while queues[ONION_KEY_QUEUE].qsize() == 0:
|
||||
time.sleep(0.1)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
@ -63,7 +63,7 @@ def src_incoming(queues: 'QueueDict',
|
|||
unittest: bool = False
|
||||
) -> None:
|
||||
"""\
|
||||
Redirect messages received from Source Computer to appropriate queues.
|
||||
Redirect datagrams received from Source Computer to appropriate queues.
|
||||
"""
|
||||
packets_from_sc = queues[GATEWAY_QUEUE]
|
||||
packets_to_dc = queues[DST_MESSAGE_QUEUE]
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
@ -198,7 +198,8 @@ def change_nick(user_input: 'UserInput',
|
|||
if window.type == WIN_TYPE_GROUP:
|
||||
rename_group(nick, window, contact_list, group_list, settings, queues)
|
||||
|
||||
assert window.contact is not None
|
||||
if window.contact is None:
|
||||
raise FunctionReturn("Error: Window does not have contact.")
|
||||
|
||||
onion_pub_key = window.contact.onion_pub_key
|
||||
error_msg = validate_nick(nick, (contact_list, group_list, onion_pub_key))
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
@ -266,7 +266,7 @@ def start_key_exchange(onion_pub_key: bytes, # Public key of contact's
|
|||
|
||||
This function first creates the X448 key pair. It then outputs the
|
||||
public key to Relay Program on Networked Computer, that passes the
|
||||
public key to contact's Relay Program. When Contact's public key
|
||||
public key to contact's Relay Program. When contact's public key
|
||||
reaches the user's Relay Program, the user will manually copy the
|
||||
key into their Transmitter Program.
|
||||
|
||||
|
@ -467,7 +467,7 @@ def create_pre_shared_key(onion_pub_key: bytes, # Public key of contac
|
|||
password = MasterKey.new_password("password for PSK")
|
||||
|
||||
phase("Deriving key encryption key", head=2)
|
||||
kek = argon2_kdf(password, salt, rounds=ARGON2_ROUNDS, memory=ARGON2_MIN_MEMORY)
|
||||
kek = argon2_kdf(password, salt, time_cost=ARGON2_PSK_TIME_COST, memory_cost=ARGON2_PSK_MEMORY_COST)
|
||||
phase(DONE)
|
||||
|
||||
ct_tag = encrypt_and_sign(tx_mk + tx_hk, key=kek)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
@ -88,7 +88,7 @@ def traffic_masking_loop(queues: 'QueueDict',
|
|||
The traffic is masked the following way: If both m_queue and f_queue
|
||||
are empty, a noise assembly packet is loaded from np_queue. If no
|
||||
command packet is available in c_queue, a noise command packet is
|
||||
loaded from nc_queue. Both noise queues are filled with independent
|
||||
loaded from nc_queue. Both noise queues are filled by independent
|
||||
processes that ensure both noise queues always have packets to
|
||||
output.
|
||||
|
||||
|
@ -167,11 +167,14 @@ def traffic_masking_loop(queues: 'QueueDict',
|
|||
command = packet[DATAGRAM_HEADER_LENGTH:]
|
||||
if command in [UNENCRYPTED_EXIT_COMMAND, UNENCRYPTED_WIPE_COMMAND]:
|
||||
gateway.write(packet)
|
||||
queues[EXIT_QUEUE].put(command)
|
||||
time.sleep(gateway.settings.local_testing_mode * 0.1)
|
||||
time.sleep(gateway.settings.data_diode_sockets * 1.5)
|
||||
signal = WIPE if command == UNENCRYPTED_WIPE_COMMAND else EXIT
|
||||
queues[EXIT_QUEUE].put(signal)
|
||||
|
||||
# If traffic masking has been disabled, move all packets to standard_sender_loop queues.
|
||||
# If traffic masking has been disabled, wait until queued messages are sent before returning.
|
||||
if sm_queue.qsize() != 0 and all(q.qsize() == 0 for q in (m_queue, f_queue, c_queue)):
|
||||
settings = queues[SENDER_MODE_QUEUE].get()
|
||||
settings = sm_queue.get()
|
||||
return settings
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
@ -208,13 +208,13 @@ class TxWindow(Iterable, Sized):
|
|||
def deselect(self) -> None:
|
||||
"""Deselect active window."""
|
||||
self.window_contacts = []
|
||||
self.contact = None # type: Contact
|
||||
self.group = None # type: Group
|
||||
self.contact = None # type: Optional[Contact]
|
||||
self.group = None # type: Optional[Group]
|
||||
self.name = '' # type: str
|
||||
self.uid = b'' # type: bytes
|
||||
self.log_messages = None # type: bool
|
||||
self.log_messages = None # type: Optional[bool]
|
||||
self.type = '' # type: str
|
||||
self.type_print = None # type: str
|
||||
self.type_print = None # type: Optional[str]
|
||||
|
||||
def is_selected(self) -> bool:
|
||||
"""Return True if a window is selected, else False."""
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
@ -99,7 +99,7 @@ class TestArgon2KDF(unittest.TestCase):
|
|||
self.assertEqual(key.hex(), '7e12cb75695277c0ab974e4ae943b87da08e36dd065aca8de3ca009125ae8953')
|
||||
|
||||
def test_argon2d_kdf(self):
|
||||
key = argon2_kdf('password', ARGON2_SALT_LENGTH*b'a', rounds=1, memory=100)
|
||||
key = argon2_kdf('password', ARGON2_SALT_LENGTH*b'a', time_cost=1, memory_cost=100)
|
||||
self.assertIsInstance(key, bytes)
|
||||
self.assertEqual(len(key), SYMMETRIC_KEY_LENGTH)
|
||||
|
||||
|
@ -265,14 +265,22 @@ class TestXChaCha20Poly1305(unittest.TestCase):
|
|||
|
||||
|
||||
class TestBytePadding(unittest.TestCase):
|
||||
"""Unittests of the cryptography library are available at
|
||||
https://github.com/pyca/cryptography/blob/master/tests/hazmat/primitives/test_padding.py
|
||||
"""
|
||||
|
||||
def test_padding_length_is_divisible_by_packet_length(self):
|
||||
padded_bytestrings = []
|
||||
|
||||
for length in range(1000):
|
||||
string = length * b'm'
|
||||
padded = byte_padding(string)
|
||||
self.assertIsInstance(padded, bytes)
|
||||
self.assertEqual(len(padded) % PADDING_LENGTH, 0)
|
||||
|
||||
padded_bytestrings.append(len(padded))
|
||||
self.assertNotEqual(len(list(set(padded_bytestrings))), 1)
|
||||
|
||||
def test_packet_length_equal_to_padding_size_adds_dummy_block(self):
|
||||
string = PADDING_LENGTH * b'm'
|
||||
padded = byte_padding(string)
|
||||
|
@ -317,6 +325,7 @@ class TestCSPRNG(unittest.TestCase):
|
|||
def test_invalid_entropy_raises_critical_error(self, _):
|
||||
with self.assertRaises(SystemExit):
|
||||
csprng()
|
||||
with self.assertRaises(SystemExit):
|
||||
csprng()
|
||||
|
||||
@mock.patch('src.common.crypto.blake2b', side_effect=[(SYMMETRIC_KEY_LENGTH-1) * b'a',
|
||||
|
@ -324,6 +333,7 @@ class TestCSPRNG(unittest.TestCase):
|
|||
def test_invalid_blake2b_digest_raises_critical_error(self, _):
|
||||
with self.assertRaises(SystemExit):
|
||||
csprng()
|
||||
with self.assertRaises(SystemExit):
|
||||
csprng()
|
||||
|
||||
class TestCheckKernelEntropy(unittest.TestCase):
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
@ -23,7 +23,8 @@ import os
|
|||
import os.path
|
||||
import unittest
|
||||
|
||||
from unittest import mock
|
||||
from unittest import mock
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
from src.common.db_masterkey import MasterKey
|
||||
from src.common.misc import ensure_dir
|
||||
|
@ -56,10 +57,10 @@ class TestMasterKey(unittest.TestCase):
|
|||
with self.assertRaises(SystemExit):
|
||||
_ = MasterKey(self.operation, local_test=False)
|
||||
|
||||
@mock.patch('src.common.db_masterkey.ARGON2_MIN_MEMORY', 100)
|
||||
@mock.patch('src.common.db_masterkey.ARGON2_ROUNDS', 1)
|
||||
@mock.patch('src.common.db_masterkey.MIN_KEY_DERIVATION_TIME', 0.1)
|
||||
@mock.patch('src.common.db_masterkey.MAX_KEY_DERIVATION_TIME', 1.1)
|
||||
@mock.patch('os.path.isfile', side_effect=[KeyboardInterrupt, False, True])
|
||||
@mock.patch('os.popen', return_value=MagicMock(read=MagicMock(return_value='foo\nMemFree 200')))
|
||||
@mock.patch('getpass.getpass', side_effect=input_list)
|
||||
@mock.patch('time.sleep', return_value=None)
|
||||
def test_master_key_generation_and_load(self, *_):
|
||||
|
@ -74,6 +75,17 @@ class TestMasterKey(unittest.TestCase):
|
|||
self.assertIsInstance(master_key2.master_key, bytes)
|
||||
self.assertEqual(master_key.master_key, master_key2.master_key)
|
||||
|
||||
@mock.patch('src.common.db_masterkey.MasterKey.timed_key_derivation', MagicMock(side_effect=10 * [(32*b'b', 5.0)]
|
||||
+ [(32*b'a', 2.5),
|
||||
(32*b'a', 2.5),
|
||||
(32*b'a', 3.0)]))
|
||||
@mock.patch('os.path.isfile', side_effect=[False, True])
|
||||
@mock.patch('os.popen', return_value=MagicMock(read=MagicMock(return_value='foo\nMemFree 200')))
|
||||
@mock.patch('getpass.getpass', side_effect=input_list)
|
||||
@mock.patch('time.sleep', return_value=None)
|
||||
def test_kd_binary_serach(self, *_):
|
||||
MasterKey(self.operation, local_test=True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(exit=False)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
@ -29,7 +29,7 @@ from unittest.mock import MagicMock
|
|||
from src.common.path import ask_path_cli, ask_path_gui, Completer
|
||||
|
||||
from tests.mock_classes import Settings
|
||||
from tests.utils import ignored, TFCTestCase
|
||||
from tests.utils import cd_unittest, cleanup, ignored, TFCTestCase
|
||||
|
||||
|
||||
class TestAskPathGui(TFCTestCase):
|
||||
|
@ -78,21 +78,34 @@ class TestAskPathGui(TFCTestCase):
|
|||
class TestCompleter(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.cwd = os.getcwd()
|
||||
os.chdir('/bin')
|
||||
self.cwd = os.getcwd()
|
||||
self.unittest_dir = cd_unittest()
|
||||
|
||||
# Create test directory structure for the completer.
|
||||
os.mkdir('outer')
|
||||
os.chdir('outer/')
|
||||
with open('file', 'w+') as f:
|
||||
f.write('text')
|
||||
os.mkdir('middle')
|
||||
os.chdir('middle/')
|
||||
os.mkdir('inner')
|
||||
os.chdir('..')
|
||||
os.chdir('..')
|
||||
|
||||
def tearDown(self):
|
||||
cleanup(self.unittest_dir)
|
||||
os.chdir(self.cwd)
|
||||
|
||||
def test_completer(self):
|
||||
# Test path
|
||||
completer = Completer(get_file=False)
|
||||
self.assertEqual(completer.complete_path('/bin/'), [])
|
||||
self.assertEqual(completer.path_complete(['/bin']), [])
|
||||
self.assertEqual(completer.path_complete(), [])
|
||||
self.assertEqual(completer.complete_path(''), [])
|
||||
self.assertEqual(completer.complete_path('/bin/sh'), ['/bin/sh '])
|
||||
self.assertNotEqual(completer.listdir('/etc/'), [])
|
||||
self.assertEqual(completer.complete_path('outer/'), ['outer/middle/'])
|
||||
self.assertEqual(completer.path_complete(['/outer']), [])
|
||||
self.assertEqual(completer.path_complete(), ['./outer/'])
|
||||
self.assertEqual(completer.complete_path(''), ['outer/'])
|
||||
self.assertEqual(completer.complete_path('outer/middle'), ['outer/middle/inner/'])
|
||||
self.assertEqual(completer.complete_path('outer/file'), ['outer/file '])
|
||||
self.assertNotEqual(completer.listdir('outer/'), [])
|
||||
|
||||
# Test file
|
||||
completer = Completer(get_file=True)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
@ -49,7 +49,7 @@ class TestStatics(unittest.TestCase):
|
|||
self.assertEqual(len(list(set(variable_list))), len(variable_list))
|
||||
|
||||
def test_group_id_length_is_not_same_as_onion_service_pub_key_length(self):
|
||||
"""}
|
||||
"""\
|
||||
In current implementation, `src.common.db_logs.remove_logs`
|
||||
determines the type of data to be removed from the length of
|
||||
provided `selector` parameter. If group ID length is set to same
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
TFC - Onion-routed, endpoint secure messaging system
|
||||
Copyright (C) 2013-2019 Markus Ottela
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
@ -26,6 +26,7 @@ import unittest
|
|||
from datetime import datetime
|
||||
from multiprocessing import Queue
|
||||
from unittest import mock
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
from src.common.db_logs import write_log_entry
|
||||
from src.common.encoding import int_to_bytes
|
||||
|
@ -236,8 +237,9 @@ class TestChMasterKey(TFCTestCase):
|
|||
|
||||
@mock.patch('getpass.getpass', return_value='a')
|
||||
@mock.patch('time.sleep', return_value=None)
|
||||
@mock.patch('src.common.db_masterkey.ARGON2_MIN_MEMORY', 1000)
|
||||
@mock.patch('os.popen', return_value=MagicMock(read=MagicMock(return_value='foo\nMemFree 200')))
|
||||
@mock.patch('src.common.db_masterkey.MIN_KEY_DERIVATION_TIME', 0.01)
|
||||
@mock.patch('src.common.db_masterkey.MIN_KEY_DERIVATION_TIME', 1.01)
|
||||
def test_master_key_change(self, *_):
|
||||
# Setup
|
||||
write_log_entry(F_S_HEADER + bytes(PADDING_LENGTH), nick_to_pub_key("Alice"), self.settings, self.master_key)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
@ -307,8 +307,8 @@ class TestKeyExPSKRx(TFCTestCase):
|
|||
# Test
|
||||
self.assert_fr("Error: The PSK data in the file was invalid.", key_ex_psk_rx, *self.args)
|
||||
|
||||
@mock.patch('time.sleep', return_value=None)
|
||||
@mock.patch('builtins.input', return_value=file_name)
|
||||
@mock.patch('time.sleep', return_value=None)
|
||||
@mock.patch('builtins.input', return_value=file_name)
|
||||
def test_permission_error_raises_fr(self, *_):
|
||||
# Setup
|
||||
with open(self.file_name, 'wb+') as f:
|
||||
|
@ -324,8 +324,8 @@ class TestKeyExPSKRx(TFCTestCase):
|
|||
self.assertEqual("Error: No read permission for the PSK file.", inst.message)
|
||||
self.assertTrue(e_raised)
|
||||
|
||||
@mock.patch('src.receiver.key_exchanges.ARGON2_ROUNDS', 1)
|
||||
@mock.patch('src.receiver.key_exchanges.ARGON2_MIN_MEMORY', 100)
|
||||
@mock.patch('src.receiver.key_exchanges.ARGON2_PSK_TIME_COST', 1)
|
||||
@mock.patch('src.receiver.key_exchanges.ARGON2_PSK_MEMORY_COST', 100)
|
||||
@mock.patch('getpass.getpass', side_effect=['invalid', 'password'])
|
||||
@mock.patch('time.sleep', return_value=None)
|
||||
@mock.patch('os.urandom', side_effect=[bytes(XCHACHA20_NONCE_LENGTH)])
|
||||
|
@ -339,7 +339,7 @@ class TestKeyExPSKRx(TFCTestCase):
|
|||
salt = bytes(ARGON2_SALT_LENGTH)
|
||||
rx_key = bytes(SYMMETRIC_KEY_LENGTH)
|
||||
rx_hek = bytes(SYMMETRIC_KEY_LENGTH)
|
||||
kek = argon2_kdf('password', salt, rounds=1, memory=100)
|
||||
kek = argon2_kdf('password', salt, time_cost=1, memory_cost=100)
|
||||
ct_tag = encrypt_and_sign(rx_key + rx_hek, key=kek)
|
||||
|
||||
with open(self.file_name, 'wb+') as f:
|
||||
|
@ -348,8 +348,8 @@ class TestKeyExPSKRx(TFCTestCase):
|
|||
# Test
|
||||
self.assert_fr("Error: Received invalid keys from contact.", key_ex_psk_rx, *self.args)
|
||||
|
||||
@mock.patch('src.receiver.key_exchanges.ARGON2_ROUNDS', 1)
|
||||
@mock.patch('src.receiver.key_exchanges.ARGON2_MIN_MEMORY', 100)
|
||||
@mock.patch('src.receiver.key_exchanges.ARGON2_PSK_TIME_COST', 1)
|
||||
@mock.patch('src.receiver.key_exchanges.ARGON2_PSK_MEMORY_COST', 100)
|
||||
@mock.patch('time.sleep', return_value=None)
|
||||
@mock.patch('builtins.input', return_value=file_name)
|
||||
@mock.patch('getpass.getpass', return_value='test_password')
|
||||
|
@ -361,7 +361,7 @@ class TestKeyExPSKRx(TFCTestCase):
|
|||
salt = os.urandom(ARGON2_SALT_LENGTH)
|
||||
rx_key = os.urandom(SYMMETRIC_KEY_LENGTH)
|
||||
rx_hek = os.urandom(SYMMETRIC_KEY_LENGTH)
|
||||
kek = argon2_kdf('test_password', salt, rounds=1, memory=100)
|
||||
kek = argon2_kdf('test_password', salt, time_cost=1, memory_cost=100)
|
||||
ct_tag = encrypt_and_sign(rx_key + rx_hek, key=kek)
|
||||
|
||||
with open(self.file_name, 'wb+') as f:
|
||||
|
@ -374,8 +374,8 @@ class TestKeyExPSKRx(TFCTestCase):
|
|||
self.assertEqual(keyset.rx_mk, rx_key)
|
||||
self.assertEqual(keyset.rx_hk, rx_hek)
|
||||
|
||||
@mock.patch('src.receiver.key_exchanges.ARGON2_ROUNDS', 1)
|
||||
@mock.patch('src.receiver.key_exchanges.ARGON2_MIN_MEMORY', 100)
|
||||
@mock.patch('src.receiver.key_exchanges.ARGON2_PSK_TIME_COST', 1)
|
||||
@mock.patch('src.receiver.key_exchanges.ARGON2_PSK_MEMORY_COST', 100)
|
||||
@mock.patch('subprocess.Popen')
|
||||
@mock.patch('time.sleep', return_value=None)
|
||||
@mock.patch('builtins.input', side_effect=[file_name, ''])
|
||||
|
@ -389,7 +389,7 @@ class TestKeyExPSKRx(TFCTestCase):
|
|||
salt = os.urandom(ARGON2_SALT_LENGTH)
|
||||
rx_key = os.urandom(SYMMETRIC_KEY_LENGTH)
|
||||
rx_hek = os.urandom(SYMMETRIC_KEY_LENGTH)
|
||||
kek = argon2_kdf('test_password', salt, rounds=1, memory=100)
|
||||
kek = argon2_kdf('test_password', salt, time_cost=1, memory_cost=100)
|
||||
ct_tag = encrypt_and_sign(rx_key + rx_hek, key=kek)
|
||||
|
||||
with open(self.file_name, 'wb+') as f:
|
||||
|
@ -402,8 +402,8 @@ class TestKeyExPSKRx(TFCTestCase):
|
|||
self.assertEqual(keyset.rx_mk, rx_key)
|
||||
self.assertEqual(keyset.rx_hk, rx_hek)
|
||||
|
||||
@mock.patch('src.receiver.key_exchanges.ARGON2_ROUNDS', 1)
|
||||
@mock.patch('src.receiver.key_exchanges.ARGON2_MIN_MEMORY', 100)
|
||||
@mock.patch('src.receiver.key_exchanges.ARGON2_PSK_TIME_COST', 1)
|
||||
@mock.patch('src.receiver.key_exchanges.ARGON2_PSK_MEMORY_COST', 100)
|
||||
@mock.patch('subprocess.Popen')
|
||||
@mock.patch('time.sleep', return_value=None)
|
||||
@mock.patch('builtins.input', side_effect=[file_name, ''])
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
@ -22,10 +22,12 @@ along with TFC. If not, see <https://www.gnu.org/licenses/>.
|
|||
import os
|
||||
import unittest
|
||||
|
||||
from unittest import mock
|
||||
from unittest import mock
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
from src.common.db_logs import write_log_entry
|
||||
from src.common.statics import *
|
||||
from src.common.db_logs import write_log_entry
|
||||
from src.common.encoding import bool_to_bytes
|
||||
from src.common.statics import *
|
||||
|
||||
from src.transmitter.commands import change_master_key, change_setting, clear_screens, exit_tfc, log_command
|
||||
from src.transmitter.commands import print_about, print_help, print_recipients, print_settings, process_command
|
||||
|
@ -240,9 +242,9 @@ class TestLogCommand(TFCTestCase):
|
|||
@mock.patch('builtins.input', return_value='Yes')
|
||||
def test_successful_export_command(self, *_):
|
||||
# Setup
|
||||
self.window.type = 'contact'
|
||||
self.window.type = WIN_TYPE_CONTACT
|
||||
self.window.uid = nick_to_pub_key('Alice')
|
||||
whisper_header = b'\x00'
|
||||
whisper_header = bool_to_bytes(False)
|
||||
packet = split_to_assembly_packets(whisper_header + PRIVATE_MESSAGE_HEADER + b'test', MESSAGE)[0]
|
||||
write_log_entry(packet, nick_to_pub_key('Alice'), self.settings, self.master_key)
|
||||
|
||||
|
@ -473,9 +475,9 @@ class TestChangeMasterKey(TFCTestCase):
|
|||
self.assert_fr("Error: Invalid target system 't'.",
|
||||
change_master_key, UserInput("passwd t"), *self.args)
|
||||
|
||||
@mock.patch('os.popen', return_value=MagicMock(read=MagicMock(return_value='foo\nMemFree 200')))
|
||||
@mock.patch('getpass.getpass', return_value='a')
|
||||
@mock.patch('time.sleep', return_value=None)
|
||||
@mock.patch('src.common.db_masterkey.ARGON2_MIN_MEMORY', 1000)
|
||||
@mock.patch('src.common.db_masterkey.MIN_KEY_DERIVATION_TIME', 0.01)
|
||||
def test_transmitter_command(self, *_):
|
||||
# Setup
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
@ -78,7 +78,7 @@ class TestAddNewContact(TFCTestCase):
|
|||
@mock.patch('builtins.input', side_effect=[nick_to_onion_address("Alice"), 'Alice_', 'psk', '.'])
|
||||
@mock.patch('getpass.getpass', return_value='test_password')
|
||||
@mock.patch('time.sleep', return_value=None)
|
||||
@mock.patch('src.transmitter.key_exchanges.ARGON2_MIN_MEMORY', 1000)
|
||||
@mock.patch('src.transmitter.key_exchanges.ARGON2_PSK_MEMORY_COST', 200)
|
||||
@mock.patch('src.transmitter.key_exchanges.MIN_KEY_DERIVATION_TIME', 0.01)
|
||||
def test_standard_nick_psk_kex(self, *_):
|
||||
self.onion_service.account = nick_to_onion_address('Bob').encode()
|
||||
|
@ -236,6 +236,15 @@ class TestChangeNick(TFCTestCase):
|
|||
# Test
|
||||
self.assert_fr("Error: Nick must be printable.", change_nick, UserInput("nick Alice\x01"), window, *self.args)
|
||||
|
||||
def test_no_contact_raises_fr(self):
|
||||
# Setup
|
||||
window = TxWindow(type=WIN_TYPE_CONTACT,
|
||||
contact=create_contact('Bob'))
|
||||
window.contact = None
|
||||
|
||||
# Test
|
||||
self.assert_fr("Error: Window does not have contact.", change_nick, UserInput("nick Alice\x01"), window, *self.args)
|
||||
|
||||
def test_successful_nick_change(self):
|
||||
# Setup
|
||||
window = TxWindow(name='Alice',
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
@ -45,7 +45,6 @@ class TestInputLoop(unittest.TestCase):
|
|||
'Yes', # Accept key fingerprints for Alice
|
||||
conf_code, # Confirmation code
|
||||
'Alice', # Select Alice as the recipient
|
||||
'Alice', # Select Alice as the recipient
|
||||
'Test', # Send test message
|
||||
'/file', # Open file selection prompt
|
||||
'', # Give empty string to abort
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
@ -252,8 +252,8 @@ class TestPSK(TFCTestCase):
|
|||
@mock.patch('builtins.input', side_effect=['/root/', '.'])
|
||||
@mock.patch('time.sleep', return_value=None)
|
||||
@mock.patch('getpass.getpass', return_value='test_password')
|
||||
@mock.patch('src.transmitter.key_exchanges.ARGON2_MIN_MEMORY', 1000)
|
||||
@mock.patch('src.transmitter.key_exchanges.MIN_KEY_DERIVATION_TIME', 0.01)
|
||||
@mock.patch('src.transmitter.key_exchanges.ARGON2_PSK_MEMORY_COST', 1000)
|
||||
@mock.patch('src.transmitter.key_exchanges.ARGON2_PSK_TIME_COST', 1)
|
||||
def test_psk_creation(self, *_):
|
||||
self.assertIsNone(create_pre_shared_key(nick_to_pub_key("Alice"), 'Alice', *self.args))
|
||||
|
||||
|
@ -323,9 +323,9 @@ class TestReceiverLoadPSK(TFCTestCase):
|
|||
# Test
|
||||
self.assert_fr(f"Error: The current key was exchanged with {ECDHE}.",
|
||||
rxp_load_psk, window, contact_list, *self.args)
|
||||
|
||||
@mock.patch('src.transmitter.key_exchanges.ARGON2_MIN_MEMORY', 1000)
|
||||
@mock.patch('src.transmitter.key_exchanges.MIN_KEY_DERIVATION_TIME', 0.01)
|
||||
|
||||
@mock.patch('src.transmitter.key_exchanges.ARGON2_PSK_MEMORY_COST', 1000)
|
||||
@mock.patch('src.transmitter.key_exchanges.ARGON2_PSK_TIME_COST', 0.01)
|
||||
@mock.patch('time.sleep', return_value=None)
|
||||
@mock.patch('builtins.input', side_effect=[b'0'.hex(), blake2b(nick_to_pub_key('Alice'),
|
||||
digest_size=CONFIRM_CODE_LENGTH).hex()])
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
@ -335,7 +335,7 @@ class TestQueueAssemblyPackets(unittest.TestCase):
|
|||
|
||||
def test_queue_message_traffic_masking(self):
|
||||
# Setup
|
||||
packet_list = split_to_assembly_packets(os.urandom(200), MESSAGE)
|
||||
packet_list = split_to_assembly_packets(os.urandom(200), MESSAGE)
|
||||
self.settings.traffic_masking = True
|
||||
|
||||
# Test
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python3.6
|
||||
#!/usr/bin/env python3.7
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue