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
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)
maintainers: @caryoscelus, @FraYoshi, @prtngn, @d47081 (ex @d4708)
@ -64,6 +106,7 @@ maintainers: @caryoscelus
### zeronet-conservancy 0.7.3 (2022-01-21) Rev5000
maintainers: @caryoscelus
- forked from the latest py3 branch of ZeroNet
- fixed potential vulnerability discovered by @purplesyringa
- onion v3 support (thanks to @anonymoose, @zeroseed and @geekless)
- partial readme rewrite (thanks to @mitya57)
- 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
### Changed
- Allow .. in file names [Thanks to imachug]
- Allow .. in file names [Thanks to purplesyringa]
- Change unstable trackers
- More clean errors on sites.json/users.json load error
- 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
- 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]
- Fix parsing config file lines that has % in the value [Thanks slrslr 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 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 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]
@ -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)
- Offline mode
- 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.
- 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)
### 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 displaying sites with utf8 title
- 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)
@ -302,7 +345,7 @@ Affected versions: All versions before ZeroNet Rev3616
- Detect network level tracker blocking and easy setting meek proxy for tracker connections.
- Support downloading 2GB+ sites as .zip (Thx to Radtoo)
- 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
- Download sites as zip link to sidebar
- File server port randomization
@ -365,7 +408,7 @@ Affected versions: All versions before ZeroNet Rev3616
### Added
- New plugin: Chart
- 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)
- New UiWebsocket API command: As to run commands as other site
- 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
### Fixed
- Open port checking error reporting (Thanks to imachug)
- Open port checking error reporting (Thanks to purplesyringa)
- Out-of-range big file requests
- Don't output errors happened on gevent greenlets twice
- 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)
- Standalone update.py argument parsing (Thanks Zalex 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
- Database error when running from directory that contains special characters (Thanks Pupiloho for reporting)
- Site lock violation logging

View file

@ -42,7 +42,7 @@ zeronet-conservancy — это форк/продолжение проекта [Z
* После запуска `zeronet.py` вы сможете посетить zeronet сайты используя адрес
`http://127.0.0.1:43110/{zeronet_address}`
(например. `http://127.0.0.1:43110/1HeLLo4uzjaLetFx6NH3PMwFP3qbRbTf3D`).
(например. `http://127.0.0.1:43110/1MCoA8rQHhwu4LY2t2aabqcGSRqrL8uf2X`).
* Когда вы посещаете новый сайт zeronet, он пытается найти пиров с помощью BitTorrent
чтобы загрузить файлы сайтов (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
- 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) запустить тор через команду `tor --ControlPort 9051 --CookieAuthentication 1` (вы можете открыть новый сеанс свайпом вправо)
#### Создание зависимостей Python и запуск
#### Скрипт, который всё сделает за вас
- после установки общих зависимостей и клонирования репозитория (как указано выше) запустите `start-venv.sh` который создаст для вас виртуальную среду (если её ещё нет) и установит необходимые пакеты Python
- больше удобных скриптов будует добавлено в ближайшее время
#### Установка Python-зависимостей и запуск
- клонируйте репозиторий (NOTE: на Android/Termux вы должны клонировать его в «домашнюю» папку Termux, потому что виртуальная среда не может находиться в `storage/`)
- `python3 -m venv venv` (создайте виртуальную среду python, последнее `venv` это просто имя/название, если вы используете другое, вы должны заменить его в более поздних командах.)
- `source venv/bin/activate` (активируйте среду)
@ -96,18 +101,14 @@ zeronet-conservancy — это форк/продолжение проекта [Z
- `source venv/bin/activate`
- `python3 zeronet.py`
#### Создание образа Docker
- создание образа: `docker build -t 0net:conservancy . -f Dockerfile`
- или создрание образа с встроенным tor: `docker build -t 0net:conservancy . -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
- создание образа: `docker build -t 0net-conservancy:latest . -f Dockerfile`
- или создрание образа с встроенным 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:latest`
- /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.
#### альтернативный скрипт
- после установки общих зависимостей и клонирования репозитория (как указано выше) запустите `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)
(NOTE THAT TRANSLATIONS ARE USUALLY BEHIND THIS FILE)
[по-русски](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
(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
## 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?
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)
* Plugin for multiuser (openproxy) support
* Works with any modern browser/OS
* Works offline and can be synced via alternative transports (or when connection is back)
## How does it work?
* 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/126NXcevn1AUehWFZLTBw7FrX1crEizQdr`).
`http://127.0.0.1:43110/1MCoA8rQHhwu4LY2t2aabqcGSRqrL8uf2X/`).
* 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.
* 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)
- [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
### 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)
- 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)
@ -84,7 +93,7 @@ if you're on NixOS
(thanks @fgaz for making & maintaining the package)
### Install from source (recommended)
### Install from source
#### System dependencies
@ -105,7 +114,7 @@ Install autoconf and other basic development tools, python3 and pip, then procee
- (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)
#### 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/`)
- `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)
@ -116,13 +125,19 @@ Install autoconf and other basic development tools, python3 and pip, then procee
- `source venv/bin/activate`
- `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
- build 0net image: `docker build -t 0net:conservancy . -f Dockerfile`
- or build 0net image with integrated tor: `docker build -t 0net:conservancy . -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`
- build 0net image: `docker build -t 0net-conservancy:latest . -f Dockerfile`
- 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: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!
- 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.
(please check if these instructions are still accurate)
#### 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
@ -142,7 +157,7 @@ Install autoconf and other basic development tools, python3 and pip, then procee
- `cd zeronet-conservancy`
- `python -m venv venv` (create virtual python 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)
- [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)
@ -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)
* No data transparency
* 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?
* 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 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/)
@ -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,
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
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
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
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.
@ -209,3 +232,26 @@ private, a Monero wallet:
If you want to donate in a different way, feel free to contact maintainer or
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
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:
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
for auth_address in matches:
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 super(SiteStoragePlugin, self).updateDbFile(inner_path, file=file, cur=cur)
def onUpdated(self, inner_path, file=None):
file_path = "%s/%s" % (self.site.address, inner_path)
if file_path in filter_storage.file_content["includes"]:
self.log.debug("Filter file updated: %s" % inner_path)
file_path = f'{self.site.address}/{inner_path}'
if file_path in filter_storage.file_content['includes']:
self.log.debug('Filter file updated: {inner_path}')
filter_storage.includeUpdateAll()
return super(SiteStoragePlugin, self).onUpdated(inner_path, file=file)

