Merge branch 'master' into codeql_fix

This commit is contained in:
caryoscelus 2023-07-20 03:34:54 +00:00
commit 45788d4749
23 changed files with 422 additions and 146 deletions

View file

@ -1,2 +1,3 @@
venv venv
Dockerfile* Dockerfile*
data

View file

@ -1,4 +1,46 @@
### zeronet-conservancy 0.7.7+ ### zeronet-conservancy 0.7.9+
- update merkletools dependency to avoid legacy pysha3 (@caryoscelus)
- fix ReDoS in file editor (UiFileManager plugin) due to outdated codemirror (@caryoscelus)
### zeronet-conservancy 0.7.9 (2023-07-02) (f966a4203fe33bd9f35)
maintainers: @caryoscelus -> none
- update README (build/dev instructions; thanks to @fgaz)
- better debugging of update non-propagation
- sec update of msgpck dependency (@chncaption)
- deprecate python-3.6 as it apparently is no longer used (by active users)
- improvement in imports and naming (@caryoscelus)
- siteSign accepts absolute paths as well as paths relative to working directory (@caryoscelus)
- updated trackers from Syncronite by @Styromaniac
- no longer officially maintained
### zeronet-conservancy 0.7.8.1 (2022-11-28) (0054eca9df0c9c8c2f4a78)
maintainers: @caryoscelus
- fix favourite/unfavourite in sidebar
- fix tracker connection regression introduced in dc804b9d5f3a2a9f1fffa1b97d82e0e04c44508b (thanks to @bitcoren)
- GiveUpGitHub notice
- update README
- new, more compact boot logo in console (more suitable for small screens)
### zeronet-conservancy 0.7.8 (2022-11-23) (110307a4198cb13cc907ae)
maintainers: @caryoscelus
- use archived version of .bit domain registry to avoid malicious rewrites
- readdress .bit domains as part of their deprecation
- remove potential vulnerability via setuptools (@ajesse11x)
- improve copying peers from sidebar
- reduce fingerprinting information available to unprivileged sites
- improve starting script
- fix default ssl version to be secure
- disable geoip-related ip address leak when in tor-only mode
- windows os build/running instruction (WIP)
- better command line parsing
- ArchLinux AUR package
- update android instruction (thanks oseido for reporting)
- better browser launch handling
- ability to add/remove from favourites from sidebar
- NoNewSites plugin
- show help message even when startup fails
- fix plugin options handling regression
- multiple code improvements
### zeronet-conservancy 0.7.7 (2022-07-27) (f40dbfeb2163b9902495ba) ### zeronet-conservancy 0.7.7 (2022-07-27) (f40dbfeb2163b9902495ba)
maintainers: @caryoscelus, @FraYoshi, @prtngn, @d47081 (ex @d4708) maintainers: @caryoscelus, @FraYoshi, @prtngn, @d47081 (ex @d4708)
@ -64,6 +106,7 @@ maintainers: @caryoscelus
### zeronet-conservancy 0.7.3 (2022-01-21) Rev5000 ### zeronet-conservancy 0.7.3 (2022-01-21) Rev5000
maintainers: @caryoscelus maintainers: @caryoscelus
- forked from the latest py3 branch of ZeroNet - forked from the latest py3 branch of ZeroNet
- fixed potential vulnerability discovered by @purplesyringa
- onion v3 support (thanks to @anonymoose, @zeroseed and @geekless) - onion v3 support (thanks to @anonymoose, @zeroseed and @geekless)
- partial readme rewrite (thanks to @mitya57) - partial readme rewrite (thanks to @mitya57)
- disable updating through zite (unsafe) - disable updating through zite (unsafe)
@ -152,7 +195,7 @@ maintainers: shortcutme a.k.a nofish a.k.a HelloZeroNet a.k.a Tamas Kocsis
- Link to site's sidebar with "#ZeroNet:OpenSidebar" hash - Link to site's sidebar with "#ZeroNet:OpenSidebar" hash
### Changed ### Changed
- Allow .. in file names [Thanks to imachug] - Allow .. in file names [Thanks to purplesyringa]
- Change unstable trackers - Change unstable trackers
- More clean errors on sites.json/users.json load error - More clean errors on sites.json/users.json load error
- Various tweaks for tracker rating on unstable connections - Various tweaks for tracker rating on unstable connections
@ -163,12 +206,12 @@ maintainers: shortcutme a.k.a nofish a.k.a HelloZeroNet a.k.a Tamas Kocsis
### Fixed ### Fixed
- Fix parsing config lines that have no value - Fix parsing config lines that have no value
- Fix start.py [Thanks to imachug] - Fix start.py [Thanks to purplesyringa]
- Allow multiple values of the same key in the config file [Thanks ssdifnskdjfnsdjk for reporting] - Allow multiple values of the same key in the config file [Thanks ssdifnskdjfnsdjk for reporting]
- Fix parsing config file lines that has % in the value [Thanks slrslr for reporting] - Fix parsing config file lines that has % in the value [Thanks slrslr for reporting]
- Fix bootstrapper plugin hash reloads [Thanks geekless for reporting] - Fix bootstrapper plugin hash reloads [Thanks geekless for reporting]
- Fix CryptMessage plugin OpenSSL dll loading on Windows (ZeroMail errors) [Thanks cxgreat2014 for reporting] - Fix CryptMessage plugin OpenSSL dll loading on Windows (ZeroMail errors) [Thanks cxgreat2014 for reporting]
- Fix startup error when using OpenSSL 1.1 [Thanks to imachug] - Fix startup error when using OpenSSL 1.1 [Thanks to purplesyringa]
- Fix a bug that did not loaded merged site data for 5 sec after the merged site got added - Fix a bug that did not loaded merged site data for 5 sec after the merged site got added
- Fix typo that allowed to add new plugins in public proxy mode. [Thanks styromaniac for reporting] - Fix typo that allowed to add new plugins in public proxy mode. [Thanks styromaniac for reporting]
- Fix loading non-big files with "|all" postfix [Thanks to krzotr] - Fix loading non-big files with "|all" postfix [Thanks to krzotr]
@ -191,10 +234,10 @@ Note: The fix is also back ported to ZeroNet Py 2.x version (Rev3870)
- Generated SSL certificate randomization to avoid protocol filters (Thanks to ValdikSS) - Generated SSL certificate randomization to avoid protocol filters (Thanks to ValdikSS)
- Offline mode - Offline mode
- P2P source code update using ZeroNet protocol - P2P source code update using ZeroNet protocol
- ecdsaSign/Verify commands to CryptMessage plugin (Thanks to imachug) - ecdsaSign/Verify commands to CryptMessage plugin (Thanks to purplesyringa)
- Efficient file rename: change file names instead of re-downloading the file. - Efficient file rename: change file names instead of re-downloading the file.
- Make redirect optional on site cloning (Thanks to Lola) - Make redirect optional on site cloning (Thanks to Lola)
- EccPrivToPub / EccPubToPriv functions (Thanks to imachug) - EccPrivToPub / EccPubToPriv functions (Thanks to purplesyringa)
- Detect and change dark/light theme based on OS setting (Thanks to filips123) - Detect and change dark/light theme based on OS setting (Thanks to filips123)
### Changed ### Changed
@ -213,7 +256,7 @@ Note: The fix is also back ported to ZeroNet Py 2.x version (Rev3870)
- Fix site download as zip file - Fix site download as zip file
- Fix displaying sites with utf8 title - Fix displaying sites with utf8 title
- Error message if dbRebuild fails (Thanks to Lola) - Error message if dbRebuild fails (Thanks to Lola)
- Fix browser reopen if executing start.py again. (Thanks to imachug) - Fix browser reopen if executing start.py again. (Thanks to purplesyringa)
### ZeroNet 0.6.5 (2019-02-16) Rev3851 (Last release targeting Python 2.7.x) ### ZeroNet 0.6.5 (2019-02-16) Rev3851 (Last release targeting Python 2.7.x)
@ -302,7 +345,7 @@ Affected versions: All versions before ZeroNet Rev3616
- Detect network level tracker blocking and easy setting meek proxy for tracker connections. - Detect network level tracker blocking and easy setting meek proxy for tracker connections.
- Support downloading 2GB+ sites as .zip (Thx to Radtoo) - Support downloading 2GB+ sites as .zip (Thx to Radtoo)
- Support ZeroNet as a transparent proxy (Thx to JeremyRand) - Support ZeroNet as a transparent proxy (Thx to JeremyRand)
- Allow fileQuery as CORS command (Thx to imachug) - Allow fileQuery as CORS command (Thx to purplesyringa)
- Windows distribution includes Tor and meek client by default - Windows distribution includes Tor and meek client by default
- Download sites as zip link to sidebar - Download sites as zip link to sidebar
- File server port randomization - File server port randomization
@ -365,7 +408,7 @@ Affected versions: All versions before ZeroNet Rev3616
### Added ### Added
- New plugin: Chart - New plugin: Chart
- Collect and display charts about your contribution to ZeroNet network - Collect and display charts about your contribution to ZeroNet network
- Allow list as argument replacement in sql queries. (Thanks to imachug) - Allow list as argument replacement in sql queries. (Thanks to purplesyringa)
- Newsfeed query time statistics (Click on "From XX sites in X.Xs on ZeroHello) - Newsfeed query time statistics (Click on "From XX sites in X.Xs on ZeroHello)
- New UiWebsocket API command: As to run commands as other site - New UiWebsocket API command: As to run commands as other site
- Ranged ajax queries for big files - Ranged ajax queries for big files
@ -386,7 +429,7 @@ Affected versions: All versions before ZeroNet Rev3616
- Only zoom sidebar globe if mouse button is pressed down - Only zoom sidebar globe if mouse button is pressed down
### Fixed ### Fixed
- Open port checking error reporting (Thanks to imachug) - Open port checking error reporting (Thanks to purplesyringa)
- Out-of-range big file requests - Out-of-range big file requests
- Don't output errors happened on gevent greenlets twice - Don't output errors happened on gevent greenlets twice
- Newsfeed skip sites with no database - Newsfeed skip sites with no database
@ -466,7 +509,7 @@ Affected versions: All versions before ZeroNet Rev3616
- Opened port checking (Thanks l5h5t7 & saber28 for reporting) - Opened port checking (Thanks l5h5t7 & saber28 for reporting)
- Standalone update.py argument parsing (Thanks Zalex for reporting) - Standalone update.py argument parsing (Thanks Zalex for reporting)
- uPnP crash on startup (Thanks Vertux for reporting) - uPnP crash on startup (Thanks Vertux for reporting)
- CoffeeScript 1.12.6 compatibility (Thanks kavamaken & imachug) - CoffeeScript 1.12.6 compatibility (Thanks kavamaken & purplesyringa)
- Multi value argument parsing - Multi value argument parsing
- Database error when running from directory that contains special characters (Thanks Pupiloho for reporting) - Database error when running from directory that contains special characters (Thanks Pupiloho for reporting)
- Site lock violation logging - Site lock violation logging

