summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMicah Lee <micah@micahflee.com>2018-11-25 13:51:41 -0800
committerMicah Lee <micah@micahflee.com>2018-11-25 13:51:41 -0800
commit87d10e196315ce8e0e1cf30307fefac8d5f9df57 (patch)
tree15197122bb7aadaab6273179bc35d8aee020a8bb
parent24a4e1567a4089982045079927cf4c114e0bc285 (diff)
parentb2a98fb5e71ab042d377bee8754c0b78adfed66a (diff)
downloadonionshare-87d10e196315ce8e0e1cf30307fefac8d5f9df57.tar.gz
onionshare-87d10e196315ce8e0e1cf30307fefac8d5f9df57.zip
Merge branch 'develop' into 819_update_readme
-rw-r--r--.circleci/config.yml26
-rw-r--r--BUILD.md12
-rwxr-xr-xinstall/build_rpm.sh2
-rw-r--r--install/requirements.txt3
-rw-r--r--onionshare/onion.py42
-rw-r--r--onionshare/onionkey.py129
-rw-r--r--stdeb.cfg6
7 files changed, 65 insertions, 155 deletions
diff --git a/.circleci/config.yml b/.circleci/config.yml
index b8758353..70fa3b7c 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -3,12 +3,18 @@
# Check https://circleci.com/docs/2.0/language-python/ for more details
#
version: 2
+workflows:
+ version: 2
+ test:
+ jobs:
+ - test-3.5
+ - test-3.6
+ - test-3.7
+
jobs:
- build:
+ test-3.5: &test-template
docker:
- # specify the version you desire here
- # use `-browsers` prefix for selenium tests, e.g. `3.6.1-browsers`
- - image: circleci/python:3.6.6
+ - image: circleci/python:3.5.6
working_directory: ~/repo
@@ -18,7 +24,8 @@ jobs:
- run:
name: install dependencies
command: |
- sudo apt-get update && sudo apt-get install -y python3-pip python3-flask python3-stem python3-pyqt5 python3-cryptography python3-crypto python3-nacl python3-socks python3-stdeb python3-all python-nautilus xvfb obfs4proxy
+ sudo apt-get update
+ sudo apt-get install -y python3-pip python3-flask python3-stem python3-pyqt5 python3-crypto python3-socks python3-stdeb python3-all python-nautilus xvfb obfs4proxy
sudo pip3 install -r install/requirements.txt
sudo pip3 install -r install/requirements-tests.txt
sudo pip3 install pytest-cov flake8
@@ -37,3 +44,12 @@ jobs:
command: |
xvfb-run pytest --cov=onionshare --cov=onionshare_gui --cov-report=term-missing -vvv tests/
+ test-3.6:
+ <<: *test-template
+ docker:
+ - image: circleci/python:3.6.6
+
+ test-3.7:
+ <<: *test-template
+ docker:
+ - image: circleci/python:3.7.1
diff --git a/BUILD.md b/BUILD.md
index 2a055d98..7663ec23 100644
--- a/BUILD.md
+++ b/BUILD.md
@@ -11,11 +11,17 @@ cd onionshare
Install the needed dependencies:
-For Debian-like distros: `apt install -y python3-flask python3-stem python3-pyqt5 python3-cryptography python3-crypto python3-nacl python3-socks python-nautilus tor obfs4proxy python3-pytest build-essential fakeroot python3-all python3-stdeb dh-python`
+For Debian-like distros:
-On some older versions of Debian you may need to install pysha3 with `pip3 install pysha3` if python3-sha3 is not available.
+```
+apt install -y python3-flask python3-stem python3-pyqt5 python3-crypto python3-socks python-nautilus tor obfs4proxy python3-pytest build-essential fakeroot python3-all python3-stdeb dh-python
+```
+
+For Fedora-like distros:
-For Fedora-like distros: `dnf install -y python3-flask python3-stem python3-qt5 python3-pynacl python3-cryptography python3-crypto python3-pysocks nautilus-python tor obfs4 python3-pytest rpm-build`
+```
+dnf install -y python3-flask python3-stem python3-qt5 python3-crypto python3-pysocks nautilus-python tor obfs4 python3-pytest rpm-build
+```
After that you can try both the CLI and the GUI version of OnionShare:
diff --git a/install/build_rpm.sh b/install/build_rpm.sh
index 3f7a68ac..7a34b271 100755
--- a/install/build_rpm.sh
+++ b/install/build_rpm.sh
@@ -9,7 +9,7 @@ VERSION=`cat share/version.txt`
rm -r build dist >/dev/null 2>&1
# build binary package
-python3 setup.py bdist_rpm --requires="python3-flask, python3-stem, python3-qt5, python3-pynacl, python3-cryptography, python3-crypto, python3-pysocks, nautilus-python, tor, obfs4"
+python3 setup.py bdist_rpm --requires="python3-flask, python3-stem, python3-qt5, python3-cryptography, python3-crypto, python3-pysocks, nautilus-python, tor, obfs4"
# install it
echo ""
diff --git a/install/requirements.txt b/install/requirements.txt
index 32ec6887..20811f7b 100644
--- a/install/requirements.txt
+++ b/install/requirements.txt
@@ -16,12 +16,11 @@ pefile==2018.8.8
pycparser==2.18
pycryptodome==3.6.6
PyInstaller==3.4
-PyNaCl==1.2.1
PyQt5==5.11.2
PyQt5-sip==4.19.12
PySocks==1.6.8
requests==2.19.1
six==1.11.0
-stem==1.6.0
+stem==1.7.0
urllib3==1.23
Werkzeug==0.14.1
diff --git a/onionshare/onion.py b/onionshare/onion.py
index cb73e976..6066f059 100644
--- a/onionshare/onion.py
+++ b/onionshare/onion.py
@@ -21,10 +21,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
from stem.control import Controller
from stem import ProtocolError, SocketClosed
from stem.connection import MissingPassword, UnreadableCookieFile, AuthenticationFailure
+from Crypto.PublicKey import RSA
import base64, os, sys, tempfile, shutil, urllib, platform, subprocess, time, shlex
from distutils.version import LooseVersion as Version
-from . import onionkey
from . import common, strings
from .settings import Settings
@@ -441,8 +441,7 @@ class Onion(object):
if self.settings.get('private_key'):
key_content = self.settings.get('private_key')
- # is the key a v2 key?
- if onionkey.is_v2_key(key_content):
+ if self.is_v2_key(key_content):
key_type = "RSA1024"
# The below section is commented out because re-publishing
# a pre-prepared v3 private key is currently unstable in Tor.
@@ -458,29 +457,33 @@ class Onion(object):
# key_type = "ED25519-V3"
else:
raise TorErrorProtocolError(strings._('error_invalid_private_key'))
+
else:
+ key_type = "NEW"
# Work out if we can support v3 onion services, which are preferred
if Version(self.tor_version) >= Version('0.3.3.1') and not self.settings.get('use_legacy_v2_onions'):
- key_type = "ED25519-V3"
- key_content = onionkey.generate_v3_private_key()[0]
+ key_content = "ED25519-V3"
else:
# fall back to v2 onion services
- key_type = "RSA1024"
- key_content = onionkey.generate_v2_private_key()[0]
+ key_content = "RSA1024"
# v3 onions don't yet support basic auth. Our ticket:
# https://github.com/micahflee/onionshare/issues/697
- if key_type == "ED25519-V3" and not self.settings.get('use_legacy_v2_onions'):
+ if key_type == "NEW" and key_content == "ED25519-V3" and not self.settings.get('use_legacy_v2_onions'):
basic_auth = None
self.stealth = False
- self.common.log('Onion', 'start_onion_service', 'key_type={}'.format(key_type))
+ debug_message = 'key_type={}'.format(key_type)
+ if key_type == "NEW":
+ debug_message += ', key_content={}'.format(key_content)
+ self.common.log('Onion', 'start_onion_service', '{}'.format(debug_message))
+ await_publication = True
try:
if basic_auth != None:
- res = self.c.create_ephemeral_hidden_service({ 80: port }, await_publication=True, basic_auth=basic_auth, key_type=key_type, key_content=key_content)
+ res = self.c.create_ephemeral_hidden_service({ 80: port }, await_publication=await_publication, basic_auth=basic_auth, key_type=key_type, key_content=key_content)
else:
# if the stem interface is older than 1.5.0, basic_auth isn't a valid keyword arg
- res = self.c.create_ephemeral_hidden_service({ 80: port }, await_publication=True, key_type=key_type, key_content=key_content)
+ res = self.c.create_ephemeral_hidden_service({ 80: port }, await_publication=await_publication, key_type=key_type, key_content=key_content)
except ProtocolError as e:
raise TorErrorProtocolError(strings._('error_tor_protocol_error').format(e.args[0]))
@@ -491,7 +494,7 @@ class Onion(object):
# A new private key was generated and is in the Control port response.
if self.settings.get('save_private_key'):
if not self.settings.get('private_key'):
- self.settings.set('private_key', key_content)
+ self.settings.set('private_key', res.private_key)
if self.stealth:
# Similar to the PrivateKey, the Control port only returns the ClientAuth
@@ -575,3 +578,18 @@ class Onion(object):
return ('127.0.0.1', 9150)
else:
return (self.settings.get('socks_address'), self.settings.get('socks_port'))
+
+ def is_v2_key(self, key):
+ """
+ Helper function for determining if a key is RSA1024 (v2) or not.
+ """
+ try:
+ # Import the key
+ key = RSA.importKey(base64.b64decode(key))
+ # Is this a v2 Onion key? (1024 bits) If so, we should keep using it.
+ if key.n.bit_length() == 1024:
+ return True
+ else:
+ return False
+ except:
+ return False
diff --git a/onionshare/onionkey.py b/onionshare/onionkey.py
deleted file mode 100644
index d2c6ad17..00000000
--- a/onionshare/onionkey.py
+++ /dev/null
@@ -1,129 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
-OnionShare | https://onionshare.org/
-
-Copyright (C) 2017 Micah Lee <micah@micahflee.com>
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see <http://www.gnu.org/licenses/>.
-"""
-
-import os
-import sys
-
-import base64
-import hashlib
-# Need sha3 if python version is older than 3.6, otherwise
-# we can't use hashlib.sha3_256
-if sys.version_info < (3, 6):
- import sha3
-
-import nacl.signing
-
-from Crypto.PublicKey import RSA
-
-from cryptography.hazmat.backends import default_backend
-from cryptography.hazmat.primitives import serialization
-from cryptography.hazmat.primitives.asymmetric import rsa
-
-
-def stem_compatible_base64_blob_from_private_key(private_key_seed: bytes) -> str:
- """
- Provides a base64-encoded private key for v3-style Onions.
- """
- b = 256
-
- def bit(h: bytes, i: int) -> int:
- return (h[i // 8] >> (i % 8)) & 1
-
- def encode_int(y: int) -> bytes:
- bits = [(y >> i) & 1 for i in range(b)]
- return b''.join([bytes([(sum([bits[i * 8 + j] << j for j in range(8)]))]) for i in range(b // 8)])
-
- def expand_private_key(sk: bytes) -> bytes:
- h = hashlib.sha512(sk).digest()
- a = 2 ** (b - 2) + sum(2 ** i * bit(h, i) for i in range(3, b - 2))
- k = b''.join([bytes([h[i]]) for i in range(b // 8, b // 4)])
- assert len(k) == 32
- return encode_int(a) + k
-
- expanded_private_key = expand_private_key(private_key_seed)
- return base64.b64encode(expanded_private_key).decode()
-
-
-def onion_url_from_private_key(private_key_seed: bytes) -> str:
- """
- Derives the public key (.onion hostname) from a v3-style
- Onion private key.
- """
- signing_key = nacl.signing.SigningKey(seed=private_key_seed)
- public_key = bytes(signing_key.verify_key)
- version = b'\x03'
- checksum = hashlib.sha3_256(b".onion checksum" + public_key + version).digest()[:2]
- onion_address = "http://{}.onion".format(base64.b32encode(public_key + checksum + version).decode().lower())
- return onion_address
-
-
-def generate_v3_private_key():
- """
- Generates a private and public key for use with v3 style Onions.
- Returns both the private key as well as the public key (.onion hostname)
- """
- private_key_seed = os.urandom(32)
- private_key = stem_compatible_base64_blob_from_private_key(private_key_seed)
- onion_url = onion_url_from_private_key(private_key_seed)
- return (private_key, onion_url)
-
-
-def generate_v2_private_key():
- """
- Generates a private and public key for use with v2 style Onions.
- Returns both the serialized private key (compatible with Stem)
- as well as the public key (.onion hostname)
- """
- # Generate v2 Onion Service private key
- private_key = rsa.generate_private_key(public_exponent=65537,
- key_size=1024,
- backend=default_backend())
- hs_public_key = private_key.public_key()
-
- # Pre-generate the public key (.onion hostname)
- der_format = hs_public_key.public_bytes(encoding=serialization.Encoding.DER,
- format=serialization.PublicFormat.PKCS1)
-
- onion_url = base64.b32encode(hashlib.sha1(der_format).digest()[:-10]).lower().decode()
-
- # Generate Stem-compatible key content
- pem_format = private_key.private_bytes(encoding=serialization.Encoding.PEM,
- format=serialization.PrivateFormat.TraditionalOpenSSL,
- encryption_algorithm=serialization.NoEncryption())
- serialized_key = ''.join(pem_format.decode().split('\n')[1:-2])
-
- return (serialized_key, onion_url)
-
-
-def is_v2_key(key):
- """
- Helper function for determining if a key is RSA1024 (v2) or not.
- """
- try:
- # Import the key
- key = RSA.importKey(base64.b64decode(key))
- # Is this a v2 Onion key? (1024 bits) If so, we should keep using it.
- if key.n.bit_length() == 1024:
- return True
- else:
- return False
- except:
- return False
-
diff --git a/stdeb.cfg b/stdeb.cfg
index 2fc3d3bf..6729d1b7 100644
--- a/stdeb.cfg
+++ b/stdeb.cfg
@@ -1,6 +1,6 @@
[DEFAULT]
Package3: onionshare
-Depends3: python3-flask, python3-stem, python3-pyqt5, python3-cryptography, python3-crypto, python3-nacl, python3-socks, python-nautilus, tor, obfs4proxy
-Build-Depends: python3-pytest, python3-flask, python3-stem, python3-pyqt5, python3-cryptography, python3-crypto, python3-nacl, python3-socks, python-nautilus, tor, obfs4proxy
+Depends3: python3-flask, python3-stem, python3-pyqt5, python3-crypto, python3-socks, python-nautilus, tor, obfs4proxy
+Build-Depends: python3-pytest, python3-flask, python3-stem, python3-pyqt5, python3-crypto, python3-socks, python-nautilus, tor, obfs4proxy
Suite: bionic
-X-Python3-Version: >= 3.6
+X-Python3-Version: >= 3.5.3