View file

@ -12,6 +12,7 @@ import urllib.parse
import gevent
import util
import main
from Config import config
from Plugin import PluginManager
from Debug import Debug
@ -115,11 +116,11 @@ class UiWebsocketPlugin(object):
local_html = ""
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)
copy_link = "http://127.0.0.1:43110/%s/?zeronet_peers=%s" % (
site.content_manager.contents.get("content.json", {}).get("domain", site.address),
",".join(peer_ips)
)
copy_link = f'http://127.0.0.1:43110/{site.address}/?zeronet_peers={",".join(peer_ips)}'
body.append(_("""
<li>
@ -421,7 +422,7 @@ class UiWebsocketPlugin(object):
print('No dashboard found, cannot favourite')
class_favourite = "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_unfavourite = "hidden"
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_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_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:
body.append(_("""
<li>
@ -482,6 +484,15 @@ class UiWebsocketPlugin(object):
<a href='monero:{donate_xmr}' class='button'>{_[Donate Monero]}</a>
</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:
body.append(_("""
</li>

View file

@ -17366,7 +17366,10 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
var kw = keywords[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("variable", "variable", word)

View file

@ -126,7 +126,10 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
var kw = keywords[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("variable", "variable", word)

View file

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

View file

@ -1,9 +1,9 @@
gevent==1.4.0; python_version <= "3.6"
greenlet==0.4.16; python_version <= "3.6"
gevent>=20.9.0; python_version >= "3.7"
msgpack>=0.4.4
setuptools>=65.5.1 # not directly required, pinned by Snyk to avoid a vulnerability
gevent>=20.9.0
msgpack>=0.6.0
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
PySocks>=1.6.8
pyasn1

View file

@ -92,15 +92,103 @@ trackers = [
'udp://vibe.sleepyinternetfun.xyz:1738/announce',
'udp://www.skynetcenter.me:6969/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):
def __init__(self, argv):
self.version = "0.7.7+"
self.version = "0.7.9+"
self.user_agent = "conservancy"
# DEPRECATED ; replace with git-generated commit
self.rev = 5036
self.rev = 5110
self.user_agent_rev = 8192
self.argv = argv
self.action = None
self.test_parser = None

View file

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

View file

@ -85,16 +85,16 @@ class ContentManager(object):
new_ts = int(float(new_content.get('modified', 0)))
old_ts = int(float(old_content.get('modified', 0)))
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 [], []
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 [], []
except Exception as err:
self.log.warning(f'{content_path} load error: {Debug.formatException(err)}')
return [], []
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
try:
@ -793,7 +793,7 @@ class ContentManager(object):
return 1 # Todo: Multisig
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)
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 json
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", "")))
for retry in range(1, 4): # Retry 3 times
for retry in range(3):
try:
if not self.connection:
# this is redundant, already established that self.connection is present
@ -165,7 +165,7 @@ class Peer(object):
if "error" in res:
self.log("%s error: %s" % (cmd, res["error"]))
self.onConnectionError("Response error")
break
return res
else: # Successful request, reset connection error num
self.connection_error = 0
self.time_response = time.time()
@ -183,9 +183,9 @@ class Peer(object):
"%s (connection_error: %s, hash_failed: %s, retry: %s)" %
(Debug.formatException(err), self.connection_error, self.hash_failed, retry)
)
time.sleep(1 * retry)
time.sleep(retry+1)
self.connect()
return None # Failed after 4 retry
return None # Failed after 3 attempts
# Get a file content from peer
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):
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()
# sha1 is used for clearnet trackers
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.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 RateLimit
from util import Cached
from .Site import Site
from Debug import Debug
@PluginManager.acceptPlugins
@ -31,6 +30,7 @@ class SiteManager(object):
# Load all sites from data/sites.json
@util.Noparallel()
def load(self, cleanup=True, startup=False):
from .Site import Site
self.log.info("Loading sites... (cleanup: %s, startup: %s)" % (cleanup, startup))
self.loaded = False
address_found = []
@ -169,6 +169,7 @@ class SiteManager(object):
return site
def add(self, address, all_file=True, settings=None, **kwargs):
from .Site import Site
self.sites_changed = int(time.time())
# Try to find site with differect case
for recover_address, recover_site in list(self.sites.items()):

View file

@ -176,7 +176,7 @@ class UiRequest(object):
return self.actionConsole()
# Wrapper-less static files
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/"):
return self.actionSiteAdd()
@ -372,7 +372,7 @@ class UiRequest(object):
# Redirect to an url
def actionRedirect(self, url):
self.start_response('301 Redirect', [('Location', str(url))])
yield self.formatRedirect(url)
return self.formatRedirect(url)
def actionIndex(self):
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)
if match:
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["request_address"] = path_parts["address"] # Original request address (for Merger sites)
path_parts["inner_path"] = path_parts["inner_path"].lstrip("/")
@ -645,12 +647,19 @@ class UiRequest(object):
return None
# 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:
path_parts = self.parsePath(path)
except SecurityError as 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:
return self.error404(path)

View file

@ -262,7 +262,14 @@ class UiWebsocket(object):
del(content["signers_sign"])
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 = {
"auth_address": self.user.getAuthAddress(site.address, create=create_user),
@ -281,49 +288,88 @@ class UiWebsocket(object):
"workers": len(site.worker_manager.workers),
"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"]:
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
return ret
def formatServerInfo(self):
import main
file_server = main.file_server
if file_server.port_opened == {}:
ip_external = None
# unprivileged sites should not get any fingerprinting information
if "ADMIN" in self.site.settings['permissions']:
import main
file_server = main.file_server
if file_server.port_opened == {}:
ip_external = None
else:
ip_external = any(file_server.port_opened.values())
back = {
'ip_external' : ip_external,
'port_opened' : file_server.port_opened,
'platform' : sys.platform,
'dist_type' : config.dist_type,
'fileserver_ip' : config.fileserver_ip,
'fileserver_port' : config.fileserver_port,
'tor_enabled' : file_server.tor_manager.enabled,
'tor_status' : file_server.tor_manager.status,
'tor_has_meek_bridges' : file_server.tor_manager.has_meek_bridges,
'tor_use_bridges' : config.tor_use_bridges,
'ui_ip' : config.ui_ip,
'ui_port' : config.ui_port,
'version' : config.version,
'rev' : config.rev,
'timecorrection' : file_server.timecorrection,
'language' : config.language,
'debug' : config.debug,
'offline' : config.offline,
'plugins' : PluginManager.plugin_manager.plugin_names,
'plugins_rev' : PluginManager.plugin_manager.plugins_rev,
'user_settings' : self.user.settings,
'lib_verify_best' : CryptBitcoin.lib_verify_best
}
else:
ip_external = any(file_server.port_opened.values())
back = {
"ip_external": ip_external,
"port_opened": file_server.port_opened,
"platform": sys.platform,
"fileserver_ip": config.fileserver_ip,
"fileserver_port": config.fileserver_port,
"tor_enabled": file_server.tor_manager.enabled,
"tor_status": file_server.tor_manager.status,
"tor_has_meek_bridges": file_server.tor_manager.has_meek_bridges,
"tor_use_bridges": config.tor_use_bridges,
"ui_ip": config.ui_ip,
"ui_port": config.ui_port,
"version": config.version,
"rev": config.rev,
"timecorrection": file_server.timecorrection,
"language": config.language,
"debug": config.debug,
"offline": config.offline,
"plugins": PluginManager.plugin_manager.plugin_names,
"plugins_rev": PluginManager.plugin_manager.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
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 #?
}
return back
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 -
@ -465,6 +511,8 @@ class UiWebsocket(object):
# 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):
# 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:
inner_path = self.actionSiteSign(
to, privatekey, inner_path, response_ok=False,

View file

@ -234,6 +234,19 @@ class Actions(object):
# Not found in users.json, ask from console
import getpass
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:
succ = site.content_manager.sign(
inner_path=inner_path, privatekey=privatekey,

View file

@ -5,4 +5,4 @@ if [ ! -f venv/bin/activate ] ; then
fi
source venv/bin/activate
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
from src.Config import config
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}'
# fix further imports from src dir
sys.modules['Config'] = sys.modules['src.Config']
def fancy_greet():
from rich.console import Console
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():
def launch():
'''renamed from main to avoid clashes with main module'''
if sys.version_info.major < 3:
print("Error: Python 3.x is required")
sys.exit(0)
if '--silent' not in sys.argv:
fancy_greet()
from greet import fancy_greet
fancy_greet(config.version)
main = None
try:
import main
main.start()
@ -155,6 +123,7 @@ def restart():
def start():
config.working_dir = os.getcwd()
app_dir = os.path.dirname(os.path.abspath(__file__))
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
@ -166,7 +135,7 @@ def start():
import update
update.update()
else:
main()
launch()
if __name__ == '__main__':