View file

@ -42,7 +42,7 @@ zeronet-conservancy — это форк/продолжение проекта [Z
* После запуска `zeronet.py` вы сможете посетить zeronet сайты используя адрес * После запуска `zeronet.py` вы сможете посетить zeronet сайты используя адрес
`http://127.0.0.1:43110/{zeronet_address}` `http://127.0.0.1:43110/{zeronet_address}`
(например. `http://127.0.0.1:43110/1HeLLo4uzjaLetFx6NH3PMwFP3qbRbTf3D`). (например. `http://127.0.0.1:43110/1MCoA8rQHhwu4LY2t2aabqcGSRqrL8uf2X`).
* Когда вы посещаете новый сайт zeronet, он пытается найти пиров с помощью BitTorrent * Когда вы посещаете новый сайт zeronet, он пытается найти пиров с помощью BitTorrent
чтобы загрузить файлы сайтов (html, css, js ...) из них. чтобы загрузить файлы сайтов (html, css, js ...) из них.
* Каждый посещенный зайт также обслуживается вами. (Т.е хранится у вас на компьютере) * Каждый посещенный зайт также обслуживается вами. (Т.е хранится у вас на компьютере)
@ -65,6 +65,7 @@ zeronet-conservancy — это форк/продолжение проекта [Z
### Установить из репозитория вашего дистрибутива ### Установить из репозитория вашего дистрибутива
- NixOS: https://search.nixos.org/packages?channel=22.05&show=zeronet-conservancy&type=packages&query=zeronet-conservancy - NixOS: https://search.nixos.org/packages?channel=22.05&show=zeronet-conservancy&type=packages&query=zeronet-conservancy
- ArchLinux: [последний релиз](https://aur.archlinux.org/packages/zeronet-conservancy), [git-версия](https://aur.archlinux.org/packages/zeronet-conservancy-git)
### Установить из исходного кода (рекомендовано) ### Установить из исходного кода (рекомендовано)
@ -85,7 +86,11 @@ zeronet-conservancy — это форк/продолжение проекта [Z
- (optional) `pkg install tor` - (optional) `pkg install tor`
- (optional) запустить тор через команду `tor --ControlPort 9051 --CookieAuthentication 1` (вы можете открыть новый сеанс свайпом вправо) - (optional) запустить тор через команду `tor --ControlPort 9051 --CookieAuthentication 1` (вы можете открыть новый сеанс свайпом вправо)
#### Создание зависимостей Python и запуск #### Скрипт, который всё сделает за вас
- после установки общих зависимостей и клонирования репозитория (как указано выше) запустите `start-venv.sh` который создаст для вас виртуальную среду (если её ещё нет) и установит необходимые пакеты Python
- больше удобных скриптов будует добавлено в ближайшее время
#### Установка Python-зависимостей и запуск
- клонируйте репозиторий (NOTE: на Android/Termux вы должны клонировать его в «домашнюю» папку Termux, потому что виртуальная среда не может находиться в `storage/`) - клонируйте репозиторий (NOTE: на Android/Termux вы должны клонировать его в «домашнюю» папку Termux, потому что виртуальная среда не может находиться в `storage/`)
- `python3 -m venv venv` (создайте виртуальную среду python, последнее `venv` это просто имя/название, если вы используете другое, вы должны заменить его в более поздних командах.) - `python3 -m venv venv` (создайте виртуальную среду python, последнее `venv` это просто имя/название, если вы используете другое, вы должны заменить его в более поздних командах.)
- `source venv/bin/activate` (активируйте среду) - `source venv/bin/activate` (активируйте среду)
@ -96,18 +101,14 @@ zeronet-conservancy — это форк/продолжение проекта [Z
- `source venv/bin/activate` - `source venv/bin/activate`
- `python3 zeronet.py` - `python3 zeronet.py`
#### Создание образа Docker #### (альтернативно) Создание образа Docker
- создание образа: `docker build -t 0net:conservancy . -f Dockerfile` - создание образа: `docker build -t 0net-conservancy:latest . -f Dockerfile`
- или создрание образа с встроенным tor: `docker build -t 0net:conservancy . -f Dockerfile.integrated_tor` - или создрание образа с встроенным tor: `docker build -t 0net-conservancy:latest . -f Dockerfile.integrated_tor`
- и его запуск: `docker run --rm -it -v </path/to/0n/data/directory>:/app/data -p 43110:43110 -p 26552:26552 0net:conservancy` - и его запуск: `docker run --rm -it -v </path/to/0n/data/directory>:/app/data -p 43110:43110 -p 26552:26552 0net-conservancy:latest`
- /path/to/0n/data/directory - директория, куда будут сохраняться все данные в том числе секретные ключи. Если вы запускаете в боевом режиме, не потеряйте эту папку! - /path/to/0n/data/directory - директория, куда будут сохраняться все данные в том числе секретные ключи. Если вы запускаете в боевом режиме, не потеряйте эту папку!
- или вы можете воспользоваться docker-compose: `docker compose up -d 0net` запускает два контейнера раздельно, для 0net и tor сервисов. - или вы можете воспользоваться docker-compose: `docker compose up -d 0net-conservancy` запускает два контейнера раздельно, для 0net и tor сервисов.
- или: `docker compose up -d 0net-tor` запускает один контейнер с tor и 0net. - или: `docker compose up -d 0net-tor` запускает один контейнер с tor и 0net.
#### альтернативный скрипт
- после установки общих зависимостей и клонирования репозитория (как указано выше) запустите `start-venv.sh` который создаст для вас виртуальную среду и установит требования Python
- больше удобных скриптов будует добавлено в ближайшее время
## Текущие ограничения ## Текущие ограничения
* Файловые транзакции не сжаты * Файловые транзакции не сжаты
@ -158,8 +159,10 @@ zeronet-conservancy — это форк/продолжение проекта [Z
также создаст командные аккаунты на дружественных краудфандинговых платформах. также создаст командные аккаунты на дружественных краудфандинговых платформах.
Если вы хотите, чтобы ваше пожертвование было признано пожертвованием для этого Если вы хотите, чтобы ваше пожертвование было признано пожертвованием для этого
проекта, для этого также есть специальный биткойн-адрес: проекта, для этого также есть специальный биткоин-адрес:
1Kjuw3reZvxRVNs27Gen7jPJYCn6LY7Fg6 1Kjuw3reZvxRVNs27Gen7jPJYCn6LY7Fg6. Либо если хотите сделать более анонимный донат, вы
можете пожертвовать Monero:
4AiYUcqVRH4C2CVr9zbBdkhRnJnHiJoypHEsq4N7mQziGUoosPCpPeg8SPr87nvwypaRzDgMHEbWWDekKtq8hm9LBmgcMzC
Если вы хотите сделать пожертвование другим способом, не стесняйтесь обращаться к сопровождающему или Если вы хотите сделать пожертвование другим способом, не стесняйтесь обращаться к сопровождающему или
создать запрос создать запрос

View file

@ -2,12 +2,20 @@
[![Packaging status](https://repology.org/badge/vertical-allrepos/zeronet-conservancy.svg)](https://repology.org/project/zeronet-conservancy/versions) [![Packaging status](https://repology.org/badge/vertical-allrepos/zeronet-conservancy.svg)](https://repology.org/project/zeronet-conservancy/versions)
(NOTE THAT TRANSLATIONS ARE USUALLY BEHIND THIS FILE)
[по-русски](README-ru.md) | [em português](README-ptbr.md) | [简体中文](README-zh-cn.md) [по-русски](README-ru.md) | [em português](README-ptbr.md) | [简体中文](README-zh-cn.md)
zeronet-conservancy is a fork/continuation of [ZeroNet](https://github.com/HelloZeroNet/ZeroNet) project zeronet-conservancy is a fork/continuation of [ZeroNet](https://github.com/HelloZeroNet/ZeroNet) project
(that has been abandoned by its creator) that is dedicated to sustaining existing p2p network and developing (that has been abandoned by its creator) that is dedicated to sustaining existing p2p network and developing
its values of decentralization and freedom, while gradually switching to a better designed network its values of decentralization and freedom, while gradually switching to a better designed network
## No active maintainer warning
This fork was created and maintained by @caryoscelus, but due to vanishing interest and in order to avoid having
another one-person project, they stepped down. This means there currently is no active maintainer (you're are
welcome to become one!), however some development might still happen.
## Why fork? ## Why fork?
During onion-v3 switch crisis, we needed a fork that worked with onion-v3 and didn't depend on trust to one or During onion-v3 switch crisis, we needed a fork that worked with onion-v3 and didn't depend on trust to one or
@ -38,13 +46,14 @@ brand new, completely transparent and audited network is ready and this project
* Automatic uPnP port opening (if opted in) * Automatic uPnP port opening (if opted in)
* Plugin for multiuser (openproxy) support * Plugin for multiuser (openproxy) support
* Works with any modern browser/OS * Works with any modern browser/OS
* Works offline and can be synced via alternative transports (or when connection is back)
## How does it work? ## How does it work?
* After starting `zeronet.py` you will be able to visit zeronet sites using * After starting `zeronet.py` you will be able to visit zeronet sites using
`http://127.0.0.1:43110/{zeronet_address}` (eg. `http://127.0.0.1:43110/{zeronet_address}` (eg.
`http://127.0.0.1:43110/126NXcevn1AUehWFZLTBw7FrX1crEizQdr`). `http://127.0.0.1:43110/1MCoA8rQHhwu4LY2t2aabqcGSRqrL8uf2X/`).
* When you visit a new zeronet site, it tries to find peers using the BitTorrent * When you visit a new zeronet site, it tries to find peers using the BitTorrent
network so it can download the site files (html, css, js...) from them. network so it can download the site files (html, css, js...) from them.
* Each visited site is also served by you. * Each visited site is also served by you.
@ -60,14 +69,14 @@ Following links relate to original ZeroNet:
- [Slideshow about ZeroNet cryptography, site updates, multi-user sites »](https://docs.google.com/presentation/d/1_2qK1IuOKJ51pgBvllZ9Yu7Au2l551t3XBgyTSvilew/pub?start=false&loop=false&delayms=3000) - [Slideshow about ZeroNet cryptography, site updates, multi-user sites »](https://docs.google.com/presentation/d/1_2qK1IuOKJ51pgBvllZ9Yu7Au2l551t3XBgyTSvilew/pub?start=false&loop=false&delayms=3000)
- [Frequently asked questions »](https://zeronet.io/docs/faq/) - [Frequently asked questions »](https://zeronet.io/docs/faq/)
- [ZeroNet Developer Documentation »](https://zeronet.io/docs/site_development/getting_started/) - [ZeroNet Developer Documentation »](https://zeronet.io/docs/site_development/getting_started/) (getting outdated)
## How to join ## How to join
### Install from your distribution repository ### Install from your distribution repository
- NixOS: https://search.nixos.org/packages?channel=22.05&show=zeronet-conservancy&type=packages&query=zeronet-conservancy (and see below) - NixOS: https://search.nixos.org/packages?channel=22.05&show=zeronet-conservancy&type=packages&query=zeronet-conservancy (and see below)
- ArchLinux: https://aur.archlinux.org/packages/zeronet-conservancy-git (fresh git version) - ArchLinux: [latest release](https://aur.archlinux.org/packages/zeronet-conservancy), [fresh git version](https://aur.archlinux.org/packages/zeronet-conservancy-git)
### Install from Nix package manager (Linux or MacOS) ### Install from Nix package manager (Linux or MacOS)
@ -84,7 +93,7 @@ if you're on NixOS
(thanks @fgaz for making & maintaining the package) (thanks @fgaz for making & maintaining the package)
### Install from source (recommended) ### Install from source
#### System dependencies #### System dependencies
@ -105,7 +114,7 @@ Install autoconf and other basic development tools, python3 and pip, then procee
- (optional) `pkg install tor` - (optional) `pkg install tor`
- (optional) run tor via `tor --ControlPort 9051 --CookieAuthentication 1` command (you can then open new session by swiping to the right) - (optional) run tor via `tor --ControlPort 9051 --CookieAuthentication 1` command (you can then open new session by swiping to the right)
#### Building python dependencies & running #### Building python dependencies venv & running
- clone this repo (NOTE: on Android/Termux you should clone it into "home" folder of Termux, because virtual environment cannot live in `storage/`) - clone this repo (NOTE: on Android/Termux you should clone it into "home" folder of Termux, because virtual environment cannot live in `storage/`)
- `python3 -m venv venv` (make python virtual environment, the last `venv` is just a name, if you use different you should replace it in later commands) - `python3 -m venv venv` (make python virtual environment, the last `venv` is just a name, if you use different you should replace it in later commands)
- `source venv/bin/activate` (activate environment) - `source venv/bin/activate` (activate environment)
@ -116,13 +125,19 @@ Install autoconf and other basic development tools, python3 and pip, then procee
- `source venv/bin/activate` - `source venv/bin/activate`
- `python3 zeronet.py` - `python3 zeronet.py`
#### (alternatively) On NixOS
- clone this repo
- `nix-shell '<nixpkgs>' -A zeronet-conservancy` to enter shell with installed dependencies
- `./zeronet.py`
#### (alternatively) Build Docker image #### (alternatively) Build Docker image
- build 0net image: `docker build -t 0net:conservancy . -f Dockerfile` - build 0net image: `docker build -t 0net-conservancy:latest . -f Dockerfile`
- or build 0net image with integrated tor: `docker build -t 0net:conservancy . -f Dockerfile.integrated_tor` - or build 0net image with integrated tor: `docker build -t 0net-conservancy:latest . -f Dockerfile.integrated_tor`
- and run it: `docker run --rm -it -v </path/to/0n/data/directory>:/app/data -p 43110:43110 -p 26552:26552 0net:conservancy` - and run it: `docker run --rm -it -v </path/to/0n/data/directory>:/app/data -p 43110:43110 -p 26552:26552 0net-conservancy:latest`
- /path/to/0n/data/directory - directory, where all data will be saved, including your secret certificates. If you run it with production mode, do not remove this folder! - /path/to/0n/data/directory - directory, where all data will be saved, including your secret certificates. If you run it with production mode, do not remove this folder!
- or you can run it with docker-compose: `docker compose up -d 0net` up two containers - 0net and tor separately. - or you can run it with docker-compose: `docker compose up -d 0net-conservancy` up two containers - 0net and tor separately.
- or: `docker compose up -d 0net-tor` for run 0net and tor in one container. - or: `docker compose up -d 0net-tor` for run 0net and tor in one container.
(please check if these instructions are still accurate)
#### Alternative script #### Alternative script
- after installing general dependencies and cloning repo (as above), run `start-venv.sh` which will create a virtual env for you and install python requirements - after installing general dependencies and cloning repo (as above), run `start-venv.sh` which will create a virtual env for you and install python requirements
@ -142,7 +157,7 @@ Install autoconf and other basic development tools, python3 and pip, then procee
- `cd zeronet-conservancy` - `cd zeronet-conservancy`
- `python -m venv venv` (create virtual python environment) - `python -m venv venv` (create virtual python environment)
- `venv\Scripts\activate` (this activates the environment) - `venv\Scripts\activate` (this activates the environment)
- `pip install -r requirements.txt` (install python dependencies) - `pip install -r requirements.txt` (install python dependencies) (some users reported that this command doesn't successfully install requirements and only manual installation of dependencies one by one works)
- (NOTE: if previous step fails, it most likely means you haven't installed c/c++ compiler successfully) - (NOTE: if previous step fails, it most likely means you haven't installed c/c++ compiler successfully)
- [optional for tor for better connectivity and anonymity] launch Tor Browser - [optional for tor for better connectivity and anonymity] launch Tor Browser
- (NOTE: windows might show a window saying it blocked access to internet for "security reasons" — you should allow the access) - (NOTE: windows might show a window saying it blocked access to internet for "security reasons" — you should allow the access)
@ -161,14 +176,16 @@ Install autoconf and other basic development tools, python3 and pip, then procee
* Doesn't work directly from browser (one of the top priorities for mid-future) * Doesn't work directly from browser (one of the top priorities for mid-future)
* No data transparency * No data transparency
* No reproducible builds * No reproducible builds
* No on-disk encryption
* No reproducible builds (hence no builds beyond certain GNU/Linux distributions)
## How can I create a ZeroNet site? ## How can I create a ZeroNet site?
* Click on **⋮** > **"Create new, empty site"** menu item on the [admin page](http://127.0.0.1:43110/126NXcevn1AUehWFZLTBw7FrX1crEizQdr). * Click on **⋮** > **"Create new, empty site"** menu item on the [dashboard](http://127.0.0.1:43110/191CazMVNaAcT9Y1zhkxd9ixMBPs59g2um/).
* You will be **redirected** to a completely new site that is only modifiable by you! * You will be **redirected** to a completely new site that is only modifiable by you!
* You can find and modify your site's content in **data/[yoursiteaddress]** directory * You can find and modify your site's content in **data/[yoursiteaddress]** directory
* After the modifications open your site, drag the topright "0" button to the left, then press **sign** and **publish** buttons on the bottom * After the modifications open your site, drag the topright "0" button to the left, then press **sign and publish** button on the bottom
Next steps: [ZeroNet Developer Documentation](https://zeronet.io/docs/site_development/getting_started/) Next steps: [ZeroNet Developer Documentation](https://zeronet.io/docs/site_development/getting_started/)
@ -179,6 +196,12 @@ Next steps: [ZeroNet Developer Documentation](https://zeronet.io/docs/site_devel
We need more maintainers! Become one today! You don't need to know how to code, We need more maintainers! Become one today! You don't need to know how to code,
there's a lot of other work to do. there's a lot of other work to do.
### Make builds for your platforms
We need reproducible stand-alone builds for major platforms, as well as presense in various FLOSS
repositories. If you're using one of Linux distributions which don't have packages yet, why not make
a package for it or (if you don't know how) ask a maintainer now?
### Fix bugs & add features ### Fix bugs & add features
We've decided to go ahead and make a perfect p2p web, so we need more help We've decided to go ahead and make a perfect p2p web, so we need more help
@ -196,7 +219,7 @@ need to know their alternatives.
### Financially support maintainers ### Financially support maintainers
Currently the lead developer / maintainer of this fork is @caryoscelus. You can This fork was created and maintained by @caryoscelus. You can
see ways to donate to them on https://caryoscelus.github.io/donate/ (or check see ways to donate to them on https://caryoscelus.github.io/donate/ (or check
sidebar if you're reading this on github for more ways). As our team grows, we sidebar if you're reading this on github for more ways). As our team grows, we
will create team accounts on friendly crowdfunding platforms as well. will create team accounts on friendly crowdfunding platforms as well.
@ -209,3 +232,26 @@ private, a Monero wallet:
If you want to donate in a different way, feel free to contact maintainer or If you want to donate in a different way, feel free to contact maintainer or
create an issue create an issue
# We're using GitHub under protest
This project is currently hosted on GitHub. This is not ideal; GitHub is a
proprietary, trade-secret system that is not Free/Libre and Open Souce Software
(FLOSS). We are deeply concerned about using a proprietary system like GitHub
to develop our FLOSS project. We have an
[open issue](https://github.com/zeronet-conservancy/zeronet-conservancy/issues/89)
to track moving away from GitHub in the long term. We urge you to read about the
[Give up GitHub](https://GiveUpGitHub.org) campaign from
[the Software Freedom Conservancy](https://sfconservancy.org) to understand
some of the reasons why GitHub is not a good place to host FOSS projects.
If you are a contributor who personally has already quit using GitHub, feel
free to [check out from our mirror on notabug](https://notabug.org/caryoscelus/zeronet-conservancy)
and develop there or send git patches directly to project maintainer via
preffered [contact channel](https://caryoscelus.github.io/contacts/).
Any use of this project's code by GitHub Copilot, past or present, is done
without our permission. We do not consent to GitHub's use of this project's
code in Copilot.
![Logo of the GiveUpGitHub campaign](https://sfconservancy.org/img/GiveUpGitHub.png)

35
greet.py Normal file
View file

@ -0,0 +1,35 @@
def grad(n):
s = 0x08
r = 0xff
g = 0x00
b = 0x00
for i in range(n):
if r >= s and b < s:
r -= s
g += s
elif g >= s and r < s:
g -= s
b += s
elif b >= s and g < s:
b -= s
r += s
return f'#{r:02x}{g:02x}{b:02x}'
def fancy_greet(version):
from rich.console import Console
from rich.text import Text
zc_msg = f'''
||| . . _ _._|_ _. . . _ .__ _.. _. . __.. _ __. .
||| //\|/ |/_| | == / / \|/ |( /_||/ | | __||/ |/ \_|
||| \_/| |\_ |. \__\_/| |_) \_ | \/ |__|| |\__ _/
|||
||| v{version}
'''
lns = zc_msg.split('\n')
console = Console()
for l in lns:
txt = Text(l)
txt.stylize('bold')
for i in range(len(l)):
txt.stylize(grad(i), i, i+1)
console.print(txt)

View file

@ -38,7 +38,7 @@ class SiteManagerPlugin(object):
block_details = None block_details = None
if block_details: if block_details:
raise Exception("Site blocked: %s" % html.escape(block_details.get("reason", "unknown reason"))) raise Exception(f'Site blocked: {html.escape(block_details.get("reason", "unknown reason"))}')
else: else:
return super(SiteManagerPlugin, self).add(address, *args, **kwargs) return super(SiteManagerPlugin, self).add(address, *args, **kwargs)
@ -204,15 +204,15 @@ class SiteStoragePlugin(object):
# Check if any of the adresses are in the mute list # Check if any of the adresses are in the mute list
for auth_address in matches: for auth_address in matches:
if filter_storage.isMuted(auth_address): if filter_storage.isMuted(auth_address):
self.log.debug("Mute match: %s, ignoring %s" % (auth_address, inner_path)) self.log.debug(f'Mute match: {auth_address}, ignoring {inner_path}')
return False return False
return super(SiteStoragePlugin, self).updateDbFile(inner_path, file=file, cur=cur) return super(SiteStoragePlugin, self).updateDbFile(inner_path, file=file, cur=cur)
def onUpdated(self, inner_path, file=None): def onUpdated(self, inner_path, file=None):
file_path = "%s/%s" % (self.site.address, inner_path) file_path = f'{self.site.address}/{inner_path}'
if file_path in filter_storage.file_content["includes"]: if file_path in filter_storage.file_content['includes']:
self.log.debug("Filter file updated: %s" % inner_path) self.log.debug('Filter file updated: {inner_path}')
filter_storage.includeUpdateAll() filter_storage.includeUpdateAll()
return super(SiteStoragePlugin, self).onUpdated(inner_path, file=file) return super(SiteStoragePlugin, self).onUpdated(inner_path, file=file)

View file

@ -12,6 +12,7 @@ import urllib.parse
import gevent import gevent
import util import util
import main
from Config import config from Config import config
from Plugin import PluginManager from Plugin import PluginManager
from Debug import Debug from Debug import Debug
@ -115,11 +116,11 @@ class UiWebsocketPlugin(object):
local_html = "" local_html = ""
peer_ips = [peer.key for peer in site.getConnectablePeers(20, allow_private=False)] peer_ips = [peer.key for peer in site.getConnectablePeers(20, allow_private=False)]
self_onion = main.file_server.tor_manager.site_onions.get(site.address, None)
if self_onion is not None:
peer_ips.append(self_onion+'.onion')
peer_ips.sort(key=lambda peer_ip: ".onion:" in peer_ip) peer_ips.sort(key=lambda peer_ip: ".onion:" in peer_ip)
copy_link = "http://127.0.0.1:43110/%s/?zeronet_peers=%s" % ( copy_link = f'http://127.0.0.1:43110/{site.address}/?zeronet_peers={",".join(peer_ips)}'
site.content_manager.contents.get("content.json", {}).get("domain", site.address),
",".join(peer_ips)
)
body.append(_(""" body.append(_("""
<li> <li>
@ -421,7 +422,7 @@ class UiWebsocketPlugin(object):
print('No dashboard found, cannot favourite') print('No dashboard found, cannot favourite')
class_favourite = "hidden" class_favourite = "hidden"
class_unfavourite = "hidden" class_unfavourite = "hidden"
elif dsite.get('sittings', {}).get('favorite_sites', {}).get(self.site.address, False): elif not dsite.get('settings', {}).get('favorite_sites', {}).get(self.site.address, False):
class_favourite = "" class_favourite = ""
class_unfavourite = "hidden" class_unfavourite = "hidden"
else: else:
@ -452,7 +453,8 @@ class UiWebsocketPlugin(object):
donate_generic = site.content_manager.contents.get("content.json", {}).get("donate", None) or site.content_manager.contents.get("content.json", {}).get("donate-generic", None) donate_generic = site.content_manager.contents.get("content.json", {}).get("donate", None) or site.content_manager.contents.get("content.json", {}).get("donate-generic", None)
donate_btc = site.content_manager.contents.get("content.json", {}).get("donate-btc", None) donate_btc = site.content_manager.contents.get("content.json", {}).get("donate-btc", None)
donate_xmr = site.content_manager.contents.get("content.json", {}).get("donate-xmr", None) donate_xmr = site.content_manager.contents.get("content.json", {}).get("donate-xmr", None)
donate_enabled = bool(donate_generic or donate_btc or donate_xmr) donate_ada = site.content_manager.contents.get("content.json", {}).get("donate-ada", None)
donate_enabled = bool(donate_generic or donate_btc or donate_xmr or donate_ada)
if donate_enabled: if donate_enabled:
body.append(_(""" body.append(_("""
<li> <li>
@ -482,6 +484,15 @@ class UiWebsocketPlugin(object):
<a href='monero:{donate_xmr}' class='button'>{_[Donate Monero]}</a> <a href='monero:{donate_xmr}' class='button'>{_[Donate Monero]}</a>
</div> </div>
""")) """))
if donate_ada:
body.append(_("""
<div class='flex'>
<span style="font-size:90%">{donate_ada}</span><br/>
</div>
<div class='flex'>
<a href='web+cardano:{donate_ada}' class='button'>{_[Donate Ada/Cardano]}</a>
</div>
"""))
if donate_enabled: if donate_enabled:
body.append(_(""" body.append(_("""
</li> </li>

View file

@ -17366,7 +17366,10 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
var kw = keywords[word] var kw = keywords[word]
return ret(kw.type, kw.style, word) return ret(kw.type, kw.style, word)
} }
if (word == "async" && stream.match(/^(\s|\/\*.*?\*\/)*[\[\(\w]/, false)) // backported ReDoS fix from
// https://github.com/codemirror/codemirror5/blob/a0854c752a76e4ba9512a9beedb9076f36e4f8f9/mode/javascript/javascript.js#L130C36-L130C36
// https://security.snyk.io/vuln/SNYK-JS-CODEMIRROR-1016937
if (word == "async" && stream.match(/^(\s|\/\*([^*]|\*(?!\/))*?\*\/)*[\[\(\w]/, false))
return ret("async", "keyword", word) return ret("async", "keyword", word)
} }
return ret("variable", "variable", word) return ret("variable", "variable", word)

View file

@ -126,7 +126,10 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
var kw = keywords[word] var kw = keywords[word]
return ret(kw.type, kw.style, word) return ret(kw.type, kw.style, word)
} }
if (word == "async" && stream.match(/^(\s|\/\*.*?\*\/)*[\[\(\w]/, false)) // backported ReDoS fix from
// https://github.com/codemirror/codemirror5/blob/a0854c752a76e4ba9512a9beedb9076f36e4f8f9/mode/javascript/javascript.js#L130C36-L130C36
// https://security.snyk.io/vuln/SNYK-JS-CODEMIRROR-1016937
if (word == "async" && stream.match(/^(\s|\/\*([^*]|\*(?!\/))*?\*\/)*[\[\(\w]/, false))
return ret("async", "keyword", word) return ret("async", "keyword", word)
} }
return ret("variable", "variable", word) return ret("variable", "variable", word)

View file

@ -63,7 +63,7 @@ class ConfigPlugin(object):
group = self.parser.add_argument_group("Zeroname plugin") group = self.parser.add_argument_group("Zeroname plugin")
group.add_argument( group.add_argument(
"--bit_resolver", help="ZeroNet site to resolve .bit domains", "--bit_resolver", help="ZeroNet site to resolve .bit domains",
default="1Name2NXVi1RDPDgf5617UoW7xA6YrhM9F", metavar="address" default="1GnACKctkJrGWHTqxk9T9zXo2bLQc2PDnF", metavar="address"
) )
return super(ConfigPlugin, self).createArguments() return super(ConfigPlugin, self).createArguments()

View file

@ -1,9 +1,9 @@
gevent==1.4.0; python_version <= "3.6" setuptools>=65.5.1 # not directly required, pinned by Snyk to avoid a vulnerability
greenlet==0.4.16; python_version <= "3.6" gevent>=20.9.0
gevent>=20.9.0; python_version >= "3.7" msgpack>=0.6.0
msgpack>=0.4.4
base58 base58
merkletools # for some reason nobody released fresh merkletools that don't require on outdated pysha3
git+https://github.com/Tierion/pymerkletools.git@f10d71e2cd529a833728e836dc301f9af502d0b0
rsa rsa
PySocks>=1.6.8 PySocks>=1.6.8
pyasn1 pyasn1

View file

@ -92,15 +92,103 @@ trackers = [
'udp://vibe.sleepyinternetfun.xyz:1738/announce', 'udp://vibe.sleepyinternetfun.xyz:1738/announce',
'udp://www.skynetcenter.me:6969/announce', 'udp://www.skynetcenter.me:6969/announce',
'udp://www.torrent.eu.org:451/announce', 'udp://www.torrent.eu.org:451/announce',
'zero://194.5.98.39:15441',
'zero://145.239.95.38:15441',
'zero://178.128.34.249:26117',
'zero://217.18.217.143:39288',
'zero://83.246.141.203:22207',
'zero://syncronite.loki:15441',
'zero://2a05:dfc1:4000:1e00::a:15441',
'zero://2400:6180:100:d0::8fd:8001:21697',
'zero://2001:19f0:8001:1d2f:5400:2ff:fe83:5bf7:30530',
'zero://73pyhfwfwsrhfw76knkjfnw6o3lk53zfo7hlxdmxbj75sjcnol5cioad.onion:15442',
'zero://fzlzmxuz2bust72cuy5g4w6d62tx624xcjaupf2kp7ffuitbiniy2hqd.onion:15441',
'zero://rlcjomszyitxpwv7kzopmqgzk3bdpsxeull4c3s6goszkk6h2sotfoad.onion:15441',
'zero://tqmo2nffqo4qc5jgmz3me5eri3zpgf3v2zciufzmhnvznjve5c3argad.onion:15441',
'http://107.189.31.134:6969/announce',
'http://119.28.71.45:8080/announce',
'http://129.146.193.240:6699/announce',
'http://159.69.65.157:6969/announce',
'http://163.172.29.130:80/announce',
'http://185.130.47.2:6969/announce',
'http://45.67.35.111:6969/announce',
'http://61.222.178.254:6969/announce',
'http://83.31.30.182:6969/announce',
'http://93.158.213.92:1337/announce',
'http://95.217.167.10:6969/announce',
'udp://102.223.180.235:6969/announce',
'udp://103.122.21.50:6969/announce',
'udp://104.131.98.232:6969/announce',
'udp://104.244.77.87:6969/announce',
'udp://107.189.11.58:6969/announce',
'udp://107.189.31.134:6969/announce',
'udp://139.144.68.88:6969/announce',
'udp://149.28.239.70:6969/announce',
'udp://15.204.205.14:6969/announce',
'udp://156.234.201.18:80/announce',
'udp://158.101.161.60:3131/announce',
'udp://163.172.29.130:80/announce',
'udp://167.99.185.219:6969/announce',
'udp://176.31.250.174:6969/announce',
'udp://176.56.4.238:6969/announce',
'udp://178.32.222.98:3391/announce',
'udp://184.105.151.166:6969/announce',
'udp://185.102.219.163:6969/announce',
'udp://185.181.60.155:80/announce',
'udp://185.217.199.21:6969/announce',
'udp://185.44.82.25:1337/announce',
'udp://185.68.21.244:6969/announce',
'udp://192.3.165.191:6969/announce',
'udp://192.3.165.198:6969/announce',
'udp://192.95.46.115:6969/announce',
'udp://193.176.158.162:6969/announce',
'udp://193.37.214.12:6969/announce',
'udp://193.42.111.57:9337/announce',
'udp://198.100.149.66:6969/announce',
'udp://20.100.205.229:6969/announce',
'udp://207.241.226.111:6969/announce',
'udp://207.241.231.226:6969/announce',
'udp://209.141.59.16:6969/announce',
'udp://212.237.53.230:6969/announce',
'udp://23.153.248.2:6969/announce',
'udp://23.254.228.89:6969/announce',
'udp://37.187.111.136:6969/announce',
'udp://37.27.4.53:6969/announce',
'udp://38.7.201.142:6969/announce',
'udp://45.154.253.6:6969/announce',
'udp://45.63.30.114:6969/announce',
'udp://45.9.60.30:6969/announce',
'udp://46.38.238.105:6969/announce',
'udp://49.12.76.8:8080/announce',
'udp://5.102.159.190:6969/announce',
'udp://5.196.89.204:6969/announce',
'udp://51.15.79.209:6969/announce',
'udp://51.159.54.68:6666/announce',
'udp://51.68.174.87:6969/announce',
'udp://51.81.222.188:6969/announce',
'udp://52.58.128.163:6969/announce',
'udp://61.222.178.254:6969/announce',
'udp://77.73.69.230:6969/announce',
'udp://83.102.180.21:80/announce',
'udp://83.31.30.182:6969/announce',
'udp://85.206.172.159:6969/announce',
'udp://85.239.33.28:6969/announce',
'udp://86.57.161.157:6969/announce',
'udp://91.216.110.52:451/announce',
'udp://93.158.213.92:1337/announce',
'udp://94.103.87.87:6969/announce',
'udp://95.216.74.39:6969/announce',
'udp://95.31.11.224:6969/announce',
] ]
class Config(object): class Config(object):
def __init__(self, argv): def __init__(self, argv):
self.version = "0.7.7+" self.version = "0.7.9+"
self.user_agent = "conservancy" self.user_agent = "conservancy"
# DEPRECATED ; replace with git-generated commit # DEPRECATED ; replace with git-generated commit
self.rev = 5036 self.rev = 5110
self.user_agent_rev = 8192
self.argv = argv self.argv = argv
self.action = None self.action = None
self.test_parser = None self.test_parser = None

View file

@ -369,7 +369,7 @@ class Connection(object):
"fileserver_port": self.server.port, "fileserver_port": self.server.port,
"port_opened": self.server.port_opened.get(self.ip_type, None), "port_opened": self.server.port_opened.get(self.ip_type, None),
"target_ip": self.ip, "target_ip": self.ip,
"rev": 8192, "rev": config.user_agent_rev,
"crypt_supported": crypt_supported, "crypt_supported": crypt_supported,
"crypt": self.crypt, "crypt": self.crypt,
"time": int(time.time()) "time": int(time.time())

View file

@ -85,16 +85,16 @@ class ContentManager(object):
new_ts = int(float(new_content.get('modified', 0))) new_ts = int(float(new_content.get('modified', 0)))
old_ts = int(float(old_content.get('modified', 0))) old_ts = int(float(old_content.get('modified', 0)))
if new_ts < old_ts: if new_ts < old_ts:
self.log.debug('got older version of {content_inner_path} ({new_ts} < {old_ts}), ignoring') self.log.debug(f'got older version of {content_inner_path} ({new_ts} < {old_ts}), ignoring')
return [], [] return [], []
elif new_ts == old_ts: elif new_ts == old_ts:
self.log.debug('got same timestamp version of {content_inner_path} ({new_ts}), ignoring') self.log.debug(f'got same timestamp version of {content_inner_path} ({new_ts}), ignoring')
return [], [] return [], []
except Exception as err: except Exception as err:
self.log.warning(f'{content_path} load error: {Debug.formatException(err)}') self.log.warning(f'{content_path} load error: {Debug.formatException(err)}')
return [], [] return [], []
else: else:
self.log.debug("Content.json not exist: %s" % content_path) self.log.debug(f'Content.json not exist: {content_path}')
return [], [] # Content.json not exist return [], [] # Content.json not exist
try: try:
@ -793,7 +793,7 @@ class ContentManager(object):
return 1 # Todo: Multisig return 1 # Todo: Multisig
def verifyCertSign(self, user_address, user_auth_type, user_name, issuer_address, sign): def verifyCertSign(self, user_address, user_auth_type, user_name, issuer_address, sign):
cert_subject = "%s#%s/%s" % (user_address, user_auth_type, user_name) cert_subject = f'{user_address}#{user_auth_type}/{user_name}'
return CryptBitcoin.verify(cert_subject, issuer_address, sign) return CryptBitcoin.verify(cert_subject, issuer_address, sign)
def verifyCert(self, inner_path, content): def verifyCert(self, inner_path, content):

View file

@ -1,3 +1,5 @@
## please note that this file uses custom db cursor and thus may surprise you with how sql queries are performed
import sqlite3 import sqlite3
import json import json
import time import time

View file

@ -154,7 +154,7 @@ class Peer(object):
self.log("Send request: %s %s %s %s" % (params.get("site", ""), cmd, params.get("inner_path", ""), params.get("location", ""))) self.log("Send request: %s %s %s %s" % (params.get("site", ""), cmd, params.get("inner_path", ""), params.get("location", "")))
for retry in range(1, 4): # Retry 3 times for retry in range(3):
try: try:
if not self.connection: if not self.connection:
# this is redundant, already established that self.connection is present # this is redundant, already established that self.connection is present
@ -165,7 +165,7 @@ class Peer(object):
if "error" in res: if "error" in res:
self.log("%s error: %s" % (cmd, res["error"])) self.log("%s error: %s" % (cmd, res["error"]))
self.onConnectionError("Response error") self.onConnectionError("Response error")
break return res
else: # Successful request, reset connection error num else: # Successful request, reset connection error num
self.connection_error = 0 self.connection_error = 0
self.time_response = time.time() self.time_response = time.time()
@ -183,9 +183,9 @@ class Peer(object):
"%s (connection_error: %s, hash_failed: %s, retry: %s)" % "%s (connection_error: %s, hash_failed: %s, retry: %s)" %
(Debug.formatException(err), self.connection_error, self.hash_failed, retry) (Debug.formatException(err), self.connection_error, self.hash_failed, retry)
) )
time.sleep(1 * retry) time.sleep(retry+1)
self.connect() self.connect()
return None # Failed after 4 retry return None # Failed after 3 attempts
# Get a file content from peer # Get a file content from peer
def getFile(self, site, inner_path, file_size=None, pos_from=0, pos_to=None, streaming=False): def getFile(self, site, inner_path, file_size=None, pos_from=0, pos_to=None, streaming=False):

View file

@ -35,6 +35,7 @@ class Site(object):
def __init__(self, address, allow_create=True, settings=None): def __init__(self, address, allow_create=True, settings=None):
self.address = str(re.sub("[^A-Za-z0-9]", "", address)) # Make sure its correct address self.address = str(re.sub("[^A-Za-z0-9]", "", address)) # Make sure its correct address
self.address_hash = hashlib.sha256(self.address.encode("ascii")).digest() self.address_hash = hashlib.sha256(self.address.encode("ascii")).digest()
# sha1 is used for clearnet trackers
self.address_sha1 = hashlib.sha1(self.address.encode("ascii")).digest() self.address_sha1 = hashlib.sha1(self.address.encode("ascii")).digest()
self.address_short = "%s..%s" % (self.address[:6], self.address[-4:]) # Short address for logging self.address_short = "%s..%s" % (self.address[:6], self.address[-4:]) # Short address for logging
self.log = logging.getLogger("Site:%s" % self.address_short) self.log = logging.getLogger("Site:%s" % self.address_short)

View file

@ -14,7 +14,6 @@ from Config import config
from util import helper from util import helper
from util import RateLimit from util import RateLimit
from util import Cached from util import Cached
from .Site import Site
from Debug import Debug from Debug import Debug
@PluginManager.acceptPlugins @PluginManager.acceptPlugins
@ -31,6 +30,7 @@ class SiteManager(object):
# Load all sites from data/sites.json # Load all sites from data/sites.json
@util.Noparallel() @util.Noparallel()
def load(self, cleanup=True, startup=False): def load(self, cleanup=True, startup=False):
from .Site import Site
self.log.info("Loading sites... (cleanup: %s, startup: %s)" % (cleanup, startup)) self.log.info("Loading sites... (cleanup: %s, startup: %s)" % (cleanup, startup))
self.loaded = False self.loaded = False
address_found = [] address_found = []
@ -169,6 +169,7 @@ class SiteManager(object):
return site return site
def add(self, address, all_file=True, settings=None, **kwargs): def add(self, address, all_file=True, settings=None, **kwargs):
from .Site import Site
self.sites_changed = int(time.time()) self.sites_changed = int(time.time())
# Try to find site with differect case # Try to find site with differect case
for recover_address, recover_site in list(self.sites.items()): for recover_address, recover_site in list(self.sites.items()):

View file

@ -176,7 +176,7 @@ class UiRequest(object):
return self.actionConsole() return self.actionConsole()
# Wrapper-less static files # Wrapper-less static files
elif path.startswith("/raw/"): elif path.startswith("/raw/"):
return self.actionSiteMedia(path.replace("/raw", "/media", 1), header_noscript=True) return self.actionSiteMedia(path.replace("/raw", "/media", 1), header_noscript=True, raw=True)
elif path.startswith("/add/"): elif path.startswith("/add/"):
return self.actionSiteAdd() return self.actionSiteAdd()
@ -372,7 +372,7 @@ class UiRequest(object):
# Redirect to an url # Redirect to an url
def actionRedirect(self, url): def actionRedirect(self, url):
self.start_response('301 Redirect', [('Location', str(url))]) self.start_response('301 Redirect', [('Location', str(url))])
yield self.formatRedirect(url) return self.formatRedirect(url)
def actionIndex(self): def actionIndex(self):
return self.actionRedirect("/" + config.homepage + "/") return self.actionRedirect("/" + config.homepage + "/")
@ -634,7 +634,9 @@ class UiRequest(object):
match = re.match(r"/(media/)?(?P<address>[A-Za-z0-9]+[A-Za-z0-9\._-]+)(?P<inner_path>/.*|$)", path) match = re.match(r"/(media/)?(?P<address>[A-Za-z0-9]+[A-Za-z0-9\._-]+)(?P<inner_path>/.*|$)", path)
if match: if match:
path_parts = match.groupdict() path_parts = match.groupdict()
if self.isDomain(path_parts["address"]): addr = path_parts["address"]
if self.isDomain(addr):
path_parts["domain"] = addr
path_parts["address"] = self.resolveDomain(path_parts["address"]) path_parts["address"] = self.resolveDomain(path_parts["address"])
path_parts["request_address"] = path_parts["address"] # Original request address (for Merger sites) path_parts["request_address"] = path_parts["address"] # Original request address (for Merger sites)
path_parts["inner_path"] = path_parts["inner_path"].lstrip("/") path_parts["inner_path"] = path_parts["inner_path"].lstrip("/")
@ -645,12 +647,19 @@ class UiRequest(object):
return None return None
# Serve a media for site # Serve a media for site
def actionSiteMedia(self, path, header_length=True, header_noscript=False): def actionSiteMedia(self, path, header_length=True, header_noscript=False, raw=False):
try: try:
path_parts = self.parsePath(path) path_parts = self.parsePath(path)
except SecurityError as err: except SecurityError as err:
return self.error403(err) return self.error403(err)
if "domain" in path_parts:
addr = path_parts['address']
path = path_parts['inner_path']
query = self.env['QUERY_STRING']
raw = "/raw" if raw else ""
return self.actionRedirect(f"{raw}/{addr}/{path}?{query}")
if not path_parts: if not path_parts:
return self.error404(path) return self.error404(path)

View file

@ -262,7 +262,14 @@ class UiWebsocket(object):
del(content["signers_sign"]) del(content["signers_sign"])
settings = site.settings.copy() settings = site.settings.copy()
del settings["wrapper_key"] # Dont expose wrapper key # remove fingerprinting information for non-admin sites
if 'ADMIN' not in self.site.settings['permissions']:
del settings['wrapper_key']
settings['added'] = 0
settings['serving'] = True
settings['ajax_key'] = ''
settings['peers'] = 1
settings['cache'] = {}
ret = { ret = {
"auth_address": self.user.getAuthAddress(site.address, create=create_user), "auth_address": self.user.getAuthAddress(site.address, create=create_user),
@ -281,13 +288,26 @@ class UiWebsocket(object):
"workers": len(site.worker_manager.workers), "workers": len(site.worker_manager.workers),
"content": content "content": content
} }
if 'ADMIN' not in self.site.settings['permissions']:
ret.update({
"content_updated": 0,
"bad_files": len(site.bad_files), # ?
"size_limit": site.getSizeLimit(), # ?
"next_size_limit": site.getNextSizeLimit(), # ?
"peers": 1,
"started_task_num": 0,
"tasks": 0,
"workers": 0,
})
if site.settings["own"]: if site.settings["own"]:
ret["privatekey"] = bool(self.user.getSiteData(site.address, create=create_user).get("privatekey")) ret["privatekey"] = bool(self.user.getSiteData(site.address, create=create_user).get("privatekey"))
if site.isServing() and content: if site.isServing() and content and "ADMIN" in self.site.settings['permissions']:
ret["peers"] += 1 # Add myself if serving ret["peers"] += 1 # Add myself if serving
return ret return ret
def formatServerInfo(self): def formatServerInfo(self):
# unprivileged sites should not get any fingerprinting information
if "ADMIN" in self.site.settings['permissions']:
import main import main
file_server = main.file_server file_server = main.file_server
if file_server.port_opened == {}: if file_server.port_opened == {}:
@ -295,35 +315,61 @@ class UiWebsocket(object):
else: else:
ip_external = any(file_server.port_opened.values()) ip_external = any(file_server.port_opened.values())
back = { back = {
"ip_external": ip_external, 'ip_external' : ip_external,
"port_opened": file_server.port_opened, 'port_opened' : file_server.port_opened,
"platform": sys.platform, 'platform' : sys.platform,
"fileserver_ip": config.fileserver_ip, 'dist_type' : config.dist_type,
"fileserver_port": config.fileserver_port, 'fileserver_ip' : config.fileserver_ip,
"tor_enabled": file_server.tor_manager.enabled, 'fileserver_port' : config.fileserver_port,
"tor_status": file_server.tor_manager.status, 'tor_enabled' : file_server.tor_manager.enabled,
"tor_has_meek_bridges": file_server.tor_manager.has_meek_bridges, 'tor_status' : file_server.tor_manager.status,
"tor_use_bridges": config.tor_use_bridges, 'tor_has_meek_bridges' : file_server.tor_manager.has_meek_bridges,
"ui_ip": config.ui_ip, 'tor_use_bridges' : config.tor_use_bridges,
"ui_port": config.ui_port, 'ui_ip' : config.ui_ip,
"version": config.version, 'ui_port' : config.ui_port,
"rev": config.rev, 'version' : config.version,
"timecorrection": file_server.timecorrection, 'rev' : config.rev,
"language": config.language, 'timecorrection' : file_server.timecorrection,
"debug": config.debug, 'language' : config.language,
"offline": config.offline, 'debug' : config.debug,
"plugins": PluginManager.plugin_manager.plugin_names, 'offline' : config.offline,
"plugins_rev": PluginManager.plugin_manager.plugins_rev, 'plugins' : PluginManager.plugin_manager.plugin_names,
"user_settings": self.user.settings 'plugins_rev' : PluginManager.plugin_manager.plugins_rev,
'user_settings' : self.user.settings,
'lib_verify_best' : CryptBitcoin.lib_verify_best
}
else:
back = {
'ip_external' : None,
'port_opened' : False,
'platform' : 'generic',
'dist_type' : 'generic',
'fileserver_ip' : '127.0.0.1',
'fileserver_port' : 15441,
'tor_enabled' : True,
'tor_status' : 'OK',
'tor_has_meek_bridges' : True,
'tor_use_bridges' : True,
'ui_ip' : '127.0.0.1',
'ui_port' : 43110,
'version' : config.user_agent,
'rev' : config.user_agent_rev,
'timecorrection' : 0.0,
'language' : config.language, #?
'debug' : False,
'offline' : False,
'plugins' : [],
'plugins_rev' : {},
'user_settings' : self.user.settings #?
} }
if "ADMIN" in self.site.settings["permissions"]:
# back["updatesite"] = config.updatesite
back["dist_type"] = config.dist_type
back["lib_verify_best"] = CryptBitcoin.lib_verify_best
return back return back
def formatAnnouncerInfo(self, site): def formatAnnouncerInfo(self, site):
return {"address": site.address, "stats": site.announcer.stats} if "ADMIN" in self.site.settings['permissions']:
stats = site.announcer.stats
else:
stats = {}
return {"address": site.address, "stats": stats}
# - Actions - # - Actions -
@ -465,6 +511,8 @@ class UiWebsocket(object):
# Sign and publish content.json # Sign and publish content.json
def actionSitePublish(self, to, privatekey=None, inner_path="content.json", sign=True, remove_missing_optional=False, update_changed_files=False): def actionSitePublish(self, to, privatekey=None, inner_path="content.json", sign=True, remove_missing_optional=False, update_changed_files=False):
# TODO: check certificates (https://github.com/zeronet-conservancy/zeronet-conservancy/issues/190)
# TODO: update certificates (https://github.com/zeronet-conservancy/zeronet-conservancy/issues/194)
if sign: if sign:
inner_path = self.actionSiteSign( inner_path = self.actionSiteSign(
to, privatekey, inner_path, response_ok=False, to, privatekey, inner_path, response_ok=False,

View file

@ -234,6 +234,19 @@ class Actions(object):
# Not found in users.json, ask from console # Not found in users.json, ask from console
import getpass import getpass
privatekey = getpass.getpass("Private key (input hidden):") privatekey = getpass.getpass("Private key (input hidden):")
# inner_path can be either relative to site directory or absolute/relative path
if os.path.isabs(inner_path):
full_path = os.path.abspath(inner_path)
else:
full_path = os.path.abspath(config.working_dir + '/' + inner_path)
print(full_path)
if os.path.isfile(full_path):
if address in full_path:
# assuming site address is unique, keep only path after it
inner_path = full_path.split(address+'/')[1]
else:
# oops, file that we found seems to be rogue, so reverting to old behaviour
logging.warning(f'using {inner_path} relative to site directory')
try: try:
succ = site.content_manager.sign( succ = site.content_manager.sign(
inner_path=inner_path, privatekey=privatekey, inner_path=inner_path, privatekey=privatekey,

View file

@ -5,4 +5,4 @@ if [ ! -f venv/bin/activate ] ; then
fi fi
source venv/bin/activate source venv/bin/activate
python3 -m pip install -r requirements.txt python3 -m pip install -r requirements.txt
python3 zeronet.py python3 zeronet.py $1 $2 $3 $4 $5 $6 $7 $8 $9

View file

@ -3,51 +3,19 @@ import os
import sys import sys
from src.Config import config from src.Config import config
def grad(n): # fix further imports from src dir
s = 0x08 sys.modules['Config'] = sys.modules['src.Config']
r = 0xff
g = 0x00
b = 0x00
for i in range(n):
if r >= s and b < s:
r -= s
g += s
elif g >= s and r < s:
g -= s
b += s
elif b >= s and g < s:
b -= s
r += s
return f'#{r:02x}{g:02x}{b:02x}'
def fancy_greet(): def launch():
from rich.console import Console '''renamed from main to avoid clashes with main module'''
from rich.text import Text
zc_msg = f'''
||| __. _.. _ . . _ _._|_ _. . . _ .-- _.. _. . __.. _ _.. .
||| / /_||/ / \|/ |/_| | == / / \|/ | \ /_||/ | | __||/ |/ \_|
||| /_.\_ | \_/| |\_ |. \__\_/| |._|\_ | \/ |__|| |\__ |
||| _/
||| v{config.version}
'''
lns = zc_msg.split('\n')
console = Console()
for l in lns:
txt = Text(l)
txt.stylize('bold')
for i in range(len(l)):
txt.stylize(grad(i), i, i+1)
console.print(txt)
def main():
if sys.version_info.major < 3: if sys.version_info.major < 3:
print("Error: Python 3.x is required") print("Error: Python 3.x is required")
sys.exit(0) sys.exit(0)
if '--silent' not in sys.argv: if '--silent' not in sys.argv:
fancy_greet() from greet import fancy_greet
fancy_greet(config.version)
main = None
try: try:
import main import main
main.start() main.start()
@ -155,6 +123,7 @@ def restart():
def start(): def start():
config.working_dir = os.getcwd()
app_dir = os.path.dirname(os.path.abspath(__file__)) app_dir = os.path.dirname(os.path.abspath(__file__))
os.chdir(app_dir) # Change working dir to zeronet.py dir os.chdir(app_dir) # Change working dir to zeronet.py dir
sys.path.insert(0, os.path.join(app_dir, "src/lib")) # External liblary directory sys.path.insert(0, os.path.join(app_dir, "src/lib")) # External liblary directory
@ -166,7 +135,7 @@ def start():
import update import update
update.update() update.update()
else: else:
main() launch()
if __name__ == '__main__': if __name__ == '__main__':