Merge remote-tracking branch 'micahlee/master'

This commit is contained in:
Ulrike Uhlig 2016-09-06 13:44:22 +02:00
commit 7a8c5d9353
36 changed files with 1202 additions and 1156 deletions

View File

@ -11,10 +11,23 @@ cd onionshare
*For .deb-based distros (like Debian, Ubuntu, Linux Mint):* *For .deb-based distros (like Debian, Ubuntu, Linux Mint):*
Note that python3-stem appears in Debian wheezy and newer, and it appears in Ubuntu 13.10 and newer. Older versions of Debian and Ubuntu aren't supported. Then install the needed dependencies:
```sh ```sh
sudo apt-get install -y build-essential fakeroot python3-all python3-stdeb python3-flask python3-stem python3-pyqt5 dh-python sudo apt-get install -y python3-flask python3-stem python3-pyqt5 python-nautilus
```
After that you can try both the CLI and the GUI version of OnionShare:
```sh
./install/scripts/onionshare
./install/scripts/onionshare-gui
```
A script to build a .deb package and install OnionShare easily is also provided for your convenience:
```sh
sudo apt-get install -y build-essential fakeroot python3-all python3-stdeb dh-python python-nautilus
./install/build_deb.sh ./install/build_deb.sh
sudo dpkg -i deb_dist/onionshare_*.deb sudo dpkg -i deb_dist/onionshare_*.deb
``` ```
@ -23,7 +36,7 @@ Note that OnionShare uses stdeb to generate Debian packages, and `python3-stdeb`
*For .rpm-based distros (Red Hat, Fedora, CentOS):* *For .rpm-based distros (Red Hat, Fedora, CentOS):*
```sh ```sh
sudo sudo dnf install -y rpm-build python3-flask python3-stem python3-qt5 sudo sudo dnf install -y rpm-build python3-flask python3-stem python3-qt5 nautilus-python
./install/build_rpm.sh ./install/build_rpm.sh
sudo yum install -y dist/onionshare-*.rpm sudo yum install -y dist/onionshare-*.rpm
``` ```
@ -49,9 +62,15 @@ brew install python3 pyqt5 qt5
Install some dependencies using pip3: Install some dependencies using pip3:
```sh ```sh
sudo pip3 install pyinstaller flask stem sudo pip3 install flask stem
``` ```
Install the latest development version of cx_Freeze:
* Download a [snapshot](https://bitbucket.org/anthony_tuininga/cx_freeze/downloads) of the latest development version of cx_Freeze, extract it, and cd into the folder you extracted it to
* Build the package: `python3 setup.py bdist_wheel`
* Install it with pip: `sudo pip3 install dist/cx_Freeze-5.0-cp35-cp35m-macosx_10_11_x86_64.whl`
Get the source code: Get the source code:
```sh ```sh
@ -70,7 +89,7 @@ Now you should have `dist/OnionShare.app`.
To codesign and build a .pkg for distribution: To codesign and build a .pkg for distribution:
```sh ```sh
install/build_osx.sh --sign install/build_osx.sh --release
``` ```
Now you should have `dist/OnionShare.pkg`. Now you should have `dist/OnionShare.pkg`.
@ -81,19 +100,25 @@ Now you should have `dist/OnionShare.pkg`.
These instructions include adding folders to the path in Windows. To do this, go to Start and type "advanced system settings", and open "View advanced system settings" in the Control Panel. Click Environment Variables. Under "System variables" double-click on Path. From there you can add and remove folders that are available in the PATH. These instructions include adding folders to the path in Windows. To do this, go to Start and type "advanced system settings", and open "View advanced system settings" in the Control Panel. Click Environment Variables. Under "System variables" double-click on Path. From there you can add and remove folders that are available in the PATH.
First, download and install the 32-bit (x86) version of Python 3.4.x from https://www.python.org/downloads/windows/. You need 3.4 instead of 3.5 because PyQt5 was built with 3.4. Add `C:\Python34` and `C:\Python34\Scripts` to the path. Download the latest Python 3.5.x, 32-bit (x86) from https://www.python.org/downloads/. I downloaded `python-3.5.2.exe`. When installing it, make sure to check the "Add Python 3.5 to PATH" checkbox on the first page of the installer.
Open a command prompt and install some dependencies with pip: `pip3 install pyinstaller pypiwin32 flask stem` Download and install Qt5 from https://www.qt.io/download-open-source/. I downloaded `qt-unified-windows-x86-2.0.3-1-online.exe`. There's no need to login to a Qt account during installation. Make sure you install the latest Qt 5.x.
Download and install Qt5 from https://www.qt.io/download-open-source/. I downloaded `qt-unified-windows-x86-2.0.2-2-online.exe`. There's no need to login to a Qt account during installation. Make sure you install the latest Qt 5.x. Open a command prompt and install dependencies with pip: `pip install pypiwin32 flask stem PyQt5`
Download and install the latest PyQt5 for 32-bit Windows from https://www.riverbankcomputing.com/software/pyqt/download5. I downloaded `PyQt5-5.5.1-gpl-Py3.4-Qt5.5.1-x32.exe`.
Download and install the [Microsoft Visual C++ 2008 Redistributable Package (x86)](http://www.microsoft.com/en-us/download/details.aspx?id=29). Download and install the [Microsoft Visual C++ 2008 Redistributable Package (x86)](http://www.microsoft.com/en-us/download/details.aspx?id=29).
Installing cx_Freeze with support for Python 3.5 is annoying. Here are the steps (thanks https://github.com/sekrause/cx_Freeze-Wheels):
* Download and install the Visual C++ Build Tools 2005 from http://go.microsoft.com/fwlink/?LinkId=691126. I downloaded `visualcppbuildtools_full.exe`.
* Install the python wheel package: `pip install wheel`
* Download a [snapshot](https://bitbucket.org/anthony_tuininga/cx_freeze/downloads) of the latest development version of cx_Freeze, extract it, and cd into the folder you extracted it to
* Build the package: `python setup.py bdist_wheel`
* Install it with pip: `pip install dist\cx_Freeze-5.0-cp35-cp35m-win32.whl`
If you want to build the installer: If you want to build the installer:
* Go to http://nsis.sourceforge.net/Download and download the latest NSIS. I downloaded `nsis-3.0b0-setup.exe`. * Go to http://nsis.sourceforge.net/Download and download the latest NSIS. I downloaded `nsis-3.0-setup.exe`.
* Add `C:\Program Files (x86)\NSIS` to the path. * Add `C:\Program Files (x86)\NSIS` to the path.
If you want to sign binaries with Authenticode: If you want to sign binaries with Authenticode:
@ -110,7 +135,7 @@ If you want to sign binaries with Authenticode:
### To make a .exe: ### To make a .exe:
* Open a command prompt, cd into the onionshare directory, and type: `pyinstaller install\pyinstaller.spec -y`. `onionshare.exe` and all of its supporting files will get created inside the `dist\onionshare` folder. * Open a command prompt, cd into the onionshare directory, and type: `python setup.py build`. `onionshare.exe`, `onionshare-gui.exe`, and all of their supporting files will get created inside the `build\exe.win32-3.5` folder.
### To build the installer: ### To build the installer:

View File

@ -8,3 +8,4 @@ include resources/html/*
include install/onionshare.desktop include install/onionshare.desktop
include install/onionshare.appdata.xml include install/onionshare.appdata.xml
include install/onionshare80.xpm include install/onionshare80.xpm
include install/scripts/onionshare-nautilus.py

View File

@ -2,7 +2,7 @@
[![Build Status](https://travis-ci.org/micahflee/onionshare.png)](https://travis-ci.org/micahflee/onionshare) [![Build Status](https://travis-ci.org/micahflee/onionshare.png)](https://travis-ci.org/micahflee/onionshare)
OnionShare lets you securely and anonymously share files of any size. It works by starting a web server, making it accessible as a Tor hidden service, and generating an unguessable URL to access and download the files. It doesn't require setting up a server on the internet somewhere or using a third party filesharing service. You host the file on your own computer and use a Tor hidden service to make it temporarily accessible over the internet. The other user just needs to use Tor Browser to download the file from you. OnionShare lets you securely and anonymously share files of any size. It works by starting a web server, making it accessible as a Tor onion service, and generating an unguessable URL to access and download the files. It doesn't require setting up a server on the internet somewhere or using a third party filesharing service. You host the file on your own computer and use a Tor onion service to make it temporarily accessible over the internet. The other user just needs to use Tor Browser to download the file from you.
Features include: Features include:
@ -27,9 +27,9 @@ You can set up your development environment to build OnionShare yourself by foll
## How to Use ## How to Use
Before you can share files, you need to open [Tor Browser](https://www.torproject.org/) in the background. This will provide the Tor service that OnionShare uses to start the hidden service. Before you can share files, you need to open [Tor Browser](https://www.torproject.org/) in the background. This will provide the Tor service that OnionShare uses to start the onion service.
Open OnionShare and drag and drop files and folders you wish to share, and click Start Sharing. It will show you .onion URL such as `http://asxmi4q6i7pajg2b.onion/egg-cain` and copy it to your clipboard. This is the secret URL that can be used to download the file you're sharing. If you'd like multiple people to be able to download this file, uncheck the "close automatically" checkbox. Open OnionShare and drag and drop files and folders you wish to share, and click Start Sharing. It will show you a .onion URL such as `http://asxmi4q6i7pajg2b.onion/egg-cain` and copy it to your clipboard. This is the secret URL that can be used to download the file you're sharing. If you'd like multiple people to be able to download this file, uncheck the "close automatically" checkbox.
Send this URL to the person you're trying to send the files to. If the files you're sending aren't secret, you can use normal means of sending the URL: emailing it, posting it to Facebook or Twitter, etc. If you're trying to send secret files then it's important to send this URL securely. Send this URL to the person you're trying to send the files to. If the files you're sending aren't secret, you can use normal means of sending the URL: emailing it, posting it to Facebook or Twitter, etc. If you're trying to send secret files then it's important to send this URL securely.

View File

@ -4,20 +4,20 @@
OnionShare is a tool that helps users securely and anonymously share files over the internet. OnionShare is a tool that helps users securely and anonymously share files over the internet.
First, the sender chooses files and folders they wish to share with the recipient. OnionShare then starts a web server at `127.0.0.1` on a random port. It chooses two words from a 6800-long wordlist called a slug, and makes the files available for download at `http://127.0.0.1:[port]/[slug]/`. It then makes the web server accessible as Tor hidden service, and displays the URL `http://[hiddenservice].onion/[slug]` to the sender to share. A final OnionShare URL looks something like `http://f5ratndpx7rgvh7i.onion/fold-foxy`. First, the sender chooses files and folders they wish to share with the recipient. OnionShare then starts a web server at `127.0.0.1` on a random port. It chooses two words from a 6800-long wordlist called a slug, and makes the files available for download at `http://127.0.0.1:[port]/[slug]/`. It then makes the web server accessible as Tor onion service, and displays the URL `http://[onionservice].onion/[slug]` to the sender to share. A final OnionShare URL looks something like `http://f5ratndpx7rgvh7i.onion/fold-foxy`.
The sender is responsible for securely sharing that URL with the recipient using a communication channel of their choice, such as in an encrypted email, chat, or voice call, or something less secure like a Twitter or Facebook message, depending on their threat model. The sender is responsible for securely sharing that URL with the recipient using a communication channel of their choice, such as in an encrypted email, chat, or voice call, or something less secure like a Twitter or Facebook message, depending on their threat model.
The recipient must use Tor Browser to load the URL and download the files. The recipient must use Tor Browser to load the URL and download the files.
As soon as the shared files get downloaded, or when the sender closes OnionShare, the Tor hidden service and web servers shut down, completely removing the files from the internet (there is an option to not shut down after the first download, to allow the files to be downloaded multiple times). Because of this, OnionShare is most useful if it's used in real-time. For example, if a user runs OnionShare on their laptop, and then suspends their laptop before the files have been downloaded, the service will not be available until the laptop is unsuspended and connected to the internet again. As soon as the shared files get downloaded, or when the sender closes OnionShare, the Tor onion service and web servers shut down, completely removing the files from the internet (there is an option to not shut down after the first download, to allow the files to be downloaded multiple times). Because of this, OnionShare is most useful if it's used in real-time. For example, if a user runs OnionShare on their laptop, and then suspends their laptop before the files have been downloaded, the service will not be available until the laptop is unsuspended and connected to the internet again.
## What it protects against ## What it protects against
* **Third parties don't have access to files being shared.** The files are hosted directly on the sender's computer and don't get uploaded to any server. Instead, the sender's computer becomes the server. Traditional ways of sending files, like in an email or using a cloud hosting service, require trusting the service with access to the files being shared. * **Third parties don't have access to files being shared.** The files are hosted directly on the sender's computer and don't get uploaded to any server. Instead, the sender's computer becomes the server. Traditional ways of sending files, like in an email or using a cloud hosting service, require trusting the service with access to the files being shared.
* **Network eavesdroppers can't spy on files in transit.** Because connections between Tor hidden services and Tor Browser are end-to-end encrypted, no network attackers can eavesdrop on the shared files while the recipient is downloading them. If the eavesdropper is positioned on the sender's end, the recipient's end, or is a malicious Tor node, they will only see Tor traffic. If the eavesdropper is a malicious rendezvous node used to connect the recipient's Tor client with the sender's hidden service, the traffic will be encrypted using the hidden service key. * **Network eavesdroppers can't spy on files in transit.** Because connections between Tor onion services and Tor Browser are end-to-end encrypted, no network attackers can eavesdrop on the shared files while the recipient is downloading them. If the eavesdropper is positioned on the sender's end, the recipient's end, or is a malicious Tor node, they will only see Tor traffic. If the eavesdropper is a malicious rendezvous node used to connect the recipient's Tor client with the sender's onion service, the traffic will be encrypted using the onion service key.
* **Anonymity of sender and recipient are protected by Tor.** OnionShare and Tor Browser protect the anonymity of the users. As long as the sender anonymously communicates the OnionShare URL with the recipient, the recipient and eavesdroppers can't learn the identity of the sender. * **Anonymity of sender and recipient are protected by Tor.** OnionShare and Tor Browser protect the anonymity of the users. As long as the sender anonymously communicates the OnionShare URL with the recipient, the recipient and eavesdroppers can't learn the identity of the sender.
* **If an attacker enumerates the hidden service, the shared files remain safe.** There have been attacks against the Tor network that can enumerate hidden services. If someone discovers the .onion address of an OnionShare hidden service, they still cannot download the shared files without knowing the slug. The slug is generated by choosing two random words from a list of 6800 words, meaning there are 6800^2, or about 46 million possible slugs. But they can only make 20 wrong guesses before OnionShare stops the server, preventing brute force attacks against the slug. The OnionShare server also checks request URIs using a constant time string comparison function, so timing attacks can't be used to help guess the slug. * **If an attacker enumerates the onion service, the shared files remain safe.** There have been attacks against the Tor network that can enumerate onion services. If someone discovers the .onion address of an OnionShare onion service, they still cannot download the shared files without knowing the slug. The slug is generated by choosing two random words from a list of 6800 words, meaning there are 6800^2, or about 46 million possible slugs. But they can only make 20 wrong guesses before OnionShare stops the server, preventing brute force attacks against the slug. The OnionShare server also checks request URIs using a constant time string comparison function, so timing attacks can't be used to help guess the slug.
## What it doesn't protect against ## What it doesn't protect against

18
install/Info.plist Normal file
View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>onionshare-gui</string>
<key>CFBundleIdentifier</key>
<string>com.micahflee.onionshare</string>
<key>NSHighResolutionCapable</key>
<true/>
<key>CFBundleShortVersionString</key>
<string>{VERSION}</string>
<key>CFBundleIconFile</key>
<string>icon.icns</string>
</dict>
</plist>

View File

@ -1,10 +1,12 @@
REM use PyInstaller to builder a folder with onionshare.exe REM build onionshare.exe, onionshare-gui.exe
pyinstaller install\pyinstaller.spec -y python setup.py build
REM sign onionshare.exe REM sign onionshare.exe, onionshare-gui.exe
signtool.exe sign /v /d "OnionShare" /a /tr http://timestamp.globalsign.com/scripts/timstamp.dll /fd sha256 dist\onionshare\onionshare.exe signtool.exe sign /v /d "OnionShare" /a /tr http://timestamp.globalsign.com/scripts/timstamp.dll /fd sha256 build\exe.win32-3.5\onionshare.exe
signtool.exe sign /v /d "OnionShare" /a /tr http://timestamp.globalsign.com/scripts/timstamp.dll /fd sha256 build\exe.win32-3.5\onionshare-gui.exe
REM build an installer, dist\OnionShare_Setup.exe REM build an installer, dist\OnionShare_Setup.exe
mkdir dist
makensis.exe install\onionshare.nsi makensis.exe install\onionshare.nsi
REM sign OnionShare_Setup.exe REM sign OnionShare_Setup.exe

View File

@ -5,19 +5,27 @@ cd $ROOT
# deleting dist # deleting dist
echo Deleting dist folder echo Deleting dist folder
rm -rf $ROOT/dist &>/dev/null 2>&1 rm -rf $ROOT/build $ROOT/dist &>/dev/null 2>&1
# build the .app # build the .app
echo Building OnionShare.app echo Building OnionShare.app
pyinstaller install/pyinstaller.spec python3 setup.py bdist_mac
if [ "$1" = "--sign" ]; then if [ "$1" = "--release" ]; then
SIGNING_IDENTITY_APP="3rd Party Mac Developer Application: Micah Lee" mkdir -p dist
SIGNING_IDENTITY_INSTALLER="3rd Party Mac Developer Installer: Micah Lee" APP_PATH="build/OnionShare.app"
PKG_PATH="dist/OnionShare.pkg"
IDENTITY_NAME_APPLICATION="Developer ID Application: Micah Lee"
IDENTITY_NAME_INSTALLER="Developer ID Installer: Micah Lee"
# codesign the .app echo "Codesigning the app bundle"
codesign -vvvv --deep -s "$SIGNING_IDENTITY_APP" dist/OnionShare.app codesign --deep -s "$IDENTITY_NAME_APPLICATION" "$APP_PATH"
# build .pkg echo "Creating an installer"
productbuild --component dist/OnionShare.app /Applications dist/OnionShare.pkg --sign "$SIGNING_IDENTITY_INSTALLER" productbuild --sign "$IDENTITY_NAME_INSTALLER" --component "$APP_PATH" /Applications "$PKG_PATH"
echo "Cleaning up"
rm -rf "$APP_PATH"
echo "All done, your installer is in: $PKG_PATH"
fi fi

View File

@ -9,7 +9,7 @@ VERSION=`cat resources/version.txt`
rm -r build dist >/dev/null 2>&1 rm -r build dist >/dev/null 2>&1
# build binary package # build binary package
python3 setup.py bdist_rpm --requires="python3-flask, python3-stem, python3-qt5" python3 setup.py bdist_rpm --requires="python3-flask, python3-stem, python3-qt5, nautilus-python"
# install it # install it
echo "" echo ""

View File

@ -1,18 +1,18 @@
!define APPNAME "OnionShare" !define APPNAME "OnionShare"
!define BINPATH "..\dist\onionshare" !define BINPATH "..\build\exe.win32-3.5"
!define ABOUTURL "https:\\onionshare.org\" !define ABOUTURL "https:\\onionshare.org\"
# change these with each release # change these with each release
!define INSTALLSIZE 60866 !define INSTALLSIZE 35630
!define VERSIONMAJOR 0 !define VERSIONMAJOR 0
!define VERSIONMINOR 9 !define VERSIONMINOR 9
!define VERSIONSTRING "0.9" !define VERSIONSTRING "0.9.1"
RequestExecutionLevel admin RequestExecutionLevel admin
Name "OnionShare" Name "OnionShare"
InstallDir "$PROGRAMFILES\${APPNAME}" InstallDir "$PROGRAMFILES\${APPNAME}"
LicenseData "license.txt" LicenseData "..\resources\license.txt"
Icon "onionshare.ico" Icon "onionshare.ico"
!include LogicLib.nsh !include LogicLib.nsh
@ -61,51 +61,68 @@ FunctionEnd
Section "install" Section "install"
SetOutPath "$INSTDIR" SetOutPath "$INSTDIR"
File "onionshare.ico" File "onionshare.ico"
SetOutPath "$INSTDIR\html" SetOutPath "$INSTDIR\imageformats"
File "${BINPATH}\html\404.html" File "${BINPATH}\imageformats\qdds.dll"
File "${BINPATH}\html\denied.html" File "${BINPATH}\imageformats\qgif.dll"
File "${BINPATH}\html\index.html" File "${BINPATH}\imageformats\qicns.dll"
SetOutPath "$INSTDIR\images" File "${BINPATH}\imageformats\qico.dll"
File "${BINPATH}\images\logo.png" File "${BINPATH}\imageformats\qjpeg.dll"
File "${BINPATH}\images\drop_files.png" File "${BINPATH}\imageformats\qsvg.dll"
File "${BINPATH}\images\server_stopped.png" File "${BINPATH}\imageformats\qtga.dll"
File "${BINPATH}\images\server_started.png" File "${BINPATH}\imageformats\qtiff.dll"
File "${BINPATH}\images\server_working.png" File "${BINPATH}\imageformats\qwbmp.dll"
SetOutPath "$INSTDIR\Include" File "${BINPATH}\imageformats\qwebp.dll"
File "${BINPATH}\include\pyconfig.h" SetOutPath "$INSTDIR\platforms"
SetOutPath "$INSTDIR\locale" File "${BINPATH}\platforms\qminimal.dll"
File "${BINPATH}\locale\de.json" File "${BINPATH}\platforms\qoffscreen.dll"
File "${BINPATH}\locale\en.json" File "${BINPATH}\platforms\qwindows.dll"
File "${BINPATH}\locale\eo.json" SetOutPath "$INSTDIR\resources"
File "${BINPATH}\locale\es.json" File "${BINPATH}\resources\license.txt"
File "${BINPATH}\locale\fi.json" File "${BINPATH}\resources\version.txt"
File "${BINPATH}\locale\fr.json" File "${BINPATH}\resources\wordlist.txt"
File "${BINPATH}\locale\it.json" SetOutPath "$INSTDIR\resources\html"
File "${BINPATH}\locale\nl.json" File "${BINPATH}\resources\html\404.html"
File "${BINPATH}\locale\no.json" File "${BINPATH}\resources\html\denied.html"
File "${BINPATH}\locale\pt.json" File "${BINPATH}\resources\html\index.html"
File "${BINPATH}\locale\ru.json" SetOutPath "$INSTDIR\resources\images"
File "${BINPATH}\locale\tr.json" File "${BINPATH}\resources\images\logo.png"
SetOutPath "$INSTDIR\qt5_plugins\iconengines" File "${BINPATH}\resources\images\drop_files.png"
File "${BINPATH}\qt5_plugins\iconengines\qsvgicon.dll" File "${BINPATH}\resources\images\server_stopped.png"
SetOutPath "$INSTDIR\qt5_plugins\imageformats" File "${BINPATH}\resources\images\server_started.png"
File "${BINPATH}\qt5_plugins\imageformats\qdds.dll" File "${BINPATH}\resources\images\server_working.png"
File "${BINPATH}\qt5_plugins\imageformats\qgif.dll" SetOutPath "$INSTDIR\resources\locale"
File "${BINPATH}\qt5_plugins\imageformats\qicns.dll" File "${BINPATH}\resources\locale\de.json"
File "${BINPATH}\qt5_plugins\imageformats\qico.dll" File "${BINPATH}\resources\locale\en.json"
File "${BINPATH}\qt5_plugins\imageformats\qjp2.dll" File "${BINPATH}\resources\locale\eo.json"
File "${BINPATH}\qt5_plugins\imageformats\qjpeg.dll" File "${BINPATH}\resources\locale\es.json"
File "${BINPATH}\qt5_plugins\imageformats\qmng.dll" File "${BINPATH}\resources\locale\fi.json"
File "${BINPATH}\qt5_plugins\imageformats\qsvg.dll" File "${BINPATH}\resources\locale\fr.json"
File "${BINPATH}\qt5_plugins\imageformats\qtga.dll" File "${BINPATH}\resources\locale\it.json"
File "${BINPATH}\qt5_plugins\imageformats\qtiff.dll" File "${BINPATH}\resources\locale\nl.json"
File "${BINPATH}\qt5_plugins\imageformats\qwbmp.dll" File "${BINPATH}\resources\locale\no.json"
File "${BINPATH}\qt5_plugins\imageformats\qwebp.dll" File "${BINPATH}\resources\locale\pt.json"
SetOutPath "$INSTDIR\qt5_plugins\platforms" File "${BINPATH}\resources\locale\ru.json"
File "${BINPATH}\qt5_plugins\platforms\qminimal.dll" File "${BINPATH}\resources\locale\tr.json"
File "${BINPATH}\qt5_plugins\platforms\qoffscreen.dll"
File "${BINPATH}\qt5_plugins\platforms\qwindows.dll"
SetOutPath "$INSTDIR" SetOutPath "$INSTDIR"
File "${BINPATH}\MSVCP140.dll"
File "${BINPATH}\onionshare-gui.exe"
File "${BINPATH}\onionshare.exe"
File "${BINPATH}\pyexpat.pyd"
File "${BINPATH}\PyQt5.QtCore.pyd"
File "${BINPATH}\PyQt5.QtGui.pyd"
File "${BINPATH}\PyQt5.QtWidgets.pyd"
File "${BINPATH}\python35.dll"
File "${BINPATH}\python35.zip"
File "${BINPATH}\pywintypes35.dll"
File "${BINPATH}\Qt5Core.dll"
File "${BINPATH}\Qt5Gui.dll"
File "${BINPATH}\Qt5Svg.dll"
File "${BINPATH}\Qt5Widgets.dll"
File "${BINPATH}\select.pyd"
File "${BINPATH}\sip.pyd"
File "${BINPATH}\unicodedata.pyd"
File "${BINPATH}\VCRUNTIME140.dll"
File "${BINPATH}\win32wnet.pyd"
File "${BINPATH}\_bz2.pyd" File "${BINPATH}\_bz2.pyd"
File "${BINPATH}\_ctypes.pyd" File "${BINPATH}\_ctypes.pyd"
File "${BINPATH}\_decimal.pyd" File "${BINPATH}\_decimal.pyd"
@ -114,33 +131,6 @@ Section "install"
File "${BINPATH}\_multiprocessing.pyd" File "${BINPATH}\_multiprocessing.pyd"
File "${BINPATH}\_socket.pyd" File "${BINPATH}\_socket.pyd"
File "${BINPATH}\_ssl.pyd" File "${BINPATH}\_ssl.pyd"
File "${BINPATH}\base_library.zip"
File "${BINPATH}\icudt53.dll"
File "${BINPATH}\icuin53.dll"
File "${BINPATH}\icuuc53.dll"
File "${BINPATH}\MSVCP100.dll"
File "${BINPATH}\MSVCR100.dll"
File "${BINPATH}\onionshare.exe"
File "${BINPATH}\onionshare.exe.manifest"
File "${BINPATH}\pyexpat.pyd"
File "${BINPATH}\PyQt5.Qt.pyd"
File "${BINPATH}\PyQt5.QtCore.pyd"
File "${BINPATH}\PyQt5.QtGui.pyd"
File "${BINPATH}\PyQt5.QtPrintSupport.pyd"
File "${BINPATH}\PyQt5.QtWidgets.pyd"
File "${BINPATH}\python34.dll"
File "${BINPATH}\pywintypes34.dll"
File "${BINPATH}\Qt5Core.dll"
File "${BINPATH}\Qt5Gui.dll"
File "${BINPATH}\Qt5PrintSupport.dll"
File "${BINPATH}\Qt5Svg.dll"
File "${BINPATH}\Qt5Widgets.dll"
File "${BINPATH}\select.pyd"
File "${BINPATH}\sip.pyd"
File "${BINPATH}\unicodedata.pyd"
File "${BINPATH}\version.txt"
File "${BINPATH}\win32wnet.pyd"
File "${BINPATH}\wordlist.txt"
# uninstaller # uninstaller
!ifndef INNER !ifndef INNER
@ -149,7 +139,7 @@ Section "install"
!endif !endif
# start menu # start menu
CreateShortCut "$SMPROGRAMS\${APPNAME}.lnk" "$INSTDIR\onionshare.exe" "" "$INSTDIR\onionshare.ico" CreateShortCut "$SMPROGRAMS\${APPNAME}.lnk" "$INSTDIR\onionshare-gui.exe" "" "$INSTDIR\onionshare.ico"
# registry information for add\remove programs # registry information for add\remove programs
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" "DisplayName" "${APPNAME}" WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" "DisplayName" "${APPNAME}"
@ -184,43 +174,61 @@ FunctionEnd
Delete "$SMPROGRAMS\${APPNAME}.lnk" Delete "$SMPROGRAMS\${APPNAME}.lnk"
# remove files # remove files
Delete "$INSTDIR\html\404.html" Delete "$INSTDIR\imageformats\qdds.dll"
Delete "$INSTDIR\html\denied.html" Delete "$INSTDIR\imageformats\qgif.dll"
Delete "$INSTDIR\html\index.html" Delete "$INSTDIR\imageformats\qicns.dll"
Delete "$INSTDIR\images\logo.png" Delete "$INSTDIR\imageformats\qico.dll"
Delete "$INSTDIR\images\drop_files.png" Delete "$INSTDIR\imageformats\qjpeg.dll"
Delete "$INSTDIR\images\server_stopped.png" Delete "$INSTDIR\imageformats\qsvg.dll"
Delete "$INSTDIR\images\server_started.png" Delete "$INSTDIR\imageformats\qtga.dll"
Delete "$INSTDIR\images\server_working.png" Delete "$INSTDIR\imageformats\qtiff.dll"
Delete "$INSTDIR\include\pyconfig.h" Delete "$INSTDIR\imageformats\qwbmp.dll"
Delete "$INSTDIR\locale\de.json" Delete "$INSTDIR\imageformats\qwebp.dll"
Delete "$INSTDIR\locale\en.json" Delete "$INSTDIR\platforms\qminimal.dll"
Delete "$INSTDIR\locale\eo.json" Delete "$INSTDIR\platforms\qoffscreen.dll"
Delete "$INSTDIR\locale\es.json" Delete "$INSTDIR\platforms\qwindows.dll"
Delete "$INSTDIR\locale\fi.json" Delete "$INSTDIR\resources\license.txt"
Delete "$INSTDIR\locale\fr.json" Delete "$INSTDIR\resources\version.txt"
Delete "$INSTDIR\locale\it.json" Delete "$INSTDIR\resources\wordlist.txt"
Delete "$INSTDIR\locale\nl.json" Delete "$INSTDIR\resources\html\404.html"
Delete "$INSTDIR\locale\no.json" Delete "$INSTDIR\resources\html\denied.html"
Delete "$INSTDIR\locale\pt.json" Delete "$INSTDIR\resources\html\index.html"
Delete "$INSTDIR\locale\ru.json" Delete "$INSTDIR\resources\images\logo.png"
Delete "$INSTDIR\locale\tr.json" Delete "$INSTDIR\resources\images\drop_files.png"
Delete "$INSTDIR\qt5_plugins\iconengines\qsvgicon.dll" Delete "$INSTDIR\resources\images\server_stopped.png"
Delete "$INSTDIR\qt5_plugins\imageformats\qdds.dll" Delete "$INSTDIR\resources\images\server_started.png"
Delete "$INSTDIR\qt5_plugins\imageformats\qgif.dll" Delete "$INSTDIR\resources\images\server_working.png"
Delete "$INSTDIR\qt5_plugins\imageformats\qicns.dll" Delete "$INSTDIR\resources\locale\de.json"
Delete "$INSTDIR\qt5_plugins\imageformats\qico.dll" Delete "$INSTDIR\resources\locale\en.json"
Delete "$INSTDIR\qt5_plugins\imageformats\qjp2.dll" Delete "$INSTDIR\resources\locale\eo.json"
Delete "$INSTDIR\qt5_plugins\imageformats\qjpeg.dll" Delete "$INSTDIR\resources\locale\es.json"
Delete "$INSTDIR\qt5_plugins\imageformats\qmng.dll" Delete "$INSTDIR\resources\locale\fi.json"
Delete "$INSTDIR\qt5_plugins\imageformats\qsvg.dll" Delete "$INSTDIR\resources\locale\fr.json"
Delete "$INSTDIR\qt5_plugins\imageformats\qtga.dll" Delete "$INSTDIR\resources\locale\it.json"
Delete "$INSTDIR\qt5_plugins\imageformats\qtiff.dll" Delete "$INSTDIR\resources\locale\nl.json"
Delete "$INSTDIR\qt5_plugins\imageformats\qwbmp.dll" Delete "$INSTDIR\resources\locale\no.json"
Delete "$INSTDIR\qt5_plugins\imageformats\qwebp.dll" Delete "$INSTDIR\resources\locale\pt.json"
Delete "$INSTDIR\qt5_plugins\platforms\qminimal.dll" Delete "$INSTDIR\resources\locale\ru.json"
Delete "$INSTDIR\qt5_plugins\platforms\qoffscreen.dll" Delete "$INSTDIR\resources\locale\tr.json"
Delete "$INSTDIR\qt5_plugins\platforms\qwindows.dll" Delete "$INSTDIR\MSVCP140.dll"
Delete "$INSTDIR\onionshare-gui.exe"
Delete "$INSTDIR\onionshare.exe"
Delete "$INSTDIR\pyexpat.pyd"
Delete "$INSTDIR\PyQt5.QtCore.pyd"
Delete "$INSTDIR\PyQt5.QtGui.pyd"
Delete "$INSTDIR\PyQt5.QtWidgets.pyd"
Delete "$INSTDIR\python35.dll"
Delete "$INSTDIR\python35.zip"
Delete "$INSTDIR\pywintypes35.dll"
Delete "$INSTDIR\Qt5Core.dll"
Delete "$INSTDIR\Qt5Gui.dll"
Delete "$INSTDIR\Qt5Svg.dll"
Delete "$INSTDIR\Qt5Widgets.dll"
Delete "$INSTDIR\select.pyd"
Delete "$INSTDIR\sip.pyd"
Delete "$INSTDIR\unicodedata.pyd"
Delete "$INSTDIR\VCRUNTIME140.dll"
Delete "$INSTDIR\win32wnet.pyd"
Delete "$INSTDIR\_bz2.pyd" Delete "$INSTDIR\_bz2.pyd"
Delete "$INSTDIR\_ctypes.pyd" Delete "$INSTDIR\_ctypes.pyd"
Delete "$INSTDIR\_decimal.pyd" Delete "$INSTDIR\_decimal.pyd"
@ -229,44 +237,16 @@ FunctionEnd
Delete "$INSTDIR\_multiprocessing.pyd" Delete "$INSTDIR\_multiprocessing.pyd"
Delete "$INSTDIR\_socket.pyd" Delete "$INSTDIR\_socket.pyd"
Delete "$INSTDIR\_ssl.pyd" Delete "$INSTDIR\_ssl.pyd"
Delete "$INSTDIR\base_library.zip"
Delete "$INSTDIR\icudt53.dll"
Delete "$INSTDIR\icuin53.dll"
Delete "$INSTDIR\icuuc53.dll"
Delete "$INSTDIR\MSVCP100.dll"
Delete "$INSTDIR\MSVCR100.dll"
Delete "$INSTDIR\onionshare.exe"
Delete "$INSTDIR\onionshare.exe.manifest"
Delete "$INSTDIR\pyexpat.pyd"
Delete "$INSTDIR\PyQt5.Qt.pyd"
Delete "$INSTDIR\PyQt5.QtCore.pyd"
Delete "$INSTDIR\PyQt5.QtGui.pyd"
Delete "$INSTDIR\PyQt5.QtPrintSupport.pyd"
Delete "$INSTDIR\PyQt5.QtWidgets.pyd"
Delete "$INSTDIR\python34.dll"
Delete "$INSTDIR\pywintypes34.dll"
Delete "$INSTDIR\Qt5Core.dll"
Delete "$INSTDIR\Qt5Gui.dll"
Delete "$INSTDIR\Qt5PrintSupport.dll"
Delete "$INSTDIR\Qt5Svg.dll"
Delete "$INSTDIR\Qt5Widgets.dll"
Delete "$INSTDIR\select.pyd"
Delete "$INSTDIR\sip.pyd"
Delete "$INSTDIR\unicodedata.pyd"
Delete "$INSTDIR\version.txt"
Delete "$INSTDIR\win32wnet.pyd"
Delete "$INSTDIR\wordlist.txt"
Delete "$INSTDIR\onionshare.ico"
Delete "$INSTDIR\uninstall.exe" Delete "$INSTDIR\uninstall.exe"
rmDir "$INSTDIR\html" rmDir "$INSTDIR\imageformats"
rmDir "$INSTDIR\images" rmDir "$INSTDIR\platforms"
rmDir "$INSTDIR\Include" rmDir "$INSTDIR\resources\html"
rmDir "$INSTDIR\locale" rmDir "$INSTDIR\resources\images"
rmDir "$INSTDIR\qt5_plugins\iconengines" rmDir "$INSTDIR\resources\locale"
rmDir "$INSTDIR\qt5_plugins\imageformats" rmDir "$INSTDIR\resources"
rmDir "$INSTDIR\qt5_plugins\platforms"
rmDir "$INSTDIR\qt5_plugins"
rmDir "$INSTDIR" rmDir "$INSTDIR"
# remove uninstaller information from the registry # remove uninstaller information from the registry

View File

@ -7,10 +7,10 @@
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && cd .. && pwd )" DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && cd .. && pwd )"
cd $DIR cd $DIR
VERSION=`cat version` VERSION=`cat resources/version.txt`
rm -rf deb_dist >/dev/null 2>&1 rm -rf deb_dist >/dev/null 2>&1
python setup.py --command-packages=stdeb.command sdist_dsc python3 setup.py --command-packages=stdeb.command sdist_dsc
cd deb_dist/onionshare-$VERSION cd deb_dist/onionshare-$VERSION
dpkg-buildpackage -S dpkg-buildpackage -S
cd .. cd ..

View File

@ -1,59 +0,0 @@
# -*- mode: python -*-
import platform
system = platform.system()
block_cipher = None
a = Analysis(
['scripts/onionshare-gui'],
pathex=['.'],
binaries=None,
datas=[
('../resources/images/*', 'images'),
('../resources/locale/*', 'locale'),
('../resources/html/*', 'html'),
('../resources/version.txt', '.'),
('../resources/wordlist.txt', '.')
],
hiddenimports=[],
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher)
pyz = PYZ(
a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(
pyz,
a.scripts,
exclude_binaries=True,
name='onionshare',
debug=False,
strip=False,
upx=True,
console=False)
coll = COLLECT(
exe,
a.binaries,
a.zipfiles,
a.datas,
strip=False,
upx=True,
name='onionshare')
if system == 'Darwin':
app = BUNDLE(
coll,
name='OnionShare.app',
icon='install/onionshare.icns',
bundle_identifier='com.micahflee.onionshare',
info_plist={
'NSHighResolutionCapable': 'True'
}
)

View File

@ -18,12 +18,5 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
""" """
import sys, os import onionshare
try:
import onionshare
except ImportError:
sys.path.append(os.path.abspath(os.path.dirname(__file__)+'/..'))
import onionshare
onionshare.main() onionshare.main()

View File

@ -18,12 +18,5 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
""" """
import sys, os import onionshare_gui
try:
import onionshare_gui
except ImportError:
sys.path.append(os.path.abspath(os.path.dirname(__file__)+'/..'))
import onionshare_gui
onionshare_gui.main() onionshare_gui.main()

View File

@ -0,0 +1,46 @@
#!/usr/bin/env python
import os
import subprocess
import urllib
import gi
gi.require_version('Nautilus', '3.0')
from gi.repository import Nautilus
from gi.repository import GObject
# Put me in /usr/share/nautilus-python/extensions/
class OnionShareExtension(GObject.GObject, Nautilus.MenuProvider):
def __init__(self):
pass
def url2path(self,url):
file_uri = url.get_activation_uri()
arg_uri = file_uri[7:]
path = urllib.url2pathname(arg_uri)
return path
def exec_onionshare(self, filenames):
# Would prefer this method but there is a conflict between GTK 2.0 vs GTK 3.0 components being loaded at once
# (nautilus:3090): Gtk-ERROR **: GTK+ 2.x symbols detected. Using GTK+ 2.x and GTK+ 3 in the same process is not supported
# sys.argv = ["", "--filenames"] + filenames
# sys.exit(onionshare_gui.main())
path = os.path.join(os.sep, 'usr', 'bin', 'onionshare-gui')
cmd = [path, "--filenames"] + filenames
subprocess.Popen(cmd)
def get_file_items(self, window, files):
menuitem = Nautilus.MenuItem(name='OnionShare::Nautilus',
label='Share via OnionShare',
tip='',
icon='')
menu = Nautilus.Menu()
menu.append_item(menuitem)
menuitem.connect("activate", self.menu_activate_cb, files)
return menuitem,
def menu_activate_cb(self, menu, files):
file_list = []
for file in files:
file_list.append(self.url2path(file))
self.exec_onionshare(file_list)

View File

@ -17,7 +17,7 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
""" """
import sys, os, inspect, hashlib, base64, hmac, platform, zipfile, tempfile, math, time import sys, os, inspect, hashlib, base64, platform, zipfile, tempfile, math, time
from random import SystemRandom from random import SystemRandom
@ -34,20 +34,14 @@ def get_resource_path(filename):
systemwide, and whether regardless of platform systemwide, and whether regardless of platform
""" """
p = get_platform() p = get_platform()
if p == 'Linux': if p == 'Linux' and sys.argv and sys.argv[0].startswith('/usr/bin/onionshare'):
# OnionShare is installed systemwide in Linux # OnionShare is installed systemwide in Linux
if len(sys.argv) > 0 and sys.argv[0].startswith('/usr/bin/onionshare'): resources_dir = os.path.join(sys.prefix, 'share/onionshare')
resources_dir = os.path.join(sys.prefix, 'share/onionshare') elif getattr(sys, 'frozen', False): # Check if app is "frozen" with cx_Freeze
# Look for resources directory relative to python file # http://cx-freeze.readthedocs.io/en/latest/faq.html#using-data-files
else: resources_dir = os.path.join(os.path.dirname(sys.executable), 'resources')
resources_dir = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))), 'resources') else: # Look for resources directory relative to python file
else: resources_dir = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))), 'resources')
# Check if app is "frozen" with pyinstaller
# https://pythonhosted.org/PyInstaller/#run-time-information
if getattr(sys, 'frozen', False):
resources_dir = sys._MEIPASS
else:
resources_dir = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))), 'resources')
return os.path.join(resources_dir, filename) return os.path.join(resources_dir, filename)

View File

@ -32,27 +32,19 @@ class NoTor(Exception):
""" """
pass pass
class HSDirError(Exception): class Onion(object):
""" """
This exception is raised when onionshare tries create a non-ephemeral Onion is an abstraction layer for connecting to the Tor control port and
hidden service and does not have permission to create or write to creating onion services. OnionShare supports creating onion services
the hidden service directory.
"""
pass
class HS(object):
"""
HS is an abstraction layer for connecting to the Tor control port and
creating hidden services. Onionshare supports creating hidden services
using two methods: using two methods:
- Modifying the Tor configuration through the control port is the old - Modifying the Tor configuration through the control port is the old
method, and will be deprecated in favor of ephemeral hidden services. method, and will be deprecated in favor of ephemeral onion services.
- Using the control port to create ephemeral hidden servers is the - Using the control port to create ephemeral onion servers is the
preferred method. preferred method.
This class detects the versions of Tor and stem to determine if ephemeral This class detects the versions of Tor and stem to determine if ephemeral
hidden services are supported. If not, it falls back to modifying the onion services are supported. If not, it falls back to modifying the
Tor configuration. Tor configuration.
""" """
def __init__(self, transparent_torification=False): def __init__(self, transparent_torification=False):
@ -77,45 +69,36 @@ class HS(object):
if not found_tor: if not found_tor:
raise NoTor(strings._("cant_connect_ctrlport").format(str(ports))) raise NoTor(strings._("cant_connect_ctrlport").format(str(ports)))
# do the versions of stem and tor that I'm using support ephemeral hidden services? # do the versions of stem and tor that I'm using support ephemeral onion services?
tor_version = self.c.get_version().version_str tor_version = self.c.get_version().version_str
list_ephemeral_hidden_services = getattr(self.c, "list_ephemeral_hidden_services", None) list_ephemeral_hidden_services = getattr(self.c, "list_ephemeral_hidden_services", None)
self.supports_ephemeral = callable(list_ephemeral_hidden_services) and tor_version >= '0.2.7.1' self.supports_ephemeral = callable(list_ephemeral_hidden_services) and tor_version >= '0.2.7.1'
def start(self, port): def start(self, port):
""" """
Start a hidden service on port 80, pointing to the given port, and Start a onion service on port 80, pointing to the given port, and
return the onion hostname. return the onion hostname.
""" """
print(strings._("connecting_ctrlport").format(int(port))) print(strings._("connecting_ctrlport").format(int(port)))
if self.supports_ephemeral: if self.supports_ephemeral:
print(strings._('using_ephemeral')) print(strings._('using_ephemeral'))
res = self.c.create_ephemeral_hidden_service({ 80: port }, await_publication = False) res = self.c.create_ephemeral_hidden_service({ 80: port }, await_publication = True)
self.service_id = res.content()[0][2].split('=')[1] self.service_id = res.content()[0][2].split('=')[1]
onion_host = res.content()[0][2].split('=')[1] + '.onion' onion_host = self.service_id + '.onion'
return onion_host return onion_host
else: else:
# come up with a hidden service directory name # come up with a onion service directory name
if helpers.get_platform() == 'Windows': if helpers.get_platform() == 'Windows':
self.hidserv_dir = tempfile.mkdtemp() self.hidserv_dir = tempfile.mkdtemp()
self.hidserv_dir = self.hidserv_dir.replace('\\', '/') self.hidserv_dir = self.hidserv_dir.replace('\\', '/')
else: else:
path = '/tmp/onionshare' self.hidserv_dir = tempfile.mkdtemp(suffix='onionshare',dir='/tmp')
try:
if not os.path.exists(path):
os.makedirs(path, 0o700)
except:
raise HSDirError(strings._("error_hs_dir_cannot_create").format(path))
if not os.access(path, os.W_OK):
raise HSDirError(strings._("error_hs_dir_not_writable").format(path))
self.hidserv_dir = tempfile.mkdtemp(dir=path)
self.cleanup_filenames.append(self.hidserv_dir) self.cleanup_filenames.append(self.hidserv_dir)
# set up hidden service # set up onion service
hsdic = self.c.get_conf_map('HiddenServiceOptions') or { hsdic = self.c.get_conf_map('HiddenServiceOptions') or {
'HiddenServiceDir': [], 'HiddenServicePort': [] 'HiddenServiceDir': [], 'HiddenServicePort': []
} }
@ -137,11 +120,11 @@ class HS(object):
def wait_for_hs(self, onion_host): def wait_for_hs(self, onion_host):
""" """
This function is only required when using non-ephemeral hidden services. After This function is only required when using non-ephemeral onion services. After
creating a hidden service, continually attempt to connect to it until it creating a onion service, continually attempt to connect to it until it
successfully connects.. successfully connects.
""" """
# legacy only, this function is no longer required with ephemeral hidden services # legacy only, this function is no longer required with ephemeral onion services
print(strings._('wait_for_hs')) print(strings._('wait_for_hs'))
ready = False ready = False
@ -186,20 +169,20 @@ class HS(object):
def cleanup(self): def cleanup(self):
""" """
Stop hidden services that were created earlier, and delete any temporary Stop onion services that were created earlier, and delete any temporary
files that were created. files that were created.
""" """
if self.supports_ephemeral: if self.supports_ephemeral:
# cleanup the ephemeral hidden service # cleanup the ephemeral onion service
if self.service_id: if self.service_id:
self.c.remove_ephemeral_hidden_service(self.service_id) self.c.remove_ephemeral_hidden_service(self.service_id)
self.service_id = None self.service_id = None
else: else:
# cleanup hidden service # cleanup onion service
try: try:
if self.controller: if self.controller:
# Get fresh hidden services (maybe changed since last time) # Get fresh onion services (maybe changed since last time)
# and remove ourselves # and remove ourselves
hsdic = self.controller.get_conf_map('HiddenServiceOptions') or { hsdic = self.controller.get_conf_map('HiddenServiceOptions') or {
'HiddenServiceDir': [], 'HiddenServicePort': [] 'HiddenServiceDir': [], 'HiddenServicePort': []
@ -233,17 +216,17 @@ class HS(object):
'80 127.0.0.1:33302' '80 127.0.0.1:33302'
], ],
'HiddenServiceDir': [ 'HiddenServiceDir': [
'/tmp/onionshare/tmplTfZZu', '/tmp/onionsharelTfZZu',
'/tmp/onionshare/tmpchDai3' '/tmp/onionsharechDai3'
] ]
} }
Output will look like this: Output will look like this:
[ [
('HiddenServiceDir', '/tmp/onionshare/tmplTfZZu'), ('HiddenServiceDir', '/tmp/onionsharelTfZZu'),
('HiddenServicePort', '80 127.0.0.1:47906'), ('HiddenServicePort', '80 127.0.0.1:47906'),
('HiddenServiceDir', '/tmp/onionshare/tmpchDai3'), ('HiddenServiceDir', '/tmp/onionsharechDai3'),
('HiddenServicePort', '80 127.0.0.1:33302') ('HiddenServicePort', '80 127.0.0.1:33302')
] ]
""" """

View File

@ -18,18 +18,18 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
""" """
import os, sys, subprocess, time, argparse, inspect, shutil, socket, threading import os, sys, time, argparse, shutil, socket, threading
from . import strings, helpers, web, hs from . import strings, helpers, web, onion
class OnionShare(object): class OnionShare(object):
""" """
OnionShare is the main application class. Pass in options and run OnionShare is the main application class. Pass in options and run
start_hidden_service and it will do the magic. start_onion_service and it will do the magic.
""" """
def __init__(self, debug=False, local_only=False, stay_open=False, transparent_torification=False): def __init__(self, debug=False, local_only=False, stay_open=False, transparent_torification=False):
self.port = None self.port = None
self.hs = None self.onion = None
self.hidserv_dir = None self.hidserv_dir = None
self.onion_host = None self.onion_host = None
@ -64,9 +64,9 @@ class OnionShare(object):
self.port = tmpsock.getsockname()[1] self.port = tmpsock.getsockname()[1]
tmpsock.close() tmpsock.close()
def start_hidden_service(self, gui=False): def start_onion_service(self):
""" """
Start the onionshare hidden service. Start the onionshare onion service.
""" """
if not self.port: if not self.port:
self.choose_port() self.choose_port()
@ -75,10 +75,10 @@ class OnionShare(object):
self.onion_host = '127.0.0.1:{0:d}'.format(self.port) self.onion_host = '127.0.0.1:{0:d}'.format(self.port)
return return
if not self.hs: if not self.onion:
self.hs = hs.HS(self.transparent_torification) self.onion = onion.Onion(self.transparent_torification)
self.onion_host = self.hs.start(self.port) self.onion_host = self.onion.start(self.port)
def cleanup(self): def cleanup(self):
""" """
@ -92,9 +92,9 @@ class OnionShare(object):
shutil.rmtree(filename) shutil.rmtree(filename)
self.cleanup_filenames = [] self.cleanup_filenames = []
# call hs's cleanup # cleanup the onion
if self.hs: if self.onion:
self.hs.cleanup() self.onion.cleanup()
def main(cwd=None): def main(cwd=None):
@ -102,7 +102,7 @@ def main(cwd=None):
The main() function implements all of the logic that the command-line version of The main() function implements all of the logic that the command-line version of
onionshare uses. onionshare uses.
""" """
strings.load_strings() strings.load_strings(helpers)
print(strings._('version_string').format(helpers.get_version())) print(strings._('version_string').format(helpers.get_version()))
# onionshare CLI in OSX needs to change current working directory (#132) # onionshare CLI in OSX needs to change current working directory (#132)
@ -141,10 +141,8 @@ def main(cwd=None):
try: try:
app = OnionShare(debug, local_only, stay_open, transparent_torification) app = OnionShare(debug, local_only, stay_open, transparent_torification)
app.choose_port() app.choose_port()
app.start_hidden_service() app.start_onion_service()
except hs.NoTor as e: except onion.NoTor as e:
sys.exit(e.args[0])
except hs.HSDirError as e:
sys.exit(e.args[0]) sys.exit(e.args[0])
# prepare files to share # prepare files to share
@ -158,15 +156,15 @@ def main(cwd=None):
print(strings._("large_filesize")) print(strings._("large_filesize"))
print('') print('')
# start onionshare service in new thread # start onionshare http service in new thread
t = threading.Thread(target=web.start, args=(app.port, app.stay_open, app.transparent_torification)) t = threading.Thread(target=web.start, args=(app.port, app.stay_open, app.transparent_torification))
t.daemon = True t.daemon = True
t.start() t.start()
try: # Trap Ctrl-C try: # Trap Ctrl-C
# wait for hs, only if using old version of tor # wait for hs, only if using old version of tor
if not app.local_only: if not app.local_only and not app.onion.supports_ephemeral:
ready = app.hs.wait_for_hs(app.onion_host) ready = app.onion.wait_for_hs(app.onion_host)
if not ready: if not ready:
sys.exit() sys.exit()
else: else:

View File

@ -17,14 +17,11 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
""" """
import json, locale, sys, os import json, locale, os
from . import helpers
strings = {} strings = {}
def load_strings(helpers, default="en"):
def load_strings(default="en"):
""" """
Loads translated strings and fallback to English Loads translated strings and fallback to English
if the translation does not exist. if the translation does not exist.

View File

@ -20,7 +20,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
import queue, mimetypes, platform, os, sys import queue, mimetypes, platform, os, sys
from urllib.request import urlopen from urllib.request import urlopen
from flask import Flask, Response, request, render_template_string, abort from flask import Flask, Response, request, render_template_string, abort
from functools import wraps
from . import strings, helpers from . import strings, helpers
@ -231,7 +230,7 @@ def download(slug_candidate):
# The user has canceled the download, so stop serving the file # The user has canceled the download, so stop serving the file
if client_cancel: if client_cancel:
add_request(REQUEST_CANCELED, path, {'id': download_id}) add_request(REQUEST_CANCELED, path, {'id': download_id})
break; break
chunk = fp.read(chunk_size) chunk = fp.read(chunk_size)
if chunk == b'': if chunk == b'':

View File

@ -58,6 +58,8 @@ class OnionShareGui(QtWidgets.QMainWindow):
start_server_finished = QtCore.pyqtSignal() start_server_finished = QtCore.pyqtSignal()
stop_server_finished = QtCore.pyqtSignal() stop_server_finished = QtCore.pyqtSignal()
starting_server_step2 = QtCore.pyqtSignal() starting_server_step2 = QtCore.pyqtSignal()
starting_server_step3 = QtCore.pyqtSignal()
starting_server_error = QtCore.pyqtSignal(str)
def __init__(self, qtapp, app): def __init__(self, qtapp, app):
super(OnionShareGui, self).__init__() super(OnionShareGui, self).__init__()
@ -90,6 +92,8 @@ class OnionShareGui(QtWidgets.QMainWindow):
self.file_selection.file_list.files_updated.connect(self.server_status.update) self.file_selection.file_list.files_updated.connect(self.server_status.update)
self.server_status.url_copied.connect(self.copy_url) self.server_status.url_copied.connect(self.copy_url)
self.starting_server_step2.connect(self.start_server_step2) self.starting_server_step2.connect(self.start_server_step2)
self.starting_server_step3.connect(self.start_server_step3)
self.starting_server_error.connect(self.start_server_error)
# filesize warning # filesize warning
self.filesize_warning = QtWidgets.QLabel() self.filesize_warning = QtWidgets.QLabel()
@ -127,52 +131,53 @@ class OnionShareGui(QtWidgets.QMainWindow):
self.timer.timeout.connect(self.check_for_requests) self.timer.timeout.connect(self.check_for_requests)
self.timer.start(500) self.timer.start(500)
def start_server_step2(self):
"""
Step 2 in starting the onionshare server. This displays the large filesize
warning, if applicable.
"""
# warn about sending large files over Tor
if web.zip_filesize >= 157286400: # 150mb
self.filesize_warning.setText(strings._("large_filesize", True))
self.filesize_warning.show()
def start_server(self): def start_server(self):
""" """
Start the onionshare server. This uses multiple threads to start the Tor hidden Start the onionshare server. This uses multiple threads to start the Tor onion
server and the web app. server and the web app.
""" """
# Reset web counters # Reset web counters
web.download_count = 0 web.download_count = 0
web.error404_count = 0 web.error404_count = 0
# start the hidden service # pick an available local port for the http service to listen on
self.status_bar.showMessage(strings._('gui_starting_server1', True))
self.app.choose_port() self.app.choose_port()
try:
self.app.start_hidden_service(gui=True)
except onionshare.hs.NoTor as e:
alert(e.args[0], QtWidgets.QMessageBox.Warning)
self.server_status.stop_server()
self.status_bar.clearMessage()
return
# start onionshare service in new thread # start the onion service in a new thread
t = threading.Thread(target=web.start, args=(self.app.port, self.app.stay_open, self.app.transparent_torification)) def start_onion_service(self):
t.daemon = True self.status_bar.showMessage(strings._('gui_starting_server1', True))
t.start() try:
self.app.start_onion_service()
self.starting_server_step2.emit()
except onionshare.onion.NoTor as e:
self.starting_server_error.emit(e.args[0])
return
t1 = threading.Thread(target=start_onion_service, kwargs={'self': self})
t1.daemon = True
t1.start()
# start onionshare http service in new thread
t2 = threading.Thread(target=web.start, args=(self.app.port, self.app.stay_open, self.app.transparent_torification))
t2.daemon = True
t2.start()
def start_server_step2(self):
"""
Step 2 in starting the onionshare server. Prepare files for serving.
"""
# prepare the files for sending in a new thread # prepare the files for sending in a new thread
def finish_starting_server(self): def finish_starting_server(self):
# prepare files to share # prepare files to share
web.set_file_info(self.file_selection.file_list.filenames) web.set_file_info(self.file_selection.file_list.filenames)
self.app.cleanup_filenames.append(web.zip_filename) self.app.cleanup_filenames.append(web.zip_filename)
self.starting_server_step2.emit() self.starting_server_step3.emit()
# wait for hs # wait for hs
if not self.app.local_only: if not self.app.local_only and not self.app.onion.supports_ephemeral:
self.status_bar.showMessage(strings._('gui_starting_server3', True)) self.status_bar.showMessage(strings._('gui_starting_server3', True))
self.app.hs.wait_for_hs(self.app.onion_host) self.app.onion.wait_for_hs(self.app.onion_host)
# done # done
self.start_server_finished.emit() self.start_server_finished.emit()
@ -182,6 +187,24 @@ class OnionShareGui(QtWidgets.QMainWindow):
t.daemon = True t.daemon = True
t.start() t.start()
def start_server_step3(self):
"""
Step 3 in starting the onionshare server. This displays the large filesize
warning, if applicable.
"""
# warn about sending large files over Tor
if web.zip_filesize >= 157286400: # 150mb
self.filesize_warning.setText(strings._("large_filesize", True))
self.filesize_warning.show()
def start_server_error(self, error):
"""
If there's an error when trying to start the onion service
"""
alert(error, QtWidgets.QMessageBox.Warning)
self.server_status.stop_server()
self.status_bar.clearMessage()
def stop_server(self): def stop_server(self):
""" """
Stop the onionshare server. Stop the onionshare server.
@ -284,7 +307,7 @@ def main():
""" """
The main() function implements all of the logic that the GUI version of onionshare uses. The main() function implements all of the logic that the GUI version of onionshare uses.
""" """
strings.load_strings() strings.load_strings(helpers)
print(strings._('version_string').format(helpers.get_version())) print(strings._('version_string').format(helpers.get_version()))
# start the Qt app # start the Qt app

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +1,9 @@
{ {
"connecting_ctrlport": "Připojuju se na kontrolní port Toru pro nastavení hidden service na portu {0:d}.", "connecting_ctrlport": "Připojuju se na kontrolní port Toru pro nastavení onion service na portu {0:d}.",
"cant_connect_ctrlport": "Nejde se připojit na kontrolní port Toru na portu {0:s}. OnionShare vyžaduje, aby Tor Browser běžel na pozadí. Pokud ho nemáte, můžete ho stáhnout z https://www.torproject.org/.", "cant_connect_ctrlport": "Nejde se připojit na kontrolní port Toru na portu {0:s}. OnionShare vyžaduje, aby Tor Browser běžel na pozadí. Pokud ho nemáte, můžete ho stáhnout z https://www.torproject.org/.",
"cant_connect_socksport": "Nejde se připojit na Tor SOCKS5 server na portu {0:s}. OnionShare vyžaduje, aby Tor Browser běžel na pozadí. Pokud ho nemáte, můžete ho stáhnout z https://www.torproject.org/.", "cant_connect_socksport": "Nejde se připojit na Tor SOCKS5 server na portu {0:s}. OnionShare vyžaduje, aby Tor Browser běžel na pozadí. Pokud ho nemáte, můžete ho stáhnout z https://www.torproject.org/.",
"preparing_files": "Připravuji soubory na sdílení.", "preparing_files": "Připravuji soubory na sdílení.",
"wait_for_hs": "Čekám až bude hidden service připravena:", "wait_for_hs": "Čekám až bude onion service připravena:",
"wait_for_hs_trying": "Zkouším...", "wait_for_hs_trying": "Zkouším...",
"wait_for_hs_nope": "Ještě nepřipraven.", "wait_for_hs_nope": "Ještě nepřipraven.",
"wait_for_hs_yup": "Připraven!", "wait_for_hs_yup": "Připraven!",
@ -17,9 +17,9 @@
"large_filesize": "Varování: Posílání velkých souborů může trvat hodiny", "large_filesize": "Varování: Posílání velkých souborů může trvat hodiny",
"error_tails_invalid_port": "Nesprávná hodnota, port musí být celé číslo", "error_tails_invalid_port": "Nesprávná hodnota, port musí být celé číslo",
"error_tails_unknown_root": "Unknown error with Tails root process", "error_tails_unknown_root": "Unknown error with Tails root process",
"help_tails_port": "Tails only: port for opening firewall, starting hidden service", "help_tails_port": "Tails only: port for opening firewall, starting onion service",
"help_local_only": "Nepoužívat Tor: jen pro vývoj", "help_local_only": "Nepoužívat Tor: jen pro vývoj",
"help_stay_open": "Nechat běžet hidden service po skončení stahování", "help_stay_open": "Nechat běžet onion service po skončení stahování",
"help_transparent_torification": "My system is transparently torified", "help_transparent_torification": "My system is transparently torified",
"help_debug": "Zaznamenat chyby na disk", "help_debug": "Zaznamenat chyby na disk",
"help_filename": "Seznam souborů a složek ke sdílení", "help_filename": "Seznam souborů a složek ke sdílení",
@ -35,11 +35,11 @@
"gui_downloads": "Stahování:", "gui_downloads": "Stahování:",
"gui_canceled": "Zrušeno", "gui_canceled": "Zrušeno",
"gui_copied_url": "URL zkopírováno do schránky", "gui_copied_url": "URL zkopírováno do schránky",
"gui_starting_server1": "Spouštím Tor hidden service...", "gui_starting_server1": "Spouštím Tor onion service...",
"gui_starting_server2": "Crunching files...", "gui_starting_server2": "Crunching files...",
"gui_starting_server3": "Čekám na Tor hidden service...", "gui_starting_server3": "Čekám na Tor onion service...",
"gui_please_wait": "Prosím čekejte...", "gui_please_wait": "Prosím čekejte...",
"error_hs_dir_cannot_create": "Nejde vytvořit složka {0:s} pro hidden service", "error_hs_dir_cannot_create": "Nejde vytvořit složka {0:s} pro onion service",
"error_hs_dir_not_writable": "Nejde zapisovat do složky {0:s} pro hidden service", "error_hs_dir_not_writable": "Nejde zapisovat do složky {0:s} pro onion service",
"using_ephemeral": "Staring ephemeral Tor hidden service and awaiting publication" "using_ephemeral": "Staring ephemeral Tor onion service and awaiting publication"
} }

View File

@ -17,9 +17,9 @@
"large_filesize": "Warnung: Das Senden von großen Dateien kann Stunden dauern", "large_filesize": "Warnung: Das Senden von großen Dateien kann Stunden dauern",
"error_tails_invalid_port": "Ungültiger Wert, Port muss eine ganze Zahl sein", "error_tails_invalid_port": "Ungültiger Wert, Port muss eine ganze Zahl sein",
"error_tails_unknown_root": "Unbekannter Fehler mit Tails root Prozess", "error_tails_unknown_root": "Unbekannter Fehler mit Tails root Prozess",
"help_tails_port": "Nur für Tails: Port um den Firewall zu öffnen, starte Hidden Service", "help_tails_port": "Nur für Tails: Port um den Firewall zu öffnen, starte onion service",
"help_local_only": "Nicht mit Tor benutzen, nur für Entwicklung", "help_local_only": "Nicht mit Tor benutzen, nur für Entwicklung",
"help_stay_open": "Den Hidden Service nicht anhalten nachdem ein Download beendet wurde", "help_stay_open": "Den onion service nicht anhalten nachdem ein Download beendet wurde",
"help_debug": "Fehler auf Festplatte schreiben", "help_debug": "Fehler auf Festplatte schreiben",
"help_filename": "Liste der zu teilenden Dateien oder Verzeichnisse", "help_filename": "Liste der zu teilenden Dateien oder Verzeichnisse",
"gui_drag_and_drop": "Drag & drop\nDateien hier", "gui_drag_and_drop": "Drag & drop\nDateien hier",

View File

@ -1,5 +1,5 @@
{ {
"connecting_ctrlport": "Connecting to Tor control port to set up hidden service on port {0:d}.", "connecting_ctrlport": "Connecting to Tor control port to set up onion service on port {0:d}.",
"cant_connect_ctrlport": "Can't connect to Tor control port on port {0:s}. OnionShare requires Tor Browser to be running in the background to work. If you don't have it you can get it from https://www.torproject.org/.", "cant_connect_ctrlport": "Can't connect to Tor control port on port {0:s}. OnionShare requires Tor Browser to be running in the background to work. If you don't have it you can get it from https://www.torproject.org/.",
"cant_connect_socksport": "Can't connect to Tor SOCKS5 server on port {0:s}. OnionShare requires Tor Browser to be running in the background to work. If you don't have it you can get it from https://www.torproject.org/.", "cant_connect_socksport": "Can't connect to Tor SOCKS5 server on port {0:s}. OnionShare requires Tor Browser to be running in the background to work. If you don't have it you can get it from https://www.torproject.org/.",
"preparing_files": "Preparing files to share.", "preparing_files": "Preparing files to share.",
@ -17,9 +17,9 @@
"large_filesize": "Warning: Sending large files could take hours", "large_filesize": "Warning: Sending large files could take hours",
"error_tails_invalid_port": "Invalid value, port must be an integer", "error_tails_invalid_port": "Invalid value, port must be an integer",
"error_tails_unknown_root": "Unknown error with Tails root process", "error_tails_unknown_root": "Unknown error with Tails root process",
"help_tails_port": "Tails only: port for opening firewall, starting hidden service", "help_tails_port": "Tails only: port for opening firewall, starting onion service",
"help_local_only": "Do not attempt to use tor: for development only", "help_local_only": "Do not attempt to use tor: for development only",
"help_stay_open": "Keep hidden service running after download has finished", "help_stay_open": "Keep onion service running after download has finished",
"help_transparent_torification": "My system is transparently torified", "help_transparent_torification": "My system is transparently torified",
"help_debug": "Log errors to disk", "help_debug": "Log errors to disk",
"help_filename": "List of files or folders to share", "help_filename": "List of files or folders to share",
@ -35,13 +35,13 @@
"gui_downloads": "Downloads:", "gui_downloads": "Downloads:",
"gui_canceled": "Canceled", "gui_canceled": "Canceled",
"gui_copied_url": "Copied URL to clipboard", "gui_copied_url": "Copied URL to clipboard",
"gui_starting_server1": "Starting Tor hidden service...", "gui_starting_server1": "Starting Tor onion service...",
"gui_starting_server2": "Crunching files...", "gui_starting_server2": "Crunching files...",
"gui_starting_server3": "Waiting for Tor hidden service...", "gui_starting_server3": "Waiting for Tor onion service...",
"gui_please_wait": "Please wait...", "gui_please_wait": "Please wait...",
"error_hs_dir_cannot_create": "Cannot create hidden service dir {0:s}", "error_hs_dir_cannot_create": "Cannot create onion service dir {0:s}",
"error_hs_dir_not_writable": "Hidden service dir {0:s} is not writable", "error_hs_dir_not_writable": "onion service dir {0:s} is not writable",
"using_ephemeral": "Staring ephemeral Tor hidden service and awaiting publication", "using_ephemeral": "Staring ephemeral Tor onion service and awaiting publication",
"gui_download_progress_complete": "%p%, Time Elapsed: {0:s}", "gui_download_progress_complete": "%p%, Time Elapsed: {0:s}",
"gui_download_progress_starting": "{0:s}, %p% (Computing ETA)", "gui_download_progress_starting": "{0:s}, %p% (Computing ETA)",
"gui_download_progress_eta": "{0:s}, ETA: {1:s}, %p%", "gui_download_progress_eta": "{0:s}, ETA: {1:s}, %p%",

View File

@ -1,5 +1,5 @@
{ {
"connecting_ctrlport": "Konektas al Tor-kontrolpordo por starigi hidden service je pordo {0:d}.", "connecting_ctrlport": "Konektas al Tor-kontrolpordo por starigi onion service je pordo {0:d}.",
"cant_connect_ctrlport": "Ne eblas konekti al Tor-kontrolpordo je pordo {0:s}. OnionShare bezonas Tor Browser por esti ŝaltita en la fono. Se vi ne havas ĝin, vi povas ricevi ĝin je https://www.torproject.org/.", "cant_connect_ctrlport": "Ne eblas konekti al Tor-kontrolpordo je pordo {0:s}. OnionShare bezonas Tor Browser por esti ŝaltita en la fono. Se vi ne havas ĝin, vi povas ricevi ĝin je https://www.torproject.org/.",
"cant_connect_socksport": "Ne eblas konekti al Tor-SOCKS5-servilo je pordo {0:s}. OnionShare bezonas Tor Browser por esti ŝaltita en la fono. Se vi ne havas ĝin, vi povas ricevi ĝin je https://www.torproject.org/.", "cant_connect_socksport": "Ne eblas konekti al Tor-SOCKS5-servilo je pordo {0:s}. OnionShare bezonas Tor Browser por esti ŝaltita en la fono. Se vi ne havas ĝin, vi povas ricevi ĝin je https://www.torproject.org/.",
"preparing_files": "Preparas dosierojn por kundivido.", "preparing_files": "Preparas dosierojn por kundivido.",
@ -17,9 +17,9 @@
"large_filesize": "Atentigo: Sendado de grandaj dosieroj povas daŭri horojn", "large_filesize": "Atentigo: Sendado de grandaj dosieroj povas daŭri horojn",
"error_tails_invalid_port": "Malĝusta valoro, pordo devas esti plena nombro", "error_tails_invalid_port": "Malĝusta valoro, pordo devas esti plena nombro",
"error_tails_unknown_root": "Nekonata eraro kun Tails-root-procezo", "error_tails_unknown_root": "Nekonata eraro kun Tails-root-procezo",
"help_tails_port": "Tails only: port for opening firewall, starting hidden service", "help_tails_port": "Tails only: port for opening firewall, starting onion service",
"help_local_only": "Ne strebu uzi tor: nur por evoluado", "help_local_only": "Ne strebu uzi tor: nur por evoluado",
"help_stay_open": "Lasu hidden service funkcii post fino de elŝuto", "help_stay_open": "Lasu onion service funkcii post fino de elŝuto",
"help_transparent_torification": "My system is transparently torified", "help_transparent_torification": "My system is transparently torified",
"help_debug": "Protokoli erarojn sur diskon", "help_debug": "Protokoli erarojn sur diskon",
"help_filename": "Listo de dosieroj aŭ dosierujoj por kundividi", "help_filename": "Listo de dosieroj aŭ dosierujoj por kundividi",
@ -35,11 +35,11 @@
"gui_downloads": "Elŝutoj:", "gui_downloads": "Elŝutoj:",
"gui_canceled": "Nuligita", "gui_canceled": "Nuligita",
"gui_copied_url": "URL kopiita en tondujon", "gui_copied_url": "URL kopiita en tondujon",
"gui_starting_server1": "Startigas Tor hidden service...", "gui_starting_server1": "Startigas Tor onion service...",
"gui_starting_server2": "Crunching files...", "gui_starting_server2": "Crunching files...",
"gui_starting_server3": "Atendas por Tor hidden service...", "gui_starting_server3": "Atendas por Tor onion service...",
"gui_please_wait": "Bonvolu atendi...", "gui_please_wait": "Bonvolu atendi...",
"error_hs_dir_cannot_create": "Ne eblas krei hidden-service-dosierujon {0:s}", "error_hs_dir_cannot_create": "Ne eblas krei hidden-service-dosierujon {0:s}",
"error_hs_dir_not_writable": "Ne eblas konservi dosierojn en hidden-service-dosierujo {0:s}", "error_hs_dir_not_writable": "Ne eblas konservi dosierojn en hidden-service-dosierujo {0:s}",
"using_ephemeral": "Staring ephemeral Tor hidden service and awaiting publication" "using_ephemeral": "Staring ephemeral Tor onion service and awaiting publication"
} }

View File

@ -15,10 +15,10 @@
"close_on_finish": "Apagar el servidor automáticamente.", "close_on_finish": "Apagar el servidor automáticamente.",
"closing_automatically": "Apagando automáticamente porque la descarga finalizó", "closing_automatically": "Apagando automáticamente porque la descarga finalizó",
"error_tails_invalid_port": "Valor inválido, el puerto debe ser un entero", "error_tails_invalid_port": "Valor inválido, el puerto debe ser un entero",
"error_tails_unknown_root": "Error desconocido en el proceso de Tails corriendo como root", "error_tails_unknown_root": "Error desconocido en el proceso de Tails ejecutando como roo",
"help_tails_port": "Sólo Tails: puerto para abrir en el firewall, al levantar el servicio oculto", "help_tails_port": "Sólo Tails: puerto para abrir en el firewall, al levantar el servicio oculto",
"help_local_only": "No intentar usar tor: para desarrollo solamente", "help_local_only": "No intentar usar Tor: sólo para desarrollo",
"help_stay_open": "Mantener el servicio oculto corriendo después de que la descarga haya finalizado", "help_stay_open": "Mantener el servicio oculto ejecutando después de que la descarga haya finalizado",
"help_debug": "Guardar registro de errores en el disco", "help_debug": "Guardar registro de errores en el disco",
"help_filename": "Lista de archivos o carpetas para compartir", "help_filename": "Lista de archivos o carpetas para compartir",
"gui_drag_and_drop": "Arrastre\narchivos aquí", "gui_drag_and_drop": "Arrastre\narchivos aquí",

View File

@ -1,5 +1,5 @@
{ {
"connecting_ctrlport": "Connexion au réseau Tor pour mettre en place un Hidden Service sur le port {0:d}.", "connecting_ctrlport": "Connexion au réseau Tor pour mettre en place un onion service sur le port {0:d}.",
"cant_connect_ctrlport": "Impossible de se connecter au port de contrôle Tor sur le port {0:s}. Est-ce que Tor tourne ?", "cant_connect_ctrlport": "Impossible de se connecter au port de contrôle Tor sur le port {0:s}. Est-ce que Tor tourne ?",
"preparing_files": "Préparation des fichiers à partager.", "preparing_files": "Préparation des fichiers à partager.",
"wait_for_hs": "En attente du HS:", "wait_for_hs": "En attente du HS:",
@ -15,9 +15,9 @@
"closing_automatically": "Fermeture automatique car le téléchargement est fini", "closing_automatically": "Fermeture automatique car le téléchargement est fini",
"error_tails_invalid_port": "Valeur invalide, le port doit être un nombre entier", "error_tails_invalid_port": "Valeur invalide, le port doit être un nombre entier",
"error_tails_unknown_root": "Erreur inconnue avec un processus root sur Tails", "error_tails_unknown_root": "Erreur inconnue avec un processus root sur Tails",
"help_tails_port": "Seulement sur Tails: port pour ouvrir le firewall, démarrage du Hidden Service", "help_tails_port": "Seulement sur Tails: port pour ouvrir le firewall, démarrage du onion service",
"help_local_only": "Ne tentez pas d'utiliser Tor, uniquement pour développement", "help_local_only": "Ne tentez pas d'utiliser Tor, uniquement pour développement",
"help_stay_open": "Laisser tourner le Hidden Service après que le téléchargment soit fini", "help_stay_open": "Laisser tourner le onion service après que le téléchargment soit fini",
"help_debug": "Enregistrer les erreurs sur le disque", "help_debug": "Enregistrer les erreurs sur le disque",
"help_filename": "Liste des fichiers ou dossiers à partager", "help_filename": "Liste des fichiers ou dossiers à partager",
"gui_drag_and_drop": "Glissez déposez\nles fichiers ici", "gui_drag_and_drop": "Glissez déposez\nles fichiers ici",

View File

@ -35,11 +35,11 @@
"gui_downloads": "Downloads:", "gui_downloads": "Downloads:",
"gui_canceled": "Afgebroken", "gui_canceled": "Afgebroken",
"gui_copied_url": "URL gekopieerd naar klembord", "gui_copied_url": "URL gekopieerd naar klembord",
"gui_starting_server1": "Tor hidden service wordt gestart...", "gui_starting_server1": "Tor onion service wordt gestart...",
"gui_starting_server2": "Bestanden verwerken...", "gui_starting_server2": "Bestanden verwerken...",
"gui_starting_server3": "Wachten op Tor hidden service...", "gui_starting_server3": "Wachten op Tor onion service...",
"gui_please_wait": "Moment geduld...", "gui_please_wait": "Moment geduld...",
"error_hs_dir_cannot_create": "Kan verborgen service map {0:s} niet aanmaken", "error_hs_dir_cannot_create": "Kan verborgen service map {0:s} niet aanmaken",
"error_hs_dir_not_writable": "Verborgen service map {0:s} is niet schrijfbaar", "error_hs_dir_not_writable": "Verborgen service map {0:s} is niet schrijfbaar",
"using_ephemeral": "Kortstondige Tor hidden service gestart en in afwachting van publicatie" "using_ephemeral": "Kortstondige Tor onion service gestart en in afwachting van publicatie"
} }

View File

@ -17,7 +17,7 @@
"large_filesize": "Uyarı: Büyük dosyaların gönderimi saatler sürebilir", "large_filesize": "Uyarı: Büyük dosyaların gönderimi saatler sürebilir",
"error_tails_invalid_port": "Geçersiz değer, port sayı olmalıdır", "error_tails_invalid_port": "Geçersiz değer, port sayı olmalıdır",
"error_tails_unknown_root": "Tails ana işlemi ile ilgili bilinmeyen hata", "error_tails_unknown_root": "Tails ana işlemi ile ilgili bilinmeyen hata",
"help_tails_port": "Sadece Tails: port for opening firewall, starting hidden service", "help_tails_port": "Sadece Tails: port for opening firewall, starting onion service",
"help_local_only": "Tor kullanmaya kalkışmayın: sadece geliştirme için", "help_local_only": "Tor kullanmaya kalkışmayın: sadece geliştirme için",
"help_stay_open": "İndirme tamamlandıktan sonra gizli hizmeti çalıştırmaya devam et", "help_stay_open": "İndirme tamamlandıktan sonra gizli hizmeti çalıştırmaya devam et",
"help_transparent_torification": "Sistemim apaçık torlu", "help_transparent_torification": "Sistemim apaçık torlu",

View File

@ -1 +1 @@
0.9 0.9.1-dev

165
setup.py
View File

@ -19,12 +19,7 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
""" """
import os, sys import os, sys, platform, tempfile
try:
from setuptools import setup
except ImportError:
from distutils.core import setup
def file_list(path): def file_list(path):
files = [] files = []
@ -34,72 +29,120 @@ def file_list(path):
return files return files
version = open('resources/version.txt').read().strip() version = open('resources/version.txt').read().strip()
description = ( description = (
"""OnionShare lets you securely and anonymously share a file of any size with someone. """ """OnionShare lets you securely and anonymously share a file of any size with someone. """
"""It works by starting a web server, making it accessible as a Tor hidden service, """ """It works by starting a web server, making it accessible as a Tor hidden service, """
"""and generating an unguessable URL to access and download the file.""") """and generating an unguessable URL to access and download the file.""")
long_description = description + " " + ( long_description = description + " " + (
"""It doesn't require setting up a server on the internet somewhere or using a third """ """It doesn't require setting up a server on the internet somewhere or using a third """
"""party filesharing service. You host the file on your own computer and use a Tor """ """party filesharing service. You host the file on your own computer and use a Tor """
"""hidden service to make it temporarily accessible over the internet. The other user """ """hidden service to make it temporarily accessible over the internet. The other user """
"""just needs to use Tor Browser to download the file from you.""" """just needs to use Tor Browser to download the file from you."""
) )
author = 'Micah Lee'
author_email = 'micah@micahflee.com'
url = 'https://github.com/micahflee/onionshare'
license = 'GPL v3'
keywords = 'onion, share, onionshare, tor, anonymous, web server'
images = [ p = platform.system()
'resources/images/logo.png',
'resources/images/drop_files.png',
'resources/images/server_stopped.png',
'resources/images/server_started.png',
'resources/images/server_working.png'
]
locale = [ # Windows and Mac
'resources/locale/cs.json', if p == 'Windows' or p == 'Darwin':
'resources/locale/de.json', from cx_Freeze import setup, Executable
'resources/locale/en.json',
'resources/locale/eo.json',
'resources/locale/es.json',
'resources/locale/fi.json',
'resources/locale/fr.json',
'resources/locale/it.json',
'resources/locale/nl.json',
'resources/locale/no.json',
'resources/locale/pt.json',
'resources/locale/ru.json',
'resources/locale/tr.json'
]
html = [ if p == 'Windows':
'resources/html/index.html', executables = [
'resources/html/denied.html', Executable('install/scripts/onionshare',
'resources/html/404.html' icon='install/onionshare.ico',
] base=None),
Executable('install/scripts/onionshare-gui',
icon='install/onionshare.ico',
shortcutName='OnionShare',
shortcutDir='ProgramMenuFolder',
base='Win32GUI')
]
custom_info_plist = ''
setup( elif p == 'Darwin':
name='onionshare', executables = [
version=version, Executable('install/scripts/onionshare-gui'),
description=description, Executable('install/scripts/onionshare')
long_description=long_description, ]
author='Micah Lee',
author_email='micah@micahflee.com', # Write the correct version into Info.plist
url='https://github.com/micahflee/onionshare', f = tempfile.NamedTemporaryFile(mode='w')
license="GPL v3", custom_info_plist = f.name
keywords='onion, share, onionshare, tor, anonymous, web server', f.write(open('install/Info.plist').read().replace('{VERSION}', str(version)))
packages=['onionshare', 'onionshare_gui'], f.flush()
include_package_data=True,
scripts=['install/scripts/onionshare', 'install/scripts/onionshare-gui'], setup(
data_files=[ name='OnionShare', version=version,
(os.path.join(sys.prefix, 'share/applications'), ['install/onionshare.desktop']), description=description, long_description=long_description,
(os.path.join(sys.prefix, 'share/appdata'), ['install/onionshare.appdata.xml']), author=author, author_email=author_email,
(os.path.join(sys.prefix, 'share/pixmaps'), ['install/onionshare80.xpm']), url=url, license=license, keywords=keywords,
(os.path.join(sys.prefix, 'share/onionshare'), [ options={
'resources/version.txt', 'build_exe': {
'resources/wordlist.txt' 'packages': ['jinja2.ext'],
]), 'excludes': [],
(os.path.join(sys.prefix, 'share/onionshare/images'), images), 'include_files': ['resources']
(os.path.join(sys.prefix, 'share/onionshare/locale'), locale), },
(os.path.join(sys.prefix, 'share/onionshare/html'), html) 'bdist_mac': {
] 'iconfile': 'install/onionshare.icns',
) 'bundle_name': 'OnionShare',
'qt_menu_nib': '/usr/local/Cellar/qt5/5.6.1-1/plugins/platforms',
'custom_info_plist': custom_info_plist
}
},
executables=executables
)
# Linux
else:
from setuptools import setup
setup(
name='onionshare', version=version,
description=description, long_description=long_description,
author=author, author_email=author_email,
url=url, license=license, keywords=keywords,
packages=['onionshare', 'onionshare_gui'],
include_package_data=True,
scripts=['install/scripts/onionshare', 'install/scripts/onionshare-gui'],
data_files=[
(os.path.join(sys.prefix, 'share/applications'), ['install/onionshare.desktop']),
(os.path.join(sys.prefix, 'share/appdata'), ['install/onionshare.appdata.xml']),
(os.path.join(sys.prefix, 'share/pixmaps'), ['install/onionshare80.xpm']),
(os.path.join(sys.prefix, 'share/onionshare'), [
'resources/version.txt',
'resources/wordlist.txt'
]),
(os.path.join(sys.prefix, 'share/onionshare/images'), [
'resources/images/logo.png',
'resources/images/drop_files.png',
'resources/images/server_stopped.png',
'resources/images/server_started.png',
'resources/images/server_working.png'
]),
(os.path.join(sys.prefix, 'share/onionshare/locale'), [
'resources/locale/cs.json',
'resources/locale/de.json',
'resources/locale/en.json',
'resources/locale/eo.json',
'resources/locale/es.json',
'resources/locale/fi.json',
'resources/locale/fr.json',
'resources/locale/it.json',
'resources/locale/nl.json',
'resources/locale/no.json',
'resources/locale/pt.json',
'resources/locale/ru.json',
'resources/locale/tr.json'
]),
(os.path.join(sys.prefix, 'share/onionshare/html'), [
'resources/html/index.html',
'resources/html/denied.html',
'resources/html/404.html'
]),
('/usr/share/nautilus-python/extensions/', ['install/scripts/onionshare-nautilus.py']),
]
)

View File

@ -1,6 +1,7 @@
[DEFAULT] [DEFAULT]
Package3: onionshare Package3: onionshare
Depends3: python3-flask, python3-stem, python3-pyqt5 Depends3: python3-flask, python3-stem, python3-pyqt5, python-nautilus
Build-Depends3: python3-nose Build-Depends3: python3-nose, python3-flask, python3-stem, python3-pyqt5
Suite: trusty utopic vivid wily xenial jessie Build-Depends: python3-nose, python3-flask, python3-stem, python3-pyqt5
Suite: wily
X-Python3-Version: >= 3.2 X-Python3-Version: >= 3.2

View File

@ -17,9 +17,7 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
""" """
from onionshare import helpers from onionshare import helpers
from nose import with_setup
import test_helpers
def test_get_platform_returns_platform_system(): def test_get_platform_returns_platform_system():
"""get_platform() returns platform.system() when ONIONSHARE_PLATFORM is not defined""" """get_platform() returns platform.system() when ONIONSHARE_PLATFORM is not defined"""

View File

@ -17,10 +17,15 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
""" """
import locale import locale, os
from onionshare import strings from onionshare import helpers, strings
from nose import with_setup
# Stub get_resource_path so it finds the correct path while running tests
def get_resource_path(filename):
resources_dir = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'resources')
path = os.path.join(resources_dir, filename)
return path
helpers.get_resource_path = get_resource_path
def test_starts_with_empty_strings(): def test_starts_with_empty_strings():
"""creates an empty strings dict by default""" """creates an empty strings dict by default"""
@ -30,12 +35,12 @@ def test_starts_with_empty_strings():
def test_load_strings_defaults_to_english(): def test_load_strings_defaults_to_english():
"""load_strings() loads English by default""" """load_strings() loads English by default"""
locale.getdefaultlocale = lambda: ('en_US', 'UTF-8') locale.getdefaultlocale = lambda: ('en_US', 'UTF-8')
strings.load_strings() strings.load_strings(helpers)
assert strings._('wait_for_hs') == "Waiting for HS to be ready:" assert strings._('wait_for_hs') == "Waiting for HS to be ready:"
def test_load_strings_loads_other_languages(): def test_load_strings_loads_other_languages():
"""load_strings() loads other languages in different locales""" """load_strings() loads other languages in different locales"""
locale.getdefaultlocale = lambda: ('fr_FR', 'UTF-8') locale.getdefaultlocale = lambda: ('fr_FR', 'UTF-8')
strings.load_strings("fr") strings.load_strings(helpers, "fr")
assert strings._('wait_for_hs') == "En attente du HS:" assert strings._('wait_for_hs') == "En attente du HS:"

View File

@ -18,7 +18,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
""" """
import socket import socket
from onionshare import OnionShare from onionshare import OnionShare
from nose import with_setup
def test_choose_port_returns_a_port_number(): def test_choose_port_returns_a_port_number():

View File

@ -17,6 +17,7 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
""" """
import tempfile import tempfile
import os
class MockSubprocess(): class MockSubprocess():
@ -31,9 +32,7 @@ class MockSubprocess():
def write_tempfile(text): def write_tempfile(text):
tempdir = tempfile.mkdtemp() path = os.path.join(tempfile.mkdtemp(), "/test-file.txt")
path = tempdir + "/test-file.txt"
with open(path, "w") as f: with open(path, "w") as f:
f.write(text) f.write(text)
f.close()
return path return path