Compare commits
75 Commits
wot
...
integrate-
Author | SHA1 | Date | |
---|---|---|---|
|
81c8c4f124 | ||
|
7fba65c459 | ||
|
4b36e9d3da | ||
|
346d30086e | ||
|
60dfa8fb7e | ||
|
db5320124f | ||
|
2ffcc2e18e | ||
|
630a9b1522 | ||
|
4bf1acf446 | ||
|
257bef6ca0 | ||
|
d9c0adcc7b | ||
|
8a6129f4e2 | ||
|
18d4a87973 | ||
|
ad103ee8b0 | ||
|
b720f2f1d5 | ||
|
bae7f745ee | ||
|
227472d4dc | ||
|
f4182cb996 | ||
|
b4127c9836 | ||
|
9d546432f5 | ||
|
5ea90acd3f | ||
|
9d8c7a7224 | ||
|
582ac1607e | ||
|
c40effd520 | ||
|
9d13c0c989 | ||
|
ee8b81ead6 | ||
|
418237cfc6 | ||
|
84987cfc21 | ||
|
63f7209bdd | ||
|
67d9dc3557 | ||
|
a2da6b8c89 | ||
|
6625b7ce19 | ||
|
da353476cf | ||
|
828c78a569 | ||
|
a55055e720 | ||
|
ba8ba6d3d8 | ||
|
708c5d2e71 | ||
|
75234310ca | ||
|
5ed5b8455a | ||
|
003718db04 | ||
|
db96f6ad7e | ||
|
7cb4731156 | ||
|
d03620db7e | ||
|
1d1edfd0f1 | ||
|
001bdda433 | ||
|
aeb2e16d8b | ||
|
847f80b8f4 | ||
|
2ffc8c637e | ||
|
e41e3fd01d | ||
|
a3ce191ed3 | ||
|
9e2d374270 | ||
|
504ef3a49a | ||
|
ec9dbe383c | ||
|
7390539d50 | ||
|
0f7ea4e4c8 | ||
|
86dca2dd2b | ||
|
0e69d88708 | ||
|
cd0ec77189 | ||
|
6bcfd91352 | ||
|
5df747d658 | ||
|
b7ab487fac | ||
|
f44ca60c6e | ||
|
b6bb350b65 | ||
|
30b73c7f7c | ||
|
ca37f6df9d | ||
|
f5dfd16408 | ||
|
9ed17f4fb6 | ||
|
dc51c26b13 | ||
|
db641341c5 | ||
|
8ddc38515d | ||
|
7ab330a710 | ||
|
153d530f38 | ||
|
9e01c65c0f | ||
|
2eb3e93666 | ||
|
f1edd1932e |
12
AUTHORS.MD
Normal file
12
AUTHORS.MD
Normal file
@ -0,0 +1,12 @@
|
||||
# Incomplete List of Contributors
|
||||
|
||||
Onionr is created by a team of hard working volunteers.
|
||||
|
||||
In no order of importance, these people make Onionr happen:
|
||||
|
||||
* [Beardog (Kevin Froman)](https://www.chaoswebs.net/) - Project founder, owner and core developer
|
||||
* [InvisaMage](https://invisamage.com/) - Web UI Bulma design
|
||||
* [Arinerron](https://arinerron.com/) - Logger and config modules, testing and other contributions
|
||||
* [Anhar Ismail](https://github.com/anharismail) - Created Onionr's logo
|
||||
|
||||
+ Other contributors and testers
|
@ -1,4 +1,4 @@
|
||||
FROM python:3.10
|
||||
FROM python:3.7
|
||||
EXPOSE 8080
|
||||
|
||||
USER root
|
||||
@ -15,7 +15,7 @@ RUN sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && \
|
||||
locale-gen
|
||||
ENV LANG=en_US.UTF-8 LANGUAGE=en_US:en LC_ALL=en_US.UTF-8
|
||||
|
||||
ADD ./requirements-x86-all-plugins.txt /app/requirements.txt
|
||||
ADD ./requirements.txt /app/requirements.txt
|
||||
RUN pip3 install --require-hashes -r requirements.txt
|
||||
|
||||
#Add Onionr source
|
||||
@ -28,4 +28,4 @@ RUN chmod g=u -R /app
|
||||
USER 1000
|
||||
ENV HOME=/app
|
||||
|
||||
CMD ["bash", "./onionr.sh", "start"]
|
||||
CMD ["bash", "./run-onionr-node.sh"]
|
||||
|
83
README.md
83
README.md
@ -8,26 +8,24 @@
|
||||
Privacy Respecting Communication Network 📡
|
||||
</p>
|
||||
<p align="center">
|
||||
WIP anonymous social platform, mail, file sharing and marketplace
|
||||
Anonymous social platform, mail, file sharing.
|
||||
</p>
|
||||
|
||||
<img src="https://img.shields.io/badge/License-aGPLv3-yellow"> <img src='https://img.shields.io/badge/python%20version%20%F0%9F%90%8D-3.10+-blue'>
|
||||
<img src='https://img.shields.io/github/license/beardog108/onionr'> <img src="https://img.shields.io/github/repo-size/beardog108/onionr"> <img src='https://img.shields.io/badge/python%20version%20%F0%9F%90%8D-3.7+-blue'> <img src='https://img.shields.io/github/commit-activity/m/beardog108/onionr'>
|
||||
|
||||
<a href='https://twitter.com/onionrnet'><img src='https://img.shields.io/twitter/follow/onionrnet?style=social'></a> - [Discord](https://discord.gg/DVF2bEAzrt) - Matrix: #onionr:amorgan.xyz
|
||||
<a href='https://www.reddit.com/r/onionr'><img src = 'https://img.shields.io/reddit/subreddit-subscribers/onionr?style=social'></a> <a href='https://twitter.com/onionrnet'><img src='https://img.shields.io/twitter/follow/onionrnet?style=social'></a> - [Discord](https://discord.gg/DVF2bEAzrt) - Matrix: #onionr:amorgan.xyz
|
||||
|
||||
| | | |
|
||||
| ----------- | ----------- | ----------- |
|
||||
| [Install](#install-and-run-on-linux) | [Features](#main-features) | [Screenshots](#screenshots)|
|
||||
| [Docs](#documentation) | [Get involved](#help-out) | [Onionr.net](https://onionr.net/)/[.onion](http://onionrbak72t5zhbzuey2fdkpczlvhowgcpqc6uoyrd3uxztzxwz5cyd.onion/) |
|
||||
| [Docs](#documentation)/[web copy](https://beardog108.github.io/onionr/) | [Get involved](#help-out) | [Onionr.net](https://onionr.net/)/[.onion](http://onionrbak72t5zhbzuey2fdkpczlvhowgcpqc6uoyrd3uxztzxwz5cyd.onion/) |
|
||||
|
||||
|
||||
---
|
||||
|
||||
**The main repository for this software is at https://gitlab.com/beardog/onionr/**
|
||||
**The main repository for this software is at https://git.VoidNet.tech/kev/onionr/**
|
||||
|
||||
***Note that this README reflects the state of the rewrite, and not the original alpha network***
|
||||
|
||||
Mirrors [Gitea](https://git.voidnet.tech/kev/onionr)
|
||||
Mirrors: [Github](https://github.com/beardog108/onionr), [Gitlab](https://gitlab.com/beardog/onionr)
|
||||
|
||||
|
||||
Onionr ("Onion Relay") is a decentralized/distributed peer-to-peer communication network, designed to be anonymous and resistant to (meta)data analysis, spam, and corruption.
|
||||
@ -36,45 +34,65 @@ Onionr gives the individual the ability to speak freely, without fear of surveil
|
||||
|
||||
---
|
||||
|
||||
# Onionr internals
|
||||
Onionr stores data in independent packages referred to as 'blocks'. The blocks are distributed to all nodes interested in their data type. Blocks and user IDs cannot be easily proven to have been created by a particular user. Even if there is enough evidence to believe that a specific user created a block, nodes still operate behind Tor and as such cannot be trivially unmasked. Anonymity is achieved by a stateless network, with no given indication of what node a block originates from. In fact, since one is not required to participate in routing or storage to insert a message, blocks often do not originate from any identifiable node.
|
||||
|
||||
## Blocks
|
||||
Onionr works primarily via epidemic/gossip style routing, with message delivery taking roughly log<sub>F</sub>(N) cycles where F is the number of nodes to send a message to each cycle and N is the number of connected nodes. So a network of 100 million nodes can deliver messages in a few minutes even with high packet loss and malfunctioning nodes.
|
||||
|
||||
At the core, Onionr is an anonymous Distributed Hash Table (DHT) syncing prepackaged blocks using a simple Gossip protocol with Dandelion++ as an overlay network on top of Tor and I2P.
|
||||
|
||||
Onionr stores data in independent packages referred to as 'blocks'. The blocks are distributed to all nodes, but are not required to be stored. Blocks and user IDs cannot be easily proven to have been created by a particular user. Even if Dandelion++ is defeated and there is enough evidence to believe that a specific node is linked to a block's creation, nodes still operate behind Tor or I2P and as such cannot be trivially unmasked. Anonymity is achieved by a stateless network, with no given indication of what node a block originates from. In fact, since one is not required to participate in routing or storage to insert a message, blocks often do not originate from any identifiable node, similar to how Bitcoin transactions do not necessarily originate from a wallet directly associated with a node.
|
||||
|
||||
## Onionr Gossip
|
||||
|
||||
Onionr works via epidemic/gossip style routing, with message delivery taking roughly log<sub>C</sub>(N) cycles where C is the number of nodes to send a message to each cycle and N is the number of connected nodes. So a network of 100 million nodes can deliver messages in a few minutes even with high packet loss and malfunctioning nodes.
|
||||
|
||||
Through Dandelion++ message forwarding and key privacy, it is intended to be nigh impossible to discover the identity of a message creator or recipient. Via long-term traffic analysis, a well funded adversary may discover the most probable node(s) to be creating a set of related blocks, however doing so would only lead them to a node behind Tor. As the first node that a block appears on is almost always not the creator of the block, there is plausible deniability regarding the true creator of the block.
|
||||
Through message mixing and key privacy, it is intended to be nigh impossible to discover the identity of a message creator or recipient. Via long-term traffic analysis, a well funded adversary may discover the most probable node(s) to be creating a set of related blocks, however doing so would only lead them to a node behind Tor. As the first node that a block appears on is almost always not the creator of the block, there is plausible deniability regarding the true creator of the block.
|
||||
|
||||
Users are identified by ed25519/curve25519 public keys, which can be used to sign blocks or send encrypted data.
|
||||
|
||||
Onionr can be used for mail, as a social network, instant messenger, file sharing software, or for encrypted group discussion.
|
||||
|
||||
Since Onionr is technically just a data format, any routing scheme can technically be used to pass messages.
|
||||
Due to the nature of anonymity, the graph as implemented in this reference network is dense, undirected, cyclic and can be disconnected. Since Onionr is technically just a data format, any routing scheme can be used to pass messages.
|
||||
|
||||
The whitepaper is available [here](docs/whitepaper.md).
|
||||
|
||||
---
|
||||
|
||||
# Main Features
|
||||
## Main Features
|
||||
|
||||
* [X] 🌐 Fully p2p/decentralized, no trackers or other single points of failure
|
||||
* [X] 🔒 End to end encryption of user data
|
||||
* [X] 📢 Optional non-encrypted blocks, useful for blog posts or public file sharing
|
||||
* [X] 💻 Easy HTTP API for integration to websites
|
||||
* [X] 🕵️ Metadata analysis resistance and anonymity
|
||||
* [X] 📡 Transport agnosticism (no internet required)
|
||||
|
||||
Onionr ships with various application plugins ready for use out of the box:
|
||||
|
||||
# Roadmap
|
||||
Currently usable:
|
||||
|
||||
See [ROADMAP.md](ROADMAP.md)
|
||||
* 📨 Mail
|
||||
* 💬 Public anonymous chat/message board
|
||||
* 📃 Simple webpage hosting - Will be greatly extended
|
||||
* File sharing (Work in progress)
|
||||
|
||||
Not yet usable:
|
||||
|
||||
* Instant messaging
|
||||
|
||||
|
||||
# Screenshots
|
||||
|
||||
<img alt='Node statistics page screenshot' src='docs/onionr-1.png' width=600>
|
||||
|
||||
Home screen
|
||||
|
||||
<img alt='Friend/contact manager screenshot' src='docs/onionr-2.png' width=600>
|
||||
|
||||
Friend/contact manager
|
||||
|
||||
<img alt='Encrypted, metadata-masking mail application screenshot' src='docs/onionr-3.png' width=600>
|
||||
|
||||
Encrypted, metadata-masking mail application. One of the first distributed mail systems to have basic forward secrecy.
|
||||
|
||||
# Documentation
|
||||
|
||||
More docs coming soon.
|
||||
|
||||
* [Block specification](docs/dev/specs/block-spec.md)
|
||||
* [HTTP API](docs/dev/http-api.md)
|
||||
|
||||
# Install and Run on Linux
|
||||
|
||||
@ -84,27 +102,30 @@ Master may be unstable, you should use the latest release tag. (checkout via git
|
||||
|
||||
`$ sudo apt install python3-pip python3-dev tor`
|
||||
|
||||
* Have python3.10, python3-pip, Tor (daemon, not browser) installed. python3-dev is recommended.
|
||||
* Have python3.7+, python3-pip, Tor (daemon, not browser) installed. python3-dev is recommended.
|
||||
* You may need build-essentials or the equivalent of your platform
|
||||
* Clone the git repo: `$ git clone https://gitlab.com/beardog/onionr --tags`
|
||||
* cd into install direction: `$ cd onionr/`
|
||||
* Install the Python dependencies ([virtualenv strongly recommended](https://virtualenv.pypa.io/en/stable/userguide/)): `$ pip3 install --require-hashes -r requirements-x86-all-plugins.txt`
|
||||
* Install the Python dependencies ([virtualenv strongly recommended](https://virtualenv.pypa.io/en/stable/userguide/)): `$ pip3 install --require-hashes -r requirements.txt` (on ARM64 devices like Raspberry Pi 4's use requirements-ARM.txt instead.)
|
||||
* (Optional): Install desktop notification dependencies: `$ pip3 install --require-hashes -r requirements-notifications.txt`
|
||||
|
||||
Require-hashes is suggested for supply-chain security but is optional. The hashes are not correct for ARM machines. If you are just running a node or want a bare-bones install you can use requirements-base-x86.txt and selectively install the requirements.txt files in static-data/official-plugins/ subdirectories
|
||||
(--require-hashes is intended to prevent exploitation via compromise of PyPi/CA certificates)
|
||||
|
||||
## Run Onionr
|
||||
|
||||
* Run Onionr normally: `$ ./onionr.sh start`
|
||||
* Run Onionr in background as daemon: `$ ./start-daemon.sh`
|
||||
* Open Onionr web interface `$ ./onionr.sh openhome`
|
||||
* Gracefully stop Onionr from CLI `$ ./onionr.sh stop`
|
||||
|
||||
|
||||
# Contact/Community
|
||||
|
||||
* Email: onionr [ at ] voidnet.tech
|
||||
* Email: beardog [ at ] mailbox.org
|
||||
* Twitter: [@onionrnet](https://twitter.com/onionrnet)
|
||||
* Onionr Mail: decentralized-fiery-freehearted-skimmer-yodling-topstitch-divorceable-ojibwa-resettlement-infracted-lessor-noninstinctual-leaseholder-counterpoised-couture-skinful
|
||||
* Matrix: #onionr:amorgan.xyz
|
||||
* Discord: https://discord.gg/DVF2bEAzrt (Discord is bad for freedom and privacy, this is only provided for convenience)
|
||||
* Discord: https://discord.gg/DVF2bEAzrt (Discord is bad for freedom and privacy, this is only provided for convienience)
|
||||
|
||||
# Help out
|
||||
|
||||
@ -113,7 +134,7 @@ Everyone is welcome to contribute. Help is wanted for the following:
|
||||
* Development (Get in touch first)
|
||||
* Creation of a shared lib for use from other languages and faster proof-of-work
|
||||
* Android and IOS development
|
||||
* Mac support (testers needed)
|
||||
* Mac support (already partially supported, testers needed)
|
||||
* Bug fixes and development of new features
|
||||
* Testing
|
||||
* Translations/localizations
|
||||
@ -135,7 +156,7 @@ Donating at least $3 gets you cool Onionr stickers. Get in touch if you want the
|
||||
![sticker](docs/sticker.png)
|
||||
|
||||
|
||||
* Bitcoin: [bc1qpayme9rlpkch0qp3r79lvm5racr7t6llauwfmg](bitcoin:bc1qpayme9rlpkch0qp3r79lvm5racr7t6llauwfmg) (Contact us for a unique address or for other coins)
|
||||
* Bitcoin: [1onion55FXzm6h8KQw3zFw2igpHcV7LPq](bitcoin:1onion55FXzm6h8KQw3zFw2igpHcV7LPq) (Contact us for a unique address or for other coins)
|
||||
|
||||
* Monero: 4B5BA24d1P3R5aWEpkGY5TP7buJJcn2aSGBVRQCHhpiahxeB4aWsu15XwmuTjC6VF62NApZeJGTS248RMVECP8aW73Uj2ax
|
||||
|
||||
@ -143,7 +164,7 @@ Donating at least $3 gets you cool Onionr stickers. Get in touch if you want the
|
||||
|
||||
* Sign up for [privacy.com (refferal link)](https://privacy.com/join/FNNDF) to protect your personal information when contributing or shopping elsewhere, we both get $5 USD.
|
||||
|
||||
Note: not tax deductible
|
||||
Note: probably not tax deductible
|
||||
|
||||
# Security
|
||||
|
||||
|
46
ROADMAP.md
46
ROADMAP.md
@ -1,46 +0,0 @@
|
||||
# Onionr Roadmap
|
||||
|
||||
|
||||
## Taraxacum Release (9.0)
|
||||
|
||||
|
||||
* [ X ] Implement new block format with verifiable delay function
|
||||
|
||||
* [ X ] Implement overhauled gossip system with dandelion++
|
||||
|
||||
The new system is separated from the underlying networks used and makes it much easier to implement new transport methods. Dandelion++ is also better than the old block mixing we did.
|
||||
|
||||
|
||||
## Misc
|
||||
|
||||
* [ ] Spruce up documentation
|
||||
* [ ] Restore LAN transport
|
||||
* [ ] Restore webUI as a plugin
|
||||
* [ ] Restore static site/file sharing plugin
|
||||
* [ ] Restore/reimplement mail plugin
|
||||
* [ ] Restore/reimplement friends plugin
|
||||
* [ ] Refresh test suite
|
||||
* [ ] Revamped key/encrypted messaging (encrypted blocks)
|
||||
|
||||
|
||||
|
||||
## Web of trust release (~10.0)
|
||||
|
||||
To facilitate the below market plugin/application, Onionr will need a web of trust system.
|
||||
|
||||
* [ ] Web of trust plugin or module
|
||||
|
||||
|
||||
## Market Plugin Release (~10.1)
|
||||
|
||||
The Onionr team believes the Monero community is currently lacking a good p2p market, and as such we hope to build a solution using Onionr as a transport. This may be a separate project and as opposed to a plugin.
|
||||
|
||||
|
||||
* A new marketplace plugin will be developed with the following *tenative* features:
|
||||
|
||||
* [ ] Account management
|
||||
* [ ] Monero management
|
||||
* [ ] Store front discovery and search
|
||||
* [ ] Product listing search
|
||||
* [ ] User reviews
|
||||
|
@ -1,8 +0,0 @@
|
||||
PyNaCl==1.5.0
|
||||
psutil==5.9.1
|
||||
filenuke==0.0.0
|
||||
ujson==5.4.0
|
||||
cffi==1.15.1
|
||||
onionrblocks==7.0.0
|
||||
ordered-set==4.1.0
|
||||
json-rpc==1.13.0
|
6
docs/dev/blockio-keys.txt
Normal file
6
docs/dev/blockio-keys.txt
Normal file
@ -0,0 +1,6 @@
|
||||
Blockio wraps safedb, the new key value database module
|
||||
|
||||
This is how the keys are setup and what they are for:
|
||||
|
||||
bl-{type}: bytes of hashes for each block type
|
||||
{block hash}: block data
|
112
docs/dev/http-api.md
Executable file
112
docs/dev/http-api.md
Executable file
@ -0,0 +1,112 @@
|
||||
# Onionr HTTP API
|
||||
|
||||
All HTTP interfaces in the Onionr reference client use the [Flask](http://flask.pocoo.org/) web framework with the [gevent](http://www.gevent.org/) WSGI server.
|
||||
|
||||
## Client & Public difference
|
||||
|
||||
The client API server is a locked down interface intended for authenticated local communication.
|
||||
|
||||
The public API server is available only remotely from Tor & I2P. It is the interface in which peers use to communicate with one another.
|
||||
|
||||
# Client API
|
||||
|
||||
Please note: endpoints that simply provide static web app files are not documented here.
|
||||
|
||||
* /serviceactive/pubkey
|
||||
- Methods: GET
|
||||
- Returns true or false based on if a given public key has an active direct connection service.
|
||||
* /queueResponseAdd/key (DEPRECATED)
|
||||
- Methods: POST
|
||||
- Accepts form key 'data' to set queue response information from a plugin
|
||||
- Returns success if no error occurs
|
||||
* /queueResponse/key (DEPRECATED)
|
||||
- Methods: GET
|
||||
- Returns the queue response for a key. Returns failure with a 404 code if a code is not set.
|
||||
* /ping
|
||||
- Methods: GET
|
||||
- Returns "pong!"
|
||||
* /getblocksbytype/type
|
||||
- Methods: GET
|
||||
- Returns a list of stored blocks by a given type
|
||||
* /getblockbody/hash
|
||||
- Methods: GET
|
||||
- Returns the main data section of a block
|
||||
* /getblockdata/hash
|
||||
- Methods: GET
|
||||
- Returns the entire data contents of a block, including metadata.
|
||||
* /getblockheader/hash
|
||||
- Methods: GET
|
||||
- Returns the header (metadata section) of a block.
|
||||
* /gethidden/
|
||||
- Methods: GET
|
||||
- Returns line separated list of hidden blocks
|
||||
* /hitcount
|
||||
- Methods: GET
|
||||
- Return the amount of requests the public api server has received this session
|
||||
* /lastconnect
|
||||
- Methods: GET
|
||||
- Returns the epoch timestamp of when the last incoming connection to the public API server was logged
|
||||
* /site/hash
|
||||
- Methods: GET
|
||||
- Returns HTML content out of a block
|
||||
* /waitforshare/hash
|
||||
- Methods: POST
|
||||
- Prevents the public API server from listing or sharing a block until it has been uploaded to at least 1 peer.
|
||||
* /shutdown
|
||||
- Methods: GET
|
||||
- Shutdown Onionr. You should probably use /shutdownclean instead.
|
||||
* /shutdownclean
|
||||
- Methods: GET
|
||||
- Tells the communicator daemon to shutdown Onionr. Slower but cleaner.
|
||||
* /getstats
|
||||
- Methods: GET
|
||||
- Returns some JSON serialized statistics
|
||||
* /getuptime
|
||||
- Methods: GET
|
||||
- Returns uptime in seconds
|
||||
|
||||
# Public API
|
||||
|
||||
v0
|
||||
|
||||
* /
|
||||
- Methods: GET
|
||||
- Returns a basic HTML informational banner describing Onionr.
|
||||
* /getblocklist
|
||||
- Methods: GET
|
||||
- URI Parameters:
|
||||
- date: unix epoch timestamp for offset
|
||||
- Returns a list of block hashes stored on the node since an offset (all blocks if no timestamp is specified)
|
||||
* /getdata/block-hash
|
||||
- Methods: GET
|
||||
- Returns data for a block based on a provided hash
|
||||
* /www/file-path
|
||||
- Methods: GET
|
||||
- Returns file data. Intended for manually sharing file data directly from an Onionr node.
|
||||
* /ping
|
||||
- Methods: GET
|
||||
- Returns 'pong!'
|
||||
* /pex
|
||||
- Methods: GET
|
||||
- Returns a list of peer addresses reached within recent time
|
||||
* /announce
|
||||
- Methods: POST
|
||||
- Accepts form data for 'node' (valid node address) and 'random' which is a nonce when hashed (blake2b_256) in the format `hash(peerAddress+serverAddress+nonce)`, begins with at least 5 zeros.
|
||||
- Returns 200 with 'Success' if no error occurs. If the post is invalid, 'failure' with code 406 is returned.
|
||||
* /upload
|
||||
- Methods: POST
|
||||
- Accepts form data for 'block' as a 'file' upload.
|
||||
- Returns 200 with 'success' if no error occurs. If the block cannot be accepted, 'failure' with 400 is returned.
|
||||
|
||||
# Direct Connection API
|
||||
|
||||
These are constant endpoints available on direct connection servers. Plugin endpoints for direct connections are not documented here.
|
||||
|
||||
* /ping
|
||||
- Methods: GET
|
||||
- Returns 200 with 'pong!'
|
||||
|
||||
* /close
|
||||
- Methods: GET
|
||||
- Kills the direct connection server, destroying the onion address.
|
||||
- Returns 200 with 'goodbye'
|
@ -7,3 +7,4 @@ A paper being listed here is not end-all-be-all endorsement of every detail insi
|
||||
* [Protecting Free Expression Online with Freenet](https://freenetproject.org/assets/papers/ddisrs.pdf)
|
||||
* [Bitmessage: A Peer‐to‐Peer Message Authentication and Delivery System](https://archive.org/details/BitmessageWhitepaper/)
|
||||
* [MuON: Epidemic based Mutual Anonymity](https://web.archive.org/web/20060901153544/http://www.csl.mtu.edu/cs6461/www/Reading/MuON_ICNP2005.pdf)
|
||||
* [SWIM: Scalable Weakly-consistent Infection-style Process Group Membership Protocol](https://www.cs.cornell.edu/projects/Quicksilver/public_pdfs/SWIM.pdf)
|
@ -1,9 +1,6 @@
|
||||
#!/bin/sh
|
||||
ORIG_ONIONR_RUN_DIR=`pwd`
|
||||
export ORIG_ONIONR_RUN_DIR
|
||||
export PYTHONDONTWRITEBYTECODE=1
|
||||
export PYTHONUNBUFFERED=1
|
||||
export PYTHONOPTIMIZE="true"
|
||||
cd "$(dirname "$0")"
|
||||
cd src
|
||||
./__init__.py "$@"
|
392
requirements-ARM.txt
Normal file
392
requirements-ARM.txt
Normal file
@ -0,0 +1,392 @@
|
||||
#
|
||||
# This file is autogenerated by pip-compile
|
||||
# To update, run:
|
||||
#
|
||||
# pip-compile --generate-hashes --output-file=requirements-ARM.txt requirements.in
|
||||
#
|
||||
--extra-index-url https://www.piwheels.org/simple
|
||||
|
||||
certifi==2020.12.5 \
|
||||
--hash=sha256:1a4995114262bffbc2413b159f2a1a480c969de6e6eb13ee966d470af86af59c \
|
||||
--hash=sha256:719a74fb9e33b9bd44cc7f3a8d94bc35e4049deebe19ba7d8e108280cfd59830
|
||||
# via requests
|
||||
cffi==1.14.4 \
|
||||
--hash=sha256:00a1ba5e2e95684448de9b89888ccd02c98d512064b4cb987d48f4b40aa0421e \
|
||||
--hash=sha256:00e28066507bfc3fe865a31f325c8391a1ac2916219340f87dfad602c3e48e5d \
|
||||
--hash=sha256:045d792900a75e8b1e1b0ab6787dd733a8190ffcf80e8c8ceb2fb10a29ff238a \
|
||||
--hash=sha256:0638c3ae1a0edfb77c6765d487fee624d2b1ee1bdfeffc1f0b58c64d149e7eec \
|
||||
--hash=sha256:105abaf8a6075dc96c1fe5ae7aae073f4696f2905fde6aeada4c9d2926752362 \
|
||||
--hash=sha256:155136b51fd733fa94e1c2ea5211dcd4c8879869008fc811648f16541bf99668 \
|
||||
--hash=sha256:1a465cbe98a7fd391d47dce4b8f7e5b921e6cd805ef421d04f5f66ba8f06086c \
|
||||
--hash=sha256:1d2c4994f515e5b485fd6d3a73d05526aa0fcf248eb135996b088d25dfa1865b \
|
||||
--hash=sha256:2c24d61263f511551f740d1a065eb0212db1dbbbbd241db758f5244281590c06 \
|
||||
--hash=sha256:51a8b381b16ddd370178a65360ebe15fbc1c71cf6f584613a7ea08bfad946698 \
|
||||
--hash=sha256:594234691ac0e9b770aee9fcdb8fa02c22e43e5c619456efd0d6c2bf276f3eb2 \
|
||||
--hash=sha256:5cf4be6c304ad0b6602f5c4e90e2f59b47653ac1ed9c662ed379fe48a8f26b0c \
|
||||
--hash=sha256:64081b3f8f6f3c3de6191ec89d7dc6c86a8a43911f7ecb422c60e90c70be41c7 \
|
||||
--hash=sha256:6bc25fc545a6b3d57b5f8618e59fc13d3a3a68431e8ca5fd4c13241cd70d0009 \
|
||||
--hash=sha256:798caa2a2384b1cbe8a2a139d80734c9db54f9cc155c99d7cc92441a23871c03 \
|
||||
--hash=sha256:7c6b1dece89874d9541fc974917b631406233ea0440d0bdfbb8e03bf39a49b3b \
|
||||
--hash=sha256:840793c68105fe031f34d6a086eaea153a0cd5c491cde82a74b420edd0a2b909 \
|
||||
--hash=sha256:8d6603078baf4e11edc4168a514c5ce5b3ba6e3e9c374298cb88437957960a53 \
|
||||
--hash=sha256:9cc46bc107224ff5b6d04369e7c595acb700c3613ad7bcf2e2012f62ece80c35 \
|
||||
--hash=sha256:9f7a31251289b2ab6d4012f6e83e58bc3b96bd151f5b5262467f4bb6b34a7c26 \
|
||||
--hash=sha256:9ffb888f19d54a4d4dfd4b3f29bc2c16aa4972f1c2ab9c4ab09b8ab8685b9c2b \
|
||||
--hash=sha256:a5ed8c05548b54b998b9498753fb9cadbfd92ee88e884641377d8a8b291bcc01 \
|
||||
--hash=sha256:a7711edca4dcef1a75257b50a2fbfe92a65187c47dab5a0f1b9b332c5919a3fb \
|
||||
--hash=sha256:af5c59122a011049aad5dd87424b8e65a80e4a6477419c0c1015f73fb5ea0293 \
|
||||
--hash=sha256:b18e0a9ef57d2b41f5c68beefa32317d286c3d6ac0484efd10d6e07491bb95dd \
|
||||
--hash=sha256:b4e248d1087abf9f4c10f3c398896c87ce82a9856494a7155823eb45a892395d \
|
||||
--hash=sha256:ba4e9e0ae13fc41c6b23299545e5ef73055213e466bd107953e4a013a5ddd7e3 \
|
||||
--hash=sha256:c6332685306b6417a91b1ff9fae889b3ba65c2292d64bd9245c093b1b284809d \
|
||||
--hash=sha256:d5ff0621c88ce83a28a10d2ce719b2ee85635e85c515f12bac99a95306da4b2e \
|
||||
--hash=sha256:d9efd8b7a3ef378dd61a1e77367f1924375befc2eba06168b6ebfa903a5e59ca \
|
||||
--hash=sha256:df5169c4396adc04f9b0a05f13c074df878b6052430e03f50e68adf3a57aa28d \
|
||||
--hash=sha256:ebb253464a5d0482b191274f1c8bf00e33f7e0b9c66405fbffc61ed2c839c775 \
|
||||
--hash=sha256:ec80dc47f54e6e9a78181ce05feb71a0353854cc26999db963695f950b5fb375 \
|
||||
--hash=sha256:f032b34669220030f905152045dfa27741ce1a6db3324a5bc0b96b6c7420c87b \
|
||||
--hash=sha256:f60567825f791c6f8a592f3c6e3bd93dd2934e3f9dac189308426bd76b00ef3b \
|
||||
--hash=sha256:f803eaa94c2fcda012c047e62bc7a51b0bdabda1cad7a92a522694ea2d76e49f
|
||||
# via
|
||||
# -r requirements.in
|
||||
# pynacl
|
||||
chardet==4.0.0 \
|
||||
--hash=sha256:0d6f53a15db4120f2b08c94f11e7d93d2c911ee118b6b30a04ec3ee8310179fa \
|
||||
--hash=sha256:f864054d66fd9118f2e67044ac8981a54775ec5b67aed0441892edb553d21da5
|
||||
# via requests
|
||||
click==7.1.2 \
|
||||
--hash=sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a \
|
||||
--hash=sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc
|
||||
# via flask
|
||||
deadsimplekv==0.3.2 \
|
||||
--hash=sha256:a725f4a9d1156ebb66b7535ac150006881e0365b715e34e3709214827b8b0c4c \
|
||||
--hash=sha256:df00262d26c3dcfecb710425a7413059480d8cf026216042d7cbffb8514818b2
|
||||
# via -r requirements.in
|
||||
filenuke==0.0.0 \
|
||||
--hash=sha256:147011c0125121469cae0a8a7f4df399f470e54aa29a08f2d2c099bf0118dcee \
|
||||
--hash=sha256:c55535dcecfdb27c5f4ce664d46e115950b5429763b5db75c198053646177f8f
|
||||
# via -r requirements.in
|
||||
flask==1.1.2 \
|
||||
--hash=sha256:4efa1ae2d7c9865af48986de8aeb8504bf32c7f3d6fdc9353d34b21f4b127060 \
|
||||
--hash=sha256:8a4fdd8936eba2512e9c85df320a37e694c93945b33ef33c89946a340a238557
|
||||
# via -r requirements.in
|
||||
gevent==20.9.0 \
|
||||
--hash=sha256:10110d4881aec04f218c316cb796b18c8b2cac67ae0eb5b0c5780056757268a2 \
|
||||
--hash=sha256:1628a403fc9c3ea9b35924638a4d4fbe236f60ecdf4e22ed133fbbaf0bc7cb6b \
|
||||
--hash=sha256:1cfa3674866294623e324fa5b76eba7b96744d1956a605cfe24d26c5cd890f91 \
|
||||
--hash=sha256:2269574444113cb4ca1c1808ab9460a87fe25e1c34a6e36d975d4af46e4afff9 \
|
||||
--hash=sha256:283a021a2e14adfad718346f18982b80569d9c3a59e97cfae1b7d4c5b017941a \
|
||||
--hash=sha256:2aa70726ad1883fe7c17774e5ccc91ac6e30334efa29bafb9b8fe8ca6091b219 \
|
||||
--hash=sha256:315a63a35068183dfb9bc0331c7bb3c265ee7db8a11797cbe98dadbdb45b5d35 \
|
||||
--hash=sha256:324808a8558c733f7a9734525483795d52ca3bbd5662b24b361d81c075414b1f \
|
||||
--hash=sha256:33a63f230755c6813fca39d9cea2a8894df32df2ee58fd69d8bf8fcc1d8e018e \
|
||||
--hash=sha256:5f6d48051d336561ec08995431ee4d265ac723a64bba99cc58c3eb1a4d4f5c8d \
|
||||
--hash=sha256:8d338cd6d040fe2607e5305dd7991b5960b3780ae01f804c2ac5760d31d3b2c6 \
|
||||
--hash=sha256:906175e3fb25f377a0b581e79d3ed5a7d925c136ff92fd022bb3013e25f5f3a9 \
|
||||
--hash=sha256:93980e51dd2e5f81899d644a0b6ef4a73008c679fcedd50e3b21cc3451ba2424 \
|
||||
--hash=sha256:9bb477f514cf39dc20651b479bf1ad4f38b9a679be2bfa3e162ec0c3785dfa2a \
|
||||
--hash=sha256:a8733a01974433d91308f8c44fa6cc13428b15bb39d46540657e260ff8852cb1 \
|
||||
--hash=sha256:adbb267067f56696b2babced3d0856aa39dcf14b8ccd2dffa1fab587b00c6f80 \
|
||||
--hash=sha256:afc177c37de41ce9c27d351ac84cbaf34407effcab5d6641645838f39d365be1 \
|
||||
--hash=sha256:b07fcbca3e819296979d82fac3d8b44f0d5ced57b9a04dffcfd194da99c8eb2d \
|
||||
--hash=sha256:b2948566003a1030e47507755fe1f446995e8671c0c67571091539e01faf94cc \
|
||||
--hash=sha256:db208e74a32cff7f55f5aa1ba5d7d1c1a086a6325c8702ae78a5c741155552ff \
|
||||
--hash=sha256:dd4c6b2f540b25c3d0f277a725bc1a900ce30a681b90a081216e31f814be453b \
|
||||
--hash=sha256:e11de4b4d107ca2f35000eb08e9c4c4621c153103b400f48a9ea95b96d8c7e0b \
|
||||
--hash=sha256:eba19bae532d0c48d489fa16815b242ce074b1f4b63e8a8e663232cbe311ead9 \
|
||||
--hash=sha256:fb33dc1ab27557bccd64ad4bf81e68c8b0d780fe937b1e2c0814558798137229
|
||||
# via -r requirements.in
|
||||
greenlet==1.0.0 \
|
||||
--hash=sha256:0a77691f0080c9da8dfc81e23f4e3cffa5accf0f5b56478951016d7cfead9196 \
|
||||
--hash=sha256:0ddd77586553e3daf439aa88b6642c5f252f7ef79a39271c25b1d4bf1b7cbb85 \
|
||||
--hash=sha256:111cfd92d78f2af0bc7317452bd93a477128af6327332ebf3c2be7df99566683 \
|
||||
--hash=sha256:122c63ba795fdba4fc19c744df6277d9cfd913ed53d1a286f12189a0265316dd \
|
||||
--hash=sha256:181300f826625b7fd1182205b830642926f52bd8cdb08b34574c9d5b2b1813f7 \
|
||||
--hash=sha256:1a1ada42a1fd2607d232ae11a7b3195735edaa49ea787a6d9e6a53afaf6f3476 \
|
||||
--hash=sha256:1bb80c71de788b36cefb0c3bb6bfab306ba75073dbde2829c858dc3ad70f867c \
|
||||
--hash=sha256:1d1d4473ecb1c1d31ce8fd8d91e4da1b1f64d425c1dc965edc4ed2a63cfa67b2 \
|
||||
--hash=sha256:292e801fcb3a0b3a12d8c603c7cf340659ea27fd73c98683e75800d9fd8f704c \
|
||||
--hash=sha256:2c65320774a8cd5fdb6e117c13afa91c4707548282464a18cf80243cf976b3e6 \
|
||||
--hash=sha256:4365eccd68e72564c776418c53ce3c5af402bc526fe0653722bc89efd85bf12d \
|
||||
--hash=sha256:5352c15c1d91d22902582e891f27728d8dac3bd5e0ee565b6a9f575355e6d92f \
|
||||
--hash=sha256:58ca0f078d1c135ecf1879d50711f925ee238fe773dfe44e206d7d126f5bc664 \
|
||||
--hash=sha256:5d4030b04061fdf4cbc446008e238e44936d77a04b2b32f804688ad64197953c \
|
||||
--hash=sha256:5d69bbd9547d3bc49f8a545db7a0bd69f407badd2ff0f6e1a163680b5841d2b0 \
|
||||
--hash=sha256:5f297cb343114b33a13755032ecf7109b07b9a0020e841d1c3cedff6602cc139 \
|
||||
--hash=sha256:62afad6e5fd70f34d773ffcbb7c22657e1d46d7fd7c95a43361de979f0a45aef \
|
||||
--hash=sha256:647ba1df86d025f5a34043451d7c4a9f05f240bee06277a524daad11f997d1e7 \
|
||||
--hash=sha256:719e169c79255816cdcf6dccd9ed2d089a72a9f6c42273aae12d55e8d35bdcf8 \
|
||||
--hash=sha256:7cd5a237f241f2764324396e06298b5dee0df580cf06ef4ada0ff9bff851286c \
|
||||
--hash=sha256:875d4c60a6299f55df1c3bb870ebe6dcb7db28c165ab9ea6cdc5d5af36bb33ce \
|
||||
--hash=sha256:90b6a25841488cf2cb1c8623a53e6879573010a669455046df5f029d93db51b7 \
|
||||
--hash=sha256:94620ed996a7632723a424bccb84b07e7b861ab7bb06a5aeb041c111dd723d36 \
|
||||
--hash=sha256:b5f1b333015d53d4b381745f5de842f19fe59728b65f0fbb662dafbe2018c3a5 \
|
||||
--hash=sha256:c5b22b31c947ad8b6964d4ed66776bcae986f73669ba50620162ba7c832a6b6a \
|
||||
--hash=sha256:c93d1a71c3fe222308939b2e516c07f35a849c5047f0197442a4d6fbcb4128ee \
|
||||
--hash=sha256:cdb90267650c1edb54459cdb51dab865f6c6594c3a47ebd441bc493360c7af70 \
|
||||
--hash=sha256:cfd06e0f0cc8db2a854137bd79154b61ecd940dce96fad0cba23fe31de0b793c \
|
||||
--hash=sha256:d3789c1c394944084b5e57c192889985a9f23bd985f6d15728c745d380318128 \
|
||||
--hash=sha256:da7d09ad0f24270b20f77d56934e196e982af0d0a2446120cb772be4e060e1a2 \
|
||||
--hash=sha256:df3e83323268594fa9755480a442cabfe8d82b21aba815a71acf1bb6c1776218 \
|
||||
--hash=sha256:df8053867c831b2643b2c489fe1d62049a98566b1646b194cc815f13e27b90df \
|
||||
--hash=sha256:e1128e022d8dce375362e063754e129750323b67454cac5600008aad9f54139e \
|
||||
--hash=sha256:e6e9fdaf6c90d02b95e6b0709aeb1aba5affbbb9ccaea5502f8638e4323206be \
|
||||
--hash=sha256:eac8803c9ad1817ce3d8d15d1bb82c2da3feda6bee1153eec5c58fa6e5d3f770 \
|
||||
--hash=sha256:eb333b90036358a0e2c57373f72e7648d7207b76ef0bd00a4f7daad1f79f5203 \
|
||||
--hash=sha256:ed1d1351f05e795a527abc04a0d82e9aecd3bdf9f46662c36ff47b0b00ecaf06 \
|
||||
--hash=sha256:f3dc68272990849132d6698f7dc6df2ab62a88b0d36e54702a8fd16c0490e44f \
|
||||
--hash=sha256:f59eded163d9752fd49978e0bab7a1ff21b1b8d25c05f0995d140cc08ac83379 \
|
||||
--hash=sha256:f5e2d36c86c7b03c94b8459c3bd2c9fe2c7dab4b258b8885617d44a22e453fb7 \
|
||||
--hash=sha256:f6f65bf54215e4ebf6b01e4bb94c49180a589573df643735107056f7a910275b \
|
||||
--hash=sha256:f8450d5ef759dbe59f84f2c9f77491bb3d3c44bc1a573746daf086e70b14c243 \
|
||||
--hash=sha256:f97d83049715fd9dec7911860ecf0e17b48d8725de01e45de07d8ac0bd5bc378
|
||||
# via gevent
|
||||
idna==2.10 \
|
||||
--hash=sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6 \
|
||||
--hash=sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0
|
||||
# via requests
|
||||
itsdangerous==1.1.0 \
|
||||
--hash=sha256:321b033d07f2a4136d3ec762eac9f16a10ccd60f53c0c91af90217ace7ba1f19 \
|
||||
--hash=sha256:b12271b2047cb23eeb98c8b5622e2e5c5e9abd9784a153e9d8ef9cb4dd09d749
|
||||
# via flask
|
||||
jinja2==2.11.2 \
|
||||
--hash=sha256:89aab215427ef59c34ad58735269eb58b1a5808103067f7bb9d5836c651b3bb0 \
|
||||
--hash=sha256:f0a4641d3cf955324a89c04f3d94663aa4d638abe8f733ecd3582848e1c37035
|
||||
# via flask
|
||||
markupsafe==1.1.1 \
|
||||
--hash=sha256:00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473 \
|
||||
--hash=sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161 \
|
||||
--hash=sha256:09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235 \
|
||||
--hash=sha256:1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5 \
|
||||
--hash=sha256:13d3144e1e340870b25e7b10b98d779608c02016d5184cfb9927a9f10c689f42 \
|
||||
--hash=sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff \
|
||||
--hash=sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b \
|
||||
--hash=sha256:43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1 \
|
||||
--hash=sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e \
|
||||
--hash=sha256:500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183 \
|
||||
--hash=sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66 \
|
||||
--hash=sha256:596510de112c685489095da617b5bcbbac7dd6384aeebeda4df6025d0256a81b \
|
||||
--hash=sha256:62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1 \
|
||||
--hash=sha256:6788b695d50a51edb699cb55e35487e430fa21f1ed838122d722e0ff0ac5ba15 \
|
||||
--hash=sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1 \
|
||||
--hash=sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e \
|
||||
--hash=sha256:79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b \
|
||||
--hash=sha256:7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905 \
|
||||
--hash=sha256:88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735 \
|
||||
--hash=sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d \
|
||||
--hash=sha256:98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e \
|
||||
--hash=sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d \
|
||||
--hash=sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c \
|
||||
--hash=sha256:ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21 \
|
||||
--hash=sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2 \
|
||||
--hash=sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5 \
|
||||
--hash=sha256:b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b \
|
||||
--hash=sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6 \
|
||||
--hash=sha256:c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f \
|
||||
--hash=sha256:cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f \
|
||||
--hash=sha256:cdb132fc825c38e1aeec2c8aa9338310d29d337bebbd7baa06889d09a60a1fa2 \
|
||||
--hash=sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7 \
|
||||
--hash=sha256:e8313f01ba26fbbe36c7be1966a7b7424942f670f38e666995b88d012765b9be
|
||||
# via jinja2
|
||||
niceware==0.2.1 \
|
||||
--hash=sha256:0f8b192f2a1e800e068474f6e208be9c7e2857664b33a96f4045340de4e5c69c \
|
||||
--hash=sha256:cf2dc0e1567d36d067c61b32fed0f1b9c4534ed511f9eeead4ba548d03b5c9eb
|
||||
# via -r requirements.in
|
||||
psutil==5.8.0 \
|
||||
--hash=sha256:0066a82f7b1b37d334e68697faba68e5ad5e858279fd6351c8ca6024e8d6ba64 \
|
||||
--hash=sha256:02b8292609b1f7fcb34173b25e48d0da8667bc85f81d7476584d889c6e0f2131 \
|
||||
--hash=sha256:0ae6f386d8d297177fd288be6e8d1afc05966878704dad9847719650e44fc49c \
|
||||
--hash=sha256:0c9ccb99ab76025f2f0bbecf341d4656e9c1351db8cc8a03ccd62e318ab4b5c6 \
|
||||
--hash=sha256:0dd4465a039d343925cdc29023bb6960ccf4e74a65ad53e768403746a9207023 \
|
||||
--hash=sha256:12d844996d6c2b1d3881cfa6fa201fd635971869a9da945cf6756105af73d2df \
|
||||
--hash=sha256:1bff0d07e76114ec24ee32e7f7f8d0c4b0514b3fae93e3d2aaafd65d22502394 \
|
||||
--hash=sha256:245b5509968ac0bd179287d91210cd3f37add77dad385ef238b275bad35fa1c4 \
|
||||
--hash=sha256:28ff7c95293ae74bf1ca1a79e8805fcde005c18a122ca983abf676ea3466362b \
|
||||
--hash=sha256:36b3b6c9e2a34b7d7fbae330a85bf72c30b1c827a4366a07443fc4b6270449e2 \
|
||||
--hash=sha256:52de075468cd394ac98c66f9ca33b2f54ae1d9bff1ef6b67a212ee8f639ec06d \
|
||||
--hash=sha256:5da29e394bdedd9144c7331192e20c1f79283fb03b06e6abd3a8ae45ffecee65 \
|
||||
--hash=sha256:61f05864b42fedc0771d6d8e49c35f07efd209ade09a5afe6a5059e7bb7bf83d \
|
||||
--hash=sha256:6223d07a1ae93f86451d0198a0c361032c4c93ebd4bf6d25e2fb3edfad9571ef \
|
||||
--hash=sha256:6323d5d845c2785efb20aded4726636546b26d3b577aded22492908f7c1bdda7 \
|
||||
--hash=sha256:6ffe81843131ee0ffa02c317186ed1e759a145267d54fdef1bc4ea5f5931ab60 \
|
||||
--hash=sha256:74f2d0be88db96ada78756cb3a3e1b107ce8ab79f65aa885f76d7664e56928f6 \
|
||||
--hash=sha256:74fb2557d1430fff18ff0d72613c5ca30c45cdbfcddd6a5773e9fc1fe9364be8 \
|
||||
--hash=sha256:90d4091c2d30ddd0a03e0b97e6a33a48628469b99585e2ad6bf21f17423b112b \
|
||||
--hash=sha256:90f31c34d25b1b3ed6c40cdd34ff122b1887a825297c017e4cbd6796dd8b672d \
|
||||
--hash=sha256:99de3e8739258b3c3e8669cb9757c9a861b2a25ad0955f8e53ac662d66de61ac \
|
||||
--hash=sha256:c6a5fd10ce6b6344e616cf01cc5b849fa8103fbb5ba507b6b2dee4c11e84c935 \
|
||||
--hash=sha256:ce8b867423291cb65cfc6d9c4955ee9bfc1e21fe03bb50e177f2b957f1c2469d \
|
||||
--hash=sha256:d225cd8319aa1d3c85bf195c4e07d17d3cd68636b8fc97e6cf198f782f99af28 \
|
||||
--hash=sha256:ea313bb02e5e25224e518e4352af4bf5e062755160f77e4b1767dd5ccb65f876 \
|
||||
--hash=sha256:ea372bcc129394485824ae3e3ddabe67dc0b118d262c568b4d2602a7070afdb0 \
|
||||
--hash=sha256:f4634b033faf0d968bb9220dd1c793b897ab7f1189956e1aa9eae752527127d3 \
|
||||
--hash=sha256:fcc01e900c1d7bee2a37e5d6e4f9194760a93597c97fee89c4ae51701de03563
|
||||
# via -r requirements.in
|
||||
pycparser==2.20 \
|
||||
--hash=sha256:2d475327684562c3a96cc71adf7dc8c4f0565175cf86b6d7a404ff4c771f15f0 \
|
||||
--hash=sha256:7582ad22678f0fcd81102833f60ef8d0e57288b6b5fb00323d101be910e35705
|
||||
# via cffi
|
||||
pynacl==1.4.0 \
|
||||
--hash=sha256:06cbb4d9b2c4bd3c8dc0d267416aaed79906e7b33f114ddbf0911969794b1cc4 \
|
||||
--hash=sha256:11335f09060af52c97137d4ac54285bcb7df0cef29014a1a4efe64ac065434c4 \
|
||||
--hash=sha256:2fe0fc5a2480361dcaf4e6e7cea00e078fcda07ba45f811b167e3f99e8cff574 \
|
||||
--hash=sha256:30f9b96db44e09b3304f9ea95079b1b7316b2b4f3744fe3aaecccd95d547063d \
|
||||
--hash=sha256:4e10569f8cbed81cb7526ae137049759d2a8d57726d52c1a000a3ce366779634 \
|
||||
--hash=sha256:511d269ee845037b95c9781aa702f90ccc36036f95d0f31373a6a79bd8242e25 \
|
||||
--hash=sha256:537a7ccbea22905a0ab36ea58577b39d1fa9b1884869d173b5cf111f006f689f \
|
||||
--hash=sha256:54e9a2c849c742006516ad56a88f5c74bf2ce92c9f67435187c3c5953b346505 \
|
||||
--hash=sha256:757250ddb3bff1eecd7e41e65f7f833a8405fede0194319f87899690624f2122 \
|
||||
--hash=sha256:7757ae33dae81c300487591c68790dfb5145c7d03324000433d9a2c141f82af7 \
|
||||
--hash=sha256:7c6092102219f59ff29788860ccb021e80fffd953920c4a8653889c029b2d420 \
|
||||
--hash=sha256:8122ba5f2a2169ca5da936b2e5a511740ffb73979381b4229d9188f6dcb22f1f \
|
||||
--hash=sha256:9c4a7ea4fb81536c1b1f5cc44d54a296f96ae78c1ebd2311bd0b60be45a48d96 \
|
||||
--hash=sha256:c914f78da4953b33d4685e3cdc7ce63401247a21425c16a39760e282075ac4a6 \
|
||||
--hash=sha256:cd401ccbc2a249a47a3a1724c2918fcd04be1f7b54eb2a5a71ff915db0ac51c6 \
|
||||
--hash=sha256:d452a6746f0a7e11121e64625109bc4468fc3100452817001dbe018bb8b08514 \
|
||||
--hash=sha256:ea6841bc3a76fa4942ce00f3bda7d436fda21e2d91602b9e21b7ca9ecab8f3ff \
|
||||
--hash=sha256:f8851ab9041756003119368c1e6cd0b9c631f46d686b3904b18c0139f4419f80
|
||||
# via -r requirements.in
|
||||
pysocks==1.7.1 \
|
||||
--hash=sha256:08e69f092cc6dbe92a0fdd16eeb9b9ffbc13cadfe5ca4c7bd92ffb078b293299 \
|
||||
--hash=sha256:2725bd0a9925919b9b51739eea5f9e2bae91e83288108a9ad338b2e3a4435ee5 \
|
||||
--hash=sha256:3f8804571ebe159c380ac6de37643bb4685970655d3bba243530d6558b799aa0
|
||||
# via -r requirements.in
|
||||
requests==2.25.1 \
|
||||
--hash=sha256:27973dd4a904a4f13b263a19c866c13b92a39ed1c964655f025f3f8d3d75b804 \
|
||||
--hash=sha256:c210084e36a42ae6b9219e00e48287def368a26d03a048ddad7bfee44f75871e
|
||||
# via
|
||||
# -r requirements.in
|
||||
# streamedrequests
|
||||
six==1.15.0 \
|
||||
--hash=sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259 \
|
||||
--hash=sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced
|
||||
# via pynacl
|
||||
stem==1.8.0 \
|
||||
--hash=sha256:a0b48ea6224e95f22aa34c0bc3415f0eb4667ddeae3dfb5e32a6920c185568c2
|
||||
# via -r requirements.in
|
||||
streamedrequests==1.0.3 \
|
||||
--hash=sha256:4388ffc0ee94dda719dafc4324b8ddd108cb2231ec59871de79e2592bf4eef0a \
|
||||
--hash=sha256:ee68417a1522e75c35b1b2d5f3b6f7e76a3a1a6c0ef5e0c573d08307910079d8
|
||||
# via -r requirements.in
|
||||
toomanyobjs==1.1.0 \
|
||||
--hash=sha256:99e27468f9dad19127be9e2fb086b42acd69aed9ad7e63cef74d6e4389be0534
|
||||
# via -r requirements.in
|
||||
ujson==4.0.1 \
|
||||
--hash=sha256:078808c385036cba73cad96f498310c61e9b5ae5ac9ea01e7c3996ece544b556 \
|
||||
--hash=sha256:0a2e1b211714eb1ec0772a013ec9967f8f95f21c84e8f46382e9f8a32ae781fe \
|
||||
--hash=sha256:0f412c3f59b1ab0f40018235224ca0cf29232d0201ff5085618565a8a9c810ed \
|
||||
--hash=sha256:26cf6241b36ff5ce4539ae687b6b02673109c5e3efc96148806a7873eaa229d3 \
|
||||
--hash=sha256:2b2d9264ac76aeb11f590f7a1ccff0689ba1313adacbb6d38d3b15f21a392897 \
|
||||
--hash=sha256:4f12b0b4e235b35d49f15227b0a827e614c52dda903c58a8f5523936c233dfc7 \
|
||||
--hash=sha256:4fe8c6112b732cba5a722f7cbe22f18d405f6f44415794a5b46473a477635233 \
|
||||
--hash=sha256:51480048373cf97a6b97fcd70c3586ca0a31f27e22ab680fb14c1f22bedbf743 \
|
||||
--hash=sha256:568bb3e7f035006147af4ce3a9ced7d126c92e1a8607c7b2266007b1c1162c53 \
|
||||
--hash=sha256:5fe1536465b1c86e32a47113abd3178001b7c2dcd61f95f336fe2febf4661e74 \
|
||||
--hash=sha256:71703a269f074ff65b9d7746662e4b3e76a4af443e532218af1e8ce15d9b1e7b \
|
||||
--hash=sha256:7a1545ac2476db4cc1f0f236603ccbb50991fc1bba480cda1bc06348cc2a2bf0 \
|
||||
--hash=sha256:a5200a68f1dcf3ce275e1cefbcfa3914b70c2b5e2f71c2e31556aa1f7244c845 \
|
||||
--hash=sha256:a618af22407baeadb3f046f81e7a5ee5e9f8b0b716d2b564f92276a54d26a823 \
|
||||
--hash=sha256:a79bca47eafb31c74b38e68623bc9b2bb930cb48fab1af31c8f2cb68cf473421 \
|
||||
--hash=sha256:b87379a3f8046d6d111762d81f3384bf38ab24b1535c841fe867a4a097d84523 \
|
||||
--hash=sha256:bd4c77aee3ffb920e2dbc21a9e0c7945a400557ce671cfd57dbd569f5ebc619d \
|
||||
--hash=sha256:c354c1617b0a4378b6279d0cd511b769500cf3fa7c42e8e004cbbbb6b4c2a875 \
|
||||
--hash=sha256:c604024bd853b5df6be7d933e934da8dd139e6159564db7c55b92a9937678093 \
|
||||
--hash=sha256:e7ab24942b2d57920d75b817b8eead293026db003247e26f99506bdad86c61b4 \
|
||||
--hash=sha256:f8a60928737a9a47e692fcd661ef2b5d75ba22c7c930025bd95e338f2a6e15bc
|
||||
# via -r requirements.in
|
||||
unpaddedbase32==0.2.0 \
|
||||
--hash=sha256:4aacee75f8fd6c8cf129842ecba45ca59c11bfb13dae19d86f32b48fa3715403 \
|
||||
--hash=sha256:b7b780c31d27d55e66abf6c221216a35690ee8892c2daacff7f2528e229bd9c3
|
||||
# via -r requirements.in
|
||||
urllib3==1.25.11 \
|
||||
--hash=sha256:8d7eaa5a82a1cac232164990f04874c594c9453ec55eef02eab885aa02fc17a2 \
|
||||
--hash=sha256:f5321fbe4bf3fefa0efd0bfe7fb14e90909eb62a48ccda331726b4319897dd5e
|
||||
# via
|
||||
# -r requirements.in
|
||||
# requests
|
||||
watchdog==1.0.2 \
|
||||
--hash=sha256:016b01495b9c55b5d4126ed8ae75d93ea0d99377084107c33162df52887cee18 \
|
||||
--hash=sha256:101532b8db506559e52a9b5d75a308729b3f68264d930670e6155c976d0e52a0 \
|
||||
--hash=sha256:27d9b4666938d5d40afdcdf2c751781e9ce36320788b70208d0f87f7401caf93 \
|
||||
--hash=sha256:2f1ade0d0802503fda4340374d333408831cff23da66d7e711e279ba50fe6c4a \
|
||||
--hash=sha256:376cbc2a35c0392b0fe7ff16fbc1b303fd99d4dd9911ab5581ee9d69adc88982 \
|
||||
--hash=sha256:57f05e55aa603c3b053eed7e679f0a83873c540255b88d58c6223c7493833bac \
|
||||
--hash=sha256:5f1f3b65142175366ba94c64d8d4c8f4015825e0beaacee1c301823266b47b9b \
|
||||
--hash=sha256:602dbd9498592eacc42e0632c19781c3df1728ef9cbab555fab6778effc29eeb \
|
||||
--hash=sha256:68744de2003a5ea2dfbb104f9a74192cf381334a9e2c0ed2bbe1581828d50b61 \
|
||||
--hash=sha256:85e6574395aa6c1e14e0f030d9d7f35c2340a6cf95d5671354ce876ac3ffdd4d \
|
||||
--hash=sha256:b1d723852ce90a14abf0ec0ca9e80689d9509ee4c9ee27163118d87b564a12ac \
|
||||
--hash=sha256:d948ad9ab9aba705f9836625b32e965b9ae607284811cd98334423f659ea537a \
|
||||
--hash=sha256:e2a531e71be7b5cc3499ae2d1494d51b6a26684bcc7c3146f63c810c00e8a3cc \
|
||||
--hash=sha256:e7c73edef48f4ceeebb987317a67e0080e5c9228601ff67b3c4062fa020403c7 \
|
||||
--hash=sha256:ee21aeebe6b3e51e4ba64564c94cee8dbe7438b9cb60f0bb350c4fa70d1b52c2 \
|
||||
--hash=sha256:f1d0e878fd69129d0d68b87cee5d9543f20d8018e82998efb79f7e412d42154a \
|
||||
--hash=sha256:f84146f7864339c8addf2c2b9903271df21d18d2c721e9a77f779493234a82b5
|
||||
# via -r requirements.in
|
||||
werkzeug==1.0.1 \
|
||||
--hash=sha256:2de2a5db0baeae7b2d2664949077c2ac63fbd16d98da0ff71837f7d1dea3fd43 \
|
||||
--hash=sha256:6c80b1e5ad3665290ea39320b91e1be1e0d5f60652b964a3070216de83d2e47c
|
||||
# via flask
|
||||
zope.event==4.5.0 \
|
||||
--hash=sha256:2666401939cdaa5f4e0c08cf7f20c9b21423b95e88f4675b1443973bdb080c42 \
|
||||
--hash=sha256:5e76517f5b9b119acf37ca8819781db6c16ea433f7e2062c4afc2b6fbedb1330
|
||||
# via gevent
|
||||
zope.interface==5.2.0 \
|
||||
--hash=sha256:05a97ba92c1c7c26f25c9f671aa1ef85ffead6cdad13770e5b689cf983adc7e1 \
|
||||
--hash=sha256:07d61722dd7d85547b7c6b0f5486b4338001fab349f2ac5cabc0b7182eb3425d \
|
||||
--hash=sha256:0a990dcc97806e5980bbb54b2e46b9cde9e48932d8e6984daf71ef1745516123 \
|
||||
--hash=sha256:150e8bcb7253a34a4535aeea3de36c0bb3b1a6a47a183a95d65a194b3e07f232 \
|
||||
--hash=sha256:1743bcfe45af8846b775086471c28258f4c6e9ee8ef37484de4495f15a98b549 \
|
||||
--hash=sha256:1b5f6c8fff4ed32aa2dd43e84061bc8346f32d3ba6ad6e58f088fe109608f102 \
|
||||
--hash=sha256:21e49123f375703cf824214939d39df0af62c47d122d955b2a8d9153ea08cfd5 \
|
||||
--hash=sha256:21f579134a47083ffb5ddd1307f0405c91aa8b61ad4be6fd5af0171474fe0c45 \
|
||||
--hash=sha256:27c267dc38a0f0079e96a2945ee65786d38ef111e413c702fbaaacbab6361d00 \
|
||||
--hash=sha256:299bde0ab9e5c4a92f01a152b7fbabb460f31343f1416f9b7b983167ab1e33bc \
|
||||
--hash=sha256:2ab88d8f228f803fcb8cb7d222c579d13dab2d3622c51e8cf321280da01102a7 \
|
||||
--hash=sha256:2ced4c35061eea623bc84c7711eedce8ecc3c2c51cd9c6afa6290df3bae9e104 \
|
||||
--hash=sha256:2dcab01c660983ba5e5a612e0c935141ccbee67d2e2e14b833e01c2354bd8034 \
|
||||
--hash=sha256:32546af61a9a9b141ca38d971aa6eb9800450fa6620ce6323cc30eec447861f3 \
|
||||
--hash=sha256:32b40a4c46d199827d79c86bb8cb88b1bbb764f127876f2cb6f3a47f63dbada3 \
|
||||
--hash=sha256:3cc94c69f6bd48ed86e8e24f358cb75095c8129827df1298518ab860115269a4 \
|
||||
--hash=sha256:42b278ac0989d6f5cf58d7e0828ea6b5951464e3cf2ff229dd09a96cb6ba0c86 \
|
||||
--hash=sha256:495b63fd0302f282ee6c1e6ea0f1c12cb3d1a49c8292d27287f01845ff252a96 \
|
||||
--hash=sha256:4af87cdc0d4b14e600e6d3d09793dce3b7171348a094ba818e2a68ae7ee67546 \
|
||||
--hash=sha256:4b94df9f2fdde7b9314321bab8448e6ad5a23b80542dcab53e329527d4099dcb \
|
||||
--hash=sha256:4c48ddb63e2b20fba4c6a2bf81b4d49e99b6d4587fb67a6cd33a2c1f003af3e3 \
|
||||
--hash=sha256:4df9afd17bd5477e9f8c8b6bb8507e18dd0f8b4efe73bb99729ff203279e9e3b \
|
||||
--hash=sha256:518950fe6a5d56f94ba125107895f938a4f34f704c658986eae8255edb41163b \
|
||||
--hash=sha256:538298e4e113ccb8b41658d5a4b605bebe75e46a30ceca22a5a289cf02c80bec \
|
||||
--hash=sha256:55465121e72e208a7b69b53de791402affe6165083b2ea71b892728bd19ba9ae \
|
||||
--hash=sha256:588384d70a0f19b47409cfdb10e0c27c20e4293b74fc891df3d8eb47782b8b3e \
|
||||
--hash=sha256:6278c080d4afffc9016e14325f8734456831124e8c12caa754fd544435c08386 \
|
||||
--hash=sha256:64ea6c221aeee4796860405e1aedec63424cda4202a7ad27a5066876db5b0fd2 \
|
||||
--hash=sha256:681dbb33e2b40262b33fd383bae63c36d33fd79fa1a8e4092945430744ffd34a \
|
||||
--hash=sha256:6936aa9da390402d646a32a6a38d5409c2d2afb2950f045a7d02ab25a4e7d08d \
|
||||
--hash=sha256:778d0ec38bbd288b150a3ae363c8ffd88d2207a756842495e9bffd8a8afbc89a \
|
||||
--hash=sha256:8251f06a77985a2729a8bdbefbae79ee78567dddc3acbd499b87e705ca59fe24 \
|
||||
--hash=sha256:83b4aa5344cce005a9cff5d0321b2e318e871cc1dfc793b66c32dd4f59e9770d \
|
||||
--hash=sha256:844fad925ac5c2ad4faaceb3b2520ad016b5280105c6e16e79838cf951903a7b \
|
||||
--hash=sha256:8ceb3667dd13b8133f2e4d637b5b00f240f066448e2aa89a41f4c2d78a26ce50 \
|
||||
--hash=sha256:92dc0fb79675882d0b6138be4bf0cec7ea7c7eede60aaca78303d8e8dbdaa523 \
|
||||
--hash=sha256:9789bd945e9f5bd026ed3f5b453d640befb8b1fc33a779c1fe8d3eb21fe3fb4a \
|
||||
--hash=sha256:a2b6d6eb693bc2fc6c484f2e5d93bd0b0da803fa77bf974f160533e555e4d095 \
|
||||
--hash=sha256:aab9f1e34d810feb00bf841993552b8fcc6ae71d473c505381627143d0018a6a \
|
||||
--hash=sha256:abb61afd84f23099ac6099d804cdba9bd3b902aaaded3ffff47e490b0a495520 \
|
||||
--hash=sha256:adf9ee115ae8ff8b6da4b854b4152f253b390ba64407a22d75456fe07dcbda65 \
|
||||
--hash=sha256:aedc6c672b351afe6dfe17ff83ee5e7eb6ed44718f879a9328a68bdb20b57e11 \
|
||||
--hash=sha256:b7a00ecb1434f8183395fac5366a21ee73d14900082ca37cf74993cf46baa56c \
|
||||
--hash=sha256:ba32f4a91c1cb7314c429b03afbf87b1fff4fb1c8db32260e7310104bd77f0c7 \
|
||||
--hash=sha256:cbd0f2cbd8689861209cd89141371d3a22a11613304d1f0736492590aa0ab332 \
|
||||
--hash=sha256:e4bc372b953bf6cec65a8d48482ba574f6e051621d157cf224227dbb55486b1e \
|
||||
--hash=sha256:eccac3d9aadc68e994b6d228cb0c8919fc47a5350d85a1b4d3d81d1e98baf40c \
|
||||
--hash=sha256:efd550b3da28195746bb43bd1d815058181a7ca6d9d6aa89dd37f5eefe2cacb7 \
|
||||
--hash=sha256:efef581c8ba4d990770875e1a2218e856849d32ada2680e53aebc5d154a17e20 \
|
||||
--hash=sha256:f057897711a630a0b7a6a03f1acf379b6ba25d37dc5dc217a97191984ba7f2fc \
|
||||
--hash=sha256:f37d45fab14ffef9d33a0dc3bc59ce0c5313e2253323312d47739192da94f5fd \
|
||||
--hash=sha256:f44906f70205d456d503105023041f1e63aece7623b31c390a0103db4de17537
|
||||
# via gevent
|
||||
|
||||
# WARNING: The following packages were not pinned, but pip requires them to be
|
||||
# pinned when the requirements file includes hashes. Consider using the --allow-unsafe flag.
|
||||
# setuptools
|
||||
|
@ -1,270 +0,0 @@
|
||||
#
|
||||
# This file is autogenerated by pip-compile with python 3.10
|
||||
# To update, run:
|
||||
#
|
||||
# pip-compile --generate-hashes --output-file=requirements-base-x86.txt requirements-base.in
|
||||
#
|
||||
cffi==1.15.1 \
|
||||
--hash=sha256:00a9ed42e88df81ffae7a8ab6d9356b371399b91dbdf0c3cb1e84c03a13aceb5 \
|
||||
--hash=sha256:03425bdae262c76aad70202debd780501fabeaca237cdfddc008987c0e0f59ef \
|
||||
--hash=sha256:04ed324bda3cda42b9b695d51bb7d54b680b9719cfab04227cdd1e04e5de3104 \
|
||||
--hash=sha256:0e2642fe3142e4cc4af0799748233ad6da94c62a8bec3a6648bf8ee68b1c7426 \
|
||||
--hash=sha256:173379135477dc8cac4bc58f45db08ab45d228b3363adb7af79436135d028405 \
|
||||
--hash=sha256:198caafb44239b60e252492445da556afafc7d1e3ab7a1fb3f0584ef6d742375 \
|
||||
--hash=sha256:1e74c6b51a9ed6589199c787bf5f9875612ca4a8a0785fb2d4a84429badaf22a \
|
||||
--hash=sha256:2012c72d854c2d03e45d06ae57f40d78e5770d252f195b93f581acf3ba44496e \
|
||||
--hash=sha256:21157295583fe8943475029ed5abdcf71eb3911894724e360acff1d61c1d54bc \
|
||||
--hash=sha256:2470043b93ff09bf8fb1d46d1cb756ce6132c54826661a32d4e4d132e1977adf \
|
||||
--hash=sha256:285d29981935eb726a4399badae8f0ffdff4f5050eaa6d0cfc3f64b857b77185 \
|
||||
--hash=sha256:30d78fbc8ebf9c92c9b7823ee18eb92f2e6ef79b45ac84db507f52fbe3ec4497 \
|
||||
--hash=sha256:320dab6e7cb2eacdf0e658569d2575c4dad258c0fcc794f46215e1e39f90f2c3 \
|
||||
--hash=sha256:33ab79603146aace82c2427da5ca6e58f2b3f2fb5da893ceac0c42218a40be35 \
|
||||
--hash=sha256:3548db281cd7d2561c9ad9984681c95f7b0e38881201e157833a2342c30d5e8c \
|
||||
--hash=sha256:3799aecf2e17cf585d977b780ce79ff0dc9b78d799fc694221ce814c2c19db83 \
|
||||
--hash=sha256:39d39875251ca8f612b6f33e6b1195af86d1b3e60086068be9cc053aa4376e21 \
|
||||
--hash=sha256:3b926aa83d1edb5aa5b427b4053dc420ec295a08e40911296b9eb1b6170f6cca \
|
||||
--hash=sha256:3bcde07039e586f91b45c88f8583ea7cf7a0770df3a1649627bf598332cb6984 \
|
||||
--hash=sha256:3d08afd128ddaa624a48cf2b859afef385b720bb4b43df214f85616922e6a5ac \
|
||||
--hash=sha256:3eb6971dcff08619f8d91607cfc726518b6fa2a9eba42856be181c6d0d9515fd \
|
||||
--hash=sha256:40f4774f5a9d4f5e344f31a32b5096977b5d48560c5592e2f3d2c4374bd543ee \
|
||||
--hash=sha256:4289fc34b2f5316fbb762d75362931e351941fa95fa18789191b33fc4cf9504a \
|
||||
--hash=sha256:470c103ae716238bbe698d67ad020e1db9d9dba34fa5a899b5e21577e6d52ed2 \
|
||||
--hash=sha256:4f2c9f67e9821cad2e5f480bc8d83b8742896f1242dba247911072d4fa94c192 \
|
||||
--hash=sha256:50a74364d85fd319352182ef59c5c790484a336f6db772c1a9231f1c3ed0cbd7 \
|
||||
--hash=sha256:54a2db7b78338edd780e7ef7f9f6c442500fb0d41a5a4ea24fff1c929d5af585 \
|
||||
--hash=sha256:5635bd9cb9731e6d4a1132a498dd34f764034a8ce60cef4f5319c0541159392f \
|
||||
--hash=sha256:59c0b02d0a6c384d453fece7566d1c7e6b7bae4fc5874ef2ef46d56776d61c9e \
|
||||
--hash=sha256:5d598b938678ebf3c67377cdd45e09d431369c3b1a5b331058c338e201f12b27 \
|
||||
--hash=sha256:5df2768244d19ab7f60546d0c7c63ce1581f7af8b5de3eb3004b9b6fc8a9f84b \
|
||||
--hash=sha256:5ef34d190326c3b1f822a5b7a45f6c4535e2f47ed06fec77d3d799c450b2651e \
|
||||
--hash=sha256:6975a3fac6bc83c4a65c9f9fcab9e47019a11d3d2cf7f3c0d03431bf145a941e \
|
||||
--hash=sha256:6c9a799e985904922a4d207a94eae35c78ebae90e128f0c4e521ce339396be9d \
|
||||
--hash=sha256:70df4e3b545a17496c9b3f41f5115e69a4f2e77e94e1d2a8e1070bc0c38c8a3c \
|
||||
--hash=sha256:7473e861101c9e72452f9bf8acb984947aa1661a7704553a9f6e4baa5ba64415 \
|
||||
--hash=sha256:8102eaf27e1e448db915d08afa8b41d6c7ca7a04b7d73af6514df10a3e74bd82 \
|
||||
--hash=sha256:87c450779d0914f2861b8526e035c5e6da0a3199d8f1add1a665e1cbc6fc6d02 \
|
||||
--hash=sha256:8b7ee99e510d7b66cdb6c593f21c043c248537a32e0bedf02e01e9553a172314 \
|
||||
--hash=sha256:91fc98adde3d7881af9b59ed0294046f3806221863722ba7d8d120c575314325 \
|
||||
--hash=sha256:94411f22c3985acaec6f83c6df553f2dbe17b698cc7f8ae751ff2237d96b9e3c \
|
||||
--hash=sha256:98d85c6a2bef81588d9227dde12db8a7f47f639f4a17c9ae08e773aa9c697bf3 \
|
||||
--hash=sha256:9ad5db27f9cabae298d151c85cf2bad1d359a1b9c686a275df03385758e2f914 \
|
||||
--hash=sha256:a0b71b1b8fbf2b96e41c4d990244165e2c9be83d54962a9a1d118fd8657d2045 \
|
||||
--hash=sha256:a0f100c8912c114ff53e1202d0078b425bee3649ae34d7b070e9697f93c5d52d \
|
||||
--hash=sha256:a591fe9e525846e4d154205572a029f653ada1a78b93697f3b5a8f1f2bc055b9 \
|
||||
--hash=sha256:a5c84c68147988265e60416b57fc83425a78058853509c1b0629c180094904a5 \
|
||||
--hash=sha256:a66d3508133af6e8548451b25058d5812812ec3798c886bf38ed24a98216fab2 \
|
||||
--hash=sha256:a8c4917bd7ad33e8eb21e9a5bbba979b49d9a97acb3a803092cbc1133e20343c \
|
||||
--hash=sha256:b3bbeb01c2b273cca1e1e0c5df57f12dce9a4dd331b4fa1635b8bec26350bde3 \
|
||||
--hash=sha256:cba9d6b9a7d64d4bd46167096fc9d2f835e25d7e4c121fb2ddfc6528fb0413b2 \
|
||||
--hash=sha256:cc4d65aeeaa04136a12677d3dd0b1c0c94dc43abac5860ab33cceb42b801c1e8 \
|
||||
--hash=sha256:ce4bcc037df4fc5e3d184794f27bdaab018943698f4ca31630bc7f84a7b69c6d \
|
||||
--hash=sha256:cec7d9412a9102bdc577382c3929b337320c4c4c4849f2c5cdd14d7368c5562d \
|
||||
--hash=sha256:d400bfb9a37b1351253cb402671cea7e89bdecc294e8016a707f6d1d8ac934f9 \
|
||||
--hash=sha256:d61f4695e6c866a23a21acab0509af1cdfd2c013cf256bbf5b6b5e2695827162 \
|
||||
--hash=sha256:db0fbb9c62743ce59a9ff687eb5f4afbe77e5e8403d6697f7446e5f609976f76 \
|
||||
--hash=sha256:dd86c085fae2efd48ac91dd7ccffcfc0571387fe1193d33b6394db7ef31fe2a4 \
|
||||
--hash=sha256:e00b098126fd45523dd056d2efba6c5a63b71ffe9f2bbe1a4fe1716e1d0c331e \
|
||||
--hash=sha256:e229a521186c75c8ad9490854fd8bbdd9a0c9aa3a524326b55be83b54d4e0ad9 \
|
||||
--hash=sha256:e263d77ee3dd201c3a142934a086a4450861778baaeeb45db4591ef65550b0a6 \
|
||||
--hash=sha256:ed9cb427ba5504c1dc15ede7d516b84757c3e3d7868ccc85121d9310d27eed0b \
|
||||
--hash=sha256:fa6693661a4c91757f4412306191b6dc88c1703f780c8234035eac011922bc01 \
|
||||
--hash=sha256:fcd131dd944808b5bdb38e6f5b53013c5aa4f334c5cad0c72742f6eba4b73db0
|
||||
# via pynacl
|
||||
filenuke==0.0.0 \
|
||||
--hash=sha256:147011c0125121469cae0a8a7f4df399f470e54aa29a08f2d2c099bf0118dcee \
|
||||
--hash=sha256:c55535dcecfdb27c5f4ce664d46e115950b5429763b5db75c198053646177f8f
|
||||
# via -r requirements-base.in
|
||||
kasten==3.0.0 \
|
||||
--hash=sha256:52894af46d6e1339f0d5fa8961892b292f99176848bce11877fe4a435b6782e5 \
|
||||
--hash=sha256:b22ebdc5f475c2ef9ab74abc36552add0b37732a7ce2be6bd7977ee41b2163b4
|
||||
# via onionrblocks
|
||||
mimcvdf==1.2.1 \
|
||||
--hash=sha256:7c837c46cfb9dce4ba895bc706a69646d4d5185c66aeaa333b5cfaa9a7d06dc4
|
||||
# via kasten
|
||||
msgpack==1.0.4 \
|
||||
--hash=sha256:002b5c72b6cd9b4bafd790f364b8480e859b4712e91f43014fe01e4f957b8467 \
|
||||
--hash=sha256:0a68d3ac0104e2d3510de90a1091720157c319ceeb90d74f7b5295a6bee51bae \
|
||||
--hash=sha256:0df96d6eaf45ceca04b3f3b4b111b86b33785683d682c655063ef8057d61fd92 \
|
||||
--hash=sha256:0dfe3947db5fb9ce52aaea6ca28112a170db9eae75adf9339a1aec434dc954ef \
|
||||
--hash=sha256:0e3590f9fb9f7fbc36df366267870e77269c03172d086fa76bb4eba8b2b46624 \
|
||||
--hash=sha256:11184bc7e56fd74c00ead4f9cc9a3091d62ecb96e97653add7a879a14b003227 \
|
||||
--hash=sha256:112b0f93202d7c0fef0b7810d465fde23c746a2d482e1e2de2aafd2ce1492c88 \
|
||||
--hash=sha256:1276e8f34e139aeff1c77a3cefb295598b504ac5314d32c8c3d54d24fadb94c9 \
|
||||
--hash=sha256:1576bd97527a93c44fa856770197dec00d223b0b9f36ef03f65bac60197cedf8 \
|
||||
--hash=sha256:1e91d641d2bfe91ba4c52039adc5bccf27c335356055825c7f88742c8bb900dd \
|
||||
--hash=sha256:26b8feaca40a90cbe031b03d82b2898bf560027160d3eae1423f4a67654ec5d6 \
|
||||
--hash=sha256:2999623886c5c02deefe156e8f869c3b0aaeba14bfc50aa2486a0415178fce55 \
|
||||
--hash=sha256:2a2df1b55a78eb5f5b7d2a4bb221cd8363913830145fad05374a80bf0877cb1e \
|
||||
--hash=sha256:2bb8cdf50dd623392fa75525cce44a65a12a00c98e1e37bf0fb08ddce2ff60d2 \
|
||||
--hash=sha256:2cc5ca2712ac0003bcb625c96368fd08a0f86bbc1a5578802512d87bc592fe44 \
|
||||
--hash=sha256:35bc0faa494b0f1d851fd29129b2575b2e26d41d177caacd4206d81502d4c6a6 \
|
||||
--hash=sha256:3c11a48cf5e59026ad7cb0dc29e29a01b5a66a3e333dc11c04f7e991fc5510a9 \
|
||||
--hash=sha256:449e57cc1ff18d3b444eb554e44613cffcccb32805d16726a5494038c3b93dab \
|
||||
--hash=sha256:462497af5fd4e0edbb1559c352ad84f6c577ffbbb708566a0abaaa84acd9f3ae \
|
||||
--hash=sha256:4733359808c56d5d7756628736061c432ded018e7a1dff2d35a02439043321aa \
|
||||
--hash=sha256:48f5d88c99f64c456413d74a975bd605a9b0526293218a3b77220a2c15458ba9 \
|
||||
--hash=sha256:49565b0e3d7896d9ea71d9095df15b7f75a035c49be733051c34762ca95bbf7e \
|
||||
--hash=sha256:4ab251d229d10498e9a2f3b1e68ef64cb393394ec477e3370c457f9430ce9250 \
|
||||
--hash=sha256:4d5834a2a48965a349da1c5a79760d94a1a0172fbb5ab6b5b33cbf8447e109ce \
|
||||
--hash=sha256:4dea20515f660aa6b7e964433b1808d098dcfcabbebeaaad240d11f909298075 \
|
||||
--hash=sha256:545e3cf0cf74f3e48b470f68ed19551ae6f9722814ea969305794645da091236 \
|
||||
--hash=sha256:63e29d6e8c9ca22b21846234913c3466b7e4ee6e422f205a2988083de3b08cae \
|
||||
--hash=sha256:6916c78f33602ecf0509cc40379271ba0f9ab572b066bd4bdafd7434dee4bc6e \
|
||||
--hash=sha256:6a4192b1ab40f8dca3f2877b70e63799d95c62c068c84dc028b40a6cb03ccd0f \
|
||||
--hash=sha256:6c9566f2c39ccced0a38d37c26cc3570983b97833c365a6044edef3574a00c08 \
|
||||
--hash=sha256:76ee788122de3a68a02ed6f3a16bbcd97bc7c2e39bd4d94be2f1821e7c4a64e6 \
|
||||
--hash=sha256:7760f85956c415578c17edb39eed99f9181a48375b0d4a94076d84148cf67b2d \
|
||||
--hash=sha256:77ccd2af37f3db0ea59fb280fa2165bf1b096510ba9fe0cc2bf8fa92a22fdb43 \
|
||||
--hash=sha256:81fc7ba725464651190b196f3cd848e8553d4d510114a954681fd0b9c479d7e1 \
|
||||
--hash=sha256:85f279d88d8e833ec015650fd15ae5eddce0791e1e8a59165318f371158efec6 \
|
||||
--hash=sha256:9667bdfdf523c40d2511f0e98a6c9d3603be6b371ae9a238b7ef2dc4e7a427b0 \
|
||||
--hash=sha256:a75dfb03f8b06f4ab093dafe3ddcc2d633259e6c3f74bb1b01996f5d8aa5868c \
|
||||
--hash=sha256:ac5bd7901487c4a1dd51a8c58f2632b15d838d07ceedaa5e4c080f7190925bff \
|
||||
--hash=sha256:aca0f1644d6b5a73eb3e74d4d64d5d8c6c3d577e753a04c9e9c87d07692c58db \
|
||||
--hash=sha256:b17be2478b622939e39b816e0aa8242611cc8d3583d1cd8ec31b249f04623243 \
|
||||
--hash=sha256:c1683841cd4fa45ac427c18854c3ec3cd9b681694caf5bff04edb9387602d661 \
|
||||
--hash=sha256:c23080fdeec4716aede32b4e0ef7e213c7b1093eede9ee010949f2a418ced6ba \
|
||||
--hash=sha256:d5b5b962221fa2c5d3a7f8133f9abffc114fe218eb4365e40f17732ade576c8e \
|
||||
--hash=sha256:d603de2b8d2ea3f3bcb2efe286849aa7a81531abc52d8454da12f46235092bcb \
|
||||
--hash=sha256:e83f80a7fec1a62cf4e6c9a660e39c7f878f603737a0cdac8c13131d11d97f52 \
|
||||
--hash=sha256:eb514ad14edf07a1dbe63761fd30f89ae79b42625731e1ccf5e1f1092950eaa6 \
|
||||
--hash=sha256:eba96145051ccec0ec86611fe9cf693ce55f2a3ce89c06ed307de0e085730ec1 \
|
||||
--hash=sha256:ed6f7b854a823ea44cf94919ba3f727e230da29feb4a99711433f25800cf747f \
|
||||
--hash=sha256:f0029245c51fd9473dc1aede1160b0a29f4a912e6b1dd353fa6d317085b219da \
|
||||
--hash=sha256:f5d869c18f030202eb412f08b28d2afeea553d6613aee89e200d7aca7ef01f5f \
|
||||
--hash=sha256:fb62ea4b62bfcb0b380d5680f9a4b3f9a2d166d9394e9bbd9666c0ee09a3645c \
|
||||
--hash=sha256:fcb8a47f43acc113e24e910399376f7277cf8508b27e5b88499f053de6b115a8
|
||||
# via kasten
|
||||
onionrblocks==7.0.0 \
|
||||
--hash=sha256:53e90964371076d9daf2ed0790b21f174ef3321f4f1808209cc6dd9b7ff6d8ff \
|
||||
--hash=sha256:54af28d0be856209525646c4ef9f977f95f0ae1329b2cc023b351317c9d0eef7
|
||||
# via -r requirements-base.in
|
||||
ordered-set==4.1.0 \
|
||||
--hash=sha256:046e1132c71fcf3330438a539928932caf51ddbc582496833e23de611de14562 \
|
||||
--hash=sha256:694a8e44c87657c59292ede72891eb91d34131f6531463aab3009191c77364a8
|
||||
# via -r requirements-base.in
|
||||
psutil==5.9.3 \
|
||||
--hash=sha256:07d880053c6461c9b89cd5d4808f3b8336665fa3acdefd6777662c5ed73a851a \
|
||||
--hash=sha256:12500d761ac091f2426567f19f95fd3f15a197d96befb44a5c1e3cbe6db5752c \
|
||||
--hash=sha256:1b540599481c73408f6b392cdffef5b01e8ff7a2ac8caae0a91b8222e88e8f1e \
|
||||
--hash=sha256:35feafe232d1aaf35d51bd42790cbccb882456f9f18cdc411532902370d660df \
|
||||
--hash=sha256:3a7826e68b0cf4ce2c1ee385d64eab7d70e3133171376cac53d7c1790357ec8f \
|
||||
--hash=sha256:46907fa62acaac364fff0b8a9da7b360265d217e4fdeaca0a2397a6883dffba2 \
|
||||
--hash=sha256:4bd4854f0c83aa84a5a40d3b5d0eb1f3c128f4146371e03baed4589fe4f3c931 \
|
||||
--hash=sha256:538fcf6ae856b5e12d13d7da25ad67f02113c96f5989e6ad44422cb5994ca7fc \
|
||||
--hash=sha256:547ebb02031fdada635452250ff39942db8310b5c4a8102dfe9384ee5791e650 \
|
||||
--hash=sha256:5e8b50241dd3c2ed498507f87a6602825073c07f3b7e9560c58411c14fe1e1c9 \
|
||||
--hash=sha256:5fa88e3d5d0b480602553d362c4b33a63e0c40bfea7312a7bf78799e01e0810b \
|
||||
--hash=sha256:68fa227c32240c52982cb931801c5707a7f96dd8927f9102d6c7771ea1ff5698 \
|
||||
--hash=sha256:6ced1ad823ecfa7d3ce26fe8aa4996e2e53fb49b7fed8ad81c80958501ec0619 \
|
||||
--hash=sha256:71b1206e7909792d16933a0d2c1c7f04ae196186c51ba8567abae1d041f06dcb \
|
||||
--hash=sha256:767ef4fa33acda16703725c0473a91e1832d296c37c63896c7153ba81698f1ab \
|
||||
--hash=sha256:7ccfcdfea4fc4b0a02ca2c31de7fcd186beb9cff8207800e14ab66f79c773af6 \
|
||||
--hash=sha256:7e4939ff75149b67aef77980409f156f0082fa36accc475d45c705bb00c6c16a \
|
||||
--hash=sha256:828c9dc9478b34ab96be75c81942d8df0c2bb49edbb481f597314d92b6441d89 \
|
||||
--hash=sha256:8a4e07611997acf178ad13b842377e3d8e9d0a5bac43ece9bfc22a96735d9a4f \
|
||||
--hash=sha256:941a6c2c591da455d760121b44097781bc970be40e0e43081b9139da485ad5b7 \
|
||||
--hash=sha256:9a4af6ed1094f867834f5f07acd1250605a0874169a5fcadbcec864aec2496a6 \
|
||||
--hash=sha256:9ec296f565191f89c48f33d9544d8d82b0d2af7dd7d2d4e6319f27a818f8d1cc \
|
||||
--hash=sha256:9ec95df684583b5596c82bb380c53a603bb051cf019d5c849c47e117c5064395 \
|
||||
--hash=sha256:a04a1836894c8279e5e0a0127c0db8e198ca133d28be8a2a72b4db16f6cf99c1 \
|
||||
--hash=sha256:a3d81165b8474087bb90ec4f333a638ccfd1d69d34a9b4a1a7eaac06648f9fbe \
|
||||
--hash=sha256:b4a247cd3feaae39bb6085fcebf35b3b8ecd9b022db796d89c8f05067ca28e71 \
|
||||
--hash=sha256:ba38cf9984d5462b506e239cf4bc24e84ead4b1d71a3be35e66dad0d13ded7c1 \
|
||||
--hash=sha256:beb57d8a1ca0ae0eb3d08ccaceb77e1a6d93606f0e1754f0d60a6ebd5c288837 \
|
||||
--hash=sha256:d266cd05bd4a95ca1c2b9b5aac50d249cf7c94a542f47e0b22928ddf8b80d1ef \
|
||||
--hash=sha256:d8c3cc6bb76492133474e130a12351a325336c01c96a24aae731abf5a47fe088 \
|
||||
--hash=sha256:db8e62016add2235cc87fb7ea000ede9e4ca0aa1f221b40cef049d02d5d2593d \
|
||||
--hash=sha256:e7507f6c7b0262d3e7b0eeda15045bf5881f4ada70473b87bc7b7c93b992a7d7 \
|
||||
--hash=sha256:ed15edb14f52925869250b1375f0ff58ca5c4fa8adefe4883cfb0737d32f5c02 \
|
||||
--hash=sha256:f57d63a2b5beaf797b87024d018772439f9d3103a395627b77d17a8d72009543 \
|
||||
--hash=sha256:fa5e32c7d9b60b2528108ade2929b115167fe98d59f89555574715054f50fa31 \
|
||||
--hash=sha256:fe79b4ad4836e3da6c4650cb85a663b3a51aef22e1a829c384e18fae87e5e727
|
||||
# via -r requirements-base.in
|
||||
pycparser==2.21 \
|
||||
--hash=sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9 \
|
||||
--hash=sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206
|
||||
# via cffi
|
||||
pynacl==1.5.0 \
|
||||
--hash=sha256:06b8f6fa7f5de8d5d2f7573fe8c863c051225a27b61e6860fd047b1775807858 \
|
||||
--hash=sha256:0c84947a22519e013607c9be43706dd42513f9e6ae5d39d3613ca1e142fba44d \
|
||||
--hash=sha256:20f42270d27e1b6a29f54032090b972d97f0a1b0948cc52392041ef7831fee93 \
|
||||
--hash=sha256:401002a4aaa07c9414132aaed7f6836ff98f59277a234704ff66878c2ee4a0d1 \
|
||||
--hash=sha256:52cb72a79269189d4e0dc537556f4740f7f0a9ec41c1322598799b0bdad4ef92 \
|
||||
--hash=sha256:61f642bf2378713e2c2e1de73444a3778e5f0a38be6fee0fe532fe30060282ff \
|
||||
--hash=sha256:8ac7448f09ab85811607bdd21ec2464495ac8b7c66d146bf545b0f08fb9220ba \
|
||||
--hash=sha256:a36d4a9dda1f19ce6e03c9a784a2921a4b726b02e1c736600ca9c22029474394 \
|
||||
--hash=sha256:a422368fc821589c228f4c49438a368831cb5bbc0eab5ebe1d7fac9dded6567b \
|
||||
--hash=sha256:e46dae94e34b085175f8abb3b0aaa7da40767865ac82c928eeb9e57e1ea8a543
|
||||
# via onionrblocks
|
||||
result==0.8.0 \
|
||||
--hash=sha256:c48c909e92181a075ba358228a3fe161e26d205dad416ad81f27f23515a5626d \
|
||||
--hash=sha256:d6a6258f32c057a4e0478999c6ce43dcadaf8ea435f58ac601ae2768f93ef243
|
||||
# via -r requirements-base.in
|
||||
ujson==5.5.0 \
|
||||
--hash=sha256:0762a4fdf86e01f3f8d8b6b7158d01fdd870799ff3f402b676e358fcd879e7eb \
|
||||
--hash=sha256:10095160dbe6bba8059ad6677a01da251431f4c68041bf796dcac0956b34f8f7 \
|
||||
--hash=sha256:1a485117f97312bef45f5d79d2ff97eff4da503b8a04f3691f59d31141686459 \
|
||||
--hash=sha256:1cef44ea4973344baed3d50a5da4a8843de3a6af7dea7fadf0a594e53ce5892f \
|
||||
--hash=sha256:1dc2f46c31ef22b0aaa28cd71be897bea271e700636658d573df9c43c49ebbd0 \
|
||||
--hash=sha256:21678d7e068707e4d54bdfeb8c250ebc548b51e499aed778b22112ca31a79669 \
|
||||
--hash=sha256:278aa9d7cb56435c96d19f5d702e026bcf69f824e24b41e9b52706abd3565837 \
|
||||
--hash=sha256:2ab011e3556a9a1d9461bd686870c527327765ed02fe53550531d6609a8a33ff \
|
||||
--hash=sha256:2d90414e3b4b44b39825049185959488e084ea7fcaf6124afd5c00893938b09d \
|
||||
--hash=sha256:2e506ecf89b6b9d304362ccef770831ec242a52c89dab1b4aabf1ab0eb1d5ed6 \
|
||||
--hash=sha256:33cd9084fefc74cbacf88c92fd260b61211e00bcde38d640c369e5dc34a2b4e1 \
|
||||
--hash=sha256:3b74467564814fbce322427a5664e6bcc7dae6dbc8acbef76300fe43ca4072ab \
|
||||
--hash=sha256:3f3f4240d99d55eb97cb012e9adf401f5ed9cd827af0341ac44603832202b0d2 \
|
||||
--hash=sha256:3fe1aea596f9539fc20cd9e52f098c842afc090168824fd4ca9744fe13151a03 \
|
||||
--hash=sha256:4a8cb3c8637006c5bd8237ebb5992a76ba06e39988ad5cff2096227443e8fd6a \
|
||||
--hash=sha256:4ef4ab8352861b99bd7fedb1fc6df3ea7f7d5216c789ba6d859e4ea06f1a4c45 \
|
||||
--hash=sha256:5035bb997d163f346c22abcec75190e7e756a5349e7c708bd3d5fd7066a9a854 \
|
||||
--hash=sha256:593a0f6fb0e186c5ba65465ed6f6215a30d1efa898c25e74de1c8577a1bff6d0 \
|
||||
--hash=sha256:59cdcd934385f36e8bd76aedc234371cc75c848d95bdce804ac8aa8744cfeffa \
|
||||
--hash=sha256:5a9b1320d8363a42d857fae8065a2174d38217cdd58cd8dc4f48d54e0591271e \
|
||||
--hash=sha256:5f9681ec4c60d0da590552427d770636d9079038c30b265f507ccde23caa7823 \
|
||||
--hash=sha256:5fd797a4837ba10671954e7c09010cec7aca67e09d193f4920a16beea5f66f65 \
|
||||
--hash=sha256:6019e3480d933d3698f2ecb4b46d64bfadd64e718f04fac36e681f3254b49a93 \
|
||||
--hash=sha256:603607f56a0ee84d9cd2c7e9b1d29b18a70684b94ee34f07b9ffe8dc9c8a9f81 \
|
||||
--hash=sha256:60a4b481978ea2aad8fe8af1ecc271624d01b3cf4b09e9b643dd2fe19c07634c \
|
||||
--hash=sha256:6b9812638d7aa8ecda2e8e1513fb4da999249603bffab7439a5f8f0bb362b0db \
|
||||
--hash=sha256:6c7ae6e0778ab9610f5e80e0595957d101ab8de18c32a8c053a19943ef4831d0 \
|
||||
--hash=sha256:6f83be8257b2f2dd6dea5ee62cd28db90584da7a7af1fba77a2102fc7943638a \
|
||||
--hash=sha256:701e81e047f5c0cffd4ac828efca68b0bd270c616654966a051e9a5f836b385e \
|
||||
--hash=sha256:703fd69d9cb21d6ec2086789df9be2cf8140a76ff127050c24007ea8940dcd3b \
|
||||
--hash=sha256:7471d4486f23518cff343f1eec6c68d1b977ed74c3e6cc3e1ac896b9b7d68645 \
|
||||
--hash=sha256:765d46f3d5e7a1d48075035e2d1a9164f683e3fccde834ca04602e6c588835bc \
|
||||
--hash=sha256:7a09d203983104918c62f2eef9406f24c355511f9217967df23e70fa7f5b54ff \
|
||||
--hash=sha256:7c20cc83b0df47129ec6ed8a47fa7dcfc309c5bad029464004162738502568bb \
|
||||
--hash=sha256:7d7cfac2547c93389fa303fc0c0eb6698825564e8389c41c9b60009c746207b6 \
|
||||
--hash=sha256:7d87c817b292efb748f1974f37e8bb8a8772ef92f05f84e507159360814bcc3f \
|
||||
--hash=sha256:8141f654432cf75144d6103bfac2286b8adf23467201590b173a74535d6be22d \
|
||||
--hash=sha256:849f2ff40264152f25589cb48ddb4a43d14db811f841ec73989bfc0c8c4853fa \
|
||||
--hash=sha256:880c84ce59f49776cf120f77e7ca04877c97c6887917078dbc369eb47004d7cf \
|
||||
--hash=sha256:94874584b733a18b310b0e954d53168e62cd4a0fd9db85b1903f0902a7eb33e8 \
|
||||
--hash=sha256:95603eff711b8f3b9596e1c961dbeb745a792ba1904141612f194e07edd71e5f \
|
||||
--hash=sha256:9585892091ae86045135d6a6129a644142d6a51b23e1428bb5de6d10bc0ce0c7 \
|
||||
--hash=sha256:977bf5be704a88d46bf5b228df8b44521b1f3119d741062191608b3a6a38f224 \
|
||||
--hash=sha256:9cdc46859024501c20ab74ad542cdf2f08b94b5ce384f2f569483fa3ed926d04 \
|
||||
--hash=sha256:a34a5f034b339f69ef7f6a134c22d04b92e07b6ddc1dd65382e7e4ec65d6437d \
|
||||
--hash=sha256:a655f7b755cfc5c07f2116b6dcf0ba148c89adef9a6d40c1b0f1fada878c4345 \
|
||||
--hash=sha256:a7d12f2d2df195c8c4e49d2cdbad640353a856c62ca2c624d8b47aa33b65a2a2 \
|
||||
--hash=sha256:abfe83e082c9208891e2158c1b5044a650ecec408b823bf6bf16cd7f8085cafa \
|
||||
--hash=sha256:b25077a971c7da47bd6846a912a747f6963776d90720c88603b1b55d81790780 \
|
||||
--hash=sha256:bf416a93e1331820c77e3429df26946dbd4fe105e9b487cd2d1b7298b75784a8 \
|
||||
--hash=sha256:c04ae27e076d81a3839047d8eed57c1e17e361640616fd520d752375e3ba8f0c \
|
||||
--hash=sha256:d5bea13c73f36c4346808df3fa806596163a7962b6d28001ca2a391cab856089 \
|
||||
--hash=sha256:d75bef34e69e7effb7b4849e3f830e3174d2cc6ec7273503fdde111c222dc9b3 \
|
||||
--hash=sha256:d93940664a5ccfd79f72dcb939b0c31a3479889f14f0eb95ec52976f8c0cae7d \
|
||||
--hash=sha256:d9c89c521dc90c7564358e525f849b93ad1d710553c1491f66b8cce8113bc901 \
|
||||
--hash=sha256:e0b36257dc90194784531c3b922d8d31fb2b4d8e5adfd27aff4eee7174176365 \
|
||||
--hash=sha256:e1135264bcd40965cd35b0869e36952f54825024befdc7a923df9a7d83cfd800 \
|
||||
--hash=sha256:e510d288e613d6927796dfb728e13e4530fc83b9ccac5888a21f7860486eab21 \
|
||||
--hash=sha256:ee9a2c9a4b2421e77f8fe33ed0621dea03c66c710707553020b1e32f3afb6240 \
|
||||
--hash=sha256:f19f11055ba2961eb39bdb1ff15763a53fca4fa0b5b624da3c7a528e83cdd09c \
|
||||
--hash=sha256:f26544bc10c83a2ff9aa2e093500c1b473f327faae31fb468d591e5823333376 \
|
||||
--hash=sha256:f4875cafc9a6482c04c7df52a725d1c41beb74913c0ff4ec8f189f1954a2afe9 \
|
||||
--hash=sha256:f5179088ef6487c475604b7898731a6ddeeada7702cfb2162155b016703a8475 \
|
||||
--hash=sha256:f63d1ae1ca17bb2c847e298c7bcf084a73d56d434b4c50509fb93a4b4300b0b2 \
|
||||
--hash=sha256:ff4928dc1e9704b567171c16787238201fdbf023665573c12c02146fe1e02eec
|
||||
# via -r requirements-base.in
|
@ -1,7 +0,0 @@
|
||||
psutil==5.9.3
|
||||
ujson==5.5.0
|
||||
ordered-set==4.1.0
|
||||
result==0.8.0
|
||||
# These two are also by Kevin
|
||||
filenuke==0.0.0
|
||||
onionrblocks==7.0.0
|
@ -1,2 +1,3 @@
|
||||
pip-tools==6.4.0
|
||||
pdoc3==0.9.2
|
||||
pip-tools==5.5.0
|
||||
helium==3.0.5
|
||||
|
@ -1,40 +1,73 @@
|
||||
#
|
||||
# This file is autogenerated by pip-compile with python 3.10
|
||||
# This file is autogenerated by pip-compile
|
||||
# To update, run:
|
||||
#
|
||||
# pip-compile --generate-hashes --output-file=requirements-dev.txt requirements-dev.in
|
||||
#
|
||||
click==7.0 \
|
||||
--hash=sha256:2335065e6395b9e67ca716de5f7526736bfa6ceead690adf616d925bdc622b13 \
|
||||
--hash=sha256:5b94b49521f6456670fdb30cd82a4eca9412788a93fa6dd6df72c94d5a8ff2d7
|
||||
--hash=sha256:5b94b49521f6456670fdb30cd82a4eca9412788a93fa6dd6df72c94d5a8ff2d7 \
|
||||
# via pip-tools
|
||||
helium==3.0.5 \
|
||||
--hash=sha256:74b074fbdc2ddc485a9e0e792b2d0ac3d52a8fcaf4a8ab855b690633590a0104
|
||||
--hash=sha256:74b074fbdc2ddc485a9e0e792b2d0ac3d52a8fcaf4a8ab855b690633590a0104 \
|
||||
# via -r requirements-dev.in
|
||||
pep517==0.12.0 \
|
||||
--hash=sha256:931378d93d11b298cf511dd634cf5ea4cb249a28ef84160b3247ee9afb4e8ab0 \
|
||||
--hash=sha256:dd884c326898e2c6e11f9e0b64940606a93eb10ea022a2e067959f3a110cf161
|
||||
# via pip-tools
|
||||
pip-tools==6.4.0 \
|
||||
--hash=sha256:65553a15b1ba34be5e43889345062e38fb9b219ffa23b084ca0d4c4039b6f53b \
|
||||
--hash=sha256:bb2c3272bc229b4a6d25230ebe255823aba1aa466a0d698c48ab7eb5ab7efdc9
|
||||
mako==1.1.1 \
|
||||
--hash=sha256:2984a6733e1d472796ceef37ad48c26f4a984bb18119bb2dbc37a44d8f6e75a4 \
|
||||
# via pdoc3
|
||||
markdown==3.1.1 \
|
||||
--hash=sha256:2e50876bcdd74517e7b71f3e7a76102050edec255b3983403f1a63e7c8a41e7a \
|
||||
--hash=sha256:56a46ac655704b91e5b7e6326ce43d5ef72411376588afa1dd90e881b83c7e8c \
|
||||
# via pdoc3
|
||||
markupsafe==1.1.1 \
|
||||
--hash=sha256:00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473 \
|
||||
--hash=sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161 \
|
||||
--hash=sha256:09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235 \
|
||||
--hash=sha256:1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5 \
|
||||
--hash=sha256:13d3144e1e340870b25e7b10b98d779608c02016d5184cfb9927a9f10c689f42 \
|
||||
--hash=sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff \
|
||||
--hash=sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b \
|
||||
--hash=sha256:43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1 \
|
||||
--hash=sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e \
|
||||
--hash=sha256:500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183 \
|
||||
--hash=sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66 \
|
||||
--hash=sha256:596510de112c685489095da617b5bcbbac7dd6384aeebeda4df6025d0256a81b \
|
||||
--hash=sha256:62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1 \
|
||||
--hash=sha256:6788b695d50a51edb699cb55e35487e430fa21f1ed838122d722e0ff0ac5ba15 \
|
||||
--hash=sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1 \
|
||||
--hash=sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e \
|
||||
--hash=sha256:79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b \
|
||||
--hash=sha256:7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905 \
|
||||
--hash=sha256:88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735 \
|
||||
--hash=sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d \
|
||||
--hash=sha256:98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e \
|
||||
--hash=sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d \
|
||||
--hash=sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c \
|
||||
--hash=sha256:ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21 \
|
||||
--hash=sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2 \
|
||||
--hash=sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5 \
|
||||
--hash=sha256:b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b \
|
||||
--hash=sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6 \
|
||||
--hash=sha256:c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f \
|
||||
--hash=sha256:cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f \
|
||||
--hash=sha256:cdb132fc825c38e1aeec2c8aa9338310d29d337bebbd7baa06889d09a60a1fa2 \
|
||||
--hash=sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7 \
|
||||
--hash=sha256:e8313f01ba26fbbe36c7be1966a7b7424942f670f38e666995b88d012765b9be \
|
||||
# via mako
|
||||
pdoc3==0.9.2 \
|
||||
--hash=sha256:9df5d931f25f353c69c46819a3bd03ef96dd286f2a70bb1b93a23a781f91faa1 \
|
||||
# via -r requirements-dev.in
|
||||
pip-tools==5.5.0 \
|
||||
--hash=sha256:10841c1e56c234d610d0466447685b9ea4ee4a2c274f858c0ef3c33d9bd0d985 \
|
||||
--hash=sha256:cb0108391366b3ef336185097b3c2c0f3fa115b15098dafbda5e78aef70ea114 \
|
||||
# via -r requirements-dev.in
|
||||
selenium==3.141.0 \
|
||||
--hash=sha256:2d7131d7bc5a5b99a2d9b04aaf2612c411b03b8ca1b1ee8d3de5845a9be2cb3c \
|
||||
--hash=sha256:deaf32b60ad91a4611b98d8002757f29e6f2c2d5fcaf202e1c9ad06d6772300d
|
||||
--hash=sha256:deaf32b60ad91a4611b98d8002757f29e6f2c2d5fcaf202e1c9ad06d6772300d \
|
||||
# via helium
|
||||
tomli==2.0.0 \
|
||||
--hash=sha256:b5bde28da1fed24b9bd1d4d2b8cba62300bfb4ec9a6187a957e8ddb9434c5224 \
|
||||
--hash=sha256:c292c34f58502a1eb2bbb9f5bbc9a5ebc37bee10ffb8c2d6bbdfa8eb13cc14e1
|
||||
# via pep517
|
||||
urllib3==1.25.9 \
|
||||
--hash=sha256:3018294ebefce6572a474f0604c2021e33b3fd8006ecd11d62107a5d2a963527 \
|
||||
--hash=sha256:88206b0eb87e6d677d424843ac5209e3fb9d0190d0ee169599165ec25e9d9115
|
||||
--hash=sha256:88206b0eb87e6d677d424843ac5209e3fb9d0190d0ee169599165ec25e9d9115 \
|
||||
# via selenium
|
||||
wheel==0.37.1 \
|
||||
--hash=sha256:4bdcd7d840138086126cd09254dc6195fb4fc6f01c050a1d7236f2630db1d22a \
|
||||
--hash=sha256:e9a504e793efbca1b8e0e9cb979a249cf4a0a7b5b8c9e8b65a5e39d49529c1c4
|
||||
# via pip-tools
|
||||
|
||||
# WARNING: The following packages were not pinned, but pip requires them to be
|
||||
# pinned when the requirements file includes hashes. Consider using the --allow-unsafe flag.
|
||||
|
1
requirements-notifications.in
Normal file
1
requirements-notifications.in
Normal file
@ -0,0 +1 @@
|
||||
simplenotifications==0.2.18
|
8
requirements-notifications.txt
Normal file
8
requirements-notifications.txt
Normal file
@ -0,0 +1,8 @@
|
||||
#
|
||||
# This file is autogenerated by pip-compile
|
||||
# To update, run:
|
||||
#
|
||||
# pip-compile --generate-hashes --output-file=requirements-notifications.txt requirements-notifications.in
|
||||
#
|
||||
simplenotifications==0.2.18 \
|
||||
--hash=sha256:b7efd3d834b1922a3279287913d87fe4ef6fad181ca7edf54bfb8f1d973941e0
|
@ -1,445 +0,0 @@
|
||||
#
|
||||
# This file is autogenerated by pip-compile with python 3.10
|
||||
# To update, run:
|
||||
#
|
||||
# pip-compile --generate-hashes --output-file=requirements-x86-all-plugins.txt requirements-base.in static-data/official-plugins/rpc/requirements.in static-data/official-plugins/tor/requirements.in static-data/official-plugins/wot/requirements.in
|
||||
#
|
||||
autocommand==2.2.1 \
|
||||
--hash=sha256:85d03044c2a1fc1c7844ac41545045927aecde0cbaf8ea28b88e0cd8588ce5d3 \
|
||||
--hash=sha256:fed420e9d02745821a782971b583c6970259ee0b229be2a0a401e1467a4f170f
|
||||
# via jaraco-text
|
||||
cffi==1.15.1 \
|
||||
--hash=sha256:00a9ed42e88df81ffae7a8ab6d9356b371399b91dbdf0c3cb1e84c03a13aceb5 \
|
||||
--hash=sha256:03425bdae262c76aad70202debd780501fabeaca237cdfddc008987c0e0f59ef \
|
||||
--hash=sha256:04ed324bda3cda42b9b695d51bb7d54b680b9719cfab04227cdd1e04e5de3104 \
|
||||
--hash=sha256:0e2642fe3142e4cc4af0799748233ad6da94c62a8bec3a6648bf8ee68b1c7426 \
|
||||
--hash=sha256:173379135477dc8cac4bc58f45db08ab45d228b3363adb7af79436135d028405 \
|
||||
--hash=sha256:198caafb44239b60e252492445da556afafc7d1e3ab7a1fb3f0584ef6d742375 \
|
||||
--hash=sha256:1e74c6b51a9ed6589199c787bf5f9875612ca4a8a0785fb2d4a84429badaf22a \
|
||||
--hash=sha256:2012c72d854c2d03e45d06ae57f40d78e5770d252f195b93f581acf3ba44496e \
|
||||
--hash=sha256:21157295583fe8943475029ed5abdcf71eb3911894724e360acff1d61c1d54bc \
|
||||
--hash=sha256:2470043b93ff09bf8fb1d46d1cb756ce6132c54826661a32d4e4d132e1977adf \
|
||||
--hash=sha256:285d29981935eb726a4399badae8f0ffdff4f5050eaa6d0cfc3f64b857b77185 \
|
||||
--hash=sha256:30d78fbc8ebf9c92c9b7823ee18eb92f2e6ef79b45ac84db507f52fbe3ec4497 \
|
||||
--hash=sha256:320dab6e7cb2eacdf0e658569d2575c4dad258c0fcc794f46215e1e39f90f2c3 \
|
||||
--hash=sha256:33ab79603146aace82c2427da5ca6e58f2b3f2fb5da893ceac0c42218a40be35 \
|
||||
--hash=sha256:3548db281cd7d2561c9ad9984681c95f7b0e38881201e157833a2342c30d5e8c \
|
||||
--hash=sha256:3799aecf2e17cf585d977b780ce79ff0dc9b78d799fc694221ce814c2c19db83 \
|
||||
--hash=sha256:39d39875251ca8f612b6f33e6b1195af86d1b3e60086068be9cc053aa4376e21 \
|
||||
--hash=sha256:3b926aa83d1edb5aa5b427b4053dc420ec295a08e40911296b9eb1b6170f6cca \
|
||||
--hash=sha256:3bcde07039e586f91b45c88f8583ea7cf7a0770df3a1649627bf598332cb6984 \
|
||||
--hash=sha256:3d08afd128ddaa624a48cf2b859afef385b720bb4b43df214f85616922e6a5ac \
|
||||
--hash=sha256:3eb6971dcff08619f8d91607cfc726518b6fa2a9eba42856be181c6d0d9515fd \
|
||||
--hash=sha256:40f4774f5a9d4f5e344f31a32b5096977b5d48560c5592e2f3d2c4374bd543ee \
|
||||
--hash=sha256:4289fc34b2f5316fbb762d75362931e351941fa95fa18789191b33fc4cf9504a \
|
||||
--hash=sha256:470c103ae716238bbe698d67ad020e1db9d9dba34fa5a899b5e21577e6d52ed2 \
|
||||
--hash=sha256:4f2c9f67e9821cad2e5f480bc8d83b8742896f1242dba247911072d4fa94c192 \
|
||||
--hash=sha256:50a74364d85fd319352182ef59c5c790484a336f6db772c1a9231f1c3ed0cbd7 \
|
||||
--hash=sha256:54a2db7b78338edd780e7ef7f9f6c442500fb0d41a5a4ea24fff1c929d5af585 \
|
||||
--hash=sha256:5635bd9cb9731e6d4a1132a498dd34f764034a8ce60cef4f5319c0541159392f \
|
||||
--hash=sha256:59c0b02d0a6c384d453fece7566d1c7e6b7bae4fc5874ef2ef46d56776d61c9e \
|
||||
--hash=sha256:5d598b938678ebf3c67377cdd45e09d431369c3b1a5b331058c338e201f12b27 \
|
||||
--hash=sha256:5df2768244d19ab7f60546d0c7c63ce1581f7af8b5de3eb3004b9b6fc8a9f84b \
|
||||
--hash=sha256:5ef34d190326c3b1f822a5b7a45f6c4535e2f47ed06fec77d3d799c450b2651e \
|
||||
--hash=sha256:6975a3fac6bc83c4a65c9f9fcab9e47019a11d3d2cf7f3c0d03431bf145a941e \
|
||||
--hash=sha256:6c9a799e985904922a4d207a94eae35c78ebae90e128f0c4e521ce339396be9d \
|
||||
--hash=sha256:70df4e3b545a17496c9b3f41f5115e69a4f2e77e94e1d2a8e1070bc0c38c8a3c \
|
||||
--hash=sha256:7473e861101c9e72452f9bf8acb984947aa1661a7704553a9f6e4baa5ba64415 \
|
||||
--hash=sha256:8102eaf27e1e448db915d08afa8b41d6c7ca7a04b7d73af6514df10a3e74bd82 \
|
||||
--hash=sha256:87c450779d0914f2861b8526e035c5e6da0a3199d8f1add1a665e1cbc6fc6d02 \
|
||||
--hash=sha256:8b7ee99e510d7b66cdb6c593f21c043c248537a32e0bedf02e01e9553a172314 \
|
||||
--hash=sha256:91fc98adde3d7881af9b59ed0294046f3806221863722ba7d8d120c575314325 \
|
||||
--hash=sha256:94411f22c3985acaec6f83c6df553f2dbe17b698cc7f8ae751ff2237d96b9e3c \
|
||||
--hash=sha256:98d85c6a2bef81588d9227dde12db8a7f47f639f4a17c9ae08e773aa9c697bf3 \
|
||||
--hash=sha256:9ad5db27f9cabae298d151c85cf2bad1d359a1b9c686a275df03385758e2f914 \
|
||||
--hash=sha256:a0b71b1b8fbf2b96e41c4d990244165e2c9be83d54962a9a1d118fd8657d2045 \
|
||||
--hash=sha256:a0f100c8912c114ff53e1202d0078b425bee3649ae34d7b070e9697f93c5d52d \
|
||||
--hash=sha256:a591fe9e525846e4d154205572a029f653ada1a78b93697f3b5a8f1f2bc055b9 \
|
||||
--hash=sha256:a5c84c68147988265e60416b57fc83425a78058853509c1b0629c180094904a5 \
|
||||
--hash=sha256:a66d3508133af6e8548451b25058d5812812ec3798c886bf38ed24a98216fab2 \
|
||||
--hash=sha256:a8c4917bd7ad33e8eb21e9a5bbba979b49d9a97acb3a803092cbc1133e20343c \
|
||||
--hash=sha256:b3bbeb01c2b273cca1e1e0c5df57f12dce9a4dd331b4fa1635b8bec26350bde3 \
|
||||
--hash=sha256:cba9d6b9a7d64d4bd46167096fc9d2f835e25d7e4c121fb2ddfc6528fb0413b2 \
|
||||
--hash=sha256:cc4d65aeeaa04136a12677d3dd0b1c0c94dc43abac5860ab33cceb42b801c1e8 \
|
||||
--hash=sha256:ce4bcc037df4fc5e3d184794f27bdaab018943698f4ca31630bc7f84a7b69c6d \
|
||||
--hash=sha256:cec7d9412a9102bdc577382c3929b337320c4c4c4849f2c5cdd14d7368c5562d \
|
||||
--hash=sha256:d400bfb9a37b1351253cb402671cea7e89bdecc294e8016a707f6d1d8ac934f9 \
|
||||
--hash=sha256:d61f4695e6c866a23a21acab0509af1cdfd2c013cf256bbf5b6b5e2695827162 \
|
||||
--hash=sha256:db0fbb9c62743ce59a9ff687eb5f4afbe77e5e8403d6697f7446e5f609976f76 \
|
||||
--hash=sha256:dd86c085fae2efd48ac91dd7ccffcfc0571387fe1193d33b6394db7ef31fe2a4 \
|
||||
--hash=sha256:e00b098126fd45523dd056d2efba6c5a63b71ffe9f2bbe1a4fe1716e1d0c331e \
|
||||
--hash=sha256:e229a521186c75c8ad9490854fd8bbdd9a0c9aa3a524326b55be83b54d4e0ad9 \
|
||||
--hash=sha256:e263d77ee3dd201c3a142934a086a4450861778baaeeb45db4591ef65550b0a6 \
|
||||
--hash=sha256:ed9cb427ba5504c1dc15ede7d516b84757c3e3d7868ccc85121d9310d27eed0b \
|
||||
--hash=sha256:fa6693661a4c91757f4412306191b6dc88c1703f780c8234035eac011922bc01 \
|
||||
--hash=sha256:fcd131dd944808b5bdb38e6f5b53013c5aa4f334c5cad0c72742f6eba4b73db0
|
||||
# via
|
||||
# -r static-data/official-plugins/wot/requirements.in
|
||||
# cryptography
|
||||
# pynacl
|
||||
cheroot==8.6.0 \
|
||||
--hash=sha256:366adf6e7cac9555486c2d1be6297993022eff6f8c4655c1443268cca3f08e25 \
|
||||
--hash=sha256:62cbced16f07e8aaf512673987cd6b1fc5ad00073345e9ed6c4e2a5cc2a3a22d
|
||||
# via cherrypy
|
||||
cherrypy==18.8.0 \
|
||||
--hash=sha256:9b48cfba8a2f16d5b6419cc657e6d51db005ba35c5e3824e4728bb03bbc7ef9b \
|
||||
--hash=sha256:b56097025dc78a76a59db551b3a82871c6b3a0107b80b12ff759e4c0b3b947ce
|
||||
# via -r static-data/official-plugins/rpc/requirements.in
|
||||
cryptography==38.0.1 \
|
||||
--hash=sha256:0297ffc478bdd237f5ca3a7dc96fc0d315670bfa099c04dc3a4a2172008a405a \
|
||||
--hash=sha256:10d1f29d6292fc95acb597bacefd5b9e812099d75a6469004fd38ba5471a977f \
|
||||
--hash=sha256:16fa61e7481f4b77ef53991075de29fc5bacb582a1244046d2e8b4bb72ef66d0 \
|
||||
--hash=sha256:194044c6b89a2f9f169df475cc167f6157eb9151cc69af8a2a163481d45cc407 \
|
||||
--hash=sha256:1db3d807a14931fa317f96435695d9ec386be7b84b618cc61cfa5d08b0ae33d7 \
|
||||
--hash=sha256:3261725c0ef84e7592597606f6583385fed2a5ec3909f43bc475ade9729a41d6 \
|
||||
--hash=sha256:3b72c360427889b40f36dc214630e688c2fe03e16c162ef0aa41da7ab1455153 \
|
||||
--hash=sha256:3e3a2599e640927089f932295a9a247fc40a5bdf69b0484532f530471a382750 \
|
||||
--hash=sha256:3fc26e22840b77326a764ceb5f02ca2d342305fba08f002a8c1f139540cdfaad \
|
||||
--hash=sha256:5067ee7f2bce36b11d0e334abcd1ccf8c541fc0bbdaf57cdd511fdee53e879b6 \
|
||||
--hash=sha256:52e7bee800ec869b4031093875279f1ff2ed12c1e2f74923e8f49c916afd1d3b \
|
||||
--hash=sha256:64760ba5331e3f1794d0bcaabc0d0c39e8c60bf67d09c93dc0e54189dfd7cfe5 \
|
||||
--hash=sha256:765fa194a0f3372d83005ab83ab35d7c5526c4e22951e46059b8ac678b44fa5a \
|
||||
--hash=sha256:79473cf8a5cbc471979bd9378c9f425384980fcf2ab6534b18ed7d0d9843987d \
|
||||
--hash=sha256:896dd3a66959d3a5ddcfc140a53391f69ff1e8f25d93f0e2e7830c6de90ceb9d \
|
||||
--hash=sha256:89ed49784ba88c221756ff4d4755dbc03b3c8d2c5103f6d6b4f83a0fb1e85294 \
|
||||
--hash=sha256:ac7e48f7e7261207d750fa7e55eac2d45f720027d5703cd9007e9b37bbb59ac0 \
|
||||
--hash=sha256:ad7353f6ddf285aeadfaf79e5a6829110106ff8189391704c1d8801aa0bae45a \
|
||||
--hash=sha256:b0163a849b6f315bf52815e238bc2b2346604413fa7c1601eea84bcddb5fb9ac \
|
||||
--hash=sha256:b6c9b706316d7b5a137c35e14f4103e2115b088c412140fdbd5f87c73284df61 \
|
||||
--hash=sha256:c2e5856248a416767322c8668ef1845ad46ee62629266f84a8f007a317141013 \
|
||||
--hash=sha256:ca9f6784ea96b55ff41708b92c3f6aeaebde4c560308e5fbbd3173fbc466e94e \
|
||||
--hash=sha256:d1a5bd52d684e49a36582193e0b89ff267704cd4025abefb9e26803adeb3e5fb \
|
||||
--hash=sha256:d3971e2749a723e9084dd507584e2a2761f78ad2c638aa31e80bc7a15c9db4f9 \
|
||||
--hash=sha256:d4ef6cc305394ed669d4d9eebf10d3a101059bdcf2669c366ec1d14e4fb227bd \
|
||||
--hash=sha256:d9e69ae01f99abe6ad646947bba8941e896cb3aa805be2597a0400e0764b5818
|
||||
# via secretstorage
|
||||
filenuke==0.0.0 \
|
||||
--hash=sha256:147011c0125121469cae0a8a7f4df399f470e54aa29a08f2d2c099bf0118dcee \
|
||||
--hash=sha256:c55535dcecfdb27c5f4ce664d46e115950b5429763b5db75c198053646177f8f
|
||||
# via -r requirements-base.in
|
||||
inflect==6.0.0 \
|
||||
--hash=sha256:0bc1516ec2725e2d8221707a612245093cb6f1cea209cfd8cbd4fc5e96fa6365 \
|
||||
--hash=sha256:e3b85d65a296843268f35f4136283ad7c012a129375db1529d49b4b01ecb400b
|
||||
# via jaraco-text
|
||||
jaraco-classes==3.2.2 \
|
||||
--hash=sha256:6745f113b0b588239ceb49532aa09c3ebb947433ce311ef2f8e3ad64ebb74594 \
|
||||
--hash=sha256:e6ef6fd3fcf4579a7a019d87d1e56a883f4e4c35cfe925f86731abc58804e647
|
||||
# via
|
||||
# jaraco-collections
|
||||
# keyring
|
||||
jaraco-collections==3.5.2 \
|
||||
--hash=sha256:072b93eb35f9e48508485755534e66a34ef1cc84af291fd27f39b44d4c0dd2c3 \
|
||||
--hash=sha256:1ca12fa4b7067dfc8d7f791c1a8660d970a2bf2f80536ba0aa5cbb71fe1261f1
|
||||
# via cherrypy
|
||||
jaraco-context==4.1.2 \
|
||||
--hash=sha256:9327d3e6901923e5a7097aa2df4b9c2bc13f845c7672692e3827ebd1b3d67606 \
|
||||
--hash=sha256:a58e94dd67871639abc091b57d32842449b230777570ef2bcec3dc16b912613e
|
||||
# via jaraco-text
|
||||
jaraco-functools==3.5.1 \
|
||||
--hash=sha256:c8774f73323de42250a659934215da1d899b02c66a6133f1cb79f02a5aff4f38 \
|
||||
--hash=sha256:d0adcf91710a0853efe9f23a78fad586bf67df572f0d6d8e0fa36d289ae1c1d9
|
||||
# via
|
||||
# cheroot
|
||||
# jaraco-text
|
||||
# tempora
|
||||
jaraco-text==3.9.1 \
|
||||
--hash=sha256:3ca615c4135e151d21206075ec4aface8a2fbc3e68437fe709a6541428a635f9 \
|
||||
--hash=sha256:d57cd4448a588020318425e04194e897f96fc23b92b82ff9308a24d5cbf2b3fb
|
||||
# via jaraco-collections
|
||||
jeepney==0.8.0 \
|
||||
--hash=sha256:5efe48d255973902f6badc3ce55e2aa6c5c3b3bc642059ef3a91247bcfcc5806 \
|
||||
--hash=sha256:c0a454ad016ca575060802ee4d590dd912e35c122fa04e70306de3d076cce755
|
||||
# via
|
||||
# keyring
|
||||
# secretstorage
|
||||
json-rpc==1.13.0 \
|
||||
--hash=sha256:84b45058e5ba95f49c7b6afcf7e03ab86bee89bf2c01f3ad8dd41fe114fc1f84 \
|
||||
--hash=sha256:def0dbcf5b7084fc31d677f2f5990d988d06497f2f47f13024274cfb2d5d7589
|
||||
# via -r static-data/official-plugins/rpc/requirements.in
|
||||
kasten==3.0.0 \
|
||||
--hash=sha256:52894af46d6e1339f0d5fa8961892b292f99176848bce11877fe4a435b6782e5 \
|
||||
--hash=sha256:b22ebdc5f475c2ef9ab74abc36552add0b37732a7ce2be6bd7977ee41b2163b4
|
||||
# via onionrblocks
|
||||
keyring==23.9.3 \
|
||||
--hash=sha256:69732a15cb1433bdfbc3b980a8a36a04878a6cfd7cb99f497b573f31618001c0 \
|
||||
--hash=sha256:69b01dd83c42f590250fe7a1f503fc229b14de83857314b1933a3ddbf595c4a5
|
||||
# via -r static-data/official-plugins/wot/requirements.in
|
||||
mimcvdf==1.2.1 \
|
||||
--hash=sha256:7c837c46cfb9dce4ba895bc706a69646d4d5185c66aeaa333b5cfaa9a7d06dc4
|
||||
# via kasten
|
||||
more-itertools==8.14.0 \
|
||||
--hash=sha256:1bc4f91ee5b1b31ac7ceacc17c09befe6a40a503907baf9c839c229b5095cfd2 \
|
||||
--hash=sha256:c09443cd3d5438b8dafccd867a6bc1cb0894389e90cb53d227456b0b0bccb750
|
||||
# via
|
||||
# cheroot
|
||||
# cherrypy
|
||||
# jaraco-classes
|
||||
# jaraco-functools
|
||||
# jaraco-text
|
||||
msgpack==1.0.4 \
|
||||
--hash=sha256:002b5c72b6cd9b4bafd790f364b8480e859b4712e91f43014fe01e4f957b8467 \
|
||||
--hash=sha256:0a68d3ac0104e2d3510de90a1091720157c319ceeb90d74f7b5295a6bee51bae \
|
||||
--hash=sha256:0df96d6eaf45ceca04b3f3b4b111b86b33785683d682c655063ef8057d61fd92 \
|
||||
--hash=sha256:0dfe3947db5fb9ce52aaea6ca28112a170db9eae75adf9339a1aec434dc954ef \
|
||||
--hash=sha256:0e3590f9fb9f7fbc36df366267870e77269c03172d086fa76bb4eba8b2b46624 \
|
||||
--hash=sha256:11184bc7e56fd74c00ead4f9cc9a3091d62ecb96e97653add7a879a14b003227 \
|
||||
--hash=sha256:112b0f93202d7c0fef0b7810d465fde23c746a2d482e1e2de2aafd2ce1492c88 \
|
||||
--hash=sha256:1276e8f34e139aeff1c77a3cefb295598b504ac5314d32c8c3d54d24fadb94c9 \
|
||||
--hash=sha256:1576bd97527a93c44fa856770197dec00d223b0b9f36ef03f65bac60197cedf8 \
|
||||
--hash=sha256:1e91d641d2bfe91ba4c52039adc5bccf27c335356055825c7f88742c8bb900dd \
|
||||
--hash=sha256:26b8feaca40a90cbe031b03d82b2898bf560027160d3eae1423f4a67654ec5d6 \
|
||||
--hash=sha256:2999623886c5c02deefe156e8f869c3b0aaeba14bfc50aa2486a0415178fce55 \
|
||||
--hash=sha256:2a2df1b55a78eb5f5b7d2a4bb221cd8363913830145fad05374a80bf0877cb1e \
|
||||
--hash=sha256:2bb8cdf50dd623392fa75525cce44a65a12a00c98e1e37bf0fb08ddce2ff60d2 \
|
||||
--hash=sha256:2cc5ca2712ac0003bcb625c96368fd08a0f86bbc1a5578802512d87bc592fe44 \
|
||||
--hash=sha256:35bc0faa494b0f1d851fd29129b2575b2e26d41d177caacd4206d81502d4c6a6 \
|
||||
--hash=sha256:3c11a48cf5e59026ad7cb0dc29e29a01b5a66a3e333dc11c04f7e991fc5510a9 \
|
||||
--hash=sha256:449e57cc1ff18d3b444eb554e44613cffcccb32805d16726a5494038c3b93dab \
|
||||
--hash=sha256:462497af5fd4e0edbb1559c352ad84f6c577ffbbb708566a0abaaa84acd9f3ae \
|
||||
--hash=sha256:4733359808c56d5d7756628736061c432ded018e7a1dff2d35a02439043321aa \
|
||||
--hash=sha256:48f5d88c99f64c456413d74a975bd605a9b0526293218a3b77220a2c15458ba9 \
|
||||
--hash=sha256:49565b0e3d7896d9ea71d9095df15b7f75a035c49be733051c34762ca95bbf7e \
|
||||
--hash=sha256:4ab251d229d10498e9a2f3b1e68ef64cb393394ec477e3370c457f9430ce9250 \
|
||||
--hash=sha256:4d5834a2a48965a349da1c5a79760d94a1a0172fbb5ab6b5b33cbf8447e109ce \
|
||||
--hash=sha256:4dea20515f660aa6b7e964433b1808d098dcfcabbebeaaad240d11f909298075 \
|
||||
--hash=sha256:545e3cf0cf74f3e48b470f68ed19551ae6f9722814ea969305794645da091236 \
|
||||
--hash=sha256:63e29d6e8c9ca22b21846234913c3466b7e4ee6e422f205a2988083de3b08cae \
|
||||
--hash=sha256:6916c78f33602ecf0509cc40379271ba0f9ab572b066bd4bdafd7434dee4bc6e \
|
||||
--hash=sha256:6a4192b1ab40f8dca3f2877b70e63799d95c62c068c84dc028b40a6cb03ccd0f \
|
||||
--hash=sha256:6c9566f2c39ccced0a38d37c26cc3570983b97833c365a6044edef3574a00c08 \
|
||||
--hash=sha256:76ee788122de3a68a02ed6f3a16bbcd97bc7c2e39bd4d94be2f1821e7c4a64e6 \
|
||||
--hash=sha256:7760f85956c415578c17edb39eed99f9181a48375b0d4a94076d84148cf67b2d \
|
||||
--hash=sha256:77ccd2af37f3db0ea59fb280fa2165bf1b096510ba9fe0cc2bf8fa92a22fdb43 \
|
||||
--hash=sha256:81fc7ba725464651190b196f3cd848e8553d4d510114a954681fd0b9c479d7e1 \
|
||||
--hash=sha256:85f279d88d8e833ec015650fd15ae5eddce0791e1e8a59165318f371158efec6 \
|
||||
--hash=sha256:9667bdfdf523c40d2511f0e98a6c9d3603be6b371ae9a238b7ef2dc4e7a427b0 \
|
||||
--hash=sha256:a75dfb03f8b06f4ab093dafe3ddcc2d633259e6c3f74bb1b01996f5d8aa5868c \
|
||||
--hash=sha256:ac5bd7901487c4a1dd51a8c58f2632b15d838d07ceedaa5e4c080f7190925bff \
|
||||
--hash=sha256:aca0f1644d6b5a73eb3e74d4d64d5d8c6c3d577e753a04c9e9c87d07692c58db \
|
||||
--hash=sha256:b17be2478b622939e39b816e0aa8242611cc8d3583d1cd8ec31b249f04623243 \
|
||||
--hash=sha256:c1683841cd4fa45ac427c18854c3ec3cd9b681694caf5bff04edb9387602d661 \
|
||||
--hash=sha256:c23080fdeec4716aede32b4e0ef7e213c7b1093eede9ee010949f2a418ced6ba \
|
||||
--hash=sha256:d5b5b962221fa2c5d3a7f8133f9abffc114fe218eb4365e40f17732ade576c8e \
|
||||
--hash=sha256:d603de2b8d2ea3f3bcb2efe286849aa7a81531abc52d8454da12f46235092bcb \
|
||||
--hash=sha256:e83f80a7fec1a62cf4e6c9a660e39c7f878f603737a0cdac8c13131d11d97f52 \
|
||||
--hash=sha256:eb514ad14edf07a1dbe63761fd30f89ae79b42625731e1ccf5e1f1092950eaa6 \
|
||||
--hash=sha256:eba96145051ccec0ec86611fe9cf693ce55f2a3ce89c06ed307de0e085730ec1 \
|
||||
--hash=sha256:ed6f7b854a823ea44cf94919ba3f727e230da29feb4a99711433f25800cf747f \
|
||||
--hash=sha256:f0029245c51fd9473dc1aede1160b0a29f4a912e6b1dd353fa6d317085b219da \
|
||||
--hash=sha256:f5d869c18f030202eb412f08b28d2afeea553d6613aee89e200d7aca7ef01f5f \
|
||||
--hash=sha256:fb62ea4b62bfcb0b380d5680f9a4b3f9a2d166d9394e9bbd9666c0ee09a3645c \
|
||||
--hash=sha256:fcb8a47f43acc113e24e910399376f7277cf8508b27e5b88499f053de6b115a8
|
||||
# via kasten
|
||||
onionrblocks==7.0.0 \
|
||||
--hash=sha256:53e90964371076d9daf2ed0790b21f174ef3321f4f1808209cc6dd9b7ff6d8ff \
|
||||
--hash=sha256:54af28d0be856209525646c4ef9f977f95f0ae1329b2cc023b351317c9d0eef7
|
||||
# via -r requirements-base.in
|
||||
ordered-set==4.1.0 \
|
||||
--hash=sha256:046e1132c71fcf3330438a539928932caf51ddbc582496833e23de611de14562 \
|
||||
--hash=sha256:694a8e44c87657c59292ede72891eb91d34131f6531463aab3009191c77364a8
|
||||
# via -r requirements-base.in
|
||||
portend==3.1.0 \
|
||||
--hash=sha256:239e3116045ea823f6df87d6168107ad75ccc0590e37242af0cc1e98c5d224e4 \
|
||||
--hash=sha256:9e735cee3a5c1961f09e3f3ba6dc498198c2d70b473d98d0d1504b8d1e7a3d61
|
||||
# via cherrypy
|
||||
psutil==5.9.3 \
|
||||
--hash=sha256:07d880053c6461c9b89cd5d4808f3b8336665fa3acdefd6777662c5ed73a851a \
|
||||
--hash=sha256:12500d761ac091f2426567f19f95fd3f15a197d96befb44a5c1e3cbe6db5752c \
|
||||
--hash=sha256:1b540599481c73408f6b392cdffef5b01e8ff7a2ac8caae0a91b8222e88e8f1e \
|
||||
--hash=sha256:35feafe232d1aaf35d51bd42790cbccb882456f9f18cdc411532902370d660df \
|
||||
--hash=sha256:3a7826e68b0cf4ce2c1ee385d64eab7d70e3133171376cac53d7c1790357ec8f \
|
||||
--hash=sha256:46907fa62acaac364fff0b8a9da7b360265d217e4fdeaca0a2397a6883dffba2 \
|
||||
--hash=sha256:4bd4854f0c83aa84a5a40d3b5d0eb1f3c128f4146371e03baed4589fe4f3c931 \
|
||||
--hash=sha256:538fcf6ae856b5e12d13d7da25ad67f02113c96f5989e6ad44422cb5994ca7fc \
|
||||
--hash=sha256:547ebb02031fdada635452250ff39942db8310b5c4a8102dfe9384ee5791e650 \
|
||||
--hash=sha256:5e8b50241dd3c2ed498507f87a6602825073c07f3b7e9560c58411c14fe1e1c9 \
|
||||
--hash=sha256:5fa88e3d5d0b480602553d362c4b33a63e0c40bfea7312a7bf78799e01e0810b \
|
||||
--hash=sha256:68fa227c32240c52982cb931801c5707a7f96dd8927f9102d6c7771ea1ff5698 \
|
||||
--hash=sha256:6ced1ad823ecfa7d3ce26fe8aa4996e2e53fb49b7fed8ad81c80958501ec0619 \
|
||||
--hash=sha256:71b1206e7909792d16933a0d2c1c7f04ae196186c51ba8567abae1d041f06dcb \
|
||||
--hash=sha256:767ef4fa33acda16703725c0473a91e1832d296c37c63896c7153ba81698f1ab \
|
||||
--hash=sha256:7ccfcdfea4fc4b0a02ca2c31de7fcd186beb9cff8207800e14ab66f79c773af6 \
|
||||
--hash=sha256:7e4939ff75149b67aef77980409f156f0082fa36accc475d45c705bb00c6c16a \
|
||||
--hash=sha256:828c9dc9478b34ab96be75c81942d8df0c2bb49edbb481f597314d92b6441d89 \
|
||||
--hash=sha256:8a4e07611997acf178ad13b842377e3d8e9d0a5bac43ece9bfc22a96735d9a4f \
|
||||
--hash=sha256:941a6c2c591da455d760121b44097781bc970be40e0e43081b9139da485ad5b7 \
|
||||
--hash=sha256:9a4af6ed1094f867834f5f07acd1250605a0874169a5fcadbcec864aec2496a6 \
|
||||
--hash=sha256:9ec296f565191f89c48f33d9544d8d82b0d2af7dd7d2d4e6319f27a818f8d1cc \
|
||||
--hash=sha256:9ec95df684583b5596c82bb380c53a603bb051cf019d5c849c47e117c5064395 \
|
||||
--hash=sha256:a04a1836894c8279e5e0a0127c0db8e198ca133d28be8a2a72b4db16f6cf99c1 \
|
||||
--hash=sha256:a3d81165b8474087bb90ec4f333a638ccfd1d69d34a9b4a1a7eaac06648f9fbe \
|
||||
--hash=sha256:b4a247cd3feaae39bb6085fcebf35b3b8ecd9b022db796d89c8f05067ca28e71 \
|
||||
--hash=sha256:ba38cf9984d5462b506e239cf4bc24e84ead4b1d71a3be35e66dad0d13ded7c1 \
|
||||
--hash=sha256:beb57d8a1ca0ae0eb3d08ccaceb77e1a6d93606f0e1754f0d60a6ebd5c288837 \
|
||||
--hash=sha256:d266cd05bd4a95ca1c2b9b5aac50d249cf7c94a542f47e0b22928ddf8b80d1ef \
|
||||
--hash=sha256:d8c3cc6bb76492133474e130a12351a325336c01c96a24aae731abf5a47fe088 \
|
||||
--hash=sha256:db8e62016add2235cc87fb7ea000ede9e4ca0aa1f221b40cef049d02d5d2593d \
|
||||
--hash=sha256:e7507f6c7b0262d3e7b0eeda15045bf5881f4ada70473b87bc7b7c93b992a7d7 \
|
||||
--hash=sha256:ed15edb14f52925869250b1375f0ff58ca5c4fa8adefe4883cfb0737d32f5c02 \
|
||||
--hash=sha256:f57d63a2b5beaf797b87024d018772439f9d3103a395627b77d17a8d72009543 \
|
||||
--hash=sha256:fa5e32c7d9b60b2528108ade2929b115167fe98d59f89555574715054f50fa31 \
|
||||
--hash=sha256:fe79b4ad4836e3da6c4650cb85a663b3a51aef22e1a829c384e18fae87e5e727
|
||||
# via -r requirements-base.in
|
||||
pycparser==2.21 \
|
||||
--hash=sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9 \
|
||||
--hash=sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206
|
||||
# via cffi
|
||||
pydantic==1.10.2 \
|
||||
--hash=sha256:05e00dbebbe810b33c7a7362f231893183bcc4251f3f2ff991c31d5c08240c42 \
|
||||
--hash=sha256:06094d18dd5e6f2bbf93efa54991c3240964bb663b87729ac340eb5014310624 \
|
||||
--hash=sha256:0b959f4d8211fc964772b595ebb25f7652da3f22322c007b6fed26846a40685e \
|
||||
--hash=sha256:19b3b9ccf97af2b7519c42032441a891a5e05c68368f40865a90eb88833c2559 \
|
||||
--hash=sha256:1b6ee725bd6e83ec78b1aa32c5b1fa67a3a65badddde3976bca5fe4568f27709 \
|
||||
--hash=sha256:1ee433e274268a4b0c8fde7ad9d58ecba12b069a033ecc4645bb6303c062d2e9 \
|
||||
--hash=sha256:216f3bcbf19c726b1cc22b099dd409aa371f55c08800bcea4c44c8f74b73478d \
|
||||
--hash=sha256:2d0567e60eb01bccda3a4df01df677adf6b437958d35c12a3ac3e0f078b0ee52 \
|
||||
--hash=sha256:2e05aed07fa02231dbf03d0adb1be1d79cabb09025dd45aa094aa8b4e7b9dcda \
|
||||
--hash=sha256:352aedb1d71b8b0736c6d56ad2bd34c6982720644b0624462059ab29bd6e5912 \
|
||||
--hash=sha256:355639d9afc76bcb9b0c3000ddcd08472ae75318a6eb67a15866b87e2efa168c \
|
||||
--hash=sha256:37c90345ec7dd2f1bcef82ce49b6235b40f282b94d3eec47e801baf864d15525 \
|
||||
--hash=sha256:4b8795290deaae348c4eba0cebb196e1c6b98bdbe7f50b2d0d9a4a99716342fe \
|
||||
--hash=sha256:5760e164b807a48a8f25f8aa1a6d857e6ce62e7ec83ea5d5c5a802eac81bad41 \
|
||||
--hash=sha256:6eb843dcc411b6a2237a694f5e1d649fc66c6064d02b204a7e9d194dff81eb4b \
|
||||
--hash=sha256:7b5ba54d026c2bd2cb769d3468885f23f43710f651688e91f5fb1edcf0ee9283 \
|
||||
--hash=sha256:7c2abc4393dea97a4ccbb4ec7d8658d4e22c4765b7b9b9445588f16c71ad9965 \
|
||||
--hash=sha256:81a7b66c3f499108b448f3f004801fcd7d7165fb4200acb03f1c2402da73ce4c \
|
||||
--hash=sha256:91b8e218852ef6007c2b98cd861601c6a09f1aa32bbbb74fab5b1c33d4a1e410 \
|
||||
--hash=sha256:9300fcbebf85f6339a02c6994b2eb3ff1b9c8c14f502058b5bf349d42447dcf5 \
|
||||
--hash=sha256:9cabf4a7f05a776e7793e72793cd92cc865ea0e83a819f9ae4ecccb1b8aa6116 \
|
||||
--hash=sha256:a1f5a63a6dfe19d719b1b6e6106561869d2efaca6167f84f5ab9347887d78b98 \
|
||||
--hash=sha256:a4c805731c33a8db4b6ace45ce440c4ef5336e712508b4d9e1aafa617dc9907f \
|
||||
--hash=sha256:ae544c47bec47a86bc7d350f965d8b15540e27e5aa4f55170ac6a75e5f73b644 \
|
||||
--hash=sha256:b97890e56a694486f772d36efd2ba31612739bc6f3caeee50e9e7e3ebd2fdd13 \
|
||||
--hash=sha256:bb6ad4489af1bac6955d38ebcb95079a836af31e4c4f74aba1ca05bb9f6027bd \
|
||||
--hash=sha256:bedf309630209e78582ffacda64a21f96f3ed2e51fbf3962d4d488e503420254 \
|
||||
--hash=sha256:c1ba1afb396148bbc70e9eaa8c06c1716fdddabaf86e7027c5988bae2a829ab6 \
|
||||
--hash=sha256:c33602f93bfb67779f9c507e4d69451664524389546bacfe1bee13cae6dc7488 \
|
||||
--hash=sha256:c4aac8e7103bf598373208f6299fa9a5cfd1fc571f2d40bf1dd1955a63d6eeb5 \
|
||||
--hash=sha256:c6f981882aea41e021f72779ce2a4e87267458cc4d39ea990729e21ef18f0f8c \
|
||||
--hash=sha256:cc78cc83110d2f275ec1970e7a831f4e371ee92405332ebfe9860a715f8336e1 \
|
||||
--hash=sha256:d49f3db871575e0426b12e2f32fdb25e579dea16486a26e5a0474af87cb1ab0a \
|
||||
--hash=sha256:dd3f9a40c16daf323cf913593083698caee97df2804aa36c4b3175d5ac1b92a2 \
|
||||
--hash=sha256:e0bedafe4bc165ad0a56ac0bd7695df25c50f76961da29c050712596cf092d6d \
|
||||
--hash=sha256:e9069e1b01525a96e6ff49e25876d90d5a563bc31c658289a8772ae186552236
|
||||
# via inflect
|
||||
pynacl==1.5.0 \
|
||||
--hash=sha256:06b8f6fa7f5de8d5d2f7573fe8c863c051225a27b61e6860fd047b1775807858 \
|
||||
--hash=sha256:0c84947a22519e013607c9be43706dd42513f9e6ae5d39d3613ca1e142fba44d \
|
||||
--hash=sha256:20f42270d27e1b6a29f54032090b972d97f0a1b0948cc52392041ef7831fee93 \
|
||||
--hash=sha256:401002a4aaa07c9414132aaed7f6836ff98f59277a234704ff66878c2ee4a0d1 \
|
||||
--hash=sha256:52cb72a79269189d4e0dc537556f4740f7f0a9ec41c1322598799b0bdad4ef92 \
|
||||
--hash=sha256:61f642bf2378713e2c2e1de73444a3778e5f0a38be6fee0fe532fe30060282ff \
|
||||
--hash=sha256:8ac7448f09ab85811607bdd21ec2464495ac8b7c66d146bf545b0f08fb9220ba \
|
||||
--hash=sha256:a36d4a9dda1f19ce6e03c9a784a2921a4b726b02e1c736600ca9c22029474394 \
|
||||
--hash=sha256:a422368fc821589c228f4c49438a368831cb5bbc0eab5ebe1d7fac9dded6567b \
|
||||
--hash=sha256:e46dae94e34b085175f8abb3b0aaa7da40767865ac82c928eeb9e57e1ea8a543
|
||||
# via
|
||||
# -r static-data/official-plugins/wot/requirements.in
|
||||
# onionrblocks
|
||||
pysocks==1.7.1 \
|
||||
--hash=sha256:08e69f092cc6dbe92a0fdd16eeb9b9ffbc13cadfe5ca4c7bd92ffb078b293299 \
|
||||
--hash=sha256:2725bd0a9925919b9b51739eea5f9e2bae91e83288108a9ad338b2e3a4435ee5 \
|
||||
--hash=sha256:3f8804571ebe159c380ac6de37643bb4685970655d3bba243530d6558b799aa0
|
||||
# via -r static-data/official-plugins/tor/requirements.in
|
||||
pytz==2022.2.1 \
|
||||
--hash=sha256:220f481bdafa09c3955dfbdddb7b57780e9a94f5127e35456a48589b9e0c0197 \
|
||||
--hash=sha256:cea221417204f2d1a2aa03ddae3e867921971d0d76f14d87abb4414415bbdcf5
|
||||
# via tempora
|
||||
result==0.8.0 \
|
||||
--hash=sha256:c48c909e92181a075ba358228a3fe161e26d205dad416ad81f27f23515a5626d \
|
||||
--hash=sha256:d6a6258f32c057a4e0478999c6ce43dcadaf8ea435f58ac601ae2768f93ef243
|
||||
# via -r requirements-base.in
|
||||
secretstorage==3.3.3 \
|
||||
--hash=sha256:2403533ef369eca6d2ba81718576c5e0f564d5cca1b58f73a8b23e7d4eeebd77 \
|
||||
--hash=sha256:f356e6628222568e3af06f2eba8df495efa13b3b63081dafd4f7d9a7b7bc9f99
|
||||
# via keyring
|
||||
six==1.16.0 \
|
||||
--hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926 \
|
||||
--hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254
|
||||
# via cheroot
|
||||
stem==1.8.1 \
|
||||
--hash=sha256:81d43a7c668ba9d7bc1103b2e7a911e9d148294b373d27a59ae8da79ef7a3e2f
|
||||
# via -r static-data/official-plugins/tor/requirements.in
|
||||
tempora==5.0.2 \
|
||||
--hash=sha256:31fa5bb33b2641026211f23e808eb8bd351901988b167d45f323c8f450ecf211 \
|
||||
--hash=sha256:e65d32ae68ad772ee738d802689f689b3f883e165e8dadd39aa89ef317b12b99
|
||||
# via portend
|
||||
typing-extensions==4.3.0 \
|
||||
--hash=sha256:25642c956049920a5aa49edcdd6ab1e06d7e5d467fc00e0506c44ac86fbfca02 \
|
||||
--hash=sha256:e6d2677a32f47fc7eb2795db1dd15c1f34eff616bcaf2cfb5e997f854fa1c4a6
|
||||
# via pydantic
|
||||
ujson==5.5.0 \
|
||||
--hash=sha256:0762a4fdf86e01f3f8d8b6b7158d01fdd870799ff3f402b676e358fcd879e7eb \
|
||||
--hash=sha256:10095160dbe6bba8059ad6677a01da251431f4c68041bf796dcac0956b34f8f7 \
|
||||
--hash=sha256:1a485117f97312bef45f5d79d2ff97eff4da503b8a04f3691f59d31141686459 \
|
||||
--hash=sha256:1cef44ea4973344baed3d50a5da4a8843de3a6af7dea7fadf0a594e53ce5892f \
|
||||
--hash=sha256:1dc2f46c31ef22b0aaa28cd71be897bea271e700636658d573df9c43c49ebbd0 \
|
||||
--hash=sha256:21678d7e068707e4d54bdfeb8c250ebc548b51e499aed778b22112ca31a79669 \
|
||||
--hash=sha256:278aa9d7cb56435c96d19f5d702e026bcf69f824e24b41e9b52706abd3565837 \
|
||||
--hash=sha256:2ab011e3556a9a1d9461bd686870c527327765ed02fe53550531d6609a8a33ff \
|
||||
--hash=sha256:2d90414e3b4b44b39825049185959488e084ea7fcaf6124afd5c00893938b09d \
|
||||
--hash=sha256:2e506ecf89b6b9d304362ccef770831ec242a52c89dab1b4aabf1ab0eb1d5ed6 \
|
||||
--hash=sha256:33cd9084fefc74cbacf88c92fd260b61211e00bcde38d640c369e5dc34a2b4e1 \
|
||||
--hash=sha256:3b74467564814fbce322427a5664e6bcc7dae6dbc8acbef76300fe43ca4072ab \
|
||||
--hash=sha256:3f3f4240d99d55eb97cb012e9adf401f5ed9cd827af0341ac44603832202b0d2 \
|
||||
--hash=sha256:3fe1aea596f9539fc20cd9e52f098c842afc090168824fd4ca9744fe13151a03 \
|
||||
--hash=sha256:4a8cb3c8637006c5bd8237ebb5992a76ba06e39988ad5cff2096227443e8fd6a \
|
||||
--hash=sha256:4ef4ab8352861b99bd7fedb1fc6df3ea7f7d5216c789ba6d859e4ea06f1a4c45 \
|
||||
--hash=sha256:5035bb997d163f346c22abcec75190e7e756a5349e7c708bd3d5fd7066a9a854 \
|
||||
--hash=sha256:593a0f6fb0e186c5ba65465ed6f6215a30d1efa898c25e74de1c8577a1bff6d0 \
|
||||
--hash=sha256:59cdcd934385f36e8bd76aedc234371cc75c848d95bdce804ac8aa8744cfeffa \
|
||||
--hash=sha256:5a9b1320d8363a42d857fae8065a2174d38217cdd58cd8dc4f48d54e0591271e \
|
||||
--hash=sha256:5f9681ec4c60d0da590552427d770636d9079038c30b265f507ccde23caa7823 \
|
||||
--hash=sha256:5fd797a4837ba10671954e7c09010cec7aca67e09d193f4920a16beea5f66f65 \
|
||||
--hash=sha256:6019e3480d933d3698f2ecb4b46d64bfadd64e718f04fac36e681f3254b49a93 \
|
||||
--hash=sha256:603607f56a0ee84d9cd2c7e9b1d29b18a70684b94ee34f07b9ffe8dc9c8a9f81 \
|
||||
--hash=sha256:60a4b481978ea2aad8fe8af1ecc271624d01b3cf4b09e9b643dd2fe19c07634c \
|
||||
--hash=sha256:6b9812638d7aa8ecda2e8e1513fb4da999249603bffab7439a5f8f0bb362b0db \
|
||||
--hash=sha256:6c7ae6e0778ab9610f5e80e0595957d101ab8de18c32a8c053a19943ef4831d0 \
|
||||
--hash=sha256:6f83be8257b2f2dd6dea5ee62cd28db90584da7a7af1fba77a2102fc7943638a \
|
||||
--hash=sha256:701e81e047f5c0cffd4ac828efca68b0bd270c616654966a051e9a5f836b385e \
|
||||
--hash=sha256:703fd69d9cb21d6ec2086789df9be2cf8140a76ff127050c24007ea8940dcd3b \
|
||||
--hash=sha256:7471d4486f23518cff343f1eec6c68d1b977ed74c3e6cc3e1ac896b9b7d68645 \
|
||||
--hash=sha256:765d46f3d5e7a1d48075035e2d1a9164f683e3fccde834ca04602e6c588835bc \
|
||||
--hash=sha256:7a09d203983104918c62f2eef9406f24c355511f9217967df23e70fa7f5b54ff \
|
||||
--hash=sha256:7c20cc83b0df47129ec6ed8a47fa7dcfc309c5bad029464004162738502568bb \
|
||||
--hash=sha256:7d7cfac2547c93389fa303fc0c0eb6698825564e8389c41c9b60009c746207b6 \
|
||||
--hash=sha256:7d87c817b292efb748f1974f37e8bb8a8772ef92f05f84e507159360814bcc3f \
|
||||
--hash=sha256:8141f654432cf75144d6103bfac2286b8adf23467201590b173a74535d6be22d \
|
||||
--hash=sha256:849f2ff40264152f25589cb48ddb4a43d14db811f841ec73989bfc0c8c4853fa \
|
||||
--hash=sha256:880c84ce59f49776cf120f77e7ca04877c97c6887917078dbc369eb47004d7cf \
|
||||
--hash=sha256:94874584b733a18b310b0e954d53168e62cd4a0fd9db85b1903f0902a7eb33e8 \
|
||||
--hash=sha256:95603eff711b8f3b9596e1c961dbeb745a792ba1904141612f194e07edd71e5f \
|
||||
--hash=sha256:9585892091ae86045135d6a6129a644142d6a51b23e1428bb5de6d10bc0ce0c7 \
|
||||
--hash=sha256:977bf5be704a88d46bf5b228df8b44521b1f3119d741062191608b3a6a38f224 \
|
||||
--hash=sha256:9cdc46859024501c20ab74ad542cdf2f08b94b5ce384f2f569483fa3ed926d04 \
|
||||
--hash=sha256:a34a5f034b339f69ef7f6a134c22d04b92e07b6ddc1dd65382e7e4ec65d6437d \
|
||||
--hash=sha256:a655f7b755cfc5c07f2116b6dcf0ba148c89adef9a6d40c1b0f1fada878c4345 \
|
||||
--hash=sha256:a7d12f2d2df195c8c4e49d2cdbad640353a856c62ca2c624d8b47aa33b65a2a2 \
|
||||
--hash=sha256:abfe83e082c9208891e2158c1b5044a650ecec408b823bf6bf16cd7f8085cafa \
|
||||
--hash=sha256:b25077a971c7da47bd6846a912a747f6963776d90720c88603b1b55d81790780 \
|
||||
--hash=sha256:bf416a93e1331820c77e3429df26946dbd4fe105e9b487cd2d1b7298b75784a8 \
|
||||
--hash=sha256:c04ae27e076d81a3839047d8eed57c1e17e361640616fd520d752375e3ba8f0c \
|
||||
--hash=sha256:d5bea13c73f36c4346808df3fa806596163a7962b6d28001ca2a391cab856089 \
|
||||
--hash=sha256:d75bef34e69e7effb7b4849e3f830e3174d2cc6ec7273503fdde111c222dc9b3 \
|
||||
--hash=sha256:d93940664a5ccfd79f72dcb939b0c31a3479889f14f0eb95ec52976f8c0cae7d \
|
||||
--hash=sha256:d9c89c521dc90c7564358e525f849b93ad1d710553c1491f66b8cce8113bc901 \
|
||||
--hash=sha256:e0b36257dc90194784531c3b922d8d31fb2b4d8e5adfd27aff4eee7174176365 \
|
||||
--hash=sha256:e1135264bcd40965cd35b0869e36952f54825024befdc7a923df9a7d83cfd800 \
|
||||
--hash=sha256:e510d288e613d6927796dfb728e13e4530fc83b9ccac5888a21f7860486eab21 \
|
||||
--hash=sha256:ee9a2c9a4b2421e77f8fe33ed0621dea03c66c710707553020b1e32f3afb6240 \
|
||||
--hash=sha256:f19f11055ba2961eb39bdb1ff15763a53fca4fa0b5b624da3c7a528e83cdd09c \
|
||||
--hash=sha256:f26544bc10c83a2ff9aa2e093500c1b473f327faae31fb468d591e5823333376 \
|
||||
--hash=sha256:f4875cafc9a6482c04c7df52a725d1c41beb74913c0ff4ec8f189f1954a2afe9 \
|
||||
--hash=sha256:f5179088ef6487c475604b7898731a6ddeeada7702cfb2162155b016703a8475 \
|
||||
--hash=sha256:f63d1ae1ca17bb2c847e298c7bcf084a73d56d434b4c50509fb93a4b4300b0b2 \
|
||||
--hash=sha256:ff4928dc1e9704b567171c16787238201fdbf023665573c12c02146fe1e02eec
|
||||
# via -r requirements-base.in
|
||||
zc-lockfile==2.0 \
|
||||
--hash=sha256:307ad78227e48be260e64896ec8886edc7eae22d8ec53e4d528ab5537a83203b \
|
||||
--hash=sha256:cc33599b549f0c8a248cb72f3bf32d77712de1ff7ee8814312eb6456b42c015f
|
||||
# via cherrypy
|
||||
|
||||
# WARNING: The following packages were not pinned, but pip requires them to be
|
||||
# pinned when the requirements file includes hashes. Consider using the --allow-unsafe flag.
|
||||
# setuptools
|
18
requirements.in
Normal file
18
requirements.in
Normal file
@ -0,0 +1,18 @@
|
||||
urllib3==1.25.11
|
||||
requests==2.25.1
|
||||
PyNaCl==1.4.0
|
||||
gevent==20.12.1
|
||||
Flask==1.1.2
|
||||
PySocks==1.7.1
|
||||
stem==1.8.0
|
||||
deadsimplekv==0.3.2
|
||||
unpaddedbase32==0.2.0
|
||||
streamedrequests==1.0.3
|
||||
toomanyobjs==1.1.0
|
||||
niceware==0.2.1
|
||||
psutil==5.8.0
|
||||
filenuke==0.0.0
|
||||
watchdog==1.0.2
|
||||
ujson==4.0.1
|
||||
cffi==1.14.4
|
||||
onionrblocks==4.1.0
|
392
requirements.txt
Normal file
392
requirements.txt
Normal file
@ -0,0 +1,392 @@
|
||||
#
|
||||
# This file is autogenerated by pip-compile
|
||||
# To update, run:
|
||||
#
|
||||
# pip-compile --generate-hashes --output-file=requirements.txt requirements.in
|
||||
#
|
||||
certifi==2018.11.29 \
|
||||
--hash=sha256:47f9c83ef4c0c621eaef743f133f09fa8a74a9b75f037e8624f83bd1b6626cb7 \
|
||||
--hash=sha256:993f830721089fef441cdfeb4b2c8c9df86f0c63239f06bd025a76a7daddb033
|
||||
# via requests
|
||||
cffi==1.14.4 \
|
||||
--hash=sha256:00a1ba5e2e95684448de9b89888ccd02c98d512064b4cb987d48f4b40aa0421e \
|
||||
--hash=sha256:00e28066507bfc3fe865a31f325c8391a1ac2916219340f87dfad602c3e48e5d \
|
||||
--hash=sha256:045d792900a75e8b1e1b0ab6787dd733a8190ffcf80e8c8ceb2fb10a29ff238a \
|
||||
--hash=sha256:0638c3ae1a0edfb77c6765d487fee624d2b1ee1bdfeffc1f0b58c64d149e7eec \
|
||||
--hash=sha256:105abaf8a6075dc96c1fe5ae7aae073f4696f2905fde6aeada4c9d2926752362 \
|
||||
--hash=sha256:155136b51fd733fa94e1c2ea5211dcd4c8879869008fc811648f16541bf99668 \
|
||||
--hash=sha256:1a465cbe98a7fd391d47dce4b8f7e5b921e6cd805ef421d04f5f66ba8f06086c \
|
||||
--hash=sha256:1d2c4994f515e5b485fd6d3a73d05526aa0fcf248eb135996b088d25dfa1865b \
|
||||
--hash=sha256:2c24d61263f511551f740d1a065eb0212db1dbbbbd241db758f5244281590c06 \
|
||||
--hash=sha256:51a8b381b16ddd370178a65360ebe15fbc1c71cf6f584613a7ea08bfad946698 \
|
||||
--hash=sha256:594234691ac0e9b770aee9fcdb8fa02c22e43e5c619456efd0d6c2bf276f3eb2 \
|
||||
--hash=sha256:5cf4be6c304ad0b6602f5c4e90e2f59b47653ac1ed9c662ed379fe48a8f26b0c \
|
||||
--hash=sha256:64081b3f8f6f3c3de6191ec89d7dc6c86a8a43911f7ecb422c60e90c70be41c7 \
|
||||
--hash=sha256:6bc25fc545a6b3d57b5f8618e59fc13d3a3a68431e8ca5fd4c13241cd70d0009 \
|
||||
--hash=sha256:798caa2a2384b1cbe8a2a139d80734c9db54f9cc155c99d7cc92441a23871c03 \
|
||||
--hash=sha256:7c6b1dece89874d9541fc974917b631406233ea0440d0bdfbb8e03bf39a49b3b \
|
||||
--hash=sha256:840793c68105fe031f34d6a086eaea153a0cd5c491cde82a74b420edd0a2b909 \
|
||||
--hash=sha256:8d6603078baf4e11edc4168a514c5ce5b3ba6e3e9c374298cb88437957960a53 \
|
||||
--hash=sha256:9cc46bc107224ff5b6d04369e7c595acb700c3613ad7bcf2e2012f62ece80c35 \
|
||||
--hash=sha256:9f7a31251289b2ab6d4012f6e83e58bc3b96bd151f5b5262467f4bb6b34a7c26 \
|
||||
--hash=sha256:9ffb888f19d54a4d4dfd4b3f29bc2c16aa4972f1c2ab9c4ab09b8ab8685b9c2b \
|
||||
--hash=sha256:a5ed8c05548b54b998b9498753fb9cadbfd92ee88e884641377d8a8b291bcc01 \
|
||||
--hash=sha256:a7711edca4dcef1a75257b50a2fbfe92a65187c47dab5a0f1b9b332c5919a3fb \
|
||||
--hash=sha256:af5c59122a011049aad5dd87424b8e65a80e4a6477419c0c1015f73fb5ea0293 \
|
||||
--hash=sha256:b18e0a9ef57d2b41f5c68beefa32317d286c3d6ac0484efd10d6e07491bb95dd \
|
||||
--hash=sha256:b4e248d1087abf9f4c10f3c398896c87ce82a9856494a7155823eb45a892395d \
|
||||
--hash=sha256:ba4e9e0ae13fc41c6b23299545e5ef73055213e466bd107953e4a013a5ddd7e3 \
|
||||
--hash=sha256:c6332685306b6417a91b1ff9fae889b3ba65c2292d64bd9245c093b1b284809d \
|
||||
--hash=sha256:d5ff0621c88ce83a28a10d2ce719b2ee85635e85c515f12bac99a95306da4b2e \
|
||||
--hash=sha256:d9efd8b7a3ef378dd61a1e77367f1924375befc2eba06168b6ebfa903a5e59ca \
|
||||
--hash=sha256:df5169c4396adc04f9b0a05f13c074df878b6052430e03f50e68adf3a57aa28d \
|
||||
--hash=sha256:ebb253464a5d0482b191274f1c8bf00e33f7e0b9c66405fbffc61ed2c839c775 \
|
||||
--hash=sha256:ec80dc47f54e6e9a78181ce05feb71a0353854cc26999db963695f950b5fb375 \
|
||||
--hash=sha256:f032b34669220030f905152045dfa27741ce1a6db3324a5bc0b96b6c7420c87b \
|
||||
--hash=sha256:f60567825f791c6f8a592f3c6e3bd93dd2934e3f9dac189308426bd76b00ef3b \
|
||||
--hash=sha256:f803eaa94c2fcda012c047e62bc7a51b0bdabda1cad7a92a522694ea2d76e49f
|
||||
# via
|
||||
# -r requirements.in
|
||||
# pynacl
|
||||
chardet==3.0.4 \
|
||||
--hash=sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae \
|
||||
--hash=sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691
|
||||
# via requests
|
||||
click==7.0 \
|
||||
--hash=sha256:2335065e6395b9e67ca716de5f7526736bfa6ceead690adf616d925bdc622b13 \
|
||||
--hash=sha256:5b94b49521f6456670fdb30cd82a4eca9412788a93fa6dd6df72c94d5a8ff2d7
|
||||
# via flask
|
||||
deadsimplekv==0.3.2 \
|
||||
--hash=sha256:a725f4a9d1156ebb66b7535ac150006881e0365b715e34e3709214827b8b0c4c \
|
||||
--hash=sha256:df00262d26c3dcfecb710425a7413059480d8cf026216042d7cbffb8514818b2
|
||||
# via -r requirements.in
|
||||
filenuke==0.0.0 \
|
||||
--hash=sha256:147011c0125121469cae0a8a7f4df399f470e54aa29a08f2d2c099bf0118dcee \
|
||||
--hash=sha256:c55535dcecfdb27c5f4ce664d46e115950b5429763b5db75c198053646177f8f
|
||||
# via -r requirements.in
|
||||
flask==1.1.2 \
|
||||
--hash=sha256:4efa1ae2d7c9865af48986de8aeb8504bf32c7f3d6fdc9353d34b21f4b127060 \
|
||||
--hash=sha256:8a4fdd8936eba2512e9c85df320a37e694c93945b33ef33c89946a340a238557
|
||||
# via -r requirements.in
|
||||
gevent==20.12.1 \
|
||||
--hash=sha256:0f9fa230c5878704b9e286ad5038bac3b70d293bf10e9efa8b2ae1d7d80e7e08 \
|
||||
--hash=sha256:19bd3fe60dec45fe6420b7772496950215f1b36701905876ba1644b6b2064163 \
|
||||
--hash=sha256:2d05f38a5ef1ebb7ceb692897674b11ba603914524765b989c65c020c7b08360 \
|
||||
--hash=sha256:4b0a5626c4e534d184cdf00d66f06de3885beafaaa5f7b98d47186ea175629a1 \
|
||||
--hash=sha256:4baecba0fd614e14dc1f3f8c35616cb248cdb893de576150ed1fc7fc66b8ba3d \
|
||||
--hash=sha256:60799fd7dcbb622f8435eb12436d48a8d27f8e7b3d23631e32ccc04ddd2097c2 \
|
||||
--hash=sha256:69ddc1767a02f68e71d5e0d3215aa4d28872187715627f71ff0eadd7b7a5e7f4 \
|
||||
--hash=sha256:7a808c63f065a303bbbe87c5c0754e06abb1e23e18752f418dce1eb3189cb43d \
|
||||
--hash=sha256:81e38ed46e21e0b00b930efce1a1ff46c7722ad83d84052f71a757f23cbed1c0 \
|
||||
--hash=sha256:895c76a89907d9d37fdfaf5321cb0fff0cba396f003bedb4f5fc13836da6f250 \
|
||||
--hash=sha256:89c583744f91052ae987356660f5ed0b8fc59a1230b051d6ccc10d37a155fe01 \
|
||||
--hash=sha256:99b68765767bb3e2244a66b012883899a6f17c23b6dc1cd80b793df341e15f08 \
|
||||
--hash=sha256:9d001fc899db6e140110ae7484e58cd74b0dfa5cee021a0347f00bb441ac78bd \
|
||||
--hash=sha256:b57586ad3fedf13d351d2559b70d6fe593c50400315d52bb3c072285da60fa37 \
|
||||
--hash=sha256:ba244028225ff8d3a58f344fcd16ab05b0e3642b34d81f51f7fa3c70761f6c34 \
|
||||
--hash=sha256:bf946a99e364ebcc95b82c794d5d1a67f13115adbefab7b9e12791f13184cfd5 \
|
||||
--hash=sha256:c3706a620e167c4bd007f16f113928324c4e07a7bae11d6d18d65f82abcd7a58 \
|
||||
--hash=sha256:c570a2e3100f758a5c2f9b993ecf870ee784390e44e1a292c361d6b32fb3ad4c \
|
||||
--hash=sha256:caec00914e8f21b2c77a29bbc2ef3abfeadf7515656e5451dfb14c2064733998 \
|
||||
--hash=sha256:e233ae153b586b61e492806d4cd1be2217de7441922c02053b67de14800bce96 \
|
||||
--hash=sha256:f020bfb34d57caa10029111be776524c378a4aac8417bc6fb1154b05e00fc220 \
|
||||
--hash=sha256:f3faf1834464f1b0731aa6346cd9f41029fa9e208d6ecbce4a736c19562c86aa \
|
||||
--hash=sha256:f857adbe1bf41e620d86173a53100f4ec328eba3089069a4815b3d9f4229dee8 \
|
||||
--hash=sha256:ffa1be13963db6aa55c50d2fd4a656c82f53a03a47e37aaa69e79a488123538d
|
||||
# via -r requirements.in
|
||||
greenlet==0.4.17 \
|
||||
--hash=sha256:1023d7b43ca11264ab7052cb09f5635d4afdb43df55e0854498fc63070a0b206 \
|
||||
--hash=sha256:124a3ae41215f71dc91d1a3d45cbf2f84e46b543e5d60b99ecc20e24b4c8f272 \
|
||||
--hash=sha256:13037e2d7ab2145300676852fa069235512fdeba4ed1e3bb4b0677a04223c525 \
|
||||
--hash=sha256:3af587e9813f9bd8be9212722321a5e7be23b2bc37e6323a90e592ab0c2ef117 \
|
||||
--hash=sha256:41d8835c69a78de718e466dd0e6bfd4b46125f21a67c3ff6d76d8d8059868d6b \
|
||||
--hash=sha256:4481002118b2f1588fa3d821936ffdc03db80ef21186b62b90c18db4ba5e743b \
|
||||
--hash=sha256:47825c3a109f0331b1e54c1173d4e57fa000aa6c96756b62852bfa1af91cd652 \
|
||||
--hash=sha256:5494e3baeacc371d988345fbf8aa4bd15555b3077c40afcf1994776bb6d77eaf \
|
||||
--hash=sha256:75e4c27188f28149b74e7685809f9227410fd15432a4438fc48627f518577fa5 \
|
||||
--hash=sha256:97f2b01ab622a4aa4b3724a3e1fba66f47f054c434fbaa551833fa2b41e3db51 \
|
||||
--hash=sha256:a34023b9eabb3525ee059f3bf33a417d2e437f7f17e341d334987d4091ae6072 \
|
||||
--hash=sha256:ac85db59aa43d78547f95fc7b6fd2913e02b9e9b09e2490dfb7bbdf47b2a4914 \
|
||||
--hash=sha256:be7a79988b8fdc5bbbeaed69e79cfb373da9759242f1565668be4fb7f3f37552 \
|
||||
--hash=sha256:bee111161420f341a346731279dd976be161b465c1286f82cc0779baf7b729e8 \
|
||||
--hash=sha256:ccd62f09f90b2730150d82f2f2ffc34d73c6ce7eac234aed04d15dc8a3023994 \
|
||||
--hash=sha256:d3436110ca66fe3981031cc6aff8cc7a40d8411d173dde73ddaa5b8445385e2d \
|
||||
--hash=sha256:e495096e3e2e8f7192afb6aaeba19babc4fb2bdf543d7b7fed59e00c1df7f170 \
|
||||
--hash=sha256:e66a824f44892bc4ec66c58601a413419cafa9cec895e63d8da889c8a1a4fa4a
|
||||
# via gevent
|
||||
idna==2.7 \
|
||||
--hash=sha256:156a6814fb5ac1fc6850fb002e0852d56c0c8d2531923a51032d1b70760e186e \
|
||||
--hash=sha256:684a38a6f903c1d71d6d5fac066b58d7768af4de2b832e426ec79c30daa94a16
|
||||
# via requests
|
||||
itsdangerous==1.1.0 \
|
||||
--hash=sha256:321b033d07f2a4136d3ec762eac9f16a10ccd60f53c0c91af90217ace7ba1f19 \
|
||||
--hash=sha256:b12271b2047cb23eeb98c8b5622e2e5c5e9abd9784a153e9d8ef9cb4dd09d749
|
||||
# via flask
|
||||
jinja2==2.11.1 \
|
||||
--hash=sha256:93187ffbc7808079673ef52771baa950426fd664d3aad1d0fa3e95644360e250 \
|
||||
--hash=sha256:b0eaf100007721b5c16c1fc1eecb87409464edc10469ddc9a22a27a99123be49
|
||||
# via flask
|
||||
kasten==3.0.0 \
|
||||
--hash=sha256:52894af46d6e1339f0d5fa8961892b292f99176848bce11877fe4a435b6782e5 \
|
||||
--hash=sha256:b22ebdc5f475c2ef9ab74abc36552add0b37732a7ce2be6bd7977ee41b2163b4
|
||||
# via onionrblocks
|
||||
markupsafe==1.1.1 \
|
||||
--hash=sha256:00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473 \
|
||||
--hash=sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161 \
|
||||
--hash=sha256:09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235 \
|
||||
--hash=sha256:1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5 \
|
||||
--hash=sha256:13d3144e1e340870b25e7b10b98d779608c02016d5184cfb9927a9f10c689f42 \
|
||||
--hash=sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff \
|
||||
--hash=sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b \
|
||||
--hash=sha256:43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1 \
|
||||
--hash=sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e \
|
||||
--hash=sha256:500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183 \
|
||||
--hash=sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66 \
|
||||
--hash=sha256:596510de112c685489095da617b5bcbbac7dd6384aeebeda4df6025d0256a81b \
|
||||
--hash=sha256:62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1 \
|
||||
--hash=sha256:6788b695d50a51edb699cb55e35487e430fa21f1ed838122d722e0ff0ac5ba15 \
|
||||
--hash=sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1 \
|
||||
--hash=sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e \
|
||||
--hash=sha256:79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b \
|
||||
--hash=sha256:7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905 \
|
||||
--hash=sha256:88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735 \
|
||||
--hash=sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d \
|
||||
--hash=sha256:98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e \
|
||||
--hash=sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d \
|
||||
--hash=sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c \
|
||||
--hash=sha256:ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21 \
|
||||
--hash=sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2 \
|
||||
--hash=sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5 \
|
||||
--hash=sha256:b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b \
|
||||
--hash=sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6 \
|
||||
--hash=sha256:c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f \
|
||||
--hash=sha256:cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f \
|
||||
--hash=sha256:cdb132fc825c38e1aeec2c8aa9338310d29d337bebbd7baa06889d09a60a1fa2 \
|
||||
--hash=sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7 \
|
||||
--hash=sha256:e8313f01ba26fbbe36c7be1966a7b7424942f670f38e666995b88d012765b9be
|
||||
# via jinja2
|
||||
mimcvdf==1.2.0 \
|
||||
--hash=sha256:647009b6f13173ac84a683b491566c8b63bc3dd5d60edd1e109b41cd311e2c08
|
||||
# via kasten
|
||||
msgpack==1.0.2 \
|
||||
--hash=sha256:0cb94ee48675a45d3b86e61d13c1e6f1696f0183f0715544976356ff86f741d9 \
|
||||
--hash=sha256:1026dcc10537d27dd2d26c327e552f05ce148977e9d7b9f1718748281b38c841 \
|
||||
--hash=sha256:26a1759f1a88df5f1d0b393eb582ec022326994e311ba9c5818adc5374736439 \
|
||||
--hash=sha256:2a5866bdc88d77f6e1370f82f2371c9bc6fc92fe898fa2dec0c5d4f5435a2694 \
|
||||
--hash=sha256:31c17bbf2ae5e29e48d794c693b7ca7a0c73bd4280976d408c53df421e838d2a \
|
||||
--hash=sha256:497d2c12426adcd27ab83144057a705efb6acc7e85957a51d43cdcf7f258900f \
|
||||
--hash=sha256:5a9ee2540c78659a1dd0b110f73773533ee3108d4e1219b5a15a8d635b7aca0e \
|
||||
--hash=sha256:8521e5be9e3b93d4d5e07cb80b7e32353264d143c1f072309e1863174c6aadb1 \
|
||||
--hash=sha256:87869ba567fe371c4555d2e11e4948778ab6b59d6cc9d8460d543e4cfbbddd1c \
|
||||
--hash=sha256:8ffb24a3b7518e843cd83538cf859e026d24ec41ac5721c18ed0c55101f9775b \
|
||||
--hash=sha256:92be4b12de4806d3c36810b0fe2aeedd8d493db39e2eb90742b9c09299eb5759 \
|
||||
--hash=sha256:9ea52fff0473f9f3000987f313310208c879493491ef3ccf66268eff8d5a0326 \
|
||||
--hash=sha256:a4355d2193106c7aa77c98fc955252a737d8550320ecdb2e9ac701e15e2943bc \
|
||||
--hash=sha256:a99b144475230982aee16b3d249170f1cccebf27fb0a08e9f603b69637a62192 \
|
||||
--hash=sha256:ac25f3e0513f6673e8b405c3a80500eb7be1cf8f57584be524c4fa78fe8e0c83 \
|
||||
--hash=sha256:b28c0876cce1466d7c2195d7658cf50e4730667196e2f1355c4209444717ee06 \
|
||||
--hash=sha256:b55f7db883530b74c857e50e149126b91bb75d35c08b28db12dcb0346f15e46e \
|
||||
--hash=sha256:b6d9e2dae081aa35c44af9c4298de4ee72991305503442a5c74656d82b581fe9 \
|
||||
--hash=sha256:c747c0cc08bd6d72a586310bda6ea72eeb28e7505990f342552315b229a19b33 \
|
||||
--hash=sha256:d6c64601af8f3893d17ec233237030e3110f11b8a962cb66720bf70c0141aa54 \
|
||||
--hash=sha256:d8167b84af26654c1124857d71650404336f4eb5cc06900667a493fc619ddd9f \
|
||||
--hash=sha256:de6bd7990a2c2dabe926b7e62a92886ccbf809425c347ae7de277067f97c2887 \
|
||||
--hash=sha256:e36a812ef4705a291cdb4a2fd352f013134f26c6ff63477f20235138d1d21009 \
|
||||
--hash=sha256:e89ec55871ed5473a041c0495b7b4e6099f6263438e0bd04ccd8418f92d5d7f2 \
|
||||
--hash=sha256:f3e6aaf217ac1c7ce1563cf52a2f4f5d5b1f64e8729d794165db71da57257f0c \
|
||||
--hash=sha256:f484cd2dca68502de3704f056fa9b318c94b1539ed17a4c784266df5d6978c87 \
|
||||
--hash=sha256:fae04496f5bc150eefad4e9571d1a76c55d021325dcd484ce45065ebbdd00984 \
|
||||
--hash=sha256:fe07bc6735d08e492a327f496b7850e98cb4d112c56df69b0c844dbebcbb47f6
|
||||
# via kasten
|
||||
niceware==0.2.1 \
|
||||
--hash=sha256:0f8b192f2a1e800e068474f6e208be9c7e2857664b33a96f4045340de4e5c69c \
|
||||
--hash=sha256:cf2dc0e1567d36d067c61b32fed0f1b9c4534ed511f9eeead4ba548d03b5c9eb
|
||||
# via -r requirements.in
|
||||
onionrblocks==4.1.0 \
|
||||
--hash=sha256:2f806d1a4cf332ffef8630ac3d362499854316d957945be0a090c7ff6917a6c4 \
|
||||
--hash=sha256:bfdfa90df6fcdaef44b9ff1bc8f7b645fc41d10cf46481a3158d6c77e3832507
|
||||
# via -r requirements.in
|
||||
psutil==5.8.0 \
|
||||
--hash=sha256:0066a82f7b1b37d334e68697faba68e5ad5e858279fd6351c8ca6024e8d6ba64 \
|
||||
--hash=sha256:02b8292609b1f7fcb34173b25e48d0da8667bc85f81d7476584d889c6e0f2131 \
|
||||
--hash=sha256:0ae6f386d8d297177fd288be6e8d1afc05966878704dad9847719650e44fc49c \
|
||||
--hash=sha256:0c9ccb99ab76025f2f0bbecf341d4656e9c1351db8cc8a03ccd62e318ab4b5c6 \
|
||||
--hash=sha256:0dd4465a039d343925cdc29023bb6960ccf4e74a65ad53e768403746a9207023 \
|
||||
--hash=sha256:12d844996d6c2b1d3881cfa6fa201fd635971869a9da945cf6756105af73d2df \
|
||||
--hash=sha256:1bff0d07e76114ec24ee32e7f7f8d0c4b0514b3fae93e3d2aaafd65d22502394 \
|
||||
--hash=sha256:245b5509968ac0bd179287d91210cd3f37add77dad385ef238b275bad35fa1c4 \
|
||||
--hash=sha256:28ff7c95293ae74bf1ca1a79e8805fcde005c18a122ca983abf676ea3466362b \
|
||||
--hash=sha256:36b3b6c9e2a34b7d7fbae330a85bf72c30b1c827a4366a07443fc4b6270449e2 \
|
||||
--hash=sha256:52de075468cd394ac98c66f9ca33b2f54ae1d9bff1ef6b67a212ee8f639ec06d \
|
||||
--hash=sha256:5da29e394bdedd9144c7331192e20c1f79283fb03b06e6abd3a8ae45ffecee65 \
|
||||
--hash=sha256:61f05864b42fedc0771d6d8e49c35f07efd209ade09a5afe6a5059e7bb7bf83d \
|
||||
--hash=sha256:6223d07a1ae93f86451d0198a0c361032c4c93ebd4bf6d25e2fb3edfad9571ef \
|
||||
--hash=sha256:6323d5d845c2785efb20aded4726636546b26d3b577aded22492908f7c1bdda7 \
|
||||
--hash=sha256:6ffe81843131ee0ffa02c317186ed1e759a145267d54fdef1bc4ea5f5931ab60 \
|
||||
--hash=sha256:74f2d0be88db96ada78756cb3a3e1b107ce8ab79f65aa885f76d7664e56928f6 \
|
||||
--hash=sha256:74fb2557d1430fff18ff0d72613c5ca30c45cdbfcddd6a5773e9fc1fe9364be8 \
|
||||
--hash=sha256:90d4091c2d30ddd0a03e0b97e6a33a48628469b99585e2ad6bf21f17423b112b \
|
||||
--hash=sha256:90f31c34d25b1b3ed6c40cdd34ff122b1887a825297c017e4cbd6796dd8b672d \
|
||||
--hash=sha256:99de3e8739258b3c3e8669cb9757c9a861b2a25ad0955f8e53ac662d66de61ac \
|
||||
--hash=sha256:c6a5fd10ce6b6344e616cf01cc5b849fa8103fbb5ba507b6b2dee4c11e84c935 \
|
||||
--hash=sha256:ce8b867423291cb65cfc6d9c4955ee9bfc1e21fe03bb50e177f2b957f1c2469d \
|
||||
--hash=sha256:d225cd8319aa1d3c85bf195c4e07d17d3cd68636b8fc97e6cf198f782f99af28 \
|
||||
--hash=sha256:ea313bb02e5e25224e518e4352af4bf5e062755160f77e4b1767dd5ccb65f876 \
|
||||
--hash=sha256:ea372bcc129394485824ae3e3ddabe67dc0b118d262c568b4d2602a7070afdb0 \
|
||||
--hash=sha256:f4634b033faf0d968bb9220dd1c793b897ab7f1189956e1aa9eae752527127d3 \
|
||||
--hash=sha256:fcc01e900c1d7bee2a37e5d6e4f9194760a93597c97fee89c4ae51701de03563
|
||||
# via -r requirements.in
|
||||
pycparser==2.19 \
|
||||
--hash=sha256:a988718abfad80b6b157acce7bf130a30876d27603738ac39f140993246b25b3
|
||||
# via cffi
|
||||
pynacl==1.4.0 \
|
||||
--hash=sha256:06cbb4d9b2c4bd3c8dc0d267416aaed79906e7b33f114ddbf0911969794b1cc4 \
|
||||
--hash=sha256:11335f09060af52c97137d4ac54285bcb7df0cef29014a1a4efe64ac065434c4 \
|
||||
--hash=sha256:2fe0fc5a2480361dcaf4e6e7cea00e078fcda07ba45f811b167e3f99e8cff574 \
|
||||
--hash=sha256:30f9b96db44e09b3304f9ea95079b1b7316b2b4f3744fe3aaecccd95d547063d \
|
||||
--hash=sha256:511d269ee845037b95c9781aa702f90ccc36036f95d0f31373a6a79bd8242e25 \
|
||||
--hash=sha256:537a7ccbea22905a0ab36ea58577b39d1fa9b1884869d173b5cf111f006f689f \
|
||||
--hash=sha256:54e9a2c849c742006516ad56a88f5c74bf2ce92c9f67435187c3c5953b346505 \
|
||||
--hash=sha256:757250ddb3bff1eecd7e41e65f7f833a8405fede0194319f87899690624f2122 \
|
||||
--hash=sha256:7757ae33dae81c300487591c68790dfb5145c7d03324000433d9a2c141f82af7 \
|
||||
--hash=sha256:7c6092102219f59ff29788860ccb021e80fffd953920c4a8653889c029b2d420 \
|
||||
--hash=sha256:8122ba5f2a2169ca5da936b2e5a511740ffb73979381b4229d9188f6dcb22f1f \
|
||||
--hash=sha256:9c4a7ea4fb81536c1b1f5cc44d54a296f96ae78c1ebd2311bd0b60be45a48d96 \
|
||||
--hash=sha256:cd401ccbc2a249a47a3a1724c2918fcd04be1f7b54eb2a5a71ff915db0ac51c6 \
|
||||
--hash=sha256:d452a6746f0a7e11121e64625109bc4468fc3100452817001dbe018bb8b08514 \
|
||||
--hash=sha256:ea6841bc3a76fa4942ce00f3bda7d436fda21e2d91602b9e21b7ca9ecab8f3ff \
|
||||
--hash=sha256:f8851ab9041756003119368c1e6cd0b9c631f46d686b3904b18c0139f4419f80
|
||||
# via
|
||||
# -r requirements.in
|
||||
# onionrblocks
|
||||
pysocks==1.7.1 \
|
||||
--hash=sha256:08e69f092cc6dbe92a0fdd16eeb9b9ffbc13cadfe5ca4c7bd92ffb078b293299 \
|
||||
--hash=sha256:2725bd0a9925919b9b51739eea5f9e2bae91e83288108a9ad338b2e3a4435ee5 \
|
||||
--hash=sha256:3f8804571ebe159c380ac6de37643bb4685970655d3bba243530d6558b799aa0
|
||||
# via -r requirements.in
|
||||
requests==2.25.1 \
|
||||
--hash=sha256:27973dd4a904a4f13b263a19c866c13b92a39ed1c964655f025f3f8d3d75b804 \
|
||||
--hash=sha256:c210084e36a42ae6b9219e00e48287def368a26d03a048ddad7bfee44f75871e
|
||||
# via
|
||||
# -r requirements.in
|
||||
# streamedrequests
|
||||
six==1.12.0 \
|
||||
--hash=sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c \
|
||||
--hash=sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73
|
||||
# via pynacl
|
||||
stem==1.8.0 \
|
||||
--hash=sha256:a0b48ea6224e95f22aa34c0bc3415f0eb4667ddeae3dfb5e32a6920c185568c2
|
||||
# via -r requirements.in
|
||||
streamedrequests==1.0.3 \
|
||||
--hash=sha256:4388ffc0ee94dda719dafc4324b8ddd108cb2231ec59871de79e2592bf4eef0a \
|
||||
--hash=sha256:ee68417a1522e75c35b1b2d5f3b6f7e76a3a1a6c0ef5e0c573d08307910079d8
|
||||
# via -r requirements.in
|
||||
toomanyobjs==1.1.0 \
|
||||
--hash=sha256:99e27468f9dad19127be9e2fb086b42acd69aed9ad7e63cef74d6e4389be0534
|
||||
# via -r requirements.in
|
||||
ujson==4.0.1 \
|
||||
--hash=sha256:078808c385036cba73cad96f498310c61e9b5ae5ac9ea01e7c3996ece544b556 \
|
||||
--hash=sha256:0a2e1b211714eb1ec0772a013ec9967f8f95f21c84e8f46382e9f8a32ae781fe \
|
||||
--hash=sha256:0f412c3f59b1ab0f40018235224ca0cf29232d0201ff5085618565a8a9c810ed \
|
||||
--hash=sha256:26cf6241b36ff5ce4539ae687b6b02673109c5e3efc96148806a7873eaa229d3 \
|
||||
--hash=sha256:2b2d9264ac76aeb11f590f7a1ccff0689ba1313adacbb6d38d3b15f21a392897 \
|
||||
--hash=sha256:4f12b0b4e235b35d49f15227b0a827e614c52dda903c58a8f5523936c233dfc7 \
|
||||
--hash=sha256:4fe8c6112b732cba5a722f7cbe22f18d405f6f44415794a5b46473a477635233 \
|
||||
--hash=sha256:51480048373cf97a6b97fcd70c3586ca0a31f27e22ab680fb14c1f22bedbf743 \
|
||||
--hash=sha256:568bb3e7f035006147af4ce3a9ced7d126c92e1a8607c7b2266007b1c1162c53 \
|
||||
--hash=sha256:5fe1536465b1c86e32a47113abd3178001b7c2dcd61f95f336fe2febf4661e74 \
|
||||
--hash=sha256:71703a269f074ff65b9d7746662e4b3e76a4af443e532218af1e8ce15d9b1e7b \
|
||||
--hash=sha256:7a1545ac2476db4cc1f0f236603ccbb50991fc1bba480cda1bc06348cc2a2bf0 \
|
||||
--hash=sha256:a5200a68f1dcf3ce275e1cefbcfa3914b70c2b5e2f71c2e31556aa1f7244c845 \
|
||||
--hash=sha256:a618af22407baeadb3f046f81e7a5ee5e9f8b0b716d2b564f92276a54d26a823 \
|
||||
--hash=sha256:a79bca47eafb31c74b38e68623bc9b2bb930cb48fab1af31c8f2cb68cf473421 \
|
||||
--hash=sha256:b87379a3f8046d6d111762d81f3384bf38ab24b1535c841fe867a4a097d84523 \
|
||||
--hash=sha256:bd4c77aee3ffb920e2dbc21a9e0c7945a400557ce671cfd57dbd569f5ebc619d \
|
||||
--hash=sha256:c354c1617b0a4378b6279d0cd511b769500cf3fa7c42e8e004cbbbb6b4c2a875 \
|
||||
--hash=sha256:c604024bd853b5df6be7d933e934da8dd139e6159564db7c55b92a9937678093 \
|
||||
--hash=sha256:e7ab24942b2d57920d75b817b8eead293026db003247e26f99506bdad86c61b4 \
|
||||
--hash=sha256:f8a60928737a9a47e692fcd661ef2b5d75ba22c7c930025bd95e338f2a6e15bc
|
||||
# via -r requirements.in
|
||||
unpaddedbase32==0.2.0 \
|
||||
--hash=sha256:4aacee75f8fd6c8cf129842ecba45ca59c11bfb13dae19d86f32b48fa3715403 \
|
||||
--hash=sha256:b7b780c31d27d55e66abf6c221216a35690ee8892c2daacff7f2528e229bd9c3
|
||||
# via -r requirements.in
|
||||
urllib3==1.25.11 \
|
||||
--hash=sha256:8d7eaa5a82a1cac232164990f04874c594c9453ec55eef02eab885aa02fc17a2 \
|
||||
--hash=sha256:f5321fbe4bf3fefa0efd0bfe7fb14e90909eb62a48ccda331726b4319897dd5e
|
||||
# via
|
||||
# -r requirements.in
|
||||
# requests
|
||||
watchdog==1.0.2 \
|
||||
--hash=sha256:016b01495b9c55b5d4126ed8ae75d93ea0d99377084107c33162df52887cee18 \
|
||||
--hash=sha256:101532b8db506559e52a9b5d75a308729b3f68264d930670e6155c976d0e52a0 \
|
||||
--hash=sha256:27d9b4666938d5d40afdcdf2c751781e9ce36320788b70208d0f87f7401caf93 \
|
||||
--hash=sha256:2f1ade0d0802503fda4340374d333408831cff23da66d7e711e279ba50fe6c4a \
|
||||
--hash=sha256:376cbc2a35c0392b0fe7ff16fbc1b303fd99d4dd9911ab5581ee9d69adc88982 \
|
||||
--hash=sha256:57f05e55aa603c3b053eed7e679f0a83873c540255b88d58c6223c7493833bac \
|
||||
--hash=sha256:5f1f3b65142175366ba94c64d8d4c8f4015825e0beaacee1c301823266b47b9b \
|
||||
--hash=sha256:602dbd9498592eacc42e0632c19781c3df1728ef9cbab555fab6778effc29eeb \
|
||||
--hash=sha256:68744de2003a5ea2dfbb104f9a74192cf381334a9e2c0ed2bbe1581828d50b61 \
|
||||
--hash=sha256:85e6574395aa6c1e14e0f030d9d7f35c2340a6cf95d5671354ce876ac3ffdd4d \
|
||||
--hash=sha256:b1d723852ce90a14abf0ec0ca9e80689d9509ee4c9ee27163118d87b564a12ac \
|
||||
--hash=sha256:d948ad9ab9aba705f9836625b32e965b9ae607284811cd98334423f659ea537a \
|
||||
--hash=sha256:e2a531e71be7b5cc3499ae2d1494d51b6a26684bcc7c3146f63c810c00e8a3cc \
|
||||
--hash=sha256:e7c73edef48f4ceeebb987317a67e0080e5c9228601ff67b3c4062fa020403c7 \
|
||||
--hash=sha256:ee21aeebe6b3e51e4ba64564c94cee8dbe7438b9cb60f0bb350c4fa70d1b52c2 \
|
||||
--hash=sha256:f1d0e878fd69129d0d68b87cee5d9543f20d8018e82998efb79f7e412d42154a \
|
||||
--hash=sha256:f84146f7864339c8addf2c2b9903271df21d18d2c721e9a77f779493234a82b5
|
||||
# via -r requirements.in
|
||||
werkzeug==0.15.5 \
|
||||
--hash=sha256:87ae4e5b5366da2347eb3116c0e6c681a0e939a33b2805e2c0cbd282664932c4 \
|
||||
--hash=sha256:a13b74dd3c45f758d4ebdb224be8f1ab8ef58b3c0ffc1783a8c7d9f4f50227e6
|
||||
# via flask
|
||||
zope.event==4.4 \
|
||||
--hash=sha256:69c27debad9bdacd9ce9b735dad382142281ac770c4a432b533d6d65c4614bcf \
|
||||
--hash=sha256:d8e97d165fd5a0997b45f5303ae11ea3338becfe68c401dd88ffd2113fe5cae7
|
||||
# via gevent
|
||||
zope.interface==5.1.0 \
|
||||
--hash=sha256:0103cba5ed09f27d2e3de7e48bb320338592e2fabc5ce1432cf33808eb2dfd8b \
|
||||
--hash=sha256:14415d6979356629f1c386c8c4249b4d0082f2ea7f75871ebad2e29584bd16c5 \
|
||||
--hash=sha256:1ae4693ccee94c6e0c88a4568fb3b34af8871c60f5ba30cf9f94977ed0e53ddd \
|
||||
--hash=sha256:1b87ed2dc05cb835138f6a6e3595593fea3564d712cb2eb2de963a41fd35758c \
|
||||
--hash=sha256:269b27f60bcf45438e8683269f8ecd1235fa13e5411de93dae3b9ee4fe7f7bc7 \
|
||||
--hash=sha256:27d287e61639d692563d9dab76bafe071fbeb26818dd6a32a0022f3f7ca884b5 \
|
||||
--hash=sha256:39106649c3082972106f930766ae23d1464a73b7d30b3698c986f74bf1256a34 \
|
||||
--hash=sha256:40e4c42bd27ed3c11b2c983fecfb03356fae1209de10686d03c02c8696a1d90e \
|
||||
--hash=sha256:461d4339b3b8f3335d7e2c90ce335eb275488c587b61aca4b305196dde2ff086 \
|
||||
--hash=sha256:4f98f70328bc788c86a6a1a8a14b0ea979f81ae6015dd6c72978f1feff70ecda \
|
||||
--hash=sha256:558a20a0845d1a5dc6ff87cd0f63d7dac982d7c3be05d2ffb6322a87c17fa286 \
|
||||
--hash=sha256:562dccd37acec149458c1791da459f130c6cf8902c94c93b8d47c6337b9fb826 \
|
||||
--hash=sha256:5e86c66a6dea8ab6152e83b0facc856dc4d435fe0f872f01d66ce0a2131b7f1d \
|
||||
--hash=sha256:60a207efcd8c11d6bbeb7862e33418fba4e4ad79846d88d160d7231fcb42a5ee \
|
||||
--hash=sha256:645a7092b77fdbc3f68d3cc98f9d3e71510e419f54019d6e282328c0dd140dcd \
|
||||
--hash=sha256:6874367586c020705a44eecdad5d6b587c64b892e34305bb6ed87c9bbe22a5e9 \
|
||||
--hash=sha256:74bf0a4f9091131de09286f9a605db449840e313753949fe07c8d0fe7659ad1e \
|
||||
--hash=sha256:7b726194f938791a6691c7592c8b9e805fc6d1b9632a833b9c0640828cd49cbc \
|
||||
--hash=sha256:8149ded7f90154fdc1a40e0c8975df58041a6f693b8f7edcd9348484e9dc17fe \
|
||||
--hash=sha256:8cccf7057c7d19064a9e27660f5aec4e5c4001ffcf653a47531bde19b5aa2a8a \
|
||||
--hash=sha256:911714b08b63d155f9c948da2b5534b223a1a4fc50bb67139ab68b277c938578 \
|
||||
--hash=sha256:a5f8f85986197d1dd6444763c4a15c991bfed86d835a1f6f7d476f7198d5f56a \
|
||||
--hash=sha256:a744132d0abaa854d1aad50ba9bc64e79c6f835b3e92521db4235a1991176813 \
|
||||
--hash=sha256:af2c14efc0bb0e91af63d00080ccc067866fb8cbbaca2b0438ab4105f5e0f08d \
|
||||
--hash=sha256:b054eb0a8aa712c8e9030065a59b5e6a5cf0746ecdb5f087cca5ec7685690c19 \
|
||||
--hash=sha256:b0becb75418f8a130e9d465e718316cd17c7a8acce6fe8fe07adc72762bee425 \
|
||||
--hash=sha256:b1d2ed1cbda2ae107283befd9284e650d840f8f7568cb9060b5466d25dc48975 \
|
||||
--hash=sha256:ba4261c8ad00b49d48bbb3b5af388bb7576edfc0ca50a49c11dcb77caa1d897e \
|
||||
--hash=sha256:d1fe9d7d09bb07228650903d6a9dc48ea649e3b8c69b1d263419cc722b3938e8 \
|
||||
--hash=sha256:d7804f6a71fc2dda888ef2de266727ec2f3915373d5a785ed4ddc603bbc91e08 \
|
||||
--hash=sha256:da2844fba024dd58eaa712561da47dcd1e7ad544a257482392472eae1c86d5e5 \
|
||||
--hash=sha256:dcefc97d1daf8d55199420e9162ab584ed0893a109f45e438b9794ced44c9fd0 \
|
||||
--hash=sha256:dd98c436a1fc56f48c70882cc243df89ad036210d871c7427dc164b31500dc11 \
|
||||
--hash=sha256:e74671e43ed4569fbd7989e5eecc7d06dc134b571872ab1d5a88f4a123814e9f \
|
||||
--hash=sha256:eb9b92f456ff3ec746cd4935b73c1117538d6124b8617bc0fe6fda0b3816e345 \
|
||||
--hash=sha256:ebb4e637a1fb861c34e48a00d03cffa9234f42bef923aec44e5625ffb9a8e8f9 \
|
||||
--hash=sha256:ef739fe89e7f43fb6494a43b1878a36273e5924869ba1d866f752c5812ae8d58 \
|
||||
--hash=sha256:f40db0e02a8157d2b90857c24d89b6310f9b6c3642369852cdc3b5ac49b92afc \
|
||||
--hash=sha256:f68bf937f113b88c866d090fea0bc52a098695173fc613b055a17ff0cf9683b6 \
|
||||
--hash=sha256:fb55c182a3f7b84c1a2d6de5fa7b1a05d4660d866b91dbf8d74549c57a1499e8
|
||||
# via gevent
|
||||
|
||||
# WARNING: The following packages were not pinned, but pip requires them to be
|
||||
# pinned when the requirements file includes hashes. Consider using the --allow-unsafe flag.
|
||||
# setuptools
|
150
run-onionr-node.py
Executable file
150
run-onionr-node.py
Executable file
@ -0,0 +1,150 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import argparse
|
||||
import os
|
||||
from threading import Thread
|
||||
from time import sleep
|
||||
from subprocess import DEVNULL
|
||||
|
||||
import ujson
|
||||
from psutil import Popen
|
||||
from psutil import Process
|
||||
|
||||
import sys
|
||||
|
||||
script_dir = os.path.dirname(os.path.realpath(__file__))
|
||||
sys.path.append(script_dir + '/src/')
|
||||
|
||||
from etc import onionrvalues
|
||||
|
||||
|
||||
sub_script = script_dir + '/' + onionrvalues.SCRIPT_NAME
|
||||
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
|
||||
parser.add_argument(
|
||||
"--bind-address", help="Address to bind to. Be very careful with non-loopback",
|
||||
type=str, default="")
|
||||
parser.add_argument(
|
||||
"--port", help="Port to bind to, must be available and possible",
|
||||
type=int, default=0)
|
||||
parser.add_argument(
|
||||
"--use-bootstrap-file", help="Use bootstrap node list file",
|
||||
type=int, default=1)
|
||||
parser.add_argument(
|
||||
"--show-stats", help="Display curses output of Onionr stats",
|
||||
type=int, default=0)
|
||||
parser.add_argument(
|
||||
"--onboarding", help="Use Onionr onboarding (if first load)",
|
||||
type=int, default=1)
|
||||
parser.add_argument(
|
||||
"--security-level", help="Set Onionr security level",
|
||||
type=int, default=0)
|
||||
parser.add_argument(
|
||||
'--open-ui', help='Open onionr web ui after started',
|
||||
type=int, default=1)
|
||||
parser.add_argument(
|
||||
'--random-localhost-ip', help='bind to random localhost IP for extra security',
|
||||
type=int, default=1)
|
||||
parser.add_argument(
|
||||
'--use-tor', help='Use Tor transport',
|
||||
type=int, default=1)
|
||||
parser.add_argument(
|
||||
'--private-key', help='Use existing private key',
|
||||
type=str, default=0)
|
||||
parser.add_argument(
|
||||
'--animated-background', help='Animated background on webui index. Just for looks.',
|
||||
type=int, default=0)
|
||||
parser.add_argument(
|
||||
'--keep-log-on-exit', help='Onionr can keep or delete its log file on exit',
|
||||
type=int, default=0)
|
||||
parser.add_argument(
|
||||
'--use-upload-mixing', help='Re-upload blocks uploaded to us. Slow but more secure',
|
||||
type=int, default=0)
|
||||
parser.add_argument(
|
||||
'--dev-mode',
|
||||
help='Developer mode makes restarting and testing Onionr less tedious during development',
|
||||
type=int, default=0)
|
||||
parser.add_argument(
|
||||
'--disable-plugin-list',
|
||||
help='plugins to disable by name, separate with commas',
|
||||
type=str, default='chat'
|
||||
)
|
||||
parser.add_argument(
|
||||
'--store-plaintext',
|
||||
help='store plaintext blocks or not. note that encrypted blocks may not really be encrypted, but we cannot detect that',
|
||||
type=int, default=1
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
p = Popen([sub_script, 'version'])
|
||||
p.wait()
|
||||
print("Configuring Onionr before starting daemon")
|
||||
from filepaths import config_file, keys_file
|
||||
from coredb import blockmetadb
|
||||
import onionrcrypto
|
||||
|
||||
|
||||
with open(config_file, 'r') as cf:
|
||||
config = ujson.loads(cf.read())
|
||||
|
||||
|
||||
if args.private_key:
|
||||
priv = args.private_key
|
||||
pub = onionrcrypto.cryptoutils.get_pub_key_from_priv(priv)
|
||||
with open(keys_file, "a") as f:
|
||||
f.write(',' + pub.decode() + ',' + priv)
|
||||
config['general']['public_key'] = pub
|
||||
|
||||
config['plugins']['disabled'] = args.disable_plugin_list.split(',')
|
||||
config['general']['dev_mode'] = False
|
||||
|
||||
config['general']['store_plaintext_blocks'] = True
|
||||
config['general']['use_bootstrap_list'] = True
|
||||
config['transports']['tor'] = True
|
||||
config['general']['bind_port'] = 0 # client api server port
|
||||
config['general']['bind_address'] = '' # client api server address
|
||||
|
||||
if args.bind_address:
|
||||
config['general']['bind_address'] = args.bind_address
|
||||
if args.port:
|
||||
config['client']['client']['port'] = args.port
|
||||
|
||||
if not args.use_bootstrap_file:
|
||||
config['general']['use_bootstrap_list'] = False
|
||||
if not args.store_plaintext:
|
||||
config['general']['store_plaintext_blocks'] = False
|
||||
if args.dev_mode:
|
||||
config['general']['dev_mode'] = True
|
||||
if not args.onboarding:
|
||||
config['onboarding']['done'] = True
|
||||
if not args.random_localhost_ip:
|
||||
config['general']['random_bind_ip'] = False
|
||||
if not args.use_tor:
|
||||
config['transports']['tor'] = False
|
||||
if not args.animated_background:
|
||||
config['ui']['animated_background'] = False
|
||||
if args.keep_log_on_exit:
|
||||
config['log']['file']['remove_on_exit'] = True
|
||||
else:
|
||||
config['log']['file']['remove_on_exit'] = False
|
||||
|
||||
config['general']['upload_mixing'] = False
|
||||
if args.use_upload_mixing:
|
||||
config['general']['upload_mixing'] = True
|
||||
config['general']['display_header'] = False
|
||||
config['general']['security_level'] = args.security_level
|
||||
|
||||
with open(config_file, 'w') as cf:
|
||||
cf.write(ujson.dumps(config, reject_bytes=False))
|
||||
|
||||
if args.open_ui:
|
||||
p = Popen([sub_script, 'start'])
|
||||
sleep(2)
|
||||
Popen([sub_script, 'openhome'])
|
||||
else:
|
||||
p = Popen([sub_script, 'start'])
|
||||
|
||||
p.wait()
|
51
run-onionr-node.sh
Executable file
51
run-onionr-node.sh
Executable file
@ -0,0 +1,51 @@
|
||||
#!/bin/sh
|
||||
set -x
|
||||
ORIG_ONIONR_RUN_DIR=`pwd`
|
||||
export ORIG_ONIONR_RUN_DIR
|
||||
cd "$(dirname "$0")"
|
||||
|
||||
if [[ -n "$ONIONR_DOCKER" ]]; then
|
||||
[[ -f "/privkey" ]] && privkey_opt="--private-key /privkey"
|
||||
[[ -n "$ONIONR_ONBOARDING" ]] || ONIONR_ONBOARDING=0
|
||||
[[ -n "$ONIONR_OPEN_UI" ]] || ONIONR_OPEN_UI=0
|
||||
[[ -n "$ONIONR_RANDOM_LOCALHOST_IP" ]] || ONIONR_RANDOM_LOCALHOST_IP=0
|
||||
[[ -n "$ONIONR_BIND_ADDRESS" ]] || ONIONR_BIND_ADDRESS=0.0.0.0
|
||||
[[ -n "$ONIONR_PORT" ]] || ONIONR_PORT=8080
|
||||
fi
|
||||
|
||||
[[ -n "$ONIONR_PRIVATE_KEY_FILE" ]] && privkey_opt="--private-key $ONIONR_PRIVATE_KEY_FILE"
|
||||
[[ -n "$ONIONR_USE_BOOTSTRAP_FILE" ]] && bootstrap_opt="--use-bootstrap-file $ONIONR_USE_BOOTSTRAP_FILE"
|
||||
[[ -n "$ONIONR_SHOW_STATS" ]] && show_stats_opt="--show-stats $ONIONR_SHOW_STATS"
|
||||
[[ -n "$ONIONR_ONBOARDING" ]] && onboarding_opt="--onboarding $ONIONR_ONBOARDING"
|
||||
[[ -n "$ONIONR_SECURITY_LEVEL" ]] && security_level_opt="--security-level $ONIONR_SECURITY_LEVEL"
|
||||
[[ -n "$ONIONR_OPEN_UI" ]] && open_ui_opt="--open-ui $ONIONR_OPEN_UI"
|
||||
[[ -n "$ONIONR_RANDOM_LOCALHOST_IP" ]] && random_localhost_ip_opt="--random-localhost-ip $ONIONR_RANDOM_LOCALHOST_IP"
|
||||
[[ -n "$ONIONR_USE_TOR" ]] && use_tor_opt="--use-tor $ONIONR_USE_TOR"
|
||||
[[ -n "$ONIONR_ANIMATED_BACKGROUND" ]] && animated_background_opt="--animated-background $ONIONR_ANIMATED_BACKGROUND"
|
||||
[[ -n "$ONIONR_KEEP_LOG" ]] && keep_log_opt="--keep-log-on-exit $ONIONR_KEEP_LOG"
|
||||
[[ -n "$ONIONR_USE_UPLOAD_MIXING" ]] && use_upload_mixing_opt="--use-upload-mixing $ONIONR_USE_UPLOAD_MIXING"
|
||||
[[ -n "$ONIONR_DEV_MODE" ]] && dev_mode_opt="--dev-mode $ONIONR_DEV_MODE"
|
||||
[[ -n "$ONIONR_DISABLE_PLUGIN_LIST" ]] && disable_plugin_list_opt=" --disable-plugin-list $ONIONR_DISABLE_PLUGIN_LIST"
|
||||
[[ -n "$ONIONR_STORE_PLAINTEXT" ]] && store_plaintext_opt="--store-plaintext $ONIONR_STORE_PLAINTEXT"
|
||||
[[ -n "$ONIONR_BIND_ADDRESS" ]] && bind_address_opt="--bind-address $ONIONR_BIND_ADDRESS"
|
||||
[[ -n "$ONIONR_PORT" ]] && port_opt="--port $ONIONR_PORT"
|
||||
|
||||
|
||||
python3 run-onionr-node.py \
|
||||
$privkey_opt \
|
||||
$bootstrap_opt \
|
||||
$show_stats_opt \
|
||||
$onboarding_opt \
|
||||
$security_level_opt \
|
||||
$open_ui_opt \
|
||||
$random_localhost_ip_opt \
|
||||
$use_tor_opt \
|
||||
$animated_background_opt \
|
||||
$keep_log_opt \
|
||||
$use_upload_mixing_opt \
|
||||
$dev_mode_opt \
|
||||
$disable_plugin_list_opt \
|
||||
$store_plaintext_opt \
|
||||
$bind_address_opt \
|
||||
$port_opt \
|
||||
"$@"
|
@ -13,10 +13,6 @@ for f in tests/*.py; do
|
||||
python3 "$f" || close # if needed
|
||||
let "ran++"
|
||||
done
|
||||
for f in tests/gossip-unittests/*.py; do
|
||||
python3 "$f" || close # if needed
|
||||
let "ran++"
|
||||
done
|
||||
echo "ran $ran unittests. Unittest Time: $SECONDS"
|
||||
ran=0;
|
||||
|
||||
|
33
sandboxed-onionr.py
Normal file
33
sandboxed-onionr.py
Normal file
@ -0,0 +1,33 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import os, sys
|
||||
import tempfile, shutil
|
||||
import stat
|
||||
|
||||
env_var = "firejailed-onionr"
|
||||
|
||||
def copytree(src, dst, symlinks=False, ignore=None):
|
||||
for item in os.listdir(src):
|
||||
if item in (".git", ".vscode", ".github"):
|
||||
continue
|
||||
s = os.path.join(src, item)
|
||||
d = os.path.join(dst, item)
|
||||
if os.path.isdir(s):
|
||||
shutil.copytree(s, d, symlinks, ignore)
|
||||
else:
|
||||
shutil.copy2(s, d)
|
||||
|
||||
env_var = "firejailed-onionr"
|
||||
directory = os.path.dirname(os.path.realpath(sys.argv[0]))
|
||||
|
||||
if not os.getenv(env_var):
|
||||
temp_dir = tempfile.mkdtemp()
|
||||
print(temp_dir)
|
||||
copytree(directory, temp_dir)
|
||||
os.system(f"firejail --env={env_var}={temp_dir} --private={temp_dir} python3 ./sandboxed-onionr.py")
|
||||
sys.exit(0)
|
||||
|
||||
os.system(f"python3 -m pip install -r ./requirements.txt --user")
|
||||
os.system(f"./onionr.sh start &")
|
||||
|
||||
|
@ -1 +1,7 @@
|
||||
This directory contains useful scripts and utilities that don't make sense to include as official Onionr features.
|
||||
|
||||
passphrase-generator.py: very simple utility to generate and print a strong passphrase to stdout. 256 bits of entropy by default.
|
||||
enable-dev-config.py/disable-dev-config.py: enable/disable dev default config setup
|
||||
block-spammer.py: attack tool for spamming blocks
|
||||
announce-attack.py: flood a node with false nodes
|
||||
run-unit-test-by-name: runs a unit test (no browser, runtime or intgegration test) by name
|
25
scripts/announce-attack.py
Normal file
25
scripts/announce-attack.py
Normal file
@ -0,0 +1,25 @@
|
||||
import sys
|
||||
import os
|
||||
import secrets
|
||||
import base64
|
||||
os.chdir('../')
|
||||
sys.path.append("src/")
|
||||
from onionrutils import stringvalidators
|
||||
from onionrutils import basicrequests
|
||||
|
||||
|
||||
def random_tor_generator():
|
||||
return base64.b32encode(secrets.token_bytes(35)).decode().replace("=", "").lower() + ".onion"
|
||||
|
||||
node = input("Enter node to attack. Note that you legally must use your own, and even that might lead to technical or legal issues")
|
||||
assert stringvalidators.validate_transport(node)
|
||||
|
||||
count = int(input("Attack amount: "))
|
||||
port = input("Socks:")
|
||||
for x in range(count):
|
||||
new = random_tor_generator()
|
||||
print(f"Introducing {new} to {node}")
|
||||
basicrequests.do_post_request(
|
||||
f'http://{node}/announce',
|
||||
data = {'node': new},
|
||||
port=port)
|
31
scripts/block-spammer.py
Executable file
31
scripts/block-spammer.py
Executable file
@ -0,0 +1,31 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
"""Spam a bunch of Onionr blocks"""
|
||||
|
||||
# Please don't run this script on the real Onionr network. You wouldn't do anything but be annoying
|
||||
|
||||
print("Please don't run this script on Onionr networks that include more than you. You wouldn't do anything but be annoying, and probably violate law")
|
||||
|
||||
import sys
|
||||
import os
|
||||
if not os.path.exists('onionr.sh'):
|
||||
os.chdir('../')
|
||||
sys.path.append("src/")
|
||||
import oldblocks
|
||||
|
||||
|
||||
amount = int(input("Number of blocks:"))
|
||||
expire = input("Expire in seconds:")
|
||||
|
||||
if not expire:
|
||||
expire = ""
|
||||
else:
|
||||
expire = int(expire)
|
||||
|
||||
for i in range(amount):
|
||||
if expire:
|
||||
print(oldblocks.insert(data=os.urandom(32), expire=expire))
|
||||
else:
|
||||
print(oldblocks.insert(data=os.urandom(32)))
|
||||
print(i, "done")
|
||||
|
51
scripts/client-api-request-crafter.py
Normal file
51
scripts/client-api-request-crafter.py
Normal file
@ -0,0 +1,51 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
"""Craft and send requests to the local client API"""
|
||||
|
||||
|
||||
import sys
|
||||
import os
|
||||
if not os.path.exists('onionr.sh'):
|
||||
os.chdir('../')
|
||||
sys.path.append("src/")
|
||||
|
||||
import atexit
|
||||
import readline
|
||||
|
||||
histfile = os.path.join(os.path.expanduser("~"), ".onionr_history")
|
||||
try:
|
||||
readline.read_history_file(histfile)
|
||||
# default history len is -1 (infinite), which may grow unruly
|
||||
readline.set_history_length(1000)
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
|
||||
atexit.register(readline.write_history_file, histfile)
|
||||
from onionrutils.localcommand import local_command
|
||||
from onionrutils.localcommand import get_hostname
|
||||
|
||||
try:
|
||||
print('API file found, probably running on ' + get_hostname())
|
||||
except TypeError:
|
||||
print('Onionr not running')
|
||||
sys.exit(1)
|
||||
print('1. get request (default)')
|
||||
print('2. post request')
|
||||
choice = input(">").lower().strip()
|
||||
post = False
|
||||
post_data = {}
|
||||
json = False
|
||||
endpoint = input("URL Endpoint: ")
|
||||
data = input("Data url param: ")
|
||||
if choice in ("2", "post", "post request"):
|
||||
post = True
|
||||
print("Enter post data")
|
||||
post_data = input()
|
||||
if post_data:
|
||||
print("Is this JSON?")
|
||||
json = input("y/n").lower().strip()
|
||||
if json == "y":
|
||||
json = True
|
||||
|
||||
ret = local_command(endpoint, data=data, post=post, post_data=post_data, is_json=json)
|
||||
print("Response: \n", ret)
|
@ -6,24 +6,14 @@ import json
|
||||
|
||||
conf = json.load(open('static-data/default_config.json', 'r'))
|
||||
|
||||
conf['tor']['use_existing_tor'] = False
|
||||
conf['tor']['existing_control_port'] = 0
|
||||
conf['tor']['existing_control_password'] = ""
|
||||
conf['tor']['existing_socks_port'] = 0
|
||||
|
||||
conf['general']['insert_deniable_blocks'] = True
|
||||
conf['general']['random_bind_ip'] = True
|
||||
conf['general']['dev_mode'] = False
|
||||
conf['general']['display_header'] = True
|
||||
conf['general']['security_level'] = 0
|
||||
conf['onboarding']['done'] = False
|
||||
conf['general']['minimum_block_pow'] = 5
|
||||
conf['general']['minimum_send_pow'] = 5
|
||||
conf['log']['file']['remove_on_exit'] = True
|
||||
conf['transports']['lan'] = True
|
||||
conf['transports']['tor'] = True
|
||||
conf['transports']['sneakernet'] = True
|
||||
conf['statistics']['i_dont_want_privacy'] = False
|
||||
conf['statistics']['server'] = ''
|
||||
conf['ui']['animated_background'] = True
|
||||
conf['runtests']['skip_slow'] = False
|
||||
|
||||
json.dump(conf, open('static-data/default_config.json', 'w'), sort_keys=True, indent=4)
|
||||
|
||||
|
@ -8,27 +8,16 @@ input("enter to continue") # hack to avoid vscode term input
|
||||
|
||||
conf = json.load(open('static-data/default_config.json', 'r'))
|
||||
|
||||
block_pow = int(input("Block POW level:"))
|
||||
conf['general']['security_level'] = int(input("Security level:"))
|
||||
|
||||
conf['transports']['tor'] = False
|
||||
if input('Use Tor? y/n').lower() == 'y':
|
||||
conf['transports']['tor'] = True
|
||||
if input("Reuse Tor? y/n:").lower() == 'y':
|
||||
conf['tor']['use_existing_tor'] = True
|
||||
conf['tor']['existing_control_port'] = int(input("Enter existing control port:"))
|
||||
conf['tor']['existing_control_password'] = input("Tor pass:")
|
||||
conf['tor']['existing_socks_port'] = int(input("Existing socks port:"))
|
||||
|
||||
conf['general']['insert_deniable_blocks'] = False
|
||||
conf['general']['dev_mode'] = True
|
||||
conf['general']['random_bind_ip'] = False
|
||||
conf['onboarding']['done'] = True
|
||||
conf['general']['minimum_block_pow'] = block_pow
|
||||
conf['general']['minimum_send_pow'] = block_pow
|
||||
|
||||
conf['log']['file']['remove_on_exit'] = False
|
||||
conf['ui']['animated_background'] = False
|
||||
if input('Stat reporting? y/n') == 'y':
|
||||
conf['statistics']['i_dont_want_privacy'] = True
|
||||
conf['statistics']['server'] = input('Statistics server')
|
||||
conf['runtests']['skip_slow'] = True
|
||||
|
||||
|
||||
json.dump(conf, open('static-data/default_config.json', 'w'), sort_keys=True, indent=4)
|
||||
|
||||
|
22
scripts/generate-onions.py
Executable file
22
scripts/generate-onions.py
Executable file
@ -0,0 +1,22 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import sys
|
||||
import os
|
||||
from base64 import b32encode
|
||||
from hashlib import sha3_256
|
||||
|
||||
try:
|
||||
amount = int(sys.argv[1])
|
||||
except IndexError:
|
||||
amount = 1
|
||||
|
||||
version = int(3).to_bytes(1, "little")
|
||||
for i in range(amount):
|
||||
pubkey = os.urandom(32)
|
||||
#digest = sha3_256(b".onion checksum" + pubkey + version).digest()[:2]
|
||||
digest = sha3_256()
|
||||
digest.update(b".onion checksum")
|
||||
digest.update(pubkey)
|
||||
digest.update(version)
|
||||
digest = digest.digest()[:2]
|
||||
print(b32encode(pubkey + digest + version).decode().lower() + ".onion")
|
105
scripts/graph-simulation.py
Normal file
105
scripts/graph-simulation.py
Normal file
@ -0,0 +1,105 @@
|
||||
from typing import NamedTuple, List, Set
|
||||
|
||||
from collections import namedtuple
|
||||
from hashlib import sha3_256
|
||||
from secrets import randbelow
|
||||
from random import SystemRandom
|
||||
from threading import Thread
|
||||
from time import sleep
|
||||
import uuid
|
||||
|
||||
WeightedEdge = namedtuple("WeightedEdge", ["node", "weight"])
|
||||
|
||||
message_pool: Set["Message"] = set() # This is just to save memory for the simulation
|
||||
|
||||
def get_message(hash_id):
|
||||
for m in message_pool:
|
||||
if hash_id == m.hash_id:
|
||||
return m
|
||||
raise ValueError
|
||||
|
||||
class Node:
|
||||
def __init__(self, hidden_node: bool,
|
||||
edges: List[WeightedEdge], graph_ids=["main"]):
|
||||
self.hidden_node = hidden_node
|
||||
self.edges = edges
|
||||
self.node_id = str(uuid.uuid4())
|
||||
self._messages: List[str] = list() # hashes point to message_pool
|
||||
self._hidden_messages: List[str] = list()
|
||||
|
||||
def sharing_messages(self):
|
||||
share = list(self._messages)
|
||||
for m in self._hidden_messages:
|
||||
share.remove(m)
|
||||
return share
|
||||
|
||||
|
||||
def add_message(self, hash_id):
|
||||
if hash_id not in self._messages:
|
||||
self._messages.append(hash_id)
|
||||
|
||||
def pick_edge(self):
|
||||
selected = self.edges[0]
|
||||
alt = []
|
||||
|
||||
for weighted_edge in self.edges[1:]:
|
||||
if weighted_edge.weight[0] > selected.weight:
|
||||
selected = weighted_edge
|
||||
elif weighted_edge.weight[0] == selected.weight:
|
||||
alt.append(selected)
|
||||
alt.append(selected)
|
||||
SystemRandom().shuffle(alt)
|
||||
return alt[0]
|
||||
|
||||
|
||||
def share_to_edges(self, message_id):
|
||||
edge = self.pick_edge()
|
||||
edge.node.add_message(message_id)
|
||||
edge.weight[0] += 1
|
||||
|
||||
def lookup_messages(self):
|
||||
edge = self.pick_edge()
|
||||
for message in edge.node.sharing_messages():
|
||||
if message.hash_id not in self._messages:
|
||||
self._messages.append(message.hash_id)
|
||||
print(self.node_id, "found", message.hash_id)
|
||||
edge.weight[0] += 1
|
||||
|
||||
def make_new_connections(self):
|
||||
edge = self.pick_edge()
|
||||
for new_edge in edge.node.edges:
|
||||
if new_edge not in self.edges:
|
||||
self.edges.append(WeightedEdge(new_edge.node, [0]))
|
||||
print(self.node_id, "added peer", new_edge.node.node_id)
|
||||
edge.weight[0] += 1
|
||||
|
||||
|
||||
class Message:
|
||||
def __init__(self, data):
|
||||
def _do_hash(data):
|
||||
h = sha3_256()
|
||||
h.update(data)
|
||||
return h.digest()
|
||||
self.hash_id = _do_hash(data)
|
||||
self.data = data
|
||||
|
||||
bootstrap_node = Node(False, [])
|
||||
graph = [WeightedEdge(bootstrap_node, [0])]
|
||||
|
||||
for i in range(10):
|
||||
graph.append(WeightedEdge(Node(False, [WeightedEdge(bootstrap_node, [0])]), [0]))
|
||||
|
||||
m = Message(b"hello world")
|
||||
message_pool.add(m)
|
||||
bootstrap_node.add_message(m.hash_id)
|
||||
|
||||
def node_driver(node):
|
||||
while True:
|
||||
node.make_new_connections()
|
||||
node.lookup_messages()
|
||||
sleep(1)
|
||||
|
||||
for edge in graph:
|
||||
Thread(target=node_driver, args=[edge.node], daemon=True).start()
|
||||
input()
|
||||
|
21
scripts/passphrase-generator.py
Executable file
21
scripts/passphrase-generator.py
Executable file
@ -0,0 +1,21 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
"""Generate a 16 word passphase with 256 bits of entropy.
|
||||
|
||||
Specify true to reduce to 128 bits"""
|
||||
|
||||
|
||||
import sys
|
||||
|
||||
import niceware
|
||||
|
||||
byte_count = 32 # 256 bits of entropy with niceware
|
||||
|
||||
arg = False
|
||||
try:
|
||||
arg = sys.argv[1].lower()
|
||||
if arg == 'true':
|
||||
byte_count = 16
|
||||
except IndexError: pass
|
||||
|
||||
print(' '.join(niceware.generate_passphrase(byte_count)))
|
50
scripts/remote-ui.py
Executable file
50
scripts/remote-ui.py
Executable file
@ -0,0 +1,50 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
"""Craft and send requests to the local client API"""
|
||||
|
||||
|
||||
import sys
|
||||
import os
|
||||
import time
|
||||
from threading import Thread
|
||||
if not os.path.exists('onionr.sh'):
|
||||
os.chdir('../')
|
||||
sys.path.append("src/")
|
||||
|
||||
import filepaths
|
||||
import config
|
||||
config.reload()
|
||||
|
||||
with open(filepaths.private_API_host_file, 'r') as host:
|
||||
hostname = host.read()
|
||||
|
||||
port = config.get("client.client.port", 0)
|
||||
if not port:
|
||||
print("Could not get port for Onionr UI. Try again")
|
||||
sys.exit(1)
|
||||
torrc = f"""
|
||||
HiddenServiceDir remote-onionr-hs
|
||||
HiddenServicePort 80 {hostname}:{port}
|
||||
"""
|
||||
|
||||
with open("remote-onionr-torrc", "w") as torrc_f:
|
||||
torrc_f.write(torrc)
|
||||
|
||||
|
||||
def show_onion():
|
||||
while True:
|
||||
time.sleep(1)
|
||||
try:
|
||||
with open("remote-onionr-hs/hostname", "r") as f:
|
||||
o = f.read()
|
||||
print("UI Onion (Keep secret):", o)
|
||||
config.set("ui.public_remote_enabled", True)
|
||||
config.set("ui.public_remote_hosts", [o])
|
||||
config.save()
|
||||
break
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
|
||||
Thread(target=show_onion, daemon=True).start()
|
||||
|
||||
os.system("tor -f remote-onionr-torrc")
|
16
scripts/show-blocks.py
Normal file
16
scripts/show-blocks.py
Normal file
@ -0,0 +1,16 @@
|
||||
import sys
|
||||
import os
|
||||
import stem
|
||||
|
||||
if not os.path.exists('onionr.sh'):
|
||||
os.chdir('../')
|
||||
sys.path.append("src/")
|
||||
from coredb.blockmetadb import get_block_list
|
||||
from oldblocks.onionrblockapi import Block
|
||||
|
||||
for bl in get_block_list():
|
||||
bl_obj = Block(bl, decrypt=False)
|
||||
b_type = bl_obj.getType()
|
||||
if not b_type:
|
||||
b_type = "encrypted"
|
||||
print(bl + " - " + str(bl_obj.date) + " - " + b_type)
|
73
scripts/stats-server.py
Executable file
73
scripts/stats-server.py
Executable file
@ -0,0 +1,73 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Onionr - Private P2P Communication.
|
||||
|
||||
LAN transport server thread
|
||||
"""
|
||||
import sys
|
||||
import os
|
||||
os.chdir('../')
|
||||
sys.path.append("src/")
|
||||
from gevent.pywsgi import WSGIServer
|
||||
from flask import Flask
|
||||
from flask import Response
|
||||
from flask import request
|
||||
import stem
|
||||
from stem.control import Controller
|
||||
from netcontroller import getopenport
|
||||
import json
|
||||
"""
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
#passw = secrets.token_hex(32)
|
||||
port_num = int(input('tor control port'))
|
||||
web_port = getopenport.get_open_port()
|
||||
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
STATS_FILE = 'stats.json'
|
||||
|
||||
@app.route('/sendstats/<node>', methods = ['POST'])
|
||||
def get_stats(node):
|
||||
try:
|
||||
with open(STATS_FILE, 'r') as f:
|
||||
try:
|
||||
data = json.loads(f.read())
|
||||
except json.decoder.JSONDecodeError:
|
||||
raise FileNotFoundError
|
||||
except FileNotFoundError:
|
||||
data = {}
|
||||
data[node] = request.get_data().decode('utf-8')
|
||||
|
||||
with open(STATS_FILE, 'w') as f:
|
||||
data = json.dumps(data)
|
||||
f.write(data)
|
||||
|
||||
return Response('ok')
|
||||
|
||||
with Controller.from_port(port = port_num) as controller:
|
||||
controller.authenticate(input('pass for tor')) # provide the password here if you set one
|
||||
hs = controller.create_ephemeral_hidden_service(
|
||||
{80: web_port},
|
||||
key_type = 'NEW',
|
||||
key_content = 'ED25519-V3',
|
||||
await_publication=True,
|
||||
detached=True)
|
||||
hs = hs.service_id
|
||||
print(f'stats server {hs}')
|
||||
|
||||
server = WSGIServer(('127.0.0.1', web_port), app, log=None)
|
||||
server.serve_forever()
|
||||
|
40
scripts/sybil-attack.py
Normal file
40
scripts/sybil-attack.py
Normal file
@ -0,0 +1,40 @@
|
||||
import sys
|
||||
import os
|
||||
import stem
|
||||
|
||||
if not os.path.exists('onionr.sh'):
|
||||
os.chdir('../')
|
||||
sys.path.append("src/")
|
||||
from onionrutils import stringvalidators
|
||||
from onionrutils import basicrequests
|
||||
|
||||
from stem.control import Controller
|
||||
|
||||
onionr_ip = input("onionr ip address: ")
|
||||
onionr_port = int(input("Enter onionr public api port: "))
|
||||
|
||||
controller = Controller.from_port('127.0.0.1', int(input("Enter tor controller port: ")))
|
||||
controller.authenticate()
|
||||
|
||||
node = input("Enter node to attack. Note that you legally must use your own, and even that might lead to technical or legal issues: ")
|
||||
assert stringvalidators.validate_transport(node)
|
||||
|
||||
socks = input("Socks:")
|
||||
|
||||
adders = set([])
|
||||
for i in range(int(input("Sybil addresses: "))):
|
||||
response = controller.create_ephemeral_hidden_service({80: f'{onionr_ip}:{onionr_port}'}, await_publication=True)
|
||||
#print(i, response.service_id)
|
||||
adders.add(response.service_id)
|
||||
|
||||
|
||||
for x in adders:
|
||||
x += '.onion'
|
||||
print(f"Introducing {x} to {node}")
|
||||
basicrequests.do_post_request(
|
||||
f'http://{node}/announce',
|
||||
data = {'node': x},
|
||||
port=socks)
|
||||
|
||||
|
||||
|
12
scripts/testblock.py
Executable file
12
scripts/testblock.py
Executable file
@ -0,0 +1,12 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import sys
|
||||
import os
|
||||
if not os.path.exists('onionr.sh'):
|
||||
os.chdir('../')
|
||||
sys.path.append("src/")
|
||||
import oldblocks
|
||||
|
||||
expire = 600
|
||||
print(oldblocks.insert(data=os.urandom(32), expire=expire))
|
||||
|
105
src/__init__.py
105
src/__init__.py
@ -5,71 +5,44 @@ This file initializes Onionr when ran to be a daemon or with commands
|
||||
|
||||
Run with 'help' for usage.
|
||||
"""
|
||||
# Enable pyjion if we can because why not
|
||||
pyjion_enabled = False
|
||||
try:
|
||||
pass
|
||||
#import pyjion
|
||||
#pyjion.enable()
|
||||
#pyjion_enabled = True
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
|
||||
import os
|
||||
import cProfile
|
||||
import threading
|
||||
|
||||
onionr_profiling = os.getenv("ONIONR_PROFILING", False)
|
||||
|
||||
|
||||
import sys
|
||||
|
||||
try:
|
||||
import sqlite3
|
||||
except ModuleNotFoundError:
|
||||
sys.stderr.write(
|
||||
'Error, Onionr requires Sqlite3-enabled Python.\n' +
|
||||
'https://stackoverflow.com/a/1875095\n')
|
||||
sys.exit(1)
|
||||
"""
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
# Set the user's locale for encoding reasons
|
||||
import locale # noqa
|
||||
locale.setlocale(locale.LC_ALL, '') # noqa
|
||||
|
||||
import traceback
|
||||
import signal
|
||||
|
||||
def sigusr_stacktrace(signum, frame):
|
||||
"""Print stacktrace on SIGUSR1"""
|
||||
stack_trace_file = os.getenv('ONIONR_STACK_TRACE_FILE', False)
|
||||
for th in threading.enumerate():
|
||||
if stack_trace_file:
|
||||
with open(stack_trace_file, 'a') as f:
|
||||
f.write(f'Thread: {th.name}')
|
||||
f.write('-' * 44 + '')
|
||||
traceback.print_stack(sys._current_frames()[th.ident], file=f)
|
||||
else:
|
||||
print(f'Thread: {th.name}')
|
||||
print('-' * 44)
|
||||
traceback.print_stack(sys._current_frames()[th.ident])
|
||||
#print(traceback.format_stack(frame))
|
||||
|
||||
signal.signal(signal.SIGUSR1, sigusr_stacktrace)
|
||||
|
||||
# Importing initailzes logging
|
||||
from logger import log as logging
|
||||
|
||||
ran_as_script = False
|
||||
if __name__ == "__main__": ran_as_script = True
|
||||
|
||||
# Import standard libraries
|
||||
|
||||
try:
|
||||
from etc import dependencycheck # noqa
|
||||
except ModuleNotFoundError as e:
|
||||
print('Missing requirement: ' + str(e) + ' installed')
|
||||
sys.exit(1)
|
||||
|
||||
# Import 3rd party libraries
|
||||
|
||||
from filenuke import nuke # noqa
|
||||
@ -77,13 +50,10 @@ from filenuke import nuke # noqa
|
||||
# Onionr imports
|
||||
|
||||
# For different Onionr related constants such as versions
|
||||
import onionrvalues # noqa
|
||||
from etc import onionrvalues # noqa
|
||||
|
||||
import onionrexceptions # noqa
|
||||
import onionrsetup as setup # noqa
|
||||
setup.setup_config()
|
||||
|
||||
setup.setup_default_plugins()
|
||||
|
||||
min_ver = onionrvalues.MIN_PY_VERSION
|
||||
|
||||
@ -97,30 +67,33 @@ if sys.version_info[0] == 2 or sys.version_info[1] < min_ver:
|
||||
from utils import createdirs
|
||||
createdirs.create_dirs()
|
||||
|
||||
import bigbrother # noqa
|
||||
from onionrcommands import parser # noqa
|
||||
from onionrplugins import onionrevents as events # noqa
|
||||
|
||||
|
||||
setup.setup_config()
|
||||
|
||||
import config # noqa
|
||||
from utils import identifyhome # noqa
|
||||
import filepaths # noqa
|
||||
|
||||
if config.get('advanced.security_auditing', True):
|
||||
try:
|
||||
bigbrother.enable_ministries()
|
||||
except onionrexceptions.PythonVersion:
|
||||
pass
|
||||
|
||||
|
||||
setup.setup_default_plugins()
|
||||
|
||||
|
||||
def onionr_main():
|
||||
"""Onionr entrypoint, start command processor
|
||||
|
||||
Entrypoint for daemon is commands/daemonlaunch/__init__.py
|
||||
"""
|
||||
events.event('beforecmdparsing', threaded=False)
|
||||
"""Onionr entrypoint, start command processor"""
|
||||
parser.register()
|
||||
|
||||
|
||||
if ran_as_script:
|
||||
if onionr_profiling:
|
||||
cProfile.run('onionr_main()')
|
||||
else:
|
||||
onionr_main()
|
||||
onionr_main()
|
||||
|
||||
config.reload()
|
||||
|
||||
|
24
src/anonvdf-block-creator.py
Executable file
24
src/anonvdf-block-creator.py
Executable file
@ -0,0 +1,24 @@
|
||||
#!/usr/bin/env python
|
||||
from base64 import b85decode
|
||||
import sys
|
||||
import os
|
||||
|
||||
import ujson as json
|
||||
|
||||
from onionrblocks import blockcreator
|
||||
|
||||
# This script creates a block without storing it. it is written to stdout
|
||||
# It is used instead of in the main process to avoid GIL locking/slow down
|
||||
|
||||
metadata = json.loads(sys.argv[1])
|
||||
block_type = sys.argv[2]
|
||||
ttl = int(sys.argv[3])
|
||||
|
||||
data = b85decode(sys.stdin.read())
|
||||
|
||||
with os.fdopen(sys.stdout.fileno(), 'wb') as stdout:
|
||||
bl = blockcreator.create_anonvdf_block(data, block_type, ttl, **metadata)
|
||||
try:
|
||||
stdout.write(bl.id + bl.get_packed())
|
||||
except BrokenPipeError:
|
||||
pass
|
38
src/anonvdf-block-validator.py
Executable file
38
src/anonvdf-block-validator.py
Executable file
@ -0,0 +1,38 @@
|
||||
#!/usr/bin/env python
|
||||
# This is a subprocess because block validation is somewhat CPU intensive
|
||||
|
||||
from base64 import b85decode, b85encode
|
||||
import os
|
||||
from sys import argv, stdin, stderr, stdout, exit
|
||||
|
||||
from kasten import Kasten
|
||||
from kasten.exceptions import InvalidID
|
||||
from onionrblocks.exceptions import BlockExpired
|
||||
from onionrblocks.generators import AnonVDFGenerator
|
||||
|
||||
block_hash = b85decode(argv[1])
|
||||
|
||||
block_bytes = b85decode(stdin.read())
|
||||
|
||||
|
||||
try:
|
||||
Kasten(
|
||||
block_hash, block_bytes,
|
||||
AnonVDFGenerator, auto_check_generator=True)
|
||||
except InvalidID:
|
||||
stderr.write(
|
||||
"Invalid block ID for " +
|
||||
b85encode(block_hash).decode('utf-8'))
|
||||
except ValueError as e:
|
||||
# Supposed to be if rounds are not specified in the block
|
||||
stderr.write(e.message)
|
||||
except BlockExpired:
|
||||
stderr.write(
|
||||
b85encode(block_hash).decode('utf-8') + " is expired")
|
||||
else:
|
||||
|
||||
with os.fdopen(stdout.fileno(), 'wb') as std:
|
||||
std.write(b"valid")
|
||||
exit(0)
|
||||
stderr.flush()
|
||||
exit(1)
|
8
src/apiservers/README.md
Normal file
8
src/apiservers/README.md
Normal file
@ -0,0 +1,8 @@
|
||||
# API Servers
|
||||
|
||||
Contains the WSGI servers Onionr uses for remote peer communication and local daemon control
|
||||
|
||||
## Files
|
||||
|
||||
* \_\_init\_\_.py: Exposes the server classes
|
||||
* private: Contains the client API (the server used to interact with the local Onionr daemon, and view the web UI)
|
9
src/apiservers/__init__.py
Executable file
9
src/apiservers/__init__.py
Executable file
@ -0,0 +1,9 @@
|
||||
"""Flask WSGI apps for the public and private API servers.
|
||||
|
||||
Public is net-facing server meant for other nodes
|
||||
Private is meant for controlling and accessing this node
|
||||
"""
|
||||
|
||||
from . import private
|
||||
|
||||
ClientAPI = private.PrivateAPI
|
8
src/apiservers/private/README.md
Normal file
8
src/apiservers/private/README.md
Normal file
@ -0,0 +1,8 @@
|
||||
# Private API Server
|
||||
|
||||
Private API server, used to access the web interface locally and control Onionr
|
||||
|
||||
## Files
|
||||
|
||||
* \_\_init\_\_.py: Sets up the server and a few misc functions
|
||||
* register_private_blueprints.py: Adds in flask blueprints for various sub-APIs
|
107
src/apiservers/private/__init__.py
Normal file
107
src/apiservers/private/__init__.py
Normal file
@ -0,0 +1,107 @@
|
||||
"""Onionr - Private P2P Communication.
|
||||
|
||||
This file handles all incoming http requests to the client, using Flask
|
||||
"""
|
||||
import http
|
||||
from typing import Dict
|
||||
import hmac
|
||||
|
||||
import flask
|
||||
from gevent.pywsgi import WSGIServer
|
||||
|
||||
from onionrutils import epoch
|
||||
import httpapi
|
||||
from filepaths import private_API_host_file
|
||||
import logger
|
||||
|
||||
from etc import waitforsetvar
|
||||
from . import register_private_blueprints
|
||||
import config
|
||||
"""
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
|
||||
class PrivateAPI:
|
||||
"""Client HTTP api for controlling onionr and using UI."""
|
||||
|
||||
callbacks: Dict[str, Dict] = {'public': {}, 'private': {}}
|
||||
|
||||
def __init__(self):
|
||||
"""Initialize the api server, preping variables for later use.
|
||||
|
||||
This initialization defines all of the API entry points
|
||||
and handlers for the endpoints and errors
|
||||
This also saves the used host (random localhost IP address)
|
||||
to the data folder in host.txt
|
||||
"""
|
||||
self.config = config
|
||||
|
||||
self.startTime = epoch.get_epoch()
|
||||
app = flask.Flask(__name__)
|
||||
|
||||
|
||||
bind_port = int(config.get('client.client.port', 59496))
|
||||
self.bindPort = bind_port
|
||||
|
||||
self.clientToken = config.get('client.webpassword')
|
||||
|
||||
if config.get('general.bind_address'):
|
||||
with open(private_API_host_file, 'w') as bindFile:
|
||||
bindFile.write(config.get('general.bind_address'))
|
||||
self.host = config.get('general.bind_address')
|
||||
else:
|
||||
self.host = httpapi.apiutils.setbindip.set_bind_IP(
|
||||
private_API_host_file)
|
||||
logger.info('Running api on %s:%s' % (self.host, self.bindPort))
|
||||
self.httpServer = ''
|
||||
|
||||
self.queueResponse = {}
|
||||
|
||||
register_private_blueprints.register_private_blueprints(self, app)
|
||||
httpapi.load_plugin_blueprints(app)
|
||||
self.app = app
|
||||
|
||||
def start(self):
|
||||
"""Start client gevent API web server with flask client app."""
|
||||
waitforsetvar.wait_for_set_var(self, "_too_many")
|
||||
fd_handler = httpapi.fdsafehandler.FDSafeHandler
|
||||
self._too_many.add(httpapi.wrappedfunctions.SubProcVDFGenerator(self._too_many))
|
||||
self.httpServer = WSGIServer((self.host, self.bindPort),
|
||||
self.app, log=None,
|
||||
handler_class=fd_handler)
|
||||
self.httpServer.serve_forever()
|
||||
|
||||
def validateToken(self, token):
|
||||
"""Validate that the client token matches the given token.
|
||||
|
||||
Used to prevent CSRF and other attacks.
|
||||
"""
|
||||
if not self.clientToken:
|
||||
logger.error("client password needs to be set")
|
||||
return False
|
||||
try:
|
||||
return hmac.compare_digest(self.clientToken, token)
|
||||
except TypeError:
|
||||
return False
|
||||
|
||||
def getUptime(self) -> int:
|
||||
"""Safely wait for uptime to be set and return it."""
|
||||
while True:
|
||||
try:
|
||||
return epoch.get_epoch() - self.startTime
|
||||
except (AttributeError, NameError):
|
||||
# Don't error on race condition with startup
|
||||
pass
|
||||
|
56
src/apiservers/private/register_private_blueprints.py
Normal file
56
src/apiservers/private/register_private_blueprints.py
Normal file
@ -0,0 +1,56 @@
|
||||
"""Onionr - Private P2P Communication.
|
||||
|
||||
This file registers blueprints for the private api server
|
||||
"""
|
||||
from threading import Thread
|
||||
from gevent import sleep
|
||||
|
||||
from httpapi import security, configapi
|
||||
from httpapi import miscclientapi, apiutils
|
||||
from httpapi import themeapi
|
||||
from httpapi import fileoffsetreader
|
||||
from httpapi.sse.private import private_sse_blueprint
|
||||
from httpapi.serializedapi import serialized_api_bp
|
||||
"""
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
|
||||
def register_private_blueprints(private_api, app):
|
||||
"""Register private API plask blueprints."""
|
||||
app.register_blueprint(security.client.ClientAPISecurity(
|
||||
private_api).client_api_security_bp)
|
||||
app.register_blueprint(configapi.config_BP)
|
||||
app.register_blueprint(miscclientapi.endpoints.PrivateEndpoints(
|
||||
private_api).private_endpoints_bp)
|
||||
app.register_blueprint(apiutils.shutdown.shutdown_bp)
|
||||
app.register_blueprint(miscclientapi.staticfiles.static_files_bp)
|
||||
app.register_blueprint(themeapi.theme_blueprint)
|
||||
app.register_blueprint(private_sse_blueprint)
|
||||
app.register_blueprint(fileoffsetreader.offset_reader_api)
|
||||
app.register_blueprint(serialized_api_bp)
|
||||
|
||||
def _add_events_bp():
|
||||
while True:
|
||||
try:
|
||||
private_api._too_many
|
||||
break
|
||||
except AttributeError:
|
||||
sleep(0.2)
|
||||
app.register_blueprint(
|
||||
private_api._too_many.get_by_string('DaemonEventsBP').flask_bp)
|
||||
|
||||
Thread(target=_add_events_bp, name='Private blueprints adder').start()
|
||||
|
||||
return app
|
51
src/bigbrother/__init__.py
Normal file
51
src/bigbrother/__init__.py
Normal file
@ -0,0 +1,51 @@
|
||||
"""Onionr - Private P2P Communication.
|
||||
|
||||
Processes interpreter hook events to detect security leaks
|
||||
"""
|
||||
import sys
|
||||
from typing import Iterable
|
||||
|
||||
from onionrexceptions import PythonVersion
|
||||
from . import ministry
|
||||
"""
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
|
||||
def _auditing_supported():
|
||||
try:
|
||||
sys.audit
|
||||
sys.addaudithook
|
||||
except AttributeError:
|
||||
raise PythonVersion('Auditing not supported interpreter')
|
||||
|
||||
|
||||
def sys_hook_entrypoint(event, info):
|
||||
"""Entrypoint for big brother sys auditors."""
|
||||
if event == 'socket.connect':
|
||||
ministry.ofcommunication.detect_socket_leaks(info)
|
||||
elif event == 'exec':
|
||||
# logs and block both exec and eval
|
||||
ministry.ofexec.block_exec(event, info)
|
||||
elif event == 'system':
|
||||
ministry.ofexec.block_system(info)
|
||||
elif event == 'open':
|
||||
ministry.ofdisk.detect_disk_access(info)
|
||||
|
||||
|
||||
def enable_ministries(disable_hooks: Iterable = None):
|
||||
"""Enable auditors."""
|
||||
disable_hooks = disable_hooks or []
|
||||
_auditing_supported() # raises PythonVersion exception if <3.8
|
||||
sys.addaudithook(sys_hook_entrypoint)
|
@ -4,21 +4,21 @@ Ensure sockets don't get made to non localhost
|
||||
"""
|
||||
import ipaddress
|
||||
|
||||
from logger import log as logging
|
||||
import logger
|
||||
from onionrexceptions import NetworkLeak
|
||||
"""
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
|
||||
@ -29,20 +29,21 @@ def detect_socket_leaks(socket_event):
|
||||
raises exception & logs if not to loopback
|
||||
"""
|
||||
ip_address = socket_event[1][0]
|
||||
if ip_address.startswith('/'):
|
||||
return
|
||||
|
||||
# validate is valid ip address (no hostname, etc)
|
||||
# raises NetworkLeak if not
|
||||
try:
|
||||
ip_address = ipaddress.ip_address(ip_address)
|
||||
except ValueError:
|
||||
logging.warn(f'Conn made to {ip_address} outside of Tor/similar')
|
||||
if ip_address == "/":
|
||||
# unix socket
|
||||
return
|
||||
logger.warn(f'Conn made to {ip_address} outside of Tor/similar')
|
||||
raise \
|
||||
NetworkLeak('Conn to host/non local IP, this is a privacy issue!')
|
||||
|
||||
# Validate that the IP is localhost ipv4
|
||||
if not ip_address.is_loopback and not ip_address.is_multicast \
|
||||
and not ip_address.is_private:
|
||||
logging.warn(f'Conn made to {ip_address} outside of Tor/similar')
|
||||
logger.warn(f'Conn made to {ip_address} outside of Tor/similar')
|
||||
raise NetworkLeak('Conn to non local IP, this is a privacy concern!')
|
@ -3,7 +3,7 @@
|
||||
Log (not block) read/write of non-user data files and non-python lib files
|
||||
"""
|
||||
from utils.identifyhome import identify_home
|
||||
from logger import log as logging
|
||||
import logger
|
||||
"""
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -25,7 +25,7 @@ def detect_disk_access(info):
|
||||
|
||||
if '/dev/null' == info[0]: return
|
||||
|
||||
whitelist = [identify_home(), 'onionr/src/', '/site-packages/', '/usr/lib64/', '/usr/local/lib/python']
|
||||
whitelist = [identify_home(), 'onionr/src/', '/site-packages/', '/usr/lib64/']
|
||||
|
||||
for item in whitelist:
|
||||
if item in info[0]:
|
||||
@ -33,4 +33,4 @@ def detect_disk_access(info):
|
||||
|
||||
if identify_home() not in info[0]:
|
||||
if 'proc' not in info[0]: # if it is, it is onionr stats
|
||||
logging.warn(f'[DISK MINISTRY] {info}')
|
||||
logger.warn(f'[DISK MINISTRY] {info}')
|
97
src/bigbrother/ministry/ofexec.py
Normal file
97
src/bigbrother/ministry/ofexec.py
Normal file
@ -0,0 +1,97 @@
|
||||
"""Onionr - Private P2P Communication.
|
||||
|
||||
Prevent eval/exec/os.system and log it
|
||||
"""
|
||||
import base64
|
||||
from os import read
|
||||
|
||||
import logger
|
||||
from utils import identifyhome
|
||||
from onionrexceptions import ArbitraryCodeExec
|
||||
from utils import readstatic
|
||||
"""
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
|
||||
def block_system(cmd):
|
||||
"""Prevent os.system except for whitelisted commands+contexts."""
|
||||
logger.warn('POSSIBLE EXPLOIT DETECTED, SEE LOGS', terminal=True)
|
||||
logger.warn(f'POSSIBLE EXPLOIT: shell command not in whitelist: {cmd}')
|
||||
raise ArbitraryCodeExec('os.system command not in whitelist')
|
||||
|
||||
|
||||
def block_exec(event, info):
|
||||
"""Prevent arbitrary code execution in eval/exec and log it."""
|
||||
# because libraries have stupid amounts of compile/exec/eval,
|
||||
# We have to use a whitelist where it can be tolerated
|
||||
# Generally better than nothing, not a silver bullet
|
||||
return
|
||||
whitelisted_code = [
|
||||
'netrc.py',
|
||||
'shlex.py',
|
||||
'gzip.py',
|
||||
'<werkzeug routing>',
|
||||
'werkzeug/test.py',
|
||||
'multiprocessing/popen_fork.py',
|
||||
'multiprocessing/util.py',
|
||||
'multiprocessing/connection.py',
|
||||
'multiprocessing/queues.py',
|
||||
'multiprocessing/synchronize.py',
|
||||
'onionrutils/escapeansi.py',
|
||||
'stem/connection.py',
|
||||
'stem/response/add_onion.py',
|
||||
'stem/response/authchallenge.py',
|
||||
'stem/response/getinfo.py',
|
||||
'stem/response/getconf.py',
|
||||
'stem/response/mapaddress.py',
|
||||
'stem/response/protocolinfo.py',
|
||||
'apport/__init__.py',
|
||||
'apport/report.py',
|
||||
'gevent/pool.py',
|
||||
'gevent/queue.py',
|
||||
'gevent/lock.py',
|
||||
'gevent/monkey.py',
|
||||
'gevent/_semaphore.py',
|
||||
'gevent/_imap.py'
|
||||
]
|
||||
try:
|
||||
whitelisted_source = readstatic.read_static(
|
||||
'base64-code-whitelist.txt')
|
||||
whitelisted_source = whitelisted_source.splitlines()
|
||||
except FileNotFoundError:
|
||||
logger.warn("Failed to read whitelisted code for bigbrother")
|
||||
whitelisted_source = []
|
||||
|
||||
code_b64 = base64.b64encode(info[0].co_code).decode()
|
||||
if code_b64 in whitelisted_source:
|
||||
return
|
||||
#uncomment when you want to build on the whitelist
|
||||
else:
|
||||
with open("../static-data/base64-code-whitelist.txt", "a") as f:
|
||||
f.write(code_b64 + "\n")
|
||||
return
|
||||
|
||||
for source in whitelisted_code:
|
||||
if info[0].co_filename.endswith(source):
|
||||
return
|
||||
|
||||
if 'plugins/' in info[0].co_filename:
|
||||
return
|
||||
|
||||
logger.warn('POSSIBLE EXPLOIT DETECTED, SEE LOGS', terminal=True)
|
||||
logger.warn('POSSIBLE EXPLOIT DETECTED: ' + info[0].co_filename)
|
||||
logger.warn('Prevented exec/eval. Report this with the sample below')
|
||||
logger.warn(f'{event} code in base64 format: {code_b64}')
|
||||
raise ArbitraryCodeExec("Arbitrary code (eval/exec) detected.")
|
83
src/blockcreatorqueue/__init__.py
Normal file
83
src/blockcreatorqueue/__init__.py
Normal file
@ -0,0 +1,83 @@
|
||||
"""Onionr - Private P2P Communication.
|
||||
|
||||
BlockCreatorQueue, generate anonvdf blocks in a queue
|
||||
"""
|
||||
from typing import Callable
|
||||
from threading import Thread
|
||||
from hashlib import sha3_224
|
||||
from os import cpu_count
|
||||
import time
|
||||
|
||||
import blockio
|
||||
"""
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
|
||||
class AlreadyGenerating(Exception): pass # noqa
|
||||
|
||||
|
||||
|
||||
class PassToSafeDB:
|
||||
def __init__(self, db: 'SafeDB'):
|
||||
self.db = db
|
||||
self.block_creator_queue = BlockCreatorQueue(self.store_kasten)
|
||||
|
||||
def store_kasten(self, kasten_object):
|
||||
self.db.put(kasten_object.id, kasten_object.get_packed())
|
||||
|
||||
def queue_then_store(self, block_data, block_type, ttl, **block_metadata):
|
||||
self.block_creator_queue.queue_block(block_data, block_type, ttl, **block_metadata)
|
||||
|
||||
|
||||
class BlockCreatorQueue:
|
||||
def __init__(
|
||||
self, callback_func: Callable, *additional_callback_func_args,
|
||||
**additional_callback_func_kwargs):
|
||||
self.callback_func = callback_func
|
||||
self.queued = set()
|
||||
self.max_parallel = cpu_count()
|
||||
self.additional_callback_func_args = additional_callback_func_args
|
||||
self.additional_callback_func_kwargs = additional_callback_func_kwargs
|
||||
|
||||
def block_data_in_queue(self, block_data: bytes) -> bool:
|
||||
if sha3_224(block_data).digest() in self.queued:
|
||||
return True
|
||||
return False
|
||||
|
||||
def queue_block(
|
||||
self, block_data, block_type, ttl: int, **block_metadata) -> bytes:
|
||||
"""Spawn a thread to make a subprocess to generate a block
|
||||
if queue is not full, else wait"""
|
||||
|
||||
digest = sha3_224(block_data).digest()
|
||||
|
||||
def _do_create():
|
||||
if digest in self.queued:
|
||||
raise AlreadyGenerating()
|
||||
self.queued.add(digest)
|
||||
while len(self.queued) >= self.max_parallel:
|
||||
time.sleep(1)
|
||||
result = blockio.subprocgenerate.vdf_block(
|
||||
block_data, block_type, ttl, **block_metadata)
|
||||
self.queued.remove(digest)
|
||||
self.callback_func(
|
||||
result,
|
||||
*self.additional_callback_func_args,
|
||||
**self.additional_callback_func_kwargs)
|
||||
|
||||
Thread(
|
||||
target=_do_create, daemon=True,
|
||||
name="BlockCreatorQueue block creation").start()
|
||||
return digest
|
@ -1,33 +0,0 @@
|
||||
from typing import Callable, Generator, List
|
||||
|
||||
from onionrblocks import Block
|
||||
from onionrplugins import onionrevents
|
||||
|
||||
import db
|
||||
|
||||
from .dbpath import block_db_path
|
||||
from .blockcleaner import clean_block_database
|
||||
from .getblocks import get_blocks_after_timestamp, get_blocks_by_type
|
||||
from .deleteblock import delete_block
|
||||
|
||||
block_storage_observers: List[Callable] = []
|
||||
|
||||
|
||||
|
||||
|
||||
def add_block_to_db(block: Block):
|
||||
onionrevents.event('before_block_db_add', block, threaded=False)
|
||||
db.set_if_new(block_db_path, block.id, block.raw) # Raises db.DuplicateKey if dupe
|
||||
onionrevents.event('after_block_db_add', block, threaded=False)
|
||||
|
||||
|
||||
def has_block(block_hash):
|
||||
return block_hash in db.list_keys(block_db_path)
|
||||
|
||||
|
||||
def get_block(block_hash) -> Block:
|
||||
return Block(
|
||||
block_hash,
|
||||
db.get_db_obj(block_db_path, 'u').get(block_hash),
|
||||
auto_verify=False)
|
||||
|
@ -1,24 +0,0 @@
|
||||
from typing import Set
|
||||
|
||||
from onionrblocks import Block
|
||||
|
||||
from logger import log as logging
|
||||
|
||||
from .deleteblock import delete_block
|
||||
from .getblocks import get_blocks_after_timestamp
|
||||
|
||||
|
||||
def clean_block_database():
|
||||
"""Delete expired blocks from block db"""
|
||||
remove_set: Set[bytes] = set()
|
||||
block: Block
|
||||
|
||||
for block in get_blocks_after_timestamp(0):
|
||||
try:
|
||||
Block(block.id, block.raw, auto_verify=True)
|
||||
except ValueError: # block expired
|
||||
remove_set.add(block)
|
||||
|
||||
if len(remove_set):
|
||||
logging.info(f"Cleaning {len(remove_set)} blocks")
|
||||
[i for i in map(delete_block, remove_set)]
|
@ -1,4 +0,0 @@
|
||||
from utils import identifyhome
|
||||
|
||||
|
||||
block_db_path = identifyhome.identify_home() + 'blockdata'
|
@ -1,10 +0,0 @@
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from onionrblocks import Block
|
||||
|
||||
import db
|
||||
|
||||
from .dbpath import block_db_path
|
||||
|
||||
def delete_block(block: 'Block'): db.delete(block_db_path, block.id)
|
@ -1,33 +0,0 @@
|
||||
from typing import Generator
|
||||
|
||||
import db
|
||||
|
||||
from onionrblocks import Block
|
||||
|
||||
from .dbpath import block_db_path
|
||||
|
||||
|
||||
def get_blocks_by_type(block_type: str) -> "Generator[Block]":
|
||||
try:
|
||||
block_type = block_type.decode('utf-8')
|
||||
except AttributeError:
|
||||
pass
|
||||
block_db = db.get_db_obj(block_db_path, 'u')
|
||||
for block_hash in db.list_keys(block_db_path):
|
||||
block = Block(block_hash, block_db[block_hash], auto_verify=False)
|
||||
if block.type == block_type:
|
||||
yield block
|
||||
|
||||
|
||||
def get_blocks_after_timestamp(
|
||||
timestamp: int, block_type: str = '') -> "Generator[Block]":
|
||||
block_db = db.get_db_obj(block_db_path, 'u')
|
||||
|
||||
for block_hash in db.list_keys(block_db_path):
|
||||
block = Block(block_hash, block_db[block_hash], auto_verify=False)
|
||||
if block.timestamp > timestamp:
|
||||
if block_type:
|
||||
if block_type == block.type:
|
||||
yield block
|
||||
else:
|
||||
yield block
|
15
src/onionrvalues.py → src/blockio/__init__.py
Executable file → Normal file
15
src/onionrvalues.py → src/blockio/__init__.py
Executable file → Normal file
@ -1,7 +1,12 @@
|
||||
"""Onionr - Private P2P Communication.
|
||||
|
||||
This file defines values and requirements used by Onionr
|
||||
Wrap safedb for storing and fetching blocks
|
||||
"""
|
||||
from .store import store_block
|
||||
from .load import load_block, list_blocks_by_type, list_all_blocks
|
||||
from .clean import clean_expired_blocks, clean_block_list_entries
|
||||
from . import subprocgenerate
|
||||
from . import subprocvalidate
|
||||
"""
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -16,11 +21,3 @@ GNU General Public License for more details.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
"""
|
||||
ONIONR_TAGLINE = 'Private P2P Communication - GPLv3 - https://Onionr.net'
|
||||
ONIONR_VERSION = '9.0.0'
|
||||
ONIONR_VERSION_CODENAME = 'Taraxacum'
|
||||
ONIONR_VERSION_TUPLE = tuple(ONIONR_VERSION.split('.')) # (MAJOR, MINOR, VERSION)
|
||||
MIN_PY_VERSION = 10
|
||||
DEVELOPMENT_MODE = False
|
||||
|
||||
ORIG_RUN_DIR_ENV_VAR = 'ORIG_ONIONR_RUN_DIR'
|
2
src/blockio/clean/__init__.py
Normal file
2
src/blockio/clean/__init__.py
Normal file
@ -0,0 +1,2 @@
|
||||
from .cleanexpired import clean_expired_blocks
|
||||
from .cleanblocklistentries import clean_block_list_entries
|
@ -1,17 +1,10 @@
|
||||
from queue import Queue
|
||||
"""Onionr - Private P2P Communication.
|
||||
|
||||
block_queues where all received or created blocks are placed
|
||||
|
||||
Blocks are placed here before being sent to the network, the reason they are in
|
||||
2 queues is for dandelion++ implementation.
|
||||
|
||||
The queues are drained randomly to incoming or outgoing edges depending on
|
||||
dandelion++ phase
|
||||
Delete block type lists that are empty
|
||||
"""
|
||||
from typing import Tuple, TYPE_CHECKING
|
||||
from typing import TYPE_CHECKING
|
||||
if TYPE_CHECKING:
|
||||
from onionrblocks import Block
|
||||
from safedb import SafeDB
|
||||
"""
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -27,4 +20,14 @@ You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
gossip_block_queues: Tuple["Queue[Block]", "Queue[Block]"] = (Queue(), Queue())
|
||||
|
||||
def clean_block_list_entries(db: 'SafeDB'):
|
||||
key = db.db_conn.firstkey()
|
||||
delete_keys = []
|
||||
while key:
|
||||
if key.startswith(b'bl-'):
|
||||
if not db.get(key):
|
||||
delete_keys.append(key)
|
||||
key = db.db_conn.nextkey(key)
|
||||
for key in delete_keys:
|
||||
del db.db_conn[key]
|
48
src/blockio/clean/cleanexpired.py
Normal file
48
src/blockio/clean/cleanexpired.py
Normal file
@ -0,0 +1,48 @@
|
||||
"""Onionr - Private P2P Communication.
|
||||
|
||||
clean expired blocks
|
||||
"""
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from kasten import Kasten
|
||||
from onionrblocks.generators.anonvdf import AnonVDFGenerator
|
||||
from onionrblocks.exceptions import BlockExpired
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from safedb import SafeDB
|
||||
"""
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
|
||||
def clean_expired_blocks(db: 'SafeDB'):
|
||||
key = db.db_conn.firstkey()
|
||||
delete_list = set()
|
||||
# Scan all database keys and check kasten objs if they are a hash
|
||||
while key:
|
||||
try:
|
||||
if key.startswith(b'bl-') or key.startswith(b'enc'):
|
||||
key = db.db_conn.nextkey(key)
|
||||
continue
|
||||
Kasten(key, db.get(key), AnonVDFGenerator)
|
||||
except BlockExpired:
|
||||
block_type = Kasten(
|
||||
key, db.get(key),
|
||||
None, auto_check_generator=False).get_data_type()
|
||||
db.db_conn[f'bl-{block_type}'] = \
|
||||
db.db_conn[f'bl-{block_type}'].replace(key, b'')
|
||||
delete_list.add(key)
|
||||
key = db.db_conn.nextkey(key)
|
||||
for key in delete_list:
|
||||
del db.db_conn[key]
|
54
src/blockio/load/__init__.py
Normal file
54
src/blockio/load/__init__.py
Normal file
@ -0,0 +1,54 @@
|
||||
"""Onionr - Private P2P Communication.
|
||||
|
||||
Get blocks from safedb
|
||||
"""
|
||||
from typing import TYPE_CHECKING, List
|
||||
|
||||
from kasten import Kasten
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from kasten.types import BlockChecksumBytes
|
||||
from safedb import SafeDB
|
||||
"""
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
|
||||
def load_block(block: 'BlockChecksumBytes', safe_db: 'SafeDB') -> Kasten:
|
||||
return Kasten(
|
||||
block, safe_db.get(block), generator=None, auto_check_generator=False)
|
||||
|
||||
|
||||
def list_blocks_by_type(
|
||||
block_type: str, safe_db: 'SafeDB') -> List['BlockChecksumBytes']:
|
||||
try:
|
||||
block_type = block_type.decode('utf-8')
|
||||
except AttributeError:
|
||||
pass
|
||||
blocks = safe_db.get(f'bl-{block_type}')
|
||||
return zip(*[iter(blocks)]*64)
|
||||
|
||||
|
||||
def list_all_blocks(safe_db: 'SafeDB'):
|
||||
# Builds and return a master list of blocks by identifying all type lists
|
||||
# and iterating them
|
||||
key = safe_db.db_conn.firstkey()
|
||||
master_list = []
|
||||
while key:
|
||||
if key.startswith(b'bl-'):
|
||||
master_list.extend(
|
||||
list(list_blocks_by_type(key.replace(b'bl-', b''), safe_db)))
|
||||
key = safe_db.db_conn.nextkey(key)
|
||||
return master_list
|
||||
|
43
src/blockio/store/__init__.py
Normal file
43
src/blockio/store/__init__.py
Normal file
@ -0,0 +1,43 @@
|
||||
"""Onionr - Private P2P Communication.
|
||||
|
||||
Store blocks and cache meta info such as block type
|
||||
"""
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from kasten import Kasten
|
||||
from safedb import SafeDB
|
||||
"""
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
|
||||
def store_block(block: 'Kasten', safe_db: 'SafeDB', own_block=False):
|
||||
# This does not handle validation of blocks
|
||||
# safe_db is initialized by the daemon when starting normally
|
||||
# so any other commands need to initialize it seperately
|
||||
|
||||
block_type = block.get_data_type()
|
||||
try:
|
||||
block_list_for_type = safe_db.get(f'bl-{block_type}')
|
||||
if block.id in block_list_for_type:
|
||||
raise ValueError("Cannot store duplicate block")
|
||||
except KeyError:
|
||||
block_list_for_type = b''
|
||||
|
||||
safe_db.put(block.id, block.get_packed())
|
||||
# Append the block to the list of blocks for this given type
|
||||
block_list_for_type += block.id
|
||||
safe_db.put(f'bl-{block_type}', block_list_for_type)
|
||||
|
45
src/blockio/subprocgenerate.py
Normal file
45
src/blockio/subprocgenerate.py
Normal file
@ -0,0 +1,45 @@
|
||||
from base64 import b85encode
|
||||
import os
|
||||
import subprocess
|
||||
import threading
|
||||
|
||||
import ujson as json
|
||||
import kasten
|
||||
|
||||
from onionrplugins import onionrevents
|
||||
from blockio import store_block
|
||||
from onionrblocks.generators.anonvdf import AnonVDFGenerator
|
||||
|
||||
_DIR = os.path.dirname(os.path.realpath(__file__)) + '/../'
|
||||
|
||||
|
||||
def vdf_block(data, data_type, ttl, **metadata):
|
||||
try:
|
||||
data = data.encode('utf-8')
|
||||
except AttributeError:
|
||||
pass
|
||||
data = b85encode(data)
|
||||
generated = subprocess.Popen(
|
||||
[
|
||||
f'{_DIR}anonvdf-block-creator.py',
|
||||
json.dumps(metadata),
|
||||
data_type,
|
||||
str(ttl)],
|
||||
stdout=subprocess.PIPE,
|
||||
stdin=subprocess.PIPE)
|
||||
generated = generated.communicate(data)[0]
|
||||
return kasten.Kasten(
|
||||
generated[:64], generated[64:],
|
||||
AnonVDFGenerator, auto_check_generator=True)
|
||||
|
||||
|
||||
def gen_and_store_vdf_block(shared_state, *args, **kwargs):
|
||||
safe_db = shared_state.get_by_string('SafeDB')
|
||||
k = vdf_block(*args, **kwargs)
|
||||
store_block(
|
||||
k,
|
||||
safe_db,
|
||||
own_block=True
|
||||
)
|
||||
onionrevents.event('blockcreated', data=shared_state, threaded=True)
|
||||
|
19
src/blockio/subprocvalidate.py
Normal file
19
src/blockio/subprocvalidate.py
Normal file
@ -0,0 +1,19 @@
|
||||
import subprocess
|
||||
import os
|
||||
from base64 import b85encode
|
||||
from onionrblocks.generators import anonvdf
|
||||
|
||||
|
||||
_DIR = os.path.dirname(os.path.realpath(__file__)) + '/../'
|
||||
|
||||
|
||||
def vdf_block(block_hash: bytes, block_data: bytes):
|
||||
block_data = b85encode(block_data)
|
||||
|
||||
p = subprocess.Popen(
|
||||
[
|
||||
f'{_DIR}anonvdf-block-validator.py',
|
||||
b85encode(block_hash)], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
|
||||
result = p.communicate(block_data)
|
||||
if result[1]:
|
||||
raise anonvdf.InvalidID()
|
15
src/communicator/README.md
Normal file
15
src/communicator/README.md
Normal file
@ -0,0 +1,15 @@
|
||||
# Onionr Communicator
|
||||
|
||||
Onionr communicator is the Onionr client. It "connects" to remote Onionr peers and does things such as:
|
||||
|
||||
* Finding new peers
|
||||
* Uploading blocks
|
||||
* Downloading blocks
|
||||
* Daemon maintenance/housekeeping
|
||||
|
||||
## Files
|
||||
|
||||
* \_\_init\_\_.py: Contains the main communicator code. Inits and launches the communicator and sets up the timers
|
||||
* peeraction.py: contains a function to send commands to remote peers
|
||||
* bootstrappers.py: adds peers from the bootstrap list to the communicator to try to connect to them
|
||||
* onlinepeers: management of the online peer pool for the communicator
|
94
src/communicator/__init__.py
Executable file
94
src/communicator/__init__.py
Executable file
@ -0,0 +1,94 @@
|
||||
"""Onionr - Private P2P Communication.
|
||||
|
||||
This file contains both the OnionrCommunicate class for
|
||||
communcating with peers and code to operate as a daemon,
|
||||
getting commands from the command queue database
|
||||
"""
|
||||
import time
|
||||
|
||||
import config
|
||||
import logger
|
||||
import onionrplugins as plugins
|
||||
from onionrcommands.openwebinterface import get_url
|
||||
from . import daemoneventhooks
|
||||
"""
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
config.reload()
|
||||
|
||||
|
||||
class OnionrCommunicatorDaemon:
|
||||
def __init__(self, shared_state, developmentMode=None):
|
||||
if developmentMode is None:
|
||||
developmentMode = config.get(
|
||||
'general.dev_mode', False)
|
||||
|
||||
# configure logger and stuff
|
||||
self.config = config
|
||||
self.shared_state = shared_state # TooManyObjects module
|
||||
shared_state.add(self)
|
||||
|
||||
# populate kv values
|
||||
self.kv = self.shared_state.get_by_string('DeadSimpleKV')
|
||||
|
||||
if config.get('general.offline_mode', False):
|
||||
self.kv.put('isOnline', False)
|
||||
|
||||
|
||||
self.shared_state.share_object()
|
||||
|
||||
# loop time.sleep delay in seconds
|
||||
self.delay = 5
|
||||
|
||||
# amount of threads running by name, used to prevent too many
|
||||
self.threadCounts = {}
|
||||
|
||||
# Loads in and starts the enabled plugins
|
||||
plugins.reload()
|
||||
|
||||
|
||||
daemoneventhooks.daemon_event_handlers(shared_state)
|
||||
|
||||
get_url()
|
||||
if not config.get('onboarding.done', True):
|
||||
logger.info(
|
||||
'First run detected. Run openhome to get setup.',
|
||||
terminal=True)
|
||||
|
||||
while not config.get('onboarding.done', True) and \
|
||||
not self.shared_state.get_by_string(
|
||||
'DeadSimpleKV').get('shutdown'):
|
||||
try:
|
||||
time.sleep(2)
|
||||
except KeyboardInterrupt:
|
||||
self.shared_state.get_by_string(
|
||||
'DeadSimpleKV').put('shutdown', True)
|
||||
|
||||
# Main daemon loop, mainly for calling timers,
|
||||
# don't do any complex operations here to avoid locking
|
||||
try:
|
||||
while not self.shared_state.get_by_string(
|
||||
'DeadSimpleKV').get('shutdown'):
|
||||
time.sleep(self.delay)
|
||||
except KeyboardInterrupt:
|
||||
self.shared_state.get_by_string(
|
||||
'DeadSimpleKV').put('shutdown', True)
|
||||
|
||||
logger.info(
|
||||
'Goodbye. (Onionr is cleaning up, and will exit)', terminal=True)
|
||||
|
||||
|
||||
def startCommunicator(shared_state):
|
||||
OnionrCommunicatorDaemon(shared_state)
|
54
src/communicator/daemoneventhooks/__init__.py
Normal file
54
src/communicator/daemoneventhooks/__init__.py
Normal file
@ -0,0 +1,54 @@
|
||||
"""Onionr - Private P2P Communication.
|
||||
|
||||
Hooks to handle daemon events
|
||||
"""
|
||||
from threading import Thread
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from gevent import sleep
|
||||
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from toomanyobjs import TooMany
|
||||
from deadsimplekv import DeadSimpleKV
|
||||
from communicator import OnionrCommunicatorDaemon
|
||||
from httpapi.daemoneventsapi import DaemonEventsBP
|
||||
from onionrtypes import BlockHash
|
||||
"""
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
|
||||
def daemon_event_handlers(shared_state: 'TooMany'):
|
||||
def _get_inst(class_name: str):
|
||||
while True:
|
||||
try:
|
||||
return shared_state.get_by_string(class_name)
|
||||
except KeyError:
|
||||
sleep(0.2)
|
||||
comm_inst = _get_inst('OnionrCommunicatorDaemon')
|
||||
events_api: 'DaemonEventsBP' = _get_inst('DaemonEventsBP')
|
||||
kv: 'DeadSimpleKV' = _get_inst('DeadSimpleKV')
|
||||
|
||||
def print_test(text=''):
|
||||
print("It works!", text)
|
||||
return f"It works! {text}"
|
||||
|
||||
def test_runtime():
|
||||
Thread(target=comm_inst.shared_state.get_by_string(
|
||||
"OnionrRunTestManager").run_tests).start()
|
||||
|
||||
events_api.register_listener(print_test)
|
||||
events_api.register_listener(test_runtime)
|
@ -6,22 +6,23 @@ import os
|
||||
from json import JSONDecodeError
|
||||
|
||||
import ujson as json
|
||||
from logger import log as logging
|
||||
import logger
|
||||
import filepaths
|
||||
|
||||
from . import onboarding
|
||||
"""
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
_configfile = filepaths.config_file
|
||||
@ -106,7 +107,7 @@ def save():
|
||||
with open(get_config_file(), 'w', encoding="utf8") as configfile:
|
||||
json.dump(get_config(), configfile, indent=2)
|
||||
except JSONDecodeError:
|
||||
logging.warn('Failed to write to configuration file.')
|
||||
logger.warn('Failed to write to configuration file.')
|
||||
|
||||
|
||||
def reload():
|
||||
@ -117,7 +118,7 @@ def reload():
|
||||
set_config(json.loads(configfile.read()))
|
||||
except (FileNotFoundError, JSONDecodeError) as e:
|
||||
pass
|
||||
#logging.debug('Failed to parse configuration file.')
|
||||
#logger.debug('Failed to parse configuration file.')
|
||||
|
||||
|
||||
def get_config():
|
||||
|
79
src/config/onboarding.py
Normal file
79
src/config/onboarding.py
Normal file
@ -0,0 +1,79 @@
|
||||
"""Onionr - Private P2P Communication.
|
||||
|
||||
Setup config from onboarding choices
|
||||
"""
|
||||
from pathlib import Path
|
||||
from typing import Union
|
||||
|
||||
from filepaths import onboarding_mark_file
|
||||
from onionrtypes import JSONSerializable
|
||||
from onionrtypes import OnboardingConfig
|
||||
import config
|
||||
"""
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
|
||||
def _get_val_or_none(json: dict, key: str) -> Union[None, JSONSerializable]:
|
||||
try:
|
||||
return json['configInfo'][key]
|
||||
except KeyError:
|
||||
return None
|
||||
|
||||
|
||||
def set_config_from_onboarding(config_settings: OnboardingConfig):
|
||||
get = _get_val_or_none
|
||||
|
||||
config.reload()
|
||||
|
||||
if get(config_settings, 'optimize'):
|
||||
config.set('ui.animated_background', False)
|
||||
config.set('general.insert_deniable_blocks', False)
|
||||
|
||||
if get(config_settings, 'stateTarget') or not get(config_settings,
|
||||
'networkContrib'):
|
||||
config.set('general.security_level', 1)
|
||||
|
||||
if get(config_settings, 'localThreat'):
|
||||
config.set('general.security_level', 3)
|
||||
config.set('transports.lan', False)
|
||||
|
||||
config.set('ui.theme', 'light')
|
||||
if get(config_settings, 'useDark'):
|
||||
config.set('ui.theme', 'dark')
|
||||
|
||||
disabled = config.get('plugins.disabled', [])
|
||||
|
||||
if not get(config_settings, 'circles') or \
|
||||
config.get('general.security_level') > 0:
|
||||
disabled.append('flow')
|
||||
|
||||
if not get(config_settings, 'mail'):
|
||||
disabled.append('pms')
|
||||
|
||||
config.set('plugins.disabled', disabled)
|
||||
|
||||
config.set('general.store_plaintext_blocks',
|
||||
get(config_settings, 'plainContrib'))
|
||||
|
||||
config.set('onboarding.done', True, savefile=True)
|
||||
|
||||
|
||||
def set_onboarding_finished():
|
||||
"""Create the onboarding completed setting file"""
|
||||
Path(onboarding_mark_file).touch()
|
||||
|
||||
|
||||
def is_onboarding_finished() -> bool:
|
||||
return True
|
@ -1,96 +0,0 @@
|
||||
import dbm
|
||||
import time
|
||||
import os
|
||||
|
||||
timeout = 120
|
||||
|
||||
class DuplicateKey(ValueError): pass
|
||||
|
||||
|
||||
def _do_timeout(func, *args):
|
||||
ts = 0
|
||||
res = None
|
||||
while True:
|
||||
try:
|
||||
res = func(*args)
|
||||
except dbm.error:
|
||||
if not ts:
|
||||
ts = time.time()
|
||||
continue
|
||||
if time.time() - ts > timeout:
|
||||
raise TimeoutError()
|
||||
time.sleep(0.01)
|
||||
else:
|
||||
return res
|
||||
|
||||
|
||||
def delete(db_path, key):
|
||||
def _delete(key):
|
||||
with dbm.open(db_path, "c") as my_db:
|
||||
del my_db[key]
|
||||
try:
|
||||
_do_timeout(_delete, key)
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
|
||||
def set_if_new(db_path, key, value) -> bool:
|
||||
def _set(key, value):
|
||||
with dbm.open(db_path, "c") as my_db:
|
||||
try:
|
||||
my_db[key]
|
||||
except KeyError:
|
||||
my_db[key] = value
|
||||
else:
|
||||
raise DuplicateKey
|
||||
try:
|
||||
_do_timeout(_set, key, value)
|
||||
except DuplicateKey:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def set(db_path, key, value):
|
||||
"""Set a value in the db, open+timeout so not good for rapid use"""
|
||||
def _set(key, value):
|
||||
with dbm.open(db_path, "c") as my_db:
|
||||
my_db[key] = value
|
||||
_do_timeout(_set, key, value)
|
||||
|
||||
|
||||
def get(db_path, key):
|
||||
"""Get a value in the db, open+timeout so not good for rapid use"""
|
||||
def _get(key):
|
||||
with dbm.open(db_path, "cu") as my_db:
|
||||
return my_db[key]
|
||||
return _do_timeout(_get, key)
|
||||
|
||||
|
||||
|
||||
def get_db_obj(db_path, extra_flag=''):
|
||||
"""For when you should keep a db obj open"""
|
||||
def _get_db():
|
||||
return dbm.open(db_path, "c" + extra_flag)
|
||||
return _do_timeout(_get_db)
|
||||
|
||||
|
||||
def list_keys(db_path):
|
||||
"""Generator of all keys in the db.
|
||||
|
||||
Uses a lot of mem if no firstkey supported"""
|
||||
db_obj = _do_timeout(dbm.open, db_path, "cu")
|
||||
if not hasattr(db_obj, "firstkey"):
|
||||
for i in db_obj.keys():
|
||||
yield i
|
||||
db_obj.close()
|
||||
return
|
||||
|
||||
|
||||
def _list_keys(db_obj):
|
||||
with db_obj as my_db:
|
||||
k = my_db.firstkey()
|
||||
while k is not None:
|
||||
yield k
|
||||
k = my_db.nextkey(k)
|
||||
yield from _list_keys(db_obj)
|
||||
|
9
src/etc/README.md
Executable file
9
src/etc/README.md
Executable file
@ -0,0 +1,9 @@
|
||||
# etc
|
||||
|
||||
Files that don't really fit anywhere else, but aren't used very frequently.
|
||||
|
||||
## Files
|
||||
|
||||
humanreadabletime.py: take integer seconds and return a human readable time string
|
||||
|
||||
onionrvalues.py: spec values for onionr blocks and other things
|
38
src/etc/cleanup/__init__.py
Normal file
38
src/etc/cleanup/__init__.py
Normal file
@ -0,0 +1,38 @@
|
||||
"""Onionr - Private P2P Communication.
|
||||
|
||||
cleanup run files
|
||||
"""
|
||||
import os
|
||||
|
||||
import filepaths
|
||||
"""
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
|
||||
def _safe_remove(path):
|
||||
try:
|
||||
os.remove(path)
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
|
||||
|
||||
def delete_run_files():
|
||||
"""Delete run files, do not error if not found.
|
||||
|
||||
Test: test_cleanup.py
|
||||
"""
|
||||
_safe_remove(filepaths.private_API_host_file)
|
||||
_safe_remove(filepaths.daemon_mark_file)
|
||||
_safe_remove(filepaths.lock_file)
|
13
src/etc/dependencycheck.py
Normal file
13
src/etc/dependencycheck.py
Normal file
@ -0,0 +1,13 @@
|
||||
from urllib3.contrib.socks import SOCKSProxyManager # noqa
|
||||
import gevent
|
||||
import flask
|
||||
import mimcvdf
|
||||
import toomanyobjs
|
||||
import stem
|
||||
import psutil
|
||||
import unpaddedbase32
|
||||
import niceware
|
||||
import watchdog
|
||||
import nacl
|
||||
import deadsimplekv
|
||||
import ujson
|
40
src/etc/humanreadabletime.py
Executable file
40
src/etc/humanreadabletime.py
Executable file
@ -0,0 +1,40 @@
|
||||
"""
|
||||
Onionr - Private P2P Communication.
|
||||
|
||||
human_readable_time takes integer seconds and returns a human readable string
|
||||
"""
|
||||
"""
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
|
||||
def human_readable_time(seconds):
|
||||
build = ''
|
||||
|
||||
units = {
|
||||
'year' : 31557600,
|
||||
'month' : (31557600 / 12),
|
||||
'day' : 86400,
|
||||
'hour' : 3600,
|
||||
'minute' : 60,
|
||||
'second' : 1
|
||||
}
|
||||
|
||||
for unit in units:
|
||||
amnt_unit = int(seconds / units[unit])
|
||||
if amnt_unit >= 1:
|
||||
seconds -= amnt_unit * units[unit]
|
||||
build += '%s %s' % (amnt_unit, unit) + ('s' if amnt_unit != 1 else '') + ' '
|
||||
|
||||
return build.strip()
|
51
src/etc/onionrvalues.py
Executable file
51
src/etc/onionrvalues.py
Executable file
@ -0,0 +1,51 @@
|
||||
"""Onionr - Private P2P Communication.
|
||||
|
||||
This file defines values and requirements used by Onionr
|
||||
"""
|
||||
import platform
|
||||
import os
|
||||
|
||||
import filepaths
|
||||
"""
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
"""
|
||||
PASSWORD_LENGTH = 25
|
||||
ONIONR_TAGLINE = 'Private P2P Communication - GPLv3 - https://Onionr.net'
|
||||
ONIONR_VERSION = '9.0.0'
|
||||
ONIONR_VERSION_CODENAME = 'Nexus'
|
||||
ONIONR_VERSION_TUPLE = tuple(ONIONR_VERSION.split('.')) # (MAJOR, MINOR, VERSION)
|
||||
API_VERSION = '2' # increments of 1; only change when something fundamental about how the API works changes. This way other nodes know how to communicate without learning too much information about you.
|
||||
MIN_PY_VERSION = 7 # min version of 7 so we can take advantage of non-cyclic type hints
|
||||
DEVELOPMENT_MODE = False
|
||||
IS_QUBES = False
|
||||
|
||||
ORIG_RUN_DIR_ENV_VAR = 'ORIG_ONIONR_RUN_DIR'
|
||||
|
||||
DATABASE_LOCK_TIMEOUT = 60
|
||||
|
||||
# Block creation anonymization requirements
|
||||
MIN_BLOCK_UPLOAD_PEER_PERCENT = 0.1
|
||||
|
||||
WSGI_SERVER_REQUEST_TIMEOUT_SECS = 120
|
||||
|
||||
|
||||
BLOCK_EXPORT_FILE_EXT = '.onionr'
|
||||
|
||||
|
||||
if os.path.exists(filepaths.daemon_mark_file):
|
||||
SCRIPT_NAME = 'start-daemon.sh'
|
||||
else:
|
||||
SCRIPT_NAME = 'onionr.sh'
|
||||
if 'qubes' in platform.release().lower():
|
||||
IS_QUBES = True
|
8
src/etc/waitforsetvar.py
Normal file
8
src/etc/waitforsetvar.py
Normal file
@ -0,0 +1,8 @@
|
||||
from __future__ import annotations
|
||||
from typing import Union, Generic
|
||||
from gevent import sleep
|
||||
def wait_for_set_var(obj, attribute, sleep_seconds: Union[int, float]=0):
|
||||
"""Wait for an object to get an attribute with an optional sleep time"""
|
||||
while not hasattr(obj, attribute):
|
||||
if hasattr(obj, attribute): break
|
||||
if sleep_seconds > 0: sleep(sleep_seconds)
|
@ -4,11 +4,28 @@ home = identifyhome.identify_home()
|
||||
if not home.endswith('/'): home += '/'
|
||||
|
||||
app_root = os.path.dirname(os.path.realpath(__file__)) + '/../../'
|
||||
usage_file = home + 'disk-usage.txt'
|
||||
block_data_location = home + 'blocks/'
|
||||
|
||||
gossip_server_socket_file = home + 'gossip-server.sock'
|
||||
private_API_host_file = home + 'private-host.txt'
|
||||
|
||||
cached_storage = home + 'cachedstorage.dat'
|
||||
announce_cache = home + 'announcecache.dat'
|
||||
upload_list = home + 'upload-list.json'
|
||||
config_file = home + 'config.json'
|
||||
daemon_mark_file = home + '/daemon-true.txt'
|
||||
lock_file = home + 'onionr.lock'
|
||||
pid_file = home + 'onionr.pid'
|
||||
|
||||
main_safedb = home + "main.safe.db"
|
||||
|
||||
data_nonce_file = home + 'block-nonces.dat'
|
||||
|
||||
onboarding_mark_file = home + 'onboarding-completed'
|
||||
|
||||
log_file = home + 'onionr.log'
|
||||
|
||||
restarting_indicator = home + "is-restarting"
|
||||
|
||||
secure_erase_key_file = home + "erase-key"
|
||||
|
||||
master_db_location = home + "database/"
|
||||
|
@ -1,59 +0,0 @@
|
||||
import threading
|
||||
from time import sleep
|
||||
from typing import TYPE_CHECKING, Set, Tuple
|
||||
from logger import log as logging
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ordered_set import OrderedSet
|
||||
from onionrblocks import Block
|
||||
from queue import Queue
|
||||
|
||||
from .peer import Peer
|
||||
|
||||
from onionrthreads import add_onionr_thread
|
||||
import onionrplugins
|
||||
|
||||
from .connectpeer import connect_peer
|
||||
from .client import start_gossip_client
|
||||
from .server import gossip_server
|
||||
from .constants import BOOTSTRAP_ATTEMPTS
|
||||
from .peerset import gossip_peer_set
|
||||
"""
|
||||
Onionr uses a flavor of Dandelion++ epidemic routing
|
||||
|
||||
The starter creates a peer set and passes it to the client and server
|
||||
as well as each of the plugins.
|
||||
|
||||
The transports forward incoming requests to the gossip server
|
||||
|
||||
When a new peer announcement is recieved an event is fired and the transport
|
||||
plugin that handles it will (or wont) create a new peer object by connecting
|
||||
to that peer
|
||||
|
||||
When a new block is generated, it is added to a queue in raw form passed to
|
||||
the starter
|
||||
|
||||
In stem phase, client uploads recieved (stem) blocks to 2 random peers.
|
||||
In stem phase, server disables diffusion
|
||||
|
||||
"""
|
||||
|
||||
|
||||
def start_gossip_threads():
|
||||
# Peer set is largely handled by the transport plugins
|
||||
# There is a unified set so gossip logic is not repeated
|
||||
|
||||
add_onionr_thread(
|
||||
gossip_server, 1, 'gossip_server', initial_sleep=0.2)
|
||||
|
||||
threading.Thread(
|
||||
target=start_gossip_client, daemon=True, name="start_gossip_client").start()
|
||||
onionrplugins.events.event('gossip_start', data=None, threaded=True)
|
||||
for _ in range(BOOTSTRAP_ATTEMPTS):
|
||||
onionrplugins.events.event(
|
||||
'bootstrap', data={'callback': connect_peer},
|
||||
threaded=False)
|
||||
sleep(60)
|
||||
if len(gossip_peer_set):
|
||||
return
|
||||
logging.error("Could not connect to any peers :(")
|
@ -1,127 +0,0 @@
|
||||
"""Onionr - Private P2P Communication.
|
||||
|
||||
Dandelion ++ Gossip client logic
|
||||
"""
|
||||
import traceback
|
||||
from threading import Thread
|
||||
from typing import TYPE_CHECKING
|
||||
from typing import Set, Tuple
|
||||
from time import sleep
|
||||
import asyncio
|
||||
|
||||
from queue import Queue
|
||||
|
||||
|
||||
from onionrblocks import Block
|
||||
|
||||
from ..constants import DANDELION_EPOCH_LENGTH
|
||||
from ..connectpeer import connect_peer
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ..peer import Peer
|
||||
from ordered_set import OrderedSet
|
||||
|
||||
from logger import log as logging
|
||||
import config
|
||||
import onionrplugins
|
||||
from ..commands import GossipCommands
|
||||
from gossip.dandelion.phase import DandelionPhase
|
||||
from onionrthreads import add_onionr_thread
|
||||
from blockdb import add_block_to_db
|
||||
|
||||
|
||||
from .storeblocks import store_blocks
|
||||
from .announce import do_announce
|
||||
from .dandelionstem import stem_out
|
||||
from .peerexchange import get_new_peers
|
||||
from ..peerset import gossip_peer_set
|
||||
from .streamblocks import stream_from_peers, stream_to_peer
|
||||
|
||||
"""
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
dandelion_phase = DandelionPhase(DANDELION_EPOCH_LENGTH)
|
||||
|
||||
|
||||
def block_queue_processing():
|
||||
|
||||
|
||||
while not len(gossip_peer_set):
|
||||
sleep(1)
|
||||
if dandelion_phase.remaining_time() <= 15:
|
||||
#logging.debug("Sleeping")
|
||||
sleep(dandelion_phase.remaining_time())
|
||||
if dandelion_phase.is_stem_phase() and config.get('security.dandelion.enabled', True):
|
||||
logging.debug("Entering stem phase")
|
||||
try:
|
||||
# Stem out blocks for (roughly) remaining epoch time
|
||||
asyncio.run(stem_out(dandelion_phase))
|
||||
except TimeoutError:
|
||||
pass
|
||||
except Exception:
|
||||
logging.error(traceback.format_exc())
|
||||
pass
|
||||
else:
|
||||
#logging.debug("Entering fluff phase")
|
||||
# Add block to primary block db, where the diffuser can read it
|
||||
sleep(0.1)
|
||||
store_blocks(dandelion_phase)
|
||||
|
||||
|
||||
def start_gossip_client():
|
||||
"""
|
||||
Gossip client does the following:
|
||||
|
||||
Stem new blocks we created or downloaded *during stem phase*
|
||||
Stream new blocks
|
||||
"""
|
||||
bl: Block
|
||||
|
||||
# Start a thread to announce our transport addresses to peers
|
||||
add_onionr_thread(
|
||||
do_announce,
|
||||
300, 'do_announce', initial_sleep=5)
|
||||
|
||||
# Start a thread that runs every 1200 secs to
|
||||
# Ask peers for a subset for their peer set
|
||||
# The transport addresses for said peers will
|
||||
# be passed to a plugin event where the respective
|
||||
# transport plugin handles the new peer
|
||||
add_onionr_thread(
|
||||
get_new_peers,
|
||||
120, 'get_new_peers', initial_sleep=120)
|
||||
|
||||
# Start a new thread to stream blocks from peers
|
||||
# These blocks are being diffused and are stored in
|
||||
# the peer's block database
|
||||
add_onionr_thread(
|
||||
stream_from_peers,
|
||||
3, 'stream_from_peers', initial_sleep=10
|
||||
)
|
||||
|
||||
# Start a thread to upload blocks, useful for when
|
||||
# connectivity is poor or we are not allowing incoming
|
||||
# connections on any transports
|
||||
|
||||
add_onionr_thread(
|
||||
stream_to_peer,
|
||||
10, 'stream_to_peer', initial_sleep=1)
|
||||
|
||||
# Blocks we receive or create through all means except
|
||||
# Diffusal are put into block queues, we decide to either
|
||||
# stem or diffuse a block from the queue based on the current
|
||||
# dandelion++ phase
|
||||
while True:
|
||||
block_queue_processing()
|
@ -1,54 +0,0 @@
|
||||
from time import sleep
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .. import Peer
|
||||
|
||||
from logger import log as logging
|
||||
import onionrplugins
|
||||
|
||||
from ..commands import GossipCommands, command_to_byte
|
||||
from ..peerset import gossip_peer_set
|
||||
|
||||
|
||||
def do_announce():
|
||||
"Announce with N peers of each identified transport"
|
||||
per_transport = 4
|
||||
peer_types = {}
|
||||
count_for_peer = 0
|
||||
|
||||
def _announce(announce_peer: 'Peer', our_transport_address: str):
|
||||
assert our_transport_address
|
||||
try:
|
||||
our_transport_address = our_transport_address.encode('utf-8') + b"\n"
|
||||
except AttributeError:
|
||||
our_transport_address = our_transport_address + b'\n'
|
||||
sock = announce_peer.get_socket(40)
|
||||
sock.sendall(command_to_byte(GossipCommands.ANNOUNCE))
|
||||
sock.sendall(our_transport_address)
|
||||
if int.from_bytes(sock.recv(1), 'big') != 1:
|
||||
logging.warn(
|
||||
f"Could not announce with {announce_peer.transport_address}")
|
||||
sock.close()
|
||||
|
||||
while not len(gossip_peer_set):
|
||||
sleep(1)
|
||||
|
||||
for peer in gossip_peer_set:
|
||||
try:
|
||||
count_for_peer = peer_types[peer.__class__]
|
||||
except KeyError:
|
||||
count_for_peer = peer_types[peer.__class__] = 0
|
||||
|
||||
if count_for_peer == per_transport:
|
||||
continue
|
||||
|
||||
# Plugin for the transport associated with the peer will call _announce
|
||||
# with the peer and *our* transport address
|
||||
onionrplugins.events.event(
|
||||
'get_our_transport',
|
||||
data={'callback': _announce, 'peer': peer},
|
||||
threaded=True)
|
||||
|
||||
peer_types[peer.__class__] += 1
|
@ -1,161 +0,0 @@
|
||||
from collections import deque
|
||||
from queue import Empty, Queue
|
||||
from time import sleep
|
||||
from secrets import choice
|
||||
import traceback
|
||||
|
||||
from typing import TYPE_CHECKING, Coroutine, List
|
||||
|
||||
from ordered_set import OrderedSet
|
||||
|
||||
import config
|
||||
from onionrthreads import add_delayed_thread
|
||||
from blockdb import add_block_to_db
|
||||
from logger import log as logging
|
||||
|
||||
from ...constants import BLACKHOLE_EVADE_TIMER_SECS, OUTBOUND_DANDELION_EDGES
|
||||
from ...commands import GossipCommands, command_to_byte
|
||||
from ... import dandelion
|
||||
from ...blockqueues import gossip_block_queues
|
||||
from ...peerset import gossip_peer_set
|
||||
|
||||
from .stemstream import do_stem_stream
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ...peer import Peer
|
||||
from ...dandelion.phase import DandelionPhase
|
||||
import socket
|
||||
|
||||
|
||||
class NotEnoughEdges(ValueError): pass # noqa
|
||||
class StemConnectionDenied(ConnectionRefusedError): pass # noqa
|
||||
|
||||
|
||||
async def _setup_edge(
|
||||
peer_set: "OrderedSet[Peer]", exclude_set: "OrderedSet[Peer]"):
|
||||
"""Negotiate stem connection with random peer, add to exclu set if fail"""
|
||||
try:
|
||||
peer: 'Peer' = choice(peer_set - exclude_set)
|
||||
except IndexError:
|
||||
raise NotEnoughEdges
|
||||
|
||||
# If peer is good or bad, exclude it no matter what
|
||||
exclude_set.add(peer)
|
||||
|
||||
try:
|
||||
s = peer.get_socket(12)
|
||||
except TimeoutError:
|
||||
logging.debug(f"{peer.transport_address} timed out when trying stemout")
|
||||
except Exception:
|
||||
logging.debug(traceback.format_exc())
|
||||
return
|
||||
|
||||
try:
|
||||
s.sendall(command_to_byte(GossipCommands.PUT_BLOCKS))
|
||||
s.settimeout(10)
|
||||
if s.recv(1) == dandelion.StemAcceptResult.DENY:
|
||||
raise StemConnectionDenied
|
||||
except TimeoutError:
|
||||
logging.debug(
|
||||
"Peer timed out when establishing stem connection")
|
||||
logging.debug(traceback.format_exc())
|
||||
except StemConnectionDenied:
|
||||
logging.debug(
|
||||
"Stem connection denied (peer has too many) " +
|
||||
f"{peer.transport_address}")
|
||||
logging.debug(traceback.format_exc())
|
||||
except Exception:
|
||||
logging.warn(
|
||||
"Error asking peer to establish stem connection" +
|
||||
traceback.format_exc())
|
||||
else:
|
||||
# Return peer socket if it is in stem reception mode successfully
|
||||
return s
|
||||
|
||||
# If they won't accept stem blocks, close the socket
|
||||
s.close()
|
||||
|
||||
|
||||
async def stem_out(d_phase: 'DandelionPhase'):
|
||||
|
||||
# don't bother if there are no possible outbound edges
|
||||
if not len(gossip_peer_set):
|
||||
sleep(1)
|
||||
return
|
||||
not_enough_edges = False
|
||||
strict_dandelion = config.get('security.dandelion.strict', True)
|
||||
|
||||
def blackhole_protection(q):
|
||||
for bl in q:
|
||||
add_block_to_db(bl)
|
||||
|
||||
|
||||
# Spawn threads with deep copied block queue to add to db after time
|
||||
# for black hole attack
|
||||
for block_q in gossip_block_queues:
|
||||
add_delayed_thread(blackhole_protection, BLACKHOLE_EVADE_TIMER_SECS, block_q.queue)
|
||||
|
||||
peer_sockets: List['socket.socket'] = []
|
||||
stream_routines: List[Coroutine] = []
|
||||
|
||||
# Pick edges randomly
|
||||
# Using orderedset for the tried edges to ensure random pairing with queue
|
||||
tried_edges: "OrderedSet[Peer]" = OrderedSet()
|
||||
|
||||
while len(peer_sockets) < OUTBOUND_DANDELION_EDGES or not_enough_edges:
|
||||
if gossip_block_queues[0].qsize() == 0 and \
|
||||
gossip_block_queues[1].qsize() == 0:
|
||||
sleep(1)
|
||||
continue
|
||||
try:
|
||||
# Get a socket for stem out (makes sure they accept)
|
||||
peer_sockets.append(
|
||||
await _setup_edge(gossip_peer_set, tried_edges))
|
||||
except NotEnoughEdges:
|
||||
# No possible edges at this point (edges < OUTBOUND_DANDELION_EDGE)
|
||||
#logging.debug(
|
||||
# "Making too few edges for stemout " +
|
||||
# "this is bad for anonymity if frequent.",
|
||||
# )
|
||||
if strict_dandelion:
|
||||
not_enough_edges = True
|
||||
else:
|
||||
if peer_sockets:
|
||||
# if we have at least 1 peer,
|
||||
# do dandelion anyway in non strict mode
|
||||
# Allow poorly connected networks to communicate faster
|
||||
for block in gossip_block_queues[1].queue:
|
||||
gossip_block_queues[0].put_nowait(block)
|
||||
else:
|
||||
gossip_block_queues[1].queue = deque()
|
||||
break
|
||||
sleep(1)
|
||||
else:
|
||||
# Ran out of time for stem phase
|
||||
if not d_phase.is_stem_phase() or d_phase.remaining_time() < 5:
|
||||
logging.error(
|
||||
"Did not stem out any blocks in time, " +
|
||||
"if this happens regularly you may be under attack",
|
||||
)
|
||||
for s in peer_sockets:
|
||||
if s:
|
||||
s.close()
|
||||
peer_sockets.clear()
|
||||
break
|
||||
# If above loop ran out of time or NotEnoughEdges,
|
||||
# loops below will not execute
|
||||
|
||||
for count, peer_socket in enumerate(peer_sockets):
|
||||
stream_routines.append(
|
||||
do_stem_stream(peer_socket, gossip_block_queues[count], d_phase))
|
||||
|
||||
for routine in stream_routines:
|
||||
try:
|
||||
await routine
|
||||
except Empty:
|
||||
pass
|
||||
except Exception:
|
||||
logging.warn(traceback.format_exc())
|
||||
else:
|
||||
# stream routine exited early
|
||||
pass
|
@ -1,52 +0,0 @@
|
||||
from asyncio import sleep
|
||||
from threading import Thread
|
||||
from queue import Empty
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from logger import log as logging
|
||||
from ...constants import BLOCK_ID_SIZE, BLOCK_MAX_SIZE, BLOCK_SIZE_LEN
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from queue import Queue
|
||||
import socket
|
||||
from ...dandelion import DandelionPhase
|
||||
|
||||
from onionrblocks import Block
|
||||
|
||||
|
||||
async def do_stem_stream(
|
||||
peer_socket: 'socket.socket',
|
||||
block_queue: "Queue[Block]",
|
||||
d_phase: 'DandelionPhase'):
|
||||
remaining_time = d_phase.remaining_time()
|
||||
my_phase_id = d_phase.phase_id
|
||||
|
||||
|
||||
while remaining_time > 1 and my_phase_id == d_phase.phase_id:
|
||||
# Primary client component that communicate's with gossip.server.acceptstem
|
||||
remaining_time = d_phase.remaining_time()
|
||||
while remaining_time:
|
||||
try:
|
||||
# queues can't block because we're in async
|
||||
bl = block_queue.get(block=False)
|
||||
except Empty:
|
||||
remaining_time = d_phase.remaining_time()
|
||||
await sleep(1)
|
||||
else:
|
||||
break
|
||||
logging.info("Sending block over dandelion++")
|
||||
|
||||
block_size = str(len(bl.raw)).zfill(BLOCK_SIZE_LEN)
|
||||
def _send_it():
|
||||
try:
|
||||
with peer_socket:
|
||||
try:
|
||||
peer_socket.sendall(bl.id.zfill(BLOCK_ID_SIZE).encode('utf-8'))
|
||||
except AttributeError:
|
||||
peer_socket.sendall(bl.id.zfill(BLOCK_ID_SIZE))
|
||||
peer_socket.sendall(block_size.encode('utf-8'))
|
||||
peer_socket.sendall(bl.raw)
|
||||
except OSError:
|
||||
pass
|
||||
Thread(target=_send_it, daemon=True, name="stemout block").start()
|
@ -1,85 +0,0 @@
|
||||
from threading import Thread
|
||||
from time import sleep
|
||||
from traceback import format_exc
|
||||
from typing import TYPE_CHECKING
|
||||
if TYPE_CHECKING:
|
||||
from socket import socket
|
||||
|
||||
from onionrplugins import onionrevents
|
||||
from logger import log as logging
|
||||
|
||||
from ..peer import Peer
|
||||
from ..commands import GossipCommands, command_to_byte
|
||||
from ..constants import PEER_AMOUNT_TO_ASK, TRANSPORT_SIZE_BYTES
|
||||
from .. import connectpeer
|
||||
from ..peerset import gossip_peer_set
|
||||
|
||||
MAX_PEERS = 10
|
||||
|
||||
|
||||
def _do_ask_peer(peer):
|
||||
try:
|
||||
_ask_peer(peer)
|
||||
except TimeoutError:
|
||||
logging.debug("Timed out when asking for new peers")
|
||||
except Exception:
|
||||
logging.error(format_exc())
|
||||
|
||||
def _ask_peer(peer):
|
||||
s: 'socket' = peer.get_socket(12)
|
||||
|
||||
s.sendall(command_to_byte(GossipCommands.PEER_EXCHANGE))
|
||||
# Get 10 max peers
|
||||
for _ in range(MAX_PEERS):
|
||||
peer = b''
|
||||
c = b''
|
||||
while c != b'\n':
|
||||
if len(peer) > TRANSPORT_SIZE_BYTES:
|
||||
raise OverflowError
|
||||
c = s.recv(1)
|
||||
peer += c
|
||||
if not peer:
|
||||
break
|
||||
connect_data = {
|
||||
'address': peer,
|
||||
'callback': connectpeer.connect_peer
|
||||
}
|
||||
#logging.info("Got new peer from exchange " + peer.decode('utf-8'))
|
||||
onionrevents.event('announce_rec', data=connect_data, threaded=True)
|
||||
s.close()
|
||||
|
||||
|
||||
def get_new_peers():
|
||||
if not len(gossip_peer_set):
|
||||
logging.debug("Peer set empty, cannot get new peers")
|
||||
return
|
||||
|
||||
# Deep copy the peer list
|
||||
peer_list: Peer = list(gossip_peer_set)
|
||||
peers_we_ask: Peer = []
|
||||
asked_count = 0
|
||||
|
||||
while asked_count < PEER_AMOUNT_TO_ASK:
|
||||
try:
|
||||
peers_we_ask.append(peer_list.pop())
|
||||
except IndexError:
|
||||
break
|
||||
asked_count += 1
|
||||
|
||||
if not len(peers_we_ask):
|
||||
raise ValueError("No peers present in pool during get_new_peers")
|
||||
peer_list.clear() # Clear the deep copy so it doesn't occupy memory
|
||||
|
||||
# Start threads to ask the peers for more peers
|
||||
threads = []
|
||||
for peer in peers_we_ask:
|
||||
t = Thread(
|
||||
target=_do_ask_peer,
|
||||
args=[peer], daemon=True, name='_do_ask_peer')
|
||||
t.start()
|
||||
threads.append(t)
|
||||
peers_we_ask.clear()
|
||||
# Wait for the threads to finish because this function is on a timer
|
||||
for thread in threads:
|
||||
thread.join()
|
||||
|
@ -1,41 +0,0 @@
|
||||
from typing import TYPE_CHECKING, Tuple
|
||||
from threading import Thread
|
||||
from queue import Queue
|
||||
from queue import Empty
|
||||
|
||||
from onionrplugins.onionrevents import event
|
||||
import blockdb
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from onionrblocks import Block
|
||||
from ..dandelion.phase import DandelionPhase
|
||||
|
||||
from ..blockqueues import gossip_block_queues
|
||||
|
||||
|
||||
def store_blocks(dandelion_phase: 'DandelionPhase'):
|
||||
|
||||
new_queue: "Queue[Block]" = Queue()
|
||||
|
||||
def _watch_queue(block_queue: "Queue[Block]"):
|
||||
# Copy all incoming blocks into 1 queue which gets processed to db
|
||||
while not dandelion_phase.is_stem_phase() \
|
||||
and dandelion_phase.remaining_time() > 1:
|
||||
try:
|
||||
new_queue.put(
|
||||
block_queue.get(timeout=dandelion_phase.remaining_time()))
|
||||
except Empty:
|
||||
pass
|
||||
|
||||
for block_queue in gossip_block_queues:
|
||||
Thread(target=_watch_queue, args=[block_queue], daemon=True).start()
|
||||
|
||||
while not dandelion_phase.is_stem_phase() \
|
||||
and dandelion_phase.remaining_time() > 1:
|
||||
try:
|
||||
bl = new_queue.get(timeout=dandelion_phase.remaining_time() + 1)
|
||||
blockdb.add_block_to_db(bl)
|
||||
event('gotblock', data=bl, threaded=True)
|
||||
event(f'gotblock{bl.type}', data=bl, threaded=True)
|
||||
except Empty:
|
||||
pass
|
@ -1,2 +0,0 @@
|
||||
from .streamfrom import stream_from_peers
|
||||
from .streamto import stream_to_peer
|
@ -1,161 +0,0 @@
|
||||
"""Onionr - Private P2P Communication.
|
||||
|
||||
Download blocks that are being diffused
|
||||
|
||||
doesn't apply for blocks in the gossip queue that are awaiting
|
||||
descision to fluff or stem
|
||||
"""
|
||||
from ast import Index
|
||||
from threading import Thread, Semaphore
|
||||
from random import SystemRandom
|
||||
from time import sleep
|
||||
import traceback
|
||||
from typing import TYPE_CHECKING, List
|
||||
|
||||
import blockdb
|
||||
|
||||
from ...constants import BLOCK_ID_SIZE, BLOCK_MAX_SIZE, BLOCK_SIZE_LEN, BLOCK_STREAM_OFFSET_DIGITS
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from socket import socket
|
||||
from gossip.peer import Peer
|
||||
|
||||
from ordered_set import OrderedSet
|
||||
|
||||
from logger import log as logging
|
||||
|
||||
import onionrblocks
|
||||
from ...peerset import gossip_peer_set
|
||||
from ...commands import GossipCommands, command_to_byte
|
||||
|
||||
"""
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
|
||||
MAX_STREAMS = 6
|
||||
CONNECT_TIMEOUT = 45
|
||||
MAX_TRIED_PEERS = 10_000
|
||||
|
||||
|
||||
def stream_from_peers():
|
||||
# Pick N peers to stream from
|
||||
# Create sockets for them
|
||||
# Spawn thread to stream from the socket
|
||||
|
||||
tried_peers: OrderedSet['Peer'] = OrderedSet()
|
||||
|
||||
sys_rand = SystemRandom()
|
||||
|
||||
need_socket_lock = Semaphore(MAX_STREAMS)
|
||||
offset = 0
|
||||
|
||||
|
||||
def _stream_from_peer(peer: 'Peer'):
|
||||
stream_counter = 0
|
||||
stream_times = 100
|
||||
try:
|
||||
sock = peer.get_socket(CONNECT_TIMEOUT)
|
||||
except (TimeoutError, ConnectionRefusedError) as _:
|
||||
need_socket_lock.release()
|
||||
return
|
||||
except Exception:
|
||||
logging.warn(traceback.format_exc())
|
||||
need_socket_lock.release()
|
||||
return
|
||||
try:
|
||||
sock.sendall(
|
||||
command_to_byte(GossipCommands.STREAM_BLOCKS)
|
||||
)
|
||||
sock.sendall(
|
||||
str(offset).zfill(BLOCK_STREAM_OFFSET_DIGITS).encode('utf-8'))
|
||||
|
||||
while stream_times >= stream_counter:
|
||||
stream_counter += 1
|
||||
#logging.debug("Reading block of id in stream with " + peer.transport_address)
|
||||
sock.settimeout(5)
|
||||
block_id = sock.recv(BLOCK_ID_SIZE)
|
||||
if blockdb.has_block(block_id):
|
||||
sock.sendall(int(0).to_bytes(1, 'big'))
|
||||
continue
|
||||
sock.sendall(int(1).to_bytes(1, 'big'))
|
||||
|
||||
#logging.debug("Reading block size in stream")
|
||||
|
||||
sock.settimeout(5)
|
||||
block_size = int(sock.recv(BLOCK_SIZE_LEN))
|
||||
if block_size > BLOCK_MAX_SIZE or block_size <= 0:
|
||||
logging.warn(
|
||||
f"Peer {peer.transport_address} " +
|
||||
"reported block size out of range")
|
||||
break
|
||||
|
||||
sock.settimeout(5)
|
||||
block_data = sock.recv(block_size)
|
||||
|
||||
#logging.debug(
|
||||
# "We got a block from stream, assuming it is valid",
|
||||
# )
|
||||
try:
|
||||
blockdb.add_block_to_db(
|
||||
onionrblocks.Block(
|
||||
block_id, block_data, auto_verify=True))
|
||||
except Exception:
|
||||
# They gave us a bad block, kill the stream
|
||||
# Could be corruption or malice
|
||||
sock.sendall(int(0).to_bytes(1, 'big'))
|
||||
raise
|
||||
# Tell them to keep streaming
|
||||
sock.sendall(int(1).to_bytes(1, 'big'))
|
||||
except (BrokenPipeError, TimeoutError, ConnectionError) as e:
|
||||
pass
|
||||
#logging.debug(f"{e} when streaming from peers")
|
||||
#logging.debug(traceback.format_exc())
|
||||
except Exception:
|
||||
logging.warn(traceback.format_exc())
|
||||
finally:
|
||||
sock.close()
|
||||
need_socket_lock.release()
|
||||
|
||||
# spawn stream threads infinitely
|
||||
while True:
|
||||
if not gossip_peer_set:
|
||||
sleep(2)
|
||||
available_set = gossip_peer_set - tried_peers
|
||||
if not len(available_set) and len(tried_peers):
|
||||
try:
|
||||
tried_peers.clear()
|
||||
except IndexError:
|
||||
pass
|
||||
available_set = gossip_peer_set.copy()
|
||||
peers = sys_rand.sample(
|
||||
available_set,
|
||||
min(MAX_STREAMS, len(available_set)))
|
||||
|
||||
tried_peers.update(peers)
|
||||
if len(tried_peers) >= MAX_TRIED_PEERS:
|
||||
tried_peers.pop()
|
||||
|
||||
while len(peers):
|
||||
try:
|
||||
need_socket_lock.acquire()
|
||||
Thread(
|
||||
target=_stream_from_peer,
|
||||
args=[peers.pop()],
|
||||
daemon=True,
|
||||
name="_stream_from_peer").start()
|
||||
except IndexError:
|
||||
need_socket_lock.release()
|
||||
break
|
||||
|
@ -1,58 +0,0 @@
|
||||
from secrets import SystemRandom
|
||||
from time import time
|
||||
from typing import List, TYPE_CHECKING
|
||||
|
||||
#if TYPE_CHECKING:
|
||||
from onionrblocks import Block
|
||||
|
||||
from gossip.commands import GossipCommands, command_to_byte
|
||||
from blockdb import get_blocks_after_timestamp
|
||||
from ...constants import BLOCK_ID_SIZE, BLOCK_SIZE_LEN
|
||||
|
||||
from ...peerset import gossip_peer_set
|
||||
from ...server import lastincoming
|
||||
|
||||
SECS_ELAPSED_NO_INCOMING_BEFORE_STREAM = 3
|
||||
|
||||
class SendTimestamp:
|
||||
timestamp: int = 0
|
||||
|
||||
def stream_to_peer():
|
||||
if SECS_ELAPSED_NO_INCOMING_BEFORE_STREAM > time() - lastincoming.last_incoming_timestamp:
|
||||
SendTimestamp.timestamp = int(time()) - 60
|
||||
return
|
||||
if not len(gossip_peer_set):
|
||||
return
|
||||
rand = SystemRandom()
|
||||
peer = rand.choice(gossip_peer_set)
|
||||
buffer: List['Block'] = []
|
||||
|
||||
def _do_upload():
|
||||
print('uploading to', peer.transport_address)
|
||||
with peer.get_socket(30) as p:
|
||||
p.sendall(command_to_byte(GossipCommands.PUT_BLOCK_DIFFUSE))
|
||||
|
||||
while len(buffer):
|
||||
try:
|
||||
block = buffer.pop()
|
||||
except IndexError:
|
||||
break
|
||||
p.sendall(block.id.zfill(BLOCK_ID_SIZE))
|
||||
if int.from_bytes(p.recv(1), 'big') == 0:
|
||||
continue
|
||||
block_size = str(len(block.raw)).zfill(BLOCK_SIZE_LEN)
|
||||
p.sendall(block_size.encode('utf-8'))
|
||||
p.sendall(block.raw)
|
||||
|
||||
# Buffer some blocks so we're not streaming too many to one peer
|
||||
# and to efficiently avoid connecting without sending anything
|
||||
buffer_max = 10
|
||||
for block in get_blocks_after_timestamp(SendTimestamp.timestamp):
|
||||
assert isinstance(block, Block)
|
||||
buffer.append(block)
|
||||
if len(buffer) > buffer_max:
|
||||
_do_upload(buffer)
|
||||
if len(buffer):
|
||||
_do_upload()
|
||||
|
||||
SendTimestamp.timestamp = int(time()) - 60
|
@ -1,13 +0,0 @@
|
||||
from enum import IntEnum, auto
|
||||
|
||||
class GossipCommands(IntEnum):
|
||||
PING = 1
|
||||
ANNOUNCE = auto()
|
||||
PEER_EXCHANGE = auto()
|
||||
STREAM_BLOCKS = auto()
|
||||
PUT_BLOCKS = auto()
|
||||
PUT_BLOCK_DIFFUSE = auto()
|
||||
|
||||
|
||||
def command_to_byte(cmd: GossipCommands):
|
||||
return int(cmd).to_bytes(1, 'big')
|
@ -1,22 +0,0 @@
|
||||
import traceback
|
||||
from gossip.commands import GossipCommands, command_to_byte
|
||||
from .peerset import gossip_peer_set
|
||||
|
||||
from logger import log as logging
|
||||
|
||||
|
||||
def connect_peer(peer):
|
||||
if peer in gossip_peer_set:
|
||||
return
|
||||
try:
|
||||
s = peer.get_socket(120)
|
||||
except Exception:
|
||||
logging.warn(f"Could not connect to {peer.transport_address}")
|
||||
logging.warn(traceback.format_exc())
|
||||
else:
|
||||
with s:
|
||||
s.sendall(command_to_byte(GossipCommands.PING))
|
||||
|
||||
if s.recv(4).decode('utf-8') == 'PONG':
|
||||
gossip_peer_set.add(peer)
|
||||
logging.info(f"connected to {peer.transport_address}")
|
@ -1,17 +0,0 @@
|
||||
BOOTSTRAP_ATTEMPTS = 5
|
||||
PEER_AMOUNT_TO_ASK = 3
|
||||
TRANSPORT_SIZE_BYTES = 64
|
||||
BLOCK_MAX_SIZE = 1024 * 2000
|
||||
BLOCK_SIZE_LEN = len(str(BLOCK_MAX_SIZE))
|
||||
BLOCK_ID_SIZE = 128
|
||||
BLOCK_STREAM_OFFSET_DIGITS = 8
|
||||
DANDELION_EPOCH_LENGTH = 60
|
||||
|
||||
# Magic number i made up, not really specified in dandelion++ paper
|
||||
MAX_INBOUND_DANDELION_EDGE = 50 # Mainly picked to avoid slowloris
|
||||
|
||||
# Dandelion subgraph is aprox 4-regular
|
||||
OUTBOUND_DANDELION_EDGES = 2
|
||||
|
||||
MAX_STEM_BLOCKS_PER_STREAM = 1000
|
||||
BLACKHOLE_EVADE_TIMER_SECS = 10
|
@ -1,7 +0,0 @@
|
||||
from enum import Enum
|
||||
|
||||
from .phase import DandelionPhase
|
||||
|
||||
class StemAcceptResult:
|
||||
DENY = int(0).to_bytes(1, 'big')
|
||||
ALLOW = int(1).to_bytes(1, 'big')
|
@ -1,43 +0,0 @@
|
||||
from time import time
|
||||
from hashlib import shake_128
|
||||
from secrets import randbits
|
||||
import secrets
|
||||
|
||||
seed = secrets.token_bytes(32)
|
||||
|
||||
|
||||
class DandelionPhase:
|
||||
def __init__(self, epoch_interval_secs: int):
|
||||
assert len(seed) == 32
|
||||
self.epoch = int(time())
|
||||
self.epoch_interval = epoch_interval_secs
|
||||
self._is_stem = bool(randbits(1))
|
||||
self.phase_id = b''
|
||||
|
||||
|
||||
def _update_stem_phase(self, cur_time):
|
||||
self.epoch = cur_time
|
||||
# Hash the seed with the time stamp to produce 8 pseudorandom bytes
|
||||
# Produce an len(8) byte string for time as well for year 2038 problem
|
||||
self.phase_id = shake_128(
|
||||
seed +
|
||||
int.to_bytes(cur_time, 8, 'big')).digest(8)
|
||||
|
||||
# Use first byte of phase id as random source for stem phase picking
|
||||
if self.phase_id[0] % 2:
|
||||
self._is_stem = True
|
||||
else:
|
||||
self._is_stem = False
|
||||
|
||||
|
||||
def remaining_time(self) -> int:
|
||||
current_time = int(time())
|
||||
|
||||
return max(0, self.epoch_interval - (current_time - self.epoch))
|
||||
|
||||
|
||||
def is_stem_phase(self) -> bool:
|
||||
current_time = int(time())
|
||||
if current_time - self.epoch >= self.epoch_interval:
|
||||
self._update_stem_phase(current_time)
|
||||
return self._is_stem
|
@ -1,22 +0,0 @@
|
||||
from typing import TYPE_CHECKING, Protocol
|
||||
if TYPE_CHECKING:
|
||||
import socket
|
||||
|
||||
|
||||
class Peer(Protocol):
|
||||
transport_address = ""
|
||||
|
||||
def __init__(self):
|
||||
return
|
||||
def get_socket(self, connect_timeout) -> 'socket.socket':
|
||||
return
|
||||
|
||||
def disconnect(self):
|
||||
return
|
||||
|
||||
def __eq__(self, other):
|
||||
return
|
||||
|
||||
def __hash__(self):
|
||||
"""Use the transport address"""
|
||||
return
|
@ -1,149 +0,0 @@
|
||||
import asyncio
|
||||
import traceback
|
||||
from time import time
|
||||
from typing import TYPE_CHECKING
|
||||
from typing import Set, Tuple
|
||||
|
||||
from threading import Thread
|
||||
|
||||
from onionrblocks import Block
|
||||
|
||||
from gossip import constants
|
||||
from ..connectpeer import connect_peer
|
||||
|
||||
from onionrplugins import onionrevents
|
||||
from logger import log as logging
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from onionrblocks import Block
|
||||
from peer import Peer
|
||||
from ordered_set import OrderedSet
|
||||
from asyncio import StreamReader, StreamWriter
|
||||
|
||||
from filepaths import gossip_server_socket_file
|
||||
import blockdb
|
||||
from blockdb import add_block_to_db
|
||||
from ..commands import GossipCommands
|
||||
from ..peerset import gossip_peer_set
|
||||
from .acceptstem import accept_stem_blocks
|
||||
from .diffuseblocks import diffuse_blocks
|
||||
from .import lastincoming
|
||||
"""
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
inbound_dandelion_edge_count = [0]
|
||||
|
||||
|
||||
def gossip_server():
|
||||
|
||||
async def peer_connected(
|
||||
reader: 'StreamReader', writer: 'StreamWriter'):
|
||||
|
||||
while True:
|
||||
try:
|
||||
cmd = await asyncio.wait_for(reader.readexactly(1), 60)
|
||||
except asyncio.exceptions.CancelledError:
|
||||
break
|
||||
except asyncio.IncompleteReadError:
|
||||
break
|
||||
lastincoming.last_incoming_timestamp = int(time())
|
||||
|
||||
cmd = int.from_bytes(cmd, 'big')
|
||||
if cmd == b'' or cmd == 0:
|
||||
continue
|
||||
match GossipCommands(cmd):
|
||||
case GossipCommands.PING:
|
||||
writer.write(b'PONG')
|
||||
case GossipCommands.ANNOUNCE:
|
||||
async def _read_announce():
|
||||
address = await reader.readuntil(b'\n')
|
||||
|
||||
if address:
|
||||
onionrevents.event(
|
||||
'announce_rec',
|
||||
data={'address': address,
|
||||
'callback': connect_peer},
|
||||
threaded=True)
|
||||
writer.write(int(1).to_bytes(1, 'big'))
|
||||
await writer.drain()
|
||||
await asyncio.wait_for(_read_announce(), 30)
|
||||
case GossipCommands.PEER_EXCHANGE:
|
||||
|
||||
for peer in gossip_peer_set:
|
||||
writer.write(peer.transport_address.encode('utf-8') + b'\n')
|
||||
await writer.drain()
|
||||
case GossipCommands.STREAM_BLOCKS:
|
||||
try:
|
||||
await diffuse_blocks(reader, writer)
|
||||
except Exception:
|
||||
logging.warn(
|
||||
f"Err streaming blocks\n{traceback.format_exc()}",
|
||||
)
|
||||
case GossipCommands.PUT_BLOCKS:
|
||||
# Pick block queue & append stemmed blocks to it
|
||||
try:
|
||||
await accept_stem_blocks(
|
||||
reader, writer,
|
||||
inbound_dandelion_edge_count)
|
||||
except asyncio.exceptions.TimeoutError:
|
||||
pass
|
||||
logging.debug(
|
||||
"Inbound edge timed out when steming blocks to us",
|
||||
)
|
||||
except asyncio.exceptions.IncompleteReadError:
|
||||
pass
|
||||
logging.debug(
|
||||
"Inbound edge timed out (Incomplete Read) when steming blocks to us",
|
||||
)
|
||||
except Exception:
|
||||
logging.warn(
|
||||
f"Err accepting stem blocks\n{traceback.format_exc()}",
|
||||
)
|
||||
# Subtract dandelion edge, make sure >=0
|
||||
inbound_dandelion_edge_count[0] = \
|
||||
max(inbound_dandelion_edge_count[0] - 1, 0)
|
||||
case GossipCommands.PUT_BLOCK_DIFFUSE:
|
||||
async def _get_block_diffused():
|
||||
block_id = await reader.readexactly(constants.BLOCK_ID_SIZE)
|
||||
if blockdb.has_block(block_id):
|
||||
writer.write(int(0).to_bytes(1, 'big'))
|
||||
else:
|
||||
writer.write(int(1).to_bytes(1, 'big'))
|
||||
await writer.drain()
|
||||
block_size = int(await asyncio.wait_for(reader.readexactly(constants.BLOCK_SIZE_LEN), 30))
|
||||
block_data = await reader.readexactly(block_size)
|
||||
|
||||
Thread(
|
||||
target=add_block_to_db,
|
||||
args=[
|
||||
Block(block_id, block_data, auto_verify=True)]
|
||||
).start()
|
||||
await _get_block_diffused()
|
||||
break
|
||||
try:
|
||||
await writer.drain()
|
||||
except BrokenPipeError:
|
||||
pass
|
||||
writer.close()
|
||||
|
||||
async def main():
|
||||
|
||||
server = await asyncio.start_unix_server(
|
||||
peer_connected, gossip_server_socket_file
|
||||
)
|
||||
async with server:
|
||||
await server.serve_forever()
|
||||
|
||||
asyncio.run(main())
|
@ -1,80 +0,0 @@
|
||||
import traceback
|
||||
from typing import TYPE_CHECKING
|
||||
from typing import List
|
||||
import secrets
|
||||
from asyncio import wait_for
|
||||
|
||||
from onionrblocks import Block
|
||||
|
||||
from logger import log as logging
|
||||
from ..dandelion import StemAcceptResult
|
||||
from ..constants import BLOCK_ID_SIZE, BLOCK_SIZE_LEN, BLOCK_MAX_SIZE
|
||||
from ..constants import MAX_INBOUND_DANDELION_EDGE, MAX_STEM_BLOCKS_PER_STREAM
|
||||
from ..blockqueues import gossip_block_queues
|
||||
|
||||
|
||||
base_wait_timeout = 120
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from asyncio import StreamWriter, StreamReader
|
||||
|
||||
|
||||
async def accept_stem_blocks(
|
||||
reader: 'StreamReader',
|
||||
writer: 'StreamWriter',
|
||||
inbound_edge_count: List[int]):
|
||||
|
||||
if inbound_edge_count[0] >= MAX_INBOUND_DANDELION_EDGE:
|
||||
writer.write(StemAcceptResult.DENY)
|
||||
return
|
||||
writer.write(StemAcceptResult.ALLOW)
|
||||
await writer.drain()
|
||||
inbound_edge_count[0] += 1
|
||||
|
||||
|
||||
block_queue_to_use = secrets.choice(gossip_block_queues)
|
||||
|
||||
for _ in range(MAX_STEM_BLOCKS_PER_STREAM):
|
||||
read_routine = reader.readexactly(BLOCK_ID_SIZE)
|
||||
#logging.debug(f"Reading block id in stem server")
|
||||
block_id = await wait_for(read_routine, base_wait_timeout)
|
||||
block_id = block_id.decode('utf-8')
|
||||
if not block_id:
|
||||
break
|
||||
|
||||
#logging.debug(f"Reading block size in stem server")
|
||||
block_size = (await wait_for(
|
||||
reader.readexactly(BLOCK_SIZE_LEN),
|
||||
base_wait_timeout)).decode('utf-8')
|
||||
if not block_size:
|
||||
break
|
||||
|
||||
if not all(c in "0123456789" for c in block_size):
|
||||
raise ValueError("Invalid block size data (non 0-9 char)")
|
||||
block_size = int(block_size)
|
||||
if block_size > BLOCK_MAX_SIZE:
|
||||
raise ValueError("Max block size")
|
||||
|
||||
#logging.debug(f"Reading block of size {block_size} in stem server")
|
||||
|
||||
raw_block: bytes = await wait_for(
|
||||
reader.readexactly(block_size), base_wait_timeout * 6)
|
||||
if not raw_block:
|
||||
break
|
||||
|
||||
try:
|
||||
bl = Block(block_id, raw_block, auto_verify=True)
|
||||
except Exception as e:
|
||||
logging.warn(
|
||||
f"Error in received stem block {block_id} {str(e)}")
|
||||
logging.debug(traceback.format_exc())
|
||||
break
|
||||
|
||||
|
||||
logging.debug("Got a stem block, put into queue")
|
||||
|
||||
block_queue_to_use.put(bl)
|
||||
|
||||
# Regardless of stem phase, we add to queue
|
||||
# Client will decide if they are to be stemmed
|
||||
|
@ -1,107 +0,0 @@
|
||||
"""Onionr - Private P2P Communication.
|
||||
|
||||
Diffuse blocks we can for inbound edge peers that ask for them
|
||||
|
||||
doesn't apply for blocks in the gossip queue that are awaiting
|
||||
descision to fluff or stem
|
||||
|
||||
"""
|
||||
from asyncio import IncompleteReadError, wait_for, Queue, sleep
|
||||
|
||||
import traceback
|
||||
from typing import TYPE_CHECKING
|
||||
from time import time
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from asyncio import StreamWriter, StreamReader
|
||||
from onionrblocks import Block
|
||||
|
||||
from ..constants import BLOCK_MAX_SIZE, BLOCK_SIZE_LEN
|
||||
from ..constants import BLOCK_STREAM_OFFSET_DIGITS
|
||||
|
||||
from logger import log as logging
|
||||
import blockdb
|
||||
from blockdb import get_blocks_after_timestamp, block_storage_observers
|
||||
"""
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
|
||||
async def diffuse_blocks(reader: 'StreamReader', writer: 'StreamWriter'):
|
||||
"""stream blocks to a peer created since an offset
|
||||
"""
|
||||
time_offset = await wait_for(reader.readexactly(BLOCK_STREAM_OFFSET_DIGITS), 12)
|
||||
time_offset = time_offset.decode('utf-8')
|
||||
keep_writing = True
|
||||
|
||||
# Makes sure timestamp is positive and not weird
|
||||
if not all(c in "0123456789" for c in time_offset):
|
||||
raise ValueError("Invalid time offset")
|
||||
time_offset = int(time_offset)
|
||||
|
||||
if time_offset - time() > -5:
|
||||
raise ValueError(
|
||||
"Peer's specified time offset skewed too far into the future")
|
||||
|
||||
|
||||
|
||||
async def _send_block(block: 'Block'):
|
||||
writer.write(block.id)
|
||||
await writer.drain()
|
||||
|
||||
# we tell id above, they tell if they want the block
|
||||
if int.from_bytes(await reader.readexactly(1), 'big') == 0:
|
||||
return
|
||||
|
||||
# write block size
|
||||
writer.write(
|
||||
str(len(block.raw)).zfill(BLOCK_SIZE_LEN).encode('utf-8'))
|
||||
await writer.drain()
|
||||
writer.write(block.raw)
|
||||
await writer.drain()
|
||||
|
||||
try:
|
||||
# Send initial blocks from offset
|
||||
for block in get_blocks_after_timestamp(time_offset):
|
||||
if not keep_writing:
|
||||
break
|
||||
|
||||
await _send_block(block)
|
||||
|
||||
try:
|
||||
keep_writing = bool(
|
||||
int.from_bytes(await reader.readexactly(1), 'big')
|
||||
)
|
||||
except IncompleteReadError:
|
||||
keep_writing = False
|
||||
time_offset = time()
|
||||
|
||||
# Diffuse blocks stored since we started this stream
|
||||
while keep_writing:
|
||||
bls = blockdb.get_blocks_after_timestamp(time_offset)
|
||||
await sleep(1) # Must be here to avoid blocking the event loop
|
||||
for bl in bls:
|
||||
await _send_block(bl)
|
||||
try:
|
||||
keep_writing = bool(
|
||||
int.from_bytes(await reader.readexactly(1), 'big')
|
||||
)
|
||||
except IncompleteReadError:
|
||||
keep_writing = False
|
||||
break
|
||||
except ConnectionResetError:
|
||||
pass
|
||||
except Exception:
|
||||
logging.warn(traceback.format_exc())
|
||||
|
@ -1 +0,0 @@
|
||||
last_incoming_timestamp = 0
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user