Compare commits

..

1 Commits

Author SHA1 Message Date
3e85e9d60e
OpenSSL improve memory handling
- replace void * with BIGNUM * where applicable
- fixes #1622
- replace 0 with None when using a NULL pointer as parameter
- maybe needs more work in how the data is accessed
- EC_POINT struct is now defined but isn't used yet
2021-02-17 13:15:34 +01:00
47 changed files with 346 additions and 668 deletions

3
.gitmodules vendored
View File

@ -1,3 +0,0 @@
[submodule "packages/flatpak/shared-modules"]
path = packages/flatpak/shared-modules
url = https://github.com/flathub/shared-modules.git

View File

@ -1,9 +1,6 @@
language: python language: python
cache: pip
dist: bionic
python: python:
- "2.7_with_system_site_packages" - "2.7"
- "3.7"
addons: addons:
apt: apt:
packages: packages:
@ -14,9 +11,9 @@ addons:
- xvfb - xvfb
install: install:
- pip install -r requirements.txt - pip install -r requirements.txt
- ln -s src pybitmessage # tests environment
- python setup.py install - python setup.py install
- export PYTHONWARNINGS=all
script: script:
- python checkdeps.py - python checkdeps.py
- xvfb-run src/bitmessagemain.py -t - xvfb-run src/bitmessagemain.py -t
- python -bm tests - python setup.py test

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python #!/usr/bin/env python2
""" """
Check dependencies and give recommendations about how to satisfy them Check dependencies and give recommendations about how to satisfy them

View File

@ -1,57 +0,0 @@
{
"id": "org.bitmessage.BaseApp",
"branch": "19.08",
"runtime": "org.freedesktop.Platform",
"sdk": "org.freedesktop.Sdk",
"runtime-version": "19.08",
"separate-locales": false,
"modules": [
"shared-modules/python2.7/python-2.7.json",
"shared-modules/qt4/qt4-4.8.7-minimal.json",
{
"name": "python-sip",
"sources": [
{
"type": "archive",
"url": "https://www.riverbankcomputing.com/static/Downloads/sip/4.19.25/sip-4.19.25.tar.gz",
"sha256": "b39d93e937647807bac23579edbff25fe46d16213f708370072574ab1f1b4211"
}
],
"buildsystem": "simple",
"build-commands": [
"python configure.py --sip-module PyQt4.sip --no-dist-info",
"make",
"make install"
]
},
{
"name": "python-qt4",
"sources": [
{
"type": "archive",
"url": "http://sourceforge.net/projects/pyqt/files/PyQt4/PyQt-4.12.3/PyQt4_gpl_x11-4.12.3.tar.gz",
"sha256": "a00f5abef240a7b5852b7924fa5fdf5174569525dc076cd368a566619e56d472"
}
],
"buildsystem": "simple",
"build-commands": [
"python configure.py -w --confirm-license",
"make",
"make install"
]
},
{
"name" : "PyBitmessage-dependencies",
"buildsystem" : "simple",
"build-options": {
"build-args": [
"--share=network"
]
},
"build-commands": [
"pip --version",
"pip install setuptools msgpack"
]
}
]
}

View File

@ -1,48 +0,0 @@
{
"app-id": "org.bitmessage.PyBitmessage",
"runtime": "org.freedesktop.Platform",
"runtime-version": "19.08",
"branch": "stable",
"sdk": "org.freedesktop.Sdk",
"base": "org.bitmessage.BaseApp",
"command": "pybitmessage",
"base-version":"stable",
"finish-args" : [
"--share=network",
"--socket=x11",
"--share=ipc",
"--filesystem=xdg-config/PyBitmessage:create"
],
"modules": [
{
"name" : "PyBitmessage",
"buildsystem" : "simple",
"build-options": {
"build-args": [
"--share=network"
]
},
"build-commands": [
"python --version",
"pwd",
"ls",
"python checkdeps.py",
"python setup.py install --prefix=/app --exec-prefix=/app",
"sed -i 's~/usr/bin/~/app/bin/~' /app/bin/pybitmessage",
"cat /app/bin/pybitmessage",
"mv /app/share/applications/pybitmessage.desktop /app/share/applications/org.bitmessage.PyBitmessage.desktop",
"sed -i 's~Icon=pybitmessage~Icon=org.bitmessage.PyBitmessage~' /app/share/applications/org.bitmessage.PyBitmessage.desktop",
"mv /app/share/icons/hicolor/scalable/apps/pybitmessage.svg /app/share/icons/hicolor/scalable/apps/org.bitmessage.PyBitmessage.svg",
"mv /app/share/icons/hicolor/24x24/apps/pybitmessage.png /app/share/icons/hicolor/24x24/apps/org.bitmessage.PyBitmessage.png",
"which pybitmessage"
],
"sources" : [
{
"type" : "dir",
"path" : "../../"
}
]
}
]
}

@ -1 +0,0 @@
Subproject commit fd4d38328ccb078b88ad4a891807e593ae8de806

View File

@ -1,4 +1,3 @@
coverage
python_prctl python_prctl
psutil psutil
pycrypto pycrypto

View File

@ -95,14 +95,11 @@ if __name__ == "__main__":
['desktop/icons/24x24/pybitmessage.png']) ['desktop/icons/24x24/pybitmessage.png'])
] ]
try:
if platform.dist()[0] in ('Debian', 'Ubuntu'): if platform.dist()[0] in ('Debian', 'Ubuntu'):
data_files += [ data_files += [
("etc/apparmor.d/", ("etc/apparmor.d/",
['packages/apparmor/pybitmessage']) ['packages/apparmor/pybitmessage'])
] ]
except AttributeError:
pass # FIXME: use distro for more recent python
dist = setup( dist = setup(
name='pybitmessage', name='pybitmessage',
@ -119,7 +116,6 @@ if __name__ == "__main__":
#keywords='', #keywords='',
install_requires=installRequires, install_requires=installRequires,
tests_require=requirements, tests_require=requirements,
test_suite='tests.unittest_discover',
extras_require=EXTRAS_REQUIRE, extras_require=EXTRAS_REQUIRE,
classifiers=[ classifiers=[
"License :: OSI Approved :: MIT License" "License :: OSI Approved :: MIT License"

View File

@ -3,12 +3,10 @@ Operations with addresses
""" """
# pylint: disable=redefined-outer-name,inconsistent-return-statements # pylint: disable=redefined-outer-name,inconsistent-return-statements
import hashlib import hashlib
import logging
from binascii import hexlify, unhexlify from binascii import hexlify, unhexlify
from struct import pack, unpack from struct import pack, unpack
from debug import logger
logger = logging.getLogger('default')
ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz" ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
@ -25,7 +23,8 @@ def encodeBase58(num, alphabet=ALPHABET):
arr = [] arr = []
base = len(alphabet) base = len(alphabet)
while num: while num:
num, rem = divmod(num, base) rem = num % base
num = num // base
arr.append(alphabet[rem]) arr.append(alphabet[rem])
arr.reverse() arr.reverse()
return ''.join(arr) return ''.join(arr)
@ -149,16 +148,16 @@ def encodeAddress(version, stream, ripe):
'Programming error in encodeAddress: The length of' 'Programming error in encodeAddress: The length of'
' a given ripe hash was not 20.' ' a given ripe hash was not 20.'
) )
if ripe[:2] == b'\x00\x00': if ripe[:2] == '\x00\x00':
ripe = ripe[2:] ripe = ripe[2:]
elif ripe[:1] == b'\x00': elif ripe[:1] == '\x00':
ripe = ripe[1:] ripe = ripe[1:]
elif version == 4: elif version == 4:
if len(ripe) != 20: if len(ripe) != 20:
raise Exception( raise Exception(
'Programming error in encodeAddress: The length of' 'Programming error in encodeAddress: The length of'
' a given ripe hash was not 20.') ' a given ripe hash was not 20.')
ripe = ripe.lstrip(b'\x00') ripe = ripe.lstrip('\x00')
storedBinaryData = encodeVarint(version) + encodeVarint(stream) + ripe storedBinaryData = encodeVarint(version) + encodeVarint(stream) + ripe
@ -192,8 +191,8 @@ def decodeAddress(address):
status = 'invalidcharacters' status = 'invalidcharacters'
return status, 0, 0, '' return status, 0, 0, ''
# after converting to hex, the string will be prepended # after converting to hex, the string will be prepended
# with a 0x and appended with a L in python2 # with a 0x and appended with a L
hexdata = hex(integer)[2:].rstrip('L') hexdata = hex(integer)[2:-1]
if len(hexdata) % 2 != 0: if len(hexdata) % 2 != 0:
hexdata = '0' + hexdata hexdata = '0' + hexdata
@ -243,13 +242,13 @@ def decodeAddress(address):
data[bytesUsedByVersionNumber + bytesUsedByStreamNumber:-4] data[bytesUsedByVersionNumber + bytesUsedByStreamNumber:-4]
if len(embeddedRipeData) == 19: if len(embeddedRipeData) == 19:
return status, addressVersionNumber, streamNumber, \ return status, addressVersionNumber, streamNumber, \
b'\x00' + embeddedRipeData '\x00' + embeddedRipeData
elif len(embeddedRipeData) == 20: elif len(embeddedRipeData) == 20:
return status, addressVersionNumber, streamNumber, \ return status, addressVersionNumber, streamNumber, \
embeddedRipeData embeddedRipeData
elif len(embeddedRipeData) == 18: elif len(embeddedRipeData) == 18:
return status, addressVersionNumber, streamNumber, \ return status, addressVersionNumber, streamNumber, \
b'\x00\x00' + embeddedRipeData '\x00\x00' + embeddedRipeData
elif len(embeddedRipeData) < 18: elif len(embeddedRipeData) < 18:
return 'ripetooshort', 0, 0, '' return 'ripetooshort', 0, 0, ''
elif len(embeddedRipeData) > 20: elif len(embeddedRipeData) > 20:
@ -258,7 +257,7 @@ def decodeAddress(address):
elif addressVersionNumber == 4: elif addressVersionNumber == 4:
embeddedRipeData = \ embeddedRipeData = \
data[bytesUsedByVersionNumber + bytesUsedByStreamNumber:-4] data[bytesUsedByVersionNumber + bytesUsedByStreamNumber:-4]
if embeddedRipeData[0:1] == b'\x00': if embeddedRipeData[0:1] == '\x00':
# In order to enforce address non-malleability, encoded # In order to enforce address non-malleability, encoded
# RIPE data must have NULL bytes removed from the front # RIPE data must have NULL bytes removed from the front
return 'encodingproblem', 0, 0, '' return 'encodingproblem', 0, 0, ''
@ -266,7 +265,7 @@ def decodeAddress(address):
return 'ripetoolong', 0, 0, '' return 'ripetoolong', 0, 0, ''
elif len(embeddedRipeData) < 4: elif len(embeddedRipeData) < 4:
return 'ripetooshort', 0, 0, '' return 'ripetooshort', 0, 0, ''
x00string = b'\x00' * (20 - len(embeddedRipeData)) x00string = '\x00' * (20 - len(embeddedRipeData))
return status, addressVersionNumber, streamNumber, \ return status, addressVersionNumber, streamNumber, \
x00string + embeddedRipeData x00string + embeddedRipeData

View File

@ -983,7 +983,7 @@ def sendMessage(sender="", recv="", broadcast=None, subject="", body="", reply=F
def loadInbox(): def loadInbox():
"""Load the list of messages""" """Load the list of messages"""
sys.stdout = sys.__stdout__ sys.stdout = sys.__stdout__
print("Loading inbox messages...") print "Loading inbox messages..."
sys.stdout = printlog sys.stdout = printlog
where = "toaddress || fromaddress || subject || message" where = "toaddress || fromaddress || subject || message"
@ -1035,7 +1035,7 @@ def loadInbox():
def loadSent(): def loadSent():
"""Load the messages that sent""" """Load the messages that sent"""
sys.stdout = sys.__stdout__ sys.stdout = sys.__stdout__
print("Loading sent messages...") print "Loading sent messages..."
sys.stdout = printlog sys.stdout = printlog
where = "toaddress || fromaddress || subject || message" where = "toaddress || fromaddress || subject || message"
@ -1121,7 +1121,7 @@ def loadSent():
def loadAddrBook(): def loadAddrBook():
"""Load address book""" """Load address book"""
sys.stdout = sys.__stdout__ sys.stdout = sys.__stdout__
print("Loading address book...") print "Loading address book..."
sys.stdout = printlog sys.stdout = printlog
ret = sqlQuery("SELECT label, address FROM addressbook") ret = sqlQuery("SELECT label, address FROM addressbook")
@ -1228,7 +1228,7 @@ def run(stdscr):
def doShutdown(): def doShutdown():
"""Shutting the app down""" """Shutting the app down"""
sys.stdout = sys.__stdout__ sys.stdout = sys.__stdout__
print("Shutting down...") print "Shutting down..."
sys.stdout = printlog sys.stdout = printlog
shutdown.doCleanShutdown() shutdown.doCleanShutdown()
sys.stdout = sys.__stdout__ sys.stdout = sys.__stdout__

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python #!/usr/bin/python2.7
""" """
The PyBitmessage startup script The PyBitmessage startup script
""" """
@ -12,11 +12,10 @@ The PyBitmessage startup script
import os import os
import sys import sys
try: app_dir = os.path.dirname(os.path.abspath(__file__))
import pathmagic os.chdir(app_dir)
except ImportError: sys.path.insert(0, app_dir)
from pybitmessage import pathmagic
app_dir = pathmagic.setup()
import depends import depends
depends.check_dependencies() depends.check_dependencies()
@ -321,10 +320,9 @@ class Main(object):
receiveQueueThread = ReceiveQueueThread(i) receiveQueueThread = ReceiveQueueThread(i)
receiveQueueThread.daemon = True receiveQueueThread.daemon = True
receiveQueueThread.start() receiveQueueThread.start()
if config.safeGetBoolean('bitmessagesettings', 'udp'): announceThread = AnnounceThread()
state.announceThread = AnnounceThread() announceThread.daemon = True
state.announceThread.daemon = True announceThread.start()
state.announceThread.start()
state.invThread = InvThread() state.invThread = InvThread()
state.invThread.daemon = True state.invThread.daemon = True
state.invThread.start() state.invThread.start()
@ -379,7 +377,11 @@ class Main(object):
test_core_result = test_core.run() test_core_result = test_core.run()
self.stop() self.stop()
test_core.cleanup() test_core.cleanup()
sys.exit(not test_core_result.wasSuccessful()) sys.exit(
'Core tests failed!'
if test_core_result.errors or test_core_result.failures
else 0
)
@staticmethod @staticmethod
def daemonize(): def daemonize():

View File

@ -19,7 +19,7 @@ import widgets
from bmconfigparser import BMConfigParser from bmconfigparser import BMConfigParser
from helper_sql import sqlExecute, sqlStoredProcedure from helper_sql import sqlExecute, sqlStoredProcedure
from helper_startup import start_proxyconfig from helper_startup import start_proxyconfig
from network import knownnodes, AnnounceThread from network import knownnodes
from network.asyncore_pollchoose import set_rates from network.asyncore_pollchoose import set_rates
from tr import _translate from tr import _translate
@ -138,8 +138,6 @@ class SettingsDialog(QtGui.QDialog):
config.get('bitmessagesettings', 'port'))) config.get('bitmessagesettings', 'port')))
self.checkBoxUPnP.setChecked( self.checkBoxUPnP.setChecked(
config.safeGetBoolean('bitmessagesettings', 'upnp')) config.safeGetBoolean('bitmessagesettings', 'upnp'))
self.checkBoxUDP.setChecked(
config.safeGetBoolean('bitmessagesettings', 'udp'))
self.checkBoxAuthentication.setChecked( self.checkBoxAuthentication.setChecked(
config.getboolean('bitmessagesettings', 'socksauthentication')) config.getboolean('bitmessagesettings', 'socksauthentication'))
self.checkBoxSocksListen.setChecked( self.checkBoxSocksListen.setChecked(
@ -328,8 +326,7 @@ class SettingsDialog(QtGui.QDialog):
self.lineEditTCPPort.text()): self.lineEditTCPPort.text()):
self.config.set( self.config.set(
'bitmessagesettings', 'port', str(self.lineEditTCPPort.text())) 'bitmessagesettings', 'port', str(self.lineEditTCPPort.text()))
if not self.config.safeGetBoolean( if not self.config.safeGetBoolean('bitmessagesettings', 'dontconnect'):
'bitmessagesettings', 'dontconnect'):
self.net_restart_needed = True self.net_restart_needed = True
if self.checkBoxUPnP.isChecked() != self.config.safeGetBoolean( if self.checkBoxUPnP.isChecked() != self.config.safeGetBoolean(
@ -342,26 +339,11 @@ class SettingsDialog(QtGui.QDialog):
upnpThread = upnp.uPnPThread() upnpThread = upnp.uPnPThread()
upnpThread.start() upnpThread.start()
udp_enabled = self.checkBoxUDP.isChecked()
if udp_enabled != self.config.safeGetBoolean(
'bitmessagesettings', 'udp'):
self.config.set('bitmessagesettings', 'udp', str(udp_enabled))
if udp_enabled:
announceThread = AnnounceThread()
announceThread.daemon = True
announceThread.start()
else:
try:
state.announceThread.stopThread()
except AttributeError:
pass
proxytype_index = self.comboBoxProxyType.currentIndex() proxytype_index = self.comboBoxProxyType.currentIndex()
if proxytype_index == 0: if proxytype_index == 0:
if self._proxy_type and state.statusIconColor != 'red': if self._proxy_type and state.statusIconColor != 'red':
self.net_restart_needed = True self.net_restart_needed = True
elif state.statusIconColor == 'red' and self.config.safeGetBoolean( elif state.statusIconColor == 'red' and self.config.safeGetBoolean('bitmessagesettings', 'dontconnect'):
'bitmessagesettings', 'dontconnect'):
self.net_restart_needed = False self.net_restart_needed = False
elif self.comboBoxProxyType.currentText() != self._proxy_type: elif self.comboBoxProxyType.currentText() != self._proxy_type:
self.net_restart_needed = True self.net_restart_needed = True
@ -387,11 +369,8 @@ class SettingsDialog(QtGui.QDialog):
self.lineEditSocksPassword.text())) self.lineEditSocksPassword.text()))
self.config.set('bitmessagesettings', 'sockslisten', str( self.config.set('bitmessagesettings', 'sockslisten', str(
self.checkBoxSocksListen.isChecked())) self.checkBoxSocksListen.isChecked()))
if ( if self.checkBoxOnionOnly.isChecked() \
self.checkBoxOnionOnly.isChecked() and not self.config.safeGetBoolean('bitmessagesettings', 'onionservicesonly'):
and not self.config.safeGetBoolean(
'bitmessagesettings', 'onionservicesonly')
):
self.net_restart_needed = True self.net_restart_needed = True
self.config.set('bitmessagesettings', 'onionservicesonly', str( self.config.set('bitmessagesettings', 'onionservicesonly', str(
self.checkBoxOnionOnly.isChecked())) self.checkBoxOnionOnly.isChecked()))

View File

@ -231,7 +231,7 @@
</layout> </layout>
</widget> </widget>
</item> </item>
<item row="3" column="0"> <item row="2" column="0">
<widget class="QGroupBox" name="groupBox_3"> <widget class="QGroupBox" name="groupBox_3">
<property name="title"> <property name="title">
<string>Bandwidth limit</string> <string>Bandwidth limit</string>
@ -322,7 +322,7 @@
</layout> </layout>
</widget> </widget>
</item> </item>
<item row="2" column="0"> <item row="1" column="0">
<widget class="QGroupBox" name="groupBox_2"> <widget class="QGroupBox" name="groupBox_2">
<property name="title"> <property name="title">
<string>Proxy server / Tor</string> <string>Proxy server / Tor</string>
@ -432,14 +432,7 @@
</layout> </layout>
</widget> </widget>
</item> </item>
<item row="1" column="0"> <item row="3" column="0">
<widget class="QCheckBox" name="checkBoxUDP">
<property name="text">
<string>Announce self by UDP</string>
</property>
</widget>
</item>
<item row="4" column="0">
<spacer name="verticalSpacer"> <spacer name="verticalSpacer">
<property name="orientation"> <property name="orientation">
<enum>Qt::Vertical</enum> <enum>Qt::Vertical</enum>

View File

@ -2,10 +2,6 @@
from addressbook import TestAddressbook from addressbook import TestAddressbook
from main import TestMain, TestUISignaler from main import TestMain, TestUISignaler
from settings import TestSettings
from support import TestSupport from support import TestSupport
__all__ = [ __all__ = ["TestAddressbook", "TestMain", "TestSupport", "TestUISignaler"]
"TestAddressbook", "TestMain", "TestSettings", "TestSupport",
"TestUISignaler"
]

View File

@ -1,34 +0,0 @@
import threading
import time
from main import TestBase
from bmconfigparser import BMConfigParser
from bitmessageqt import settings
class TestSettings(TestBase):
"""A test case for the "Settings" dialog"""
def setUp(self):
super(TestSettings, self).setUp()
self.dialog = settings.SettingsDialog(self.window)
def test_udp(self):
"""Test the effect of checkBoxUDP"""
udp_setting = BMConfigParser().safeGetBoolean(
'bitmessagesettings', 'udp')
self.assertEqual(udp_setting, self.dialog.checkBoxUDP.isChecked())
self.dialog.checkBoxUDP.setChecked(not udp_setting)
self.dialog.accept()
self.assertEqual(
not udp_setting,
BMConfigParser().safeGetBoolean('bitmessagesettings', 'udp'))
time.sleep(5)
for thread in threading.enumerate():
if thread.name == 'Announcer': # find Announcer thread
if udp_setting:
self.fail(
'Announcer thread is running while udp set to False')
break
else:
if not udp_setting:
self.fail('No Announcer thread found while udp set to True')

View File

@ -2,22 +2,13 @@
BMConfigParser class definition and default configuration settings BMConfigParser class definition and default configuration settings
""" """
import sys
if sys.version_info[0] == 3:
# python 3
import configparser as ConfigParser
SafeConfigParser = ConfigParser.ConfigParser
else:
# python 2
import ConfigParser import ConfigParser
SafeConfigParser = ConfigParser.SafeConfigParser
import state
from singleton import Singleton
import os import os
import shutil import shutil
from datetime import datetime from datetime import datetime
import state
from singleton import Singleton
BMConfigDefaults = { BMConfigDefaults = {
"bitmessagesettings": { "bitmessagesettings": {
@ -28,32 +19,30 @@ BMConfigDefaults = {
"maxtotalconnections": 200, "maxtotalconnections": 200,
"maxuploadrate": 0, "maxuploadrate": 0,
"apiinterface": "127.0.0.1", "apiinterface": "127.0.0.1",
"apiport": 8442, "apiport": 8442
"udp": "True"
}, },
"threads": { "threads": {
"receive": 3, "receive": 3,
}, },
"network": { "network": {
"bind": "", "bind": '',
"dandelion": 90, "dandelion": 90,
}, },
"inventory": { "inventory": {
"storage": "sqlite", "storage": "sqlite",
"acceptmismatch": "False", "acceptmismatch": False,
}, },
"knownnodes": { "knownnodes": {
"maxnodes": 20000, "maxnodes": 20000,
}, },
"zlib": { "zlib": {
"maxsize": 1048576 'maxsize': 1048576
} }
} }
@Singleton @Singleton
class BMConfigParser(SafeConfigParser): class BMConfigParser(ConfigParser.SafeConfigParser):
""" """
Singleton class inherited from :class:`ConfigParser.SafeConfigParser` Singleton class inherited from :class:`ConfigParser.SafeConfigParser`
with additional methods specific to bitmessage config. with additional methods specific to bitmessage config.
@ -70,42 +59,21 @@ class BMConfigParser(SafeConfigParser):
raise ValueError("Invalid value %s" % value) raise ValueError("Invalid value %s" % value)
return ConfigParser.ConfigParser.set(self, section, option, value) return ConfigParser.ConfigParser.set(self, section, option, value)
def get(self, section, option, raw=False, vars=None): def get(self, section, option, raw=False, variables=None):
if sys.version_info[0] == 3:
# pylint: disable=arguments-differ # pylint: disable=arguments-differ
try: try:
if section == "bitmessagesettings" and option == "timeformat": if section == "bitmessagesettings" and option == "timeformat":
return ConfigParser.ConfigParser.get( return ConfigParser.ConfigParser.get(
self, section, option) self, section, option, raw, variables)
try: try:
return self._temp[section][option] return self._temp[section][option]
except KeyError: except KeyError:
pass pass
return ConfigParser.ConfigParser.get( return ConfigParser.ConfigParser.get(
self, section, option) self, section, option, True, variables)
except ConfigParser.InterpolationError: except ConfigParser.InterpolationError:
return ConfigParser.ConfigParser.get( return ConfigParser.ConfigParser.get(
self, section, option) self, section, option, True, variables)
except (ConfigParser.NoSectionError, ConfigParser.NoOptionError) as e:
try:
return BMConfigDefaults[section][option]
except (KeyError, ValueError, AttributeError):
raise e
else:
# pylint: disable=arguments-differ
try:
if section == "bitmessagesettings" and option == "timeformat":
return ConfigParser.ConfigParser.get(
self, section, option, raw, vars)
try:
return self._temp[section][option]
except KeyError:
pass
return ConfigParser.ConfigParser.get(
self, section, option, True, vars)
except ConfigParser.InterpolationError:
return ConfigParser.ConfigParser.get(
self, section, option, True, vars)
except (ConfigParser.NoSectionError, ConfigParser.NoOptionError) as e: except (ConfigParser.NoSectionError, ConfigParser.NoOptionError) as e:
try: try:
return BMConfigDefaults[section][option] return BMConfigDefaults[section][option]
@ -222,4 +190,3 @@ class BMConfigParser(SafeConfigParser):
if value < 0 or value > 8: if value < 0 or value > 8:
return False return False
return True return True

View File

@ -421,8 +421,8 @@ def check_dependencies(verbose=False, optional=False):
if sys.hexversion >= 0x3000000: if sys.hexversion >= 0x3000000:
logger.error( logger.error(
'PyBitmessage does not support Python 3+. Python 2.7.4' 'PyBitmessage does not support Python 3+. Python 2.7.4'
' or greater is required. Python 2.7.18 is recommended.') ' or greater is required.')
sys.exit() has_all_dependencies = False
check_functions = [check_ripemd160, check_sqlite, check_openssl] check_functions = [check_ripemd160, check_sqlite, check_openssl]
if optional: if optional:

View File

@ -7,6 +7,7 @@ import state
from bmconfigparser import BMConfigParser from bmconfigparser import BMConfigParser
from network.assemble import assemble_addr from network.assemble import assemble_addr
from network.connectionpool import BMConnectionPool from network.connectionpool import BMConnectionPool
from network.udp import UDPSocket
from node import Peer from node import Peer
from threads import StoppableThread from threads import StoppableThread
@ -14,13 +15,12 @@ from threads import StoppableThread
class AnnounceThread(StoppableThread): class AnnounceThread(StoppableThread):
"""A thread to manage regular announcing of this node""" """A thread to manage regular announcing of this node"""
name = "Announcer" name = "Announcer"
announceInterval = 60
def run(self): def run(self):
lastSelfAnnounced = 0 lastSelfAnnounced = 0
while not self._stopped and state.shutdown == 0: while not self._stopped and state.shutdown == 0:
processed = 0 processed = 0
if lastSelfAnnounced < time.time() - self.announceInterval: if lastSelfAnnounced < time.time() - UDPSocket.announceInterval:
self.announceSelf() self.announceSelf()
lastSelfAnnounced = time.time() lastSelfAnnounced = time.time()
if processed == 0: if processed == 0:

View File

@ -749,7 +749,7 @@ class dispatcher(object):
def log_info(self, message, log_type='info'): def log_info(self, message, log_type='info'):
"""Conditionally print a message""" """Conditionally print a message"""
if log_type not in self.ignore_log_types: if log_type not in self.ignore_log_types:
print('%s: %s' % (log_type, message)) print '%s: %s' % (log_type, message)
def handle_read_event(self): def handle_read_event(self):
"""Handle a read event""" """Handle a read event"""

View File

@ -18,19 +18,19 @@ class HttpConnection(AdvancedDispatcher):
self.destination = (host, 80) self.destination = (host, 80)
self.create_socket(socket.AF_INET, socket.SOCK_STREAM) self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
self.connect(self.destination) self.connect(self.destination)
print("connecting in background to %s:%i" % self.destination) print "connecting in background to %s:%i" % (self.destination[0], self.destination[1])
def state_init(self): def state_init(self):
self.append_write_buf( self.append_write_buf(
"GET %s HTTP/1.1\r\nHost: %s\r\nConnection: close\r\n\r\n" % ( "GET %s HTTP/1.1\r\nHost: %s\r\nConnection: close\r\n\r\n" % (
self.path, self.destination[0])) self.path, self.destination[0]))
print("Sending %ib" % len(self.write_buf)) print "Sending %ib" % (len(self.write_buf))
self.set_state("http_request_sent", 0) self.set_state("http_request_sent", 0)
return False return False
def state_http_request_sent(self): def state_http_request_sent(self):
if self.read_buf: if self.read_buf:
print("Received %ib" % len(self.read_buf)) print "Received %ib" % (len(self.read_buf))
self.read_buf = b"" self.read_buf = b""
if not self.connected: if not self.connected:
self.set_state("close", 0) self.set_state("close", 0)
@ -62,13 +62,13 @@ if __name__ == "__main__":
for host in ("bootstrap8080.bitmessage.org", "bootstrap8444.bitmessage.org"): for host in ("bootstrap8080.bitmessage.org", "bootstrap8444.bitmessage.org"):
proxy = Socks5Resolver(host=host) proxy = Socks5Resolver(host=host)
while asyncore.socket_map: while asyncore.socket_map:
print("loop %s, len %i" % (proxy.state, len(asyncore.socket_map))) print "loop %s, len %i" % (proxy.state, len(asyncore.socket_map))
asyncore.loop(timeout=1, count=1) asyncore.loop(timeout=1, count=1)
proxy.resolved() proxy.resolved()
proxy = Socks4aResolver(host=host) proxy = Socks4aResolver(host=host)
while asyncore.socket_map: while asyncore.socket_map:
print("loop %s, len %i" % (proxy.state, len(asyncore.socket_map))) print "loop %s, len %i" % (proxy.state, len(asyncore.socket_map))
asyncore.loop(timeout=1, count=1) asyncore.loop(timeout=1, count=1)
proxy.resolved() proxy.resolved()

View File

@ -8,7 +8,6 @@ import time
import protocol import protocol
import state import state
from bmproto import BMProto from bmproto import BMProto
from constants import MAX_TIME_OFFSET
from node import Peer from node import Peer
from objectracker import ObjectTracker from objectracker import ObjectTracker
from queues import receiveDataQueue from queues import receiveDataQueue
@ -19,6 +18,7 @@ logger = logging.getLogger('default')
class UDPSocket(BMProto): # pylint: disable=too-many-instance-attributes class UDPSocket(BMProto): # pylint: disable=too-many-instance-attributes
"""Bitmessage protocol over UDP (class)""" """Bitmessage protocol over UDP (class)"""
port = 8444 port = 8444
announceInterval = 60
def __init__(self, host=None, sock=None, announcing=False): def __init__(self, host=None, sock=None, announcing=False):
# pylint: disable=bad-super-call # pylint: disable=bad-super-call
@ -82,8 +82,8 @@ class UDPSocket(BMProto): # pylint: disable=too-many-instance-attributes
decodedIP = protocol.checkIPAddress(str(ip)) decodedIP = protocol.checkIPAddress(str(ip))
if stream not in state.streamsInWhichIAmParticipating: if stream not in state.streamsInWhichIAmParticipating:
continue continue
if (seenTime < time.time() - MAX_TIME_OFFSET if (seenTime < time.time() - self.maxTimeOffset
or seenTime > time.time() + MAX_TIME_OFFSET): or seenTime > time.time() + self.maxTimeOffset):
continue continue
if decodedIP is False: if decodedIP is False:
# if the address isn't local, interpret it as # if the address isn't local, interpret it as
@ -94,6 +94,7 @@ class UDPSocket(BMProto): # pylint: disable=too-many-instance-attributes
logger.debug( logger.debug(
"received peer discovery from %s:%i (port %i):", "received peer discovery from %s:%i (port %i):",
self.destination.host, self.destination.port, remoteport) self.destination.host, self.destination.port, remoteport)
if self.local:
state.discoveredPeers[Peer(self.destination.host, remoteport)] = \ state.discoveredPeers[Peer(self.destination.host, remoteport)] = \
time.time() time.time()
return True return True
@ -124,9 +125,9 @@ class UDPSocket(BMProto): # pylint: disable=too-many-instance-attributes
def handle_read(self): def handle_read(self):
try: try:
recdata, addr = self.socket.recvfrom(self._buf_len) (recdata, addr) = self.socket.recvfrom(self._buf_len)
except socket.error: except socket.error as e:
logger.error("socket error on recvfrom:", exc_info=True) logger.error("socket error: %s", e)
return return
self.destination = Peer(*addr) self.destination = Peer(*addr)
@ -142,7 +143,7 @@ class UDPSocket(BMProto): # pylint: disable=too-many-instance-attributes
try: try:
retval = self.socket.sendto( retval = self.socket.sendto(
self.write_buf, ('<broadcast>', self.port)) self.write_buf, ('<broadcast>', self.port))
except socket.error: except socket.error as e:
logger.error("socket error on sendto:", exc_info=True) logger.error("socket error on sendto: %s", e)
retval = len(self.write_buf) retval = len(self.write_buf)
self.slice_write_buf(retval) self.slice_write_buf(retval)

View File

@ -1,24 +1,16 @@
#!/usr/bin/env python2.7
""" """
Module for Proof of Work using OpenCL Module for Proof of Work using OpenCL
""" """
import logging
import os import os
from struct import pack from struct import pack
import paths import paths
from bmconfigparser import BMConfigParser from bmconfigparser import BMConfigParser
from debug import logger
from state import shutdown from state import shutdown
try:
import numpy
import pyopencl as cl
libAvailable = True libAvailable = True
except ImportError:
libAvailable = False
logger = logging.getLogger('default')
ctx = False ctx = False
queue = False queue = False
program = False program = False
@ -27,10 +19,17 @@ enabledGpus = []
vendors = [] vendors = []
hash_dt = None hash_dt = None
try:
import pyopencl as cl
import numpy
except ImportError:
libAvailable = False
def initCL(): def initCL():
"""Initlialise OpenCL engine""" """Initlialise OpenCL engine"""
global ctx, queue, program, hash_dt # pylint: disable=global-statement # pylint: disable=global-statement
global ctx, queue, program, hash_dt, libAvailable
if libAvailable is False: if libAvailable is False:
return return
del enabledGpus[:] del enabledGpus[:]

View File

@ -1,10 +0,0 @@
import os
import sys
def setup():
"""Add path to this file to sys.path"""
app_dir = os.path.dirname(os.path.abspath(__file__))
os.chdir(app_dir)
sys.path.insert(0, app_dir)
return app_dir

View File

@ -16,7 +16,7 @@ def inv(a, n):
lm, hm = 1, 0 lm, hm = 1, 0
low, high = a % n, n low, high = a % n, n
while low > 1: while low > 1:
r = high // low r = high / low
nm, new = hm - lm * r, high - low * r nm, new = hm - lm * r, high - low * r
lm, low, hm, high = nm, new, lm, low lm, low, hm, high = nm, new, lm, low
return lm % n return lm % n
@ -43,8 +43,8 @@ def encode(val, base, minlen=0):
code_string = get_code_string(base) code_string = get_code_string(base)
result = "" result = ""
while val > 0: while val > 0:
val, i = divmod(val, base) result = code_string[val % base] + result
result = code_string[i] + result val /= base
if len(result) < minlen: if len(result) < minlen:
result = code_string[0] * (minlen - len(result)) + result result = code_string[0] * (minlen - len(result)) + result
return result return result
@ -101,11 +101,10 @@ def base10_multiply(a, n):
return G return G
if n == 1: if n == 1:
return a return a
n, m = divmod(n, 2) if (n % 2) == 0:
if m == 0: return base10_double(base10_multiply(a, n / 2))
return base10_double(base10_multiply(a, n)) if (n % 2) == 1:
if m == 1: return base10_add(base10_double(base10_multiply(a, n / 2)), a)
return base10_add(base10_double(base10_multiply(a, n)), a)
return None return None

View File

@ -1,10 +1,12 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
""" """
Symmetric Encryption Symmetric Encryption
""" """
# Copyright (C) 2011 Yann GUIBET <yannguibet@gmail.com> # Copyright (C) 2011 Yann GUIBET <yannguibet@gmail.com>
# See LICENSE for details. # See LICENSE for details.
from .openssl import OpenSSL from openssl import OpenSSL
# pylint: disable=redefined-builtin # pylint: disable=redefined-builtin

View File

@ -1,3 +1,5 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
""" """
Asymmetric cryptography using elliptic curves Asymmetric cryptography using elliptic curves
""" """
@ -8,9 +10,9 @@ Asymmetric cryptography using elliptic curves
from hashlib import sha512 from hashlib import sha512
from struct import pack, unpack from struct import pack, unpack
from .cipher import Cipher from cipher import Cipher
from .hash import equals, hmac_sha256 from hash import equals, hmac_sha256
from .openssl import OpenSSL from openssl import OpenSSL
class ECC(object): class ECC(object):
@ -80,7 +82,6 @@ class ECC(object):
self.pubkey_y = None self.pubkey_y = None
self.privkey = None self.privkey = None
raise Exception("Bad ECC keys ...") raise Exception("Bad ECC keys ...")
else:
self.pubkey_x = pubkey_x self.pubkey_x = pubkey_x
self.pubkey_y = pubkey_y self.pubkey_y = pubkey_y
self.privkey = privkey self.privkey = privkey
@ -209,8 +210,8 @@ class ECC(object):
if other_key == 0: if other_key == 0:
raise Exception("[OpenSSL] EC_KEY_new_by_curve_name FAIL ...") raise Exception("[OpenSSL] EC_KEY_new_by_curve_name FAIL ...")
other_pub_key_x = OpenSSL.BN_bin2bn(pubkey_x, len(pubkey_x), 0) other_pub_key_x = OpenSSL.BN_bin2bn(pubkey_x, len(pubkey_x), None)
other_pub_key_y = OpenSSL.BN_bin2bn(pubkey_y, len(pubkey_y), 0) other_pub_key_y = OpenSSL.BN_bin2bn(pubkey_y, len(pubkey_y), None)
other_group = OpenSSL.EC_KEY_get0_group(other_key) other_group = OpenSSL.EC_KEY_get0_group(other_key)
other_pub_key = OpenSSL.EC_POINT_new(other_group) other_pub_key = OpenSSL.EC_POINT_new(other_group)
@ -231,7 +232,7 @@ class ECC(object):
if own_key == 0: if own_key == 0:
raise Exception("[OpenSSL] EC_KEY_new_by_curve_name FAIL ...") raise Exception("[OpenSSL] EC_KEY_new_by_curve_name FAIL ...")
own_priv_key = OpenSSL.BN_bin2bn( own_priv_key = OpenSSL.BN_bin2bn(
self.privkey, len(self.privkey), 0) self.privkey, len(self.privkey), None)
if (OpenSSL.EC_KEY_set_private_key(own_key, own_priv_key)) == 0: if (OpenSSL.EC_KEY_set_private_key(own_key, own_priv_key)) == 0:
raise Exception("[OpenSSL] EC_KEY_set_private_key FAIL ...") raise Exception("[OpenSSL] EC_KEY_set_private_key FAIL ...")
@ -277,16 +278,14 @@ class ECC(object):
curve = self.curve curve = self.curve
elif isinstance(curve, str): elif isinstance(curve, str):
curve = OpenSSL.get_curve(curve) curve = OpenSSL.get_curve(curve)
else:
curve = curve
try: try:
key = OpenSSL.EC_KEY_new_by_curve_name(curve) key = OpenSSL.EC_KEY_new_by_curve_name(curve)
if key == 0: if key == 0:
raise Exception("[OpenSSL] EC_KEY_new_by_curve_name FAIL ...") raise Exception("[OpenSSL] EC_KEY_new_by_curve_name FAIL ...")
if privkey is not None: if privkey is not None:
priv_key = OpenSSL.BN_bin2bn(privkey, len(privkey), 0) priv_key = OpenSSL.BN_bin2bn(privkey, len(privkey), None)
pub_key_x = OpenSSL.BN_bin2bn(pubkey_x, len(pubkey_x), 0) pub_key_x = OpenSSL.BN_bin2bn(pubkey_x, len(pubkey_x), None)
pub_key_y = OpenSSL.BN_bin2bn(pubkey_y, len(pubkey_y), 0) pub_key_y = OpenSSL.BN_bin2bn(pubkey_y, len(pubkey_y), None)
if privkey is not None: if privkey is not None:
if (OpenSSL.EC_KEY_set_private_key(key, priv_key)) == 0: if (OpenSSL.EC_KEY_set_private_key(key, priv_key)) == 0:
@ -336,9 +335,11 @@ class ECC(object):
if key == 0: if key == 0:
raise Exception("[OpenSSL] EC_KEY_new_by_curve_name FAIL ...") raise Exception("[OpenSSL] EC_KEY_new_by_curve_name FAIL ...")
priv_key = OpenSSL.BN_bin2bn(self.privkey, len(self.privkey), 0) priv_key = OpenSSL.BN_bin2bn(self.privkey, len(self.privkey), None)
pub_key_x = OpenSSL.BN_bin2bn(self.pubkey_x, len(self.pubkey_x), 0) pub_key_x = OpenSSL.BN_bin2bn(self.pubkey_x, len(self.pubkey_x),
pub_key_y = OpenSSL.BN_bin2bn(self.pubkey_y, len(self.pubkey_y), 0) None)
pub_key_y = OpenSSL.BN_bin2bn(self.pubkey_y, len(self.pubkey_y),
None)
if (OpenSSL.EC_KEY_set_private_key(key, priv_key)) == 0: if (OpenSSL.EC_KEY_set_private_key(key, priv_key)) == 0:
raise Exception("[OpenSSL] EC_KEY_set_private_key FAIL ...") raise Exception("[OpenSSL] EC_KEY_set_private_key FAIL ...")
@ -403,8 +404,10 @@ class ECC(object):
if key == 0: if key == 0:
raise Exception("[OpenSSL] EC_KEY_new_by_curve_name FAIL ...") raise Exception("[OpenSSL] EC_KEY_new_by_curve_name FAIL ...")
pub_key_x = OpenSSL.BN_bin2bn(self.pubkey_x, len(self.pubkey_x), 0) pub_key_x = OpenSSL.BN_bin2bn(self.pubkey_x, len(self.pubkey_x),
pub_key_y = OpenSSL.BN_bin2bn(self.pubkey_y, len(self.pubkey_y), 0) None)
pub_key_y = OpenSSL.BN_bin2bn(self.pubkey_y, len(self.pubkey_y),
None)
group = OpenSSL.EC_KEY_get0_group(key) group = OpenSSL.EC_KEY_get0_group(key)
pub_key = OpenSSL.EC_POINT_new(group) pub_key = OpenSSL.EC_POINT_new(group)
@ -475,9 +478,9 @@ class ECC(object):
key = sha512(ephem.raw_get_ecdh_key(pubkey_x, pubkey_y)).digest() key = sha512(ephem.raw_get_ecdh_key(pubkey_x, pubkey_y)).digest()
key_e, key_m = key[:32], key[32:] key_e, key_m = key[:32], key[32:]
pubkey = ephem.get_pubkey() pubkey = ephem.get_pubkey()
iv = OpenSSL.rand(OpenSSL.get_cipher(ciphername).get_blocksize()) _iv = OpenSSL.rand(OpenSSL.get_cipher(ciphername).get_blocksize())
ctx = Cipher(key_e, iv, 1, ciphername) ctx = Cipher(key_e, _iv, 1, ciphername)
ciphertext = iv + pubkey + ctx.ciphering(data) ciphertext = _iv + pubkey + ctx.ciphering(data)
mac = hmac_sha256(key_m, ciphertext) mac = hmac_sha256(key_m, ciphertext)
return ciphertext + mac return ciphertext + mac
@ -486,16 +489,21 @@ class ECC(object):
Decrypt data with ECIES method using the local private key Decrypt data with ECIES method using the local private key
""" """
blocksize = OpenSSL.get_cipher(ciphername).get_blocksize() blocksize = OpenSSL.get_cipher(ciphername).get_blocksize()
iv = data[:blocksize] _iv = data[:blocksize]
i = blocksize i = blocksize
_, pubkey_x, pubkey_y, i2 = ECC._decode_pubkey(data[i:]) _, pubkey_x, pubkey_y, _i2 = ECC._decode_pubkey(data[i:])
i += i2 i += _i2
ciphertext = data[i:len(data) - 32] ciphertext = data[i:len(data) - 32]
i += len(ciphertext) i += len(ciphertext)
mac = data[i:] mac = data[i:]
key = sha512(self.raw_get_ecdh_key(pubkey_x, pubkey_y)).digest() key = sha512(self.raw_get_ecdh_key(pubkey_x, pubkey_y)).digest()
key_e, key_m = key[:32], key[32:] key_e, key_m = key[:32], key[32:]
if not equals(hmac_sha256(key_m, data[:len(data) - 32]), mac): if not equals(hmac_sha256(key_m, data[:len(data) - 32]), mac):
print "b1"
raise RuntimeError("Fail to verify data") raise RuntimeError("Fail to verify data")
ctx = Cipher(key_e, iv, 0, ciphername) print "b2"
return ctx.ciphering(ciphertext) ctx = Cipher(key_e, _iv, 0, ciphername)
print "c"
retval = ctx.ciphering(ciphertext)
print "d"
return retval

View File

@ -1,3 +1,4 @@
#!/usr/bin/env python
""" """
ECC blind signature functionality based on ECC blind signature functionality based on
"An Efficient Blind Signature Scheme "An Efficient Blind Signature Scheme
@ -109,7 +110,7 @@ class ECCBlind(object): # pylint: disable=too-many-instance-attributes
""" """
ECC inversion ECC inversion
""" """
inverse = OpenSSL.BN_mod_inverse(0, a, self.n, self.ctx) inverse = OpenSSL.BN_mod_inverse(None, a, self.n, self.ctx)
return inverse return inverse
def ec_gen_keypair(self): def ec_gen_keypair(self):
@ -119,7 +120,7 @@ class ECCBlind(object): # pylint: disable=too-many-instance-attributes
""" """
d = self.ec_get_random() d = self.ec_get_random()
Q = OpenSSL.EC_POINT_new(self.group) Q = OpenSSL.EC_POINT_new(self.group)
OpenSSL.EC_POINT_mul(self.group, Q, d, 0, 0, 0) OpenSSL.EC_POINT_mul(self.group, Q, d, None, None, None)
return (d, Q) return (d, Q)
def ec_Ftor(self, F): def ec_Ftor(self, F):
@ -139,7 +140,7 @@ class ECCBlind(object): # pylint: disable=too-many-instance-attributes
x = OpenSSL.BN_new() x = OpenSSL.BN_new()
y = OpenSSL.BN_new() y = OpenSSL.BN_new()
OpenSSL.EC_POINT_get_affine_coordinates( OpenSSL.EC_POINT_get_affine_coordinates(
self.group, point, x, y, 0) self.group, point, x, y, None)
y_byte = (OpenSSL.BN_is_odd(y) & Y_BIT) | COMPRESSED_BIT y_byte = (OpenSSL.BN_is_odd(y) & Y_BIT) | COMPRESSED_BIT
l_ = OpenSSL.BN_num_bytes(self.n) l_ = OpenSSL.BN_num_bytes(self.n)
try: try:
@ -150,7 +151,7 @@ class ECCBlind(object): # pylint: disable=too-many-instance-attributes
# padding manually # padding manually
bx = OpenSSL.malloc(0, OpenSSL.BN_num_bytes(x)) bx = OpenSSL.malloc(0, OpenSSL.BN_num_bytes(x))
OpenSSL.BN_bn2bin(x, bx) OpenSSL.BN_bn2bin(x, bx)
out = bx.raw.rjust(l_, b'\x00') out = bx.raw.rjust(l_, chr(0))
return pack(EC, y_byte, out) return pack(EC, y_byte, out)
finally: finally:
@ -160,7 +161,7 @@ class ECCBlind(object): # pylint: disable=too-many-instance-attributes
def _ec_point_deserialize(self, data): def _ec_point_deserialize(self, data):
"""Make a string into an EC point""" """Make a string into an EC point"""
y_bit, x_raw = unpack(EC, data) y_bit, x_raw = unpack(EC, data)
x = OpenSSL.BN_bin2bn(x_raw, OpenSSL.BN_num_bytes(self.n), 0) x = OpenSSL.BN_bin2bn(x_raw, OpenSSL.BN_num_bytes(self.n), None)
y_bit &= Y_BIT y_bit &= Y_BIT
retval = OpenSSL.EC_POINT_new(self.group) retval = OpenSSL.EC_POINT_new(self.group)
OpenSSL.EC_POINT_set_compressed_coordinates(self.group, OpenSSL.EC_POINT_set_compressed_coordinates(self.group,
@ -180,11 +181,11 @@ class ECCBlind(object): # pylint: disable=too-many-instance-attributes
except AttributeError: except AttributeError:
o = OpenSSL.malloc(0, OpenSSL.BN_num_bytes(bn)) o = OpenSSL.malloc(0, OpenSSL.BN_num_bytes(bn))
OpenSSL.BN_bn2bin(bn, o) OpenSSL.BN_bn2bin(bn, o)
return o.raw.rjust(l_, b'\x00') return o.raw.rjust(l_, chr(0))
def _bn_deserialize(self, data): def _bn_deserialize(self, data):
"""Make a BigNum out of string""" """Make a BigNum out of string"""
x = OpenSSL.BN_bin2bn(data, OpenSSL.BN_num_bytes(self.n), 0) x = OpenSSL.BN_bin2bn(data, OpenSSL.BN_num_bytes(self.n), None)
return x return x
def _init_privkey(self, privkey): def _init_privkey(self, privkey):
@ -261,7 +262,7 @@ class ECCBlind(object): # pylint: disable=too-many-instance-attributes
# R = kG # R = kG
self.R = OpenSSL.EC_POINT_new(self.group) self.R = OpenSSL.EC_POINT_new(self.group)
OpenSSL.EC_POINT_mul(self.group, self.R, self.k, 0, 0, 0) OpenSSL.EC_POINT_mul(self.group, self.R, self.k, None, None, None)
return self._ec_point_serialize(self.R) return self._ec_point_serialize(self.R)
@ -286,17 +287,18 @@ class ECCBlind(object): # pylint: disable=too-many-instance-attributes
# F = b^-1 * R... # F = b^-1 * R...
self.binv = self.ec_invert(self.b) self.binv = self.ec_invert(self.b)
OpenSSL.EC_POINT_mul(self.group, temp, 0, self.R, self.binv, 0) OpenSSL.EC_POINT_mul(self.group, temp, None, self.R, self.binv,
None)
OpenSSL.EC_POINT_copy(self.F, temp) OpenSSL.EC_POINT_copy(self.F, temp)
# ... + a*b^-1 * Q... # ... + a*b^-1 * Q...
OpenSSL.BN_mul(abinv, self.a, self.binv, self.ctx) OpenSSL.BN_mul(abinv, self.a, self.binv, self.ctx)
OpenSSL.EC_POINT_mul(self.group, temp, 0, self.Q, abinv, 0) OpenSSL.EC_POINT_mul(self.group, temp, None, self.Q, abinv, None)
OpenSSL.EC_POINT_add(self.group, self.F, self.F, temp, 0) OpenSSL.EC_POINT_add(self.group, self.F, self.F, temp, None)
# ... + c*G # ... + c*G
OpenSSL.EC_POINT_mul(self.group, temp, 0, self.G, self.c, 0) OpenSSL.EC_POINT_mul(self.group, temp, None, self.G, self.c, None)
OpenSSL.EC_POINT_add(self.group, self.F, self.F, temp, 0) OpenSSL.EC_POINT_add(self.group, self.F, self.F, temp, None)
# F = (x0, y0) # F = (x0, y0)
self.r = self.ec_Ftor(self.F) self.r = self.ec_Ftor(self.F)
@ -355,10 +357,10 @@ class ECCBlind(object): # pylint: disable=too-many-instance-attributes
lhs = OpenSSL.EC_POINT_new(self.group) lhs = OpenSSL.EC_POINT_new(self.group)
rhs = OpenSSL.EC_POINT_new(self.group) rhs = OpenSSL.EC_POINT_new(self.group)
OpenSSL.EC_POINT_mul(self.group, lhs, s, 0, 0, 0) OpenSSL.EC_POINT_mul(self.group, lhs, s, None, None, None)
OpenSSL.EC_POINT_mul(self.group, rhs, 0, self.Q, self.m, 0) OpenSSL.EC_POINT_mul(self.group, rhs, None, self.Q, self.m, None)
OpenSSL.EC_POINT_mul(self.group, rhs, 0, rhs, self.r, 0) OpenSSL.EC_POINT_mul(self.group, rhs, None, rhs, self.r, None)
OpenSSL.EC_POINT_add(self.group, rhs, rhs, self.F, self.ctx) OpenSSL.EC_POINT_add(self.group, rhs, rhs, self.F, self.ctx)
retval = OpenSSL.EC_POINT_cmp(self.group, lhs, rhs, self.ctx) retval = OpenSSL.EC_POINT_cmp(self.group, lhs, rhs, self.ctx)

View File

@ -4,7 +4,7 @@ Wrappers for hash functions from OpenSSL.
# Copyright (C) 2011 Yann GUIBET <yannguibet@gmail.com> # Copyright (C) 2011 Yann GUIBET <yannguibet@gmail.com>
# See LICENSE for details. # See LICENSE for details.
from .openssl import OpenSSL from openssl import OpenSSL
# For python3 # For python3
@ -41,7 +41,13 @@ def hmac_sha256(k, m):
d = OpenSSL.malloc(m, len(m)) d = OpenSSL.malloc(m, len(m))
md = OpenSSL.malloc(0, 32) md = OpenSSL.malloc(0, 32)
i = OpenSSL.pointer(OpenSSL.c_int(0)) i = OpenSSL.pointer(OpenSSL.c_int(0))
print("calculating")
try:
OpenSSL.HMAC(OpenSSL.EVP_sha256(), key, len(k), d, len(m), md, i) OpenSSL.HMAC(OpenSSL.EVP_sha256(), key, len(k), d, len(m), md, i)
except Exception as e:
print(e)
raise e
# print(i.contents)
return md.raw return md.raw
@ -53,7 +59,9 @@ def hmac_sha512(k, m):
d = OpenSSL.malloc(m, len(m)) d = OpenSSL.malloc(m, len(m))
md = OpenSSL.malloc(0, 64) md = OpenSSL.malloc(0, 64)
i = OpenSSL.pointer(OpenSSL.c_int(0)) i = OpenSSL.pointer(OpenSSL.c_int(0))
print("calculating")
OpenSSL.HMAC(OpenSSL.EVP_sha512(), key, len(k), d, len(m), md, i) OpenSSL.HMAC(OpenSSL.EVP_sha512(), key, len(k), d, len(m), md, i)
print(i.contents)
return md.raw return md.raw

View File

@ -72,6 +72,29 @@ def get_version(library):
return (version, hexversion, cflags) return (version, hexversion, cflags)
class BIGNUM(ctypes.Structure): # pylint: disable=too-few-public-methods
"""OpenSSL's BIGNUM struct"""
_fields_ = [
('d', ctypes.POINTER(ctypes.c_ulong)),
('top', ctypes.c_int),
('dmax', ctypes.c_int),
('neg', ctypes.c_int),
('flags', ctypes.c_int),
]
class EC_POINT(ctypes.Structure): # pylint: disable=too-few-public-methods
"""OpenSSL's EC_POINT struct"""
_fields_ = [
('meth', ctypes.c_void_p),
('curve_name', ctypes.c_int),
('X', ctypes.POINTER(BIGNUM)),
('Y', ctypes.POINTER(BIGNUM)),
('Z', ctypes.POINTER(BIGNUM)),
('Z_is_one', ctypes.c_int),
]
class _OpenSSL(object): class _OpenSSL(object):
""" """
Wrapper for OpenSSL using ctypes Wrapper for OpenSSL using ctypes
@ -83,7 +106,7 @@ class _OpenSSL(object):
""" """
self._lib = ctypes.CDLL(library) self._lib = ctypes.CDLL(library)
self._version, self._hexversion, self._cflags = get_version(self._lib) self._version, self._hexversion, self._cflags = get_version(self._lib)
self._libreSSL = self._version.startswith(b"LibreSSL") self._libreSSL = self._version.startswith("LibreSSL")
self.pointer = ctypes.pointer self.pointer = ctypes.pointer
self.c_int = ctypes.c_int self.c_int = ctypes.c_int
@ -91,38 +114,38 @@ class _OpenSSL(object):
self.create_string_buffer = ctypes.create_string_buffer self.create_string_buffer = ctypes.create_string_buffer
self.BN_new = self._lib.BN_new self.BN_new = self._lib.BN_new
self.BN_new.restype = ctypes.c_void_p self.BN_new.restype = ctypes.POINTER(BIGNUM)
self.BN_new.argtypes = [] self.BN_new.argtypes = []
self.BN_free = self._lib.BN_free self.BN_free = self._lib.BN_free
self.BN_free.restype = None self.BN_free.restype = None
self.BN_free.argtypes = [ctypes.c_void_p] self.BN_free.argtypes = [ctypes.POINTER(BIGNUM)]
self.BN_clear_free = self._lib.BN_clear_free self.BN_clear_free = self._lib.BN_clear_free
self.BN_clear_free.restype = None self.BN_clear_free.restype = None
self.BN_clear_free.argtypes = [ctypes.c_void_p] self.BN_clear_free.argtypes = [ctypes.POINTER(BIGNUM)]
self.BN_num_bits = self._lib.BN_num_bits self.BN_num_bits = self._lib.BN_num_bits
self.BN_num_bits.restype = ctypes.c_int self.BN_num_bits.restype = ctypes.c_int
self.BN_num_bits.argtypes = [ctypes.c_void_p] self.BN_num_bits.argtypes = [ctypes.POINTER(BIGNUM)]
self.BN_bn2bin = self._lib.BN_bn2bin self.BN_bn2bin = self._lib.BN_bn2bin
self.BN_bn2bin.restype = ctypes.c_int self.BN_bn2bin.restype = ctypes.c_int
self.BN_bn2bin.argtypes = [ctypes.c_void_p, ctypes.c_void_p] self.BN_bn2bin.argtypes = [ctypes.POINTER(BIGNUM), ctypes.c_void_p]
try: try:
self.BN_bn2binpad = self._lib.BN_bn2binpad self.BN_bn2binpad = self._lib.BN_bn2binpad
self.BN_bn2binpad.restype = ctypes.c_int self.BN_bn2binpad.restype = ctypes.c_int
self.BN_bn2binpad.argtypes = [ctypes.c_void_p, ctypes.c_void_p, self.BN_bn2binpad.argtypes = [ctypes.POINTER(BIGNUM), ctypes.c_void_p,
ctypes.c_int] ctypes.c_int]
except AttributeError: except AttributeError:
# optional, we have a workaround # optional, we have a workaround
pass pass
self.BN_bin2bn = self._lib.BN_bin2bn self.BN_bin2bn = self._lib.BN_bin2bn
self.BN_bin2bn.restype = ctypes.c_void_p self.BN_bin2bn.restype = ctypes.POINTER(BIGNUM)
self.BN_bin2bn.argtypes = [ctypes.c_void_p, ctypes.c_int, self.BN_bin2bn.argtypes = [ctypes.c_void_p, ctypes.c_int,
ctypes.c_void_p] ctypes.POINTER(BIGNUM)]
self.EC_KEY_free = self._lib.EC_KEY_free self.EC_KEY_free = self._lib.EC_KEY_free
self.EC_KEY_free.restype = None self.EC_KEY_free.restype = None
@ -156,9 +179,9 @@ class _OpenSSL(object):
self._lib.EC_POINT_get_affine_coordinates_GFp self._lib.EC_POINT_get_affine_coordinates_GFp
self.EC_POINT_get_affine_coordinates_GFp.restype = ctypes.c_int self.EC_POINT_get_affine_coordinates_GFp.restype = ctypes.c_int
self.EC_POINT_get_affine_coordinates_GFp.argtypes = [ctypes.c_void_p, self.EC_POINT_get_affine_coordinates_GFp.argtypes = [ctypes.c_void_p,
ctypes.c_void_p, ctypes.POINTER(EC_POINT),
ctypes.c_void_p, ctypes.POINTER(BIGNUM),
ctypes.c_void_p, ctypes.POINTER(BIGNUM),
ctypes.c_void_p] ctypes.c_void_p]
try: try:
@ -170,20 +193,20 @@ class _OpenSSL(object):
self._lib.EC_POINT_get_affine_coordinates_GF2m self._lib.EC_POINT_get_affine_coordinates_GF2m
self.EC_POINT_get_affine_coordinates.restype = ctypes.c_int self.EC_POINT_get_affine_coordinates.restype = ctypes.c_int
self.EC_POINT_get_affine_coordinates.argtypes = [ctypes.c_void_p, self.EC_POINT_get_affine_coordinates.argtypes = [ctypes.c_void_p,
ctypes.c_void_p, ctypes.POINTER(EC_POINT),
ctypes.c_void_p, ctypes.POINTER(BIGNUM),
ctypes.c_void_p, ctypes.POINTER(BIGNUM),
ctypes.c_void_p] ctypes.c_void_p]
self.EC_KEY_set_private_key = self._lib.EC_KEY_set_private_key self.EC_KEY_set_private_key = self._lib.EC_KEY_set_private_key
self.EC_KEY_set_private_key.restype = ctypes.c_int self.EC_KEY_set_private_key.restype = ctypes.c_int
self.EC_KEY_set_private_key.argtypes = [ctypes.c_void_p, self.EC_KEY_set_private_key.argtypes = [ctypes.c_void_p,
ctypes.c_void_p] ctypes.POINTER(BIGNUM)]
self.EC_KEY_set_public_key = self._lib.EC_KEY_set_public_key self.EC_KEY_set_public_key = self._lib.EC_KEY_set_public_key
self.EC_KEY_set_public_key.restype = ctypes.c_int self.EC_KEY_set_public_key.restype = ctypes.c_int
self.EC_KEY_set_public_key.argtypes = [ctypes.c_void_p, self.EC_KEY_set_public_key.argtypes = [ctypes.c_void_p,
ctypes.c_void_p] ctypes.POINTER(EC_POINT)]
self.EC_KEY_set_group = self._lib.EC_KEY_set_group self.EC_KEY_set_group = self._lib.EC_KEY_set_group
self.EC_KEY_set_group.restype = ctypes.c_int self.EC_KEY_set_group.restype = ctypes.c_int
@ -194,9 +217,9 @@ class _OpenSSL(object):
self._lib.EC_POINT_set_affine_coordinates_GFp self._lib.EC_POINT_set_affine_coordinates_GFp
self.EC_POINT_set_affine_coordinates_GFp.restype = ctypes.c_int self.EC_POINT_set_affine_coordinates_GFp.restype = ctypes.c_int
self.EC_POINT_set_affine_coordinates_GFp.argtypes = [ctypes.c_void_p, self.EC_POINT_set_affine_coordinates_GFp.argtypes = [ctypes.c_void_p,
ctypes.c_void_p, ctypes.POINTER(EC_POINT),
ctypes.c_void_p, ctypes.POINTER(BIGNUM),
ctypes.c_void_p, ctypes.POINTER(BIGNUM),
ctypes.c_void_p] ctypes.c_void_p]
try: try:
@ -208,9 +231,9 @@ class _OpenSSL(object):
self._lib.EC_POINT_set_affine_coordinates_GF2m self._lib.EC_POINT_set_affine_coordinates_GF2m
self.EC_POINT_set_affine_coordinates.restype = ctypes.c_int self.EC_POINT_set_affine_coordinates.restype = ctypes.c_int
self.EC_POINT_set_affine_coordinates.argtypes = [ctypes.c_void_p, self.EC_POINT_set_affine_coordinates.argtypes = [ctypes.c_void_p,
ctypes.c_void_p, ctypes.POINTER(EC_POINT),
ctypes.c_void_p, ctypes.POINTER(BIGNUM),
ctypes.c_void_p, ctypes.POINTER(BIGNUM),
ctypes.c_void_p] ctypes.c_void_p]
try: try:
@ -219,38 +242,39 @@ class _OpenSSL(object):
except AttributeError: except AttributeError:
# OpenSSL docs say only use this for backwards compatibility # OpenSSL docs say only use this for backwards compatibility
self.EC_POINT_set_compressed_coordinates = \ self.EC_POINT_set_compressed_coordinates = \
self._lib.EC_POINT_set_compressed_coordinates_GF2m self._lib.EC_POINT_set_compressed_coordinates_GFp
self.EC_POINT_set_compressed_coordinates.restype = ctypes.c_int self.EC_POINT_set_compressed_coordinates.restype = ctypes.c_int
self.EC_POINT_set_compressed_coordinates.argtypes = [ctypes.c_void_p, self.EC_POINT_set_compressed_coordinates.argtypes = [ctypes.c_void_p,
ctypes.c_void_p, ctypes.POINTER(EC_POINT),
ctypes.c_void_p, ctypes.POINTER(BIGNUM),
ctypes.c_int, ctypes.c_int,
ctypes.c_void_p] ctypes.c_void_p]
self.EC_POINT_new = self._lib.EC_POINT_new self.EC_POINT_new = self._lib.EC_POINT_new
self.EC_POINT_new.restype = ctypes.c_void_p self.EC_POINT_new.restype = ctypes.POINTER(EC_POINT)
self.EC_POINT_new.argtypes = [ctypes.c_void_p] self.EC_POINT_new.argtypes = [ctypes.c_void_p]
self.EC_POINT_free = self._lib.EC_POINT_free self.EC_POINT_free = self._lib.EC_POINT_free
self.EC_POINT_free.restype = None self.EC_POINT_free.restype = None
self.EC_POINT_free.argtypes = [ctypes.c_void_p] self.EC_POINT_free.argtypes = [ctypes.POINTER(EC_POINT)]
self.BN_CTX_free = self._lib.BN_CTX_free self.BN_CTX_free = self._lib.BN_CTX_free
self.BN_CTX_free.restype = None self.BN_CTX_free.restype = None
self.BN_CTX_free.argtypes = [ctypes.c_void_p] self.BN_CTX_free.argtypes = [ctypes.c_void_p]
self.EC_POINT_mul = self._lib.EC_POINT_mul self.EC_POINT_mul = self._lib.EC_POINT_mul
self.EC_POINT_mul.restype = None self.EC_POINT_mul.restype = ctypes.c_int
self.EC_POINT_mul.argtypes = [ctypes.c_void_p, self.EC_POINT_mul.argtypes = [ctypes.c_void_p,
ctypes.c_void_p, ctypes.POINTER(EC_POINT),
ctypes.c_void_p, ctypes.POINTER(BIGNUM),
ctypes.c_void_p, ctypes.POINTER(EC_POINT),
ctypes.POINTER(BIGNUM),
ctypes.c_void_p] ctypes.c_void_p]
self.EC_KEY_set_private_key = self._lib.EC_KEY_set_private_key self.EC_KEY_set_private_key = self._lib.EC_KEY_set_private_key
self.EC_KEY_set_private_key.restype = ctypes.c_int self.EC_KEY_set_private_key.restype = ctypes.c_int
self.EC_KEY_set_private_key.argtypes = [ctypes.c_void_p, self.EC_KEY_set_private_key.argtypes = [ctypes.c_void_p,
ctypes.c_void_p] ctypes.POINTER(BIGNUM)]
if self._hexversion >= 0x10100000 and not self._libreSSL: if self._hexversion >= 0x10100000 and not self._libreSSL:
self.EC_KEY_OpenSSL = self._lib.EC_KEY_OpenSSL self.EC_KEY_OpenSSL = self._lib.EC_KEY_OpenSSL
@ -469,70 +493,71 @@ class _OpenSSL(object):
self.BN_CTX_new.argtypes = [] self.BN_CTX_new.argtypes = []
self.BN_dup = self._lib.BN_dup self.BN_dup = self._lib.BN_dup
self.BN_dup.restype = ctypes.c_void_p self.BN_dup.restype = ctypes.POINTER(BIGNUM)
self.BN_dup.argtypes = [ctypes.c_void_p] self.BN_dup.argtypes = [ctypes.POINTER(BIGNUM)]
self.BN_rand = self._lib.BN_rand self.BN_rand = self._lib.BN_rand
self.BN_rand.restype = ctypes.c_int self.BN_rand.restype = ctypes.c_int
self.BN_rand.argtypes = [ctypes.c_void_p, self.BN_rand.argtypes = [ctypes.POINTER(BIGNUM),
ctypes.c_int,
ctypes.c_int, ctypes.c_int,
ctypes.c_int] ctypes.c_int]
self.BN_set_word = self._lib.BN_set_word self.BN_set_word = self._lib.BN_set_word
self.BN_set_word.restype = ctypes.c_int self.BN_set_word.restype = ctypes.c_int
self.BN_set_word.argtypes = [ctypes.c_void_p, self.BN_set_word.argtypes = [ctypes.POINTER(BIGNUM),
ctypes.c_ulong] ctypes.c_ulong]
self.BN_mul = self._lib.BN_mul self.BN_mul = self._lib.BN_mul
self.BN_mul.restype = ctypes.c_int self.BN_mul.restype = ctypes.c_int
self.BN_mul.argtypes = [ctypes.c_void_p, self.BN_mul.argtypes = [ctypes.POINTER(BIGNUM),
ctypes.c_void_p, ctypes.POINTER(BIGNUM),
ctypes.c_void_p, ctypes.POINTER(BIGNUM),
ctypes.c_void_p] ctypes.c_void_p]
self.BN_mod_add = self._lib.BN_mod_add self.BN_mod_add = self._lib.BN_mod_add
self.BN_mod_add.restype = ctypes.c_int self.BN_mod_add.restype = ctypes.c_int
self.BN_mod_add.argtypes = [ctypes.c_void_p, self.BN_mod_add.argtypes = [ctypes.POINTER(BIGNUM),
ctypes.c_void_p, ctypes.POINTER(BIGNUM),
ctypes.c_void_p, ctypes.POINTER(BIGNUM),
ctypes.c_void_p, ctypes.POINTER(BIGNUM),
ctypes.c_void_p] ctypes.c_void_p]
self.BN_mod_inverse = self._lib.BN_mod_inverse self.BN_mod_inverse = self._lib.BN_mod_inverse
self.BN_mod_inverse.restype = ctypes.c_void_p self.BN_mod_inverse.restype = ctypes.POINTER(BIGNUM)
self.BN_mod_inverse.argtypes = [ctypes.c_void_p, self.BN_mod_inverse.argtypes = [ctypes.POINTER(BIGNUM),
ctypes.c_void_p, ctypes.POINTER(BIGNUM),
ctypes.c_void_p, ctypes.POINTER(BIGNUM),
ctypes.c_void_p] ctypes.c_void_p]
self.BN_mod_mul = self._lib.BN_mod_mul self.BN_mod_mul = self._lib.BN_mod_mul
self.BN_mod_mul.restype = ctypes.c_int self.BN_mod_mul.restype = ctypes.c_int
self.BN_mod_mul.argtypes = [ctypes.c_void_p, self.BN_mod_mul.argtypes = [ctypes.POINTER(BIGNUM),
ctypes.c_void_p, ctypes.POINTER(BIGNUM),
ctypes.c_void_p, ctypes.POINTER(BIGNUM),
ctypes.c_void_p, ctypes.POINTER(BIGNUM),
ctypes.c_void_p] ctypes.c_void_p]
self.BN_lshift = self._lib.BN_lshift self.BN_lshift = self._lib.BN_lshift
self.BN_lshift.restype = ctypes.c_int self.BN_lshift.restype = ctypes.c_int
self.BN_lshift.argtypes = [ctypes.c_void_p, self.BN_lshift.argtypes = [ctypes.POINTER(BIGNUM),
ctypes.c_void_p, ctypes.POINTER(BIGNUM),
ctypes.c_int] ctypes.c_int]
self.BN_sub_word = self._lib.BN_sub_word self.BN_sub_word = self._lib.BN_sub_word
self.BN_sub_word.restype = ctypes.c_int self.BN_sub_word.restype = ctypes.c_int
self.BN_sub_word.argtypes = [ctypes.c_void_p, self.BN_sub_word.argtypes = [ctypes.POINTER(BIGNUM),
ctypes.c_ulong] ctypes.c_ulong]
self.BN_cmp = self._lib.BN_cmp self.BN_cmp = self._lib.BN_cmp
self.BN_cmp.restype = ctypes.c_int self.BN_cmp.restype = ctypes.c_int
self.BN_cmp.argtypes = [ctypes.c_void_p, self.BN_cmp.argtypes = [ctypes.POINTER(BIGNUM),
ctypes.c_void_p] ctypes.POINTER(BIGNUM)]
try: try:
self.BN_is_odd = self._lib.BN_is_odd self.BN_is_odd = self._lib.BN_is_odd
self.BN_is_odd.restype = ctypes.c_int self.BN_is_odd.restype = ctypes.c_int
self.BN_is_odd.argtypes = [ctypes.c_void_p] self.BN_is_odd.argtypes = [ctypes.POINTER(BIGNUM)]
except AttributeError: except AttributeError:
# OpenSSL 1.1.0 implements this as a function, but earlier # OpenSSL 1.1.0 implements this as a function, but earlier
# versions as macro, so we need to workaround # versions as macro, so we need to workaround
@ -540,7 +565,7 @@ class _OpenSSL(object):
self.BN_bn2dec = self._lib.BN_bn2dec self.BN_bn2dec = self._lib.BN_bn2dec
self.BN_bn2dec.restype = ctypes.c_char_p self.BN_bn2dec.restype = ctypes.c_char_p
self.BN_bn2dec.argtypes = [ctypes.c_void_p] self.BN_bn2dec.argtypes = [ctypes.POINTER(BIGNUM)]
self.EC_GROUP_new_by_curve_name = self._lib.EC_GROUP_new_by_curve_name self.EC_GROUP_new_by_curve_name = self._lib.EC_GROUP_new_by_curve_name
self.EC_GROUP_new_by_curve_name.restype = ctypes.c_void_p self.EC_GROUP_new_by_curve_name.restype = ctypes.c_void_p
@ -549,43 +574,43 @@ class _OpenSSL(object):
self.EC_GROUP_get_order = self._lib.EC_GROUP_get_order self.EC_GROUP_get_order = self._lib.EC_GROUP_get_order
self.EC_GROUP_get_order.restype = ctypes.c_int self.EC_GROUP_get_order.restype = ctypes.c_int
self.EC_GROUP_get_order.argtypes = [ctypes.c_void_p, self.EC_GROUP_get_order.argtypes = [ctypes.c_void_p,
ctypes.c_void_p, ctypes.POINTER(BIGNUM),
ctypes.c_void_p] ctypes.c_void_p]
self.EC_GROUP_get_cofactor = self._lib.EC_GROUP_get_cofactor self.EC_GROUP_get_cofactor = self._lib.EC_GROUP_get_cofactor
self.EC_GROUP_get_cofactor.restype = ctypes.c_int self.EC_GROUP_get_cofactor.restype = ctypes.c_int
self.EC_GROUP_get_cofactor.argtypes = [ctypes.c_void_p, self.EC_GROUP_get_cofactor.argtypes = [ctypes.c_void_p,
ctypes.c_void_p, ctypes.POINTER(BIGNUM),
ctypes.c_void_p] ctypes.c_void_p]
self.EC_GROUP_get0_generator = self._lib.EC_GROUP_get0_generator self.EC_GROUP_get0_generator = self._lib.EC_GROUP_get0_generator
self.EC_GROUP_get0_generator.restype = ctypes.c_void_p self.EC_GROUP_get0_generator.restype = ctypes.POINTER(EC_POINT)
self.EC_GROUP_get0_generator.argtypes = [ctypes.c_void_p] self.EC_GROUP_get0_generator.argtypes = [ctypes.c_void_p]
self.EC_POINT_copy = self._lib.EC_POINT_copy self.EC_POINT_copy = self._lib.EC_POINT_copy
self.EC_POINT_copy.restype = ctypes.c_int self.EC_POINT_copy.restype = ctypes.c_int
self.EC_POINT_copy.argtypes = [ctypes.c_void_p, self.EC_POINT_copy.argtypes = [ctypes.POINTER(EC_POINT),
ctypes.c_void_p] ctypes.POINTER(EC_POINT)]
self.EC_POINT_add = self._lib.EC_POINT_add self.EC_POINT_add = self._lib.EC_POINT_add
self.EC_POINT_add.restype = ctypes.c_int self.EC_POINT_add.restype = ctypes.c_int
self.EC_POINT_add.argtypes = [ctypes.c_void_p, self.EC_POINT_add.argtypes = [ctypes.c_void_p,
ctypes.c_void_p, ctypes.POINTER(EC_POINT),
ctypes.c_void_p, ctypes.POINTER(EC_POINT),
ctypes.c_void_p, ctypes.POINTER(EC_POINT),
ctypes.c_void_p] ctypes.c_void_p]
self.EC_POINT_cmp = self._lib.EC_POINT_cmp self.EC_POINT_cmp = self._lib.EC_POINT_cmp
self.EC_POINT_cmp.restype = ctypes.c_int self.EC_POINT_cmp.restype = ctypes.c_int
self.EC_POINT_cmp.argtypes = [ctypes.c_void_p, self.EC_POINT_cmp.argtypes = [ctypes.c_void_p,
ctypes.c_void_p, ctypes.POINTER(EC_POINT),
ctypes.c_void_p, ctypes.POINTER(EC_POINT),
ctypes.c_void_p] ctypes.c_void_p]
self.EC_POINT_set_to_infinity = self._lib.EC_POINT_set_to_infinity self.EC_POINT_set_to_infinity = self._lib.EC_POINT_set_to_infinity
self.EC_POINT_set_to_infinity.restype = ctypes.c_int self.EC_POINT_set_to_infinity.restype = ctypes.c_int
self.EC_POINT_set_to_infinity.argtypes = [ctypes.c_void_p, self.EC_POINT_set_to_infinity.argtypes = [ctypes.c_void_p,
ctypes.c_void_p] ctypes.POINTER(EC_POINT)]
self._set_ciphers() self._set_ciphers()
self._set_curves() self._set_curves()
@ -722,9 +747,9 @@ class _OpenSSL(object):
if data != 0: if data != 0:
if sys.version_info.major == 3 and isinstance(data, type('')): if sys.version_info.major == 3 and isinstance(data, type('')):
data = data.encode() data = data.encode()
buffer_ = self.create_string_buffer(data, size) buffer_ = self.create_string_buffer(data, size + 1)
else: else:
buffer_ = self.create_string_buffer(size) buffer_ = self.create_string_buffer(size + 1)
return buffer_ return buffer_

View File

@ -7,7 +7,7 @@ when pybitmessage started in test mode.
import sys import sys
import tempfile import tempfile
from common import put_signal_file from test_process import put_signal_file
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -1,7 +1,4 @@
import os import os
import sys
import time
import unittest
_files = ( _files = (
@ -20,15 +17,3 @@ def cleanup(home=None, files=_files):
os.remove(os.path.join(home, pfile)) os.remove(os.path.join(home, pfile))
except OSError: except OSError:
pass pass
def skip_python3():
"""Raise unittest.SkipTest() if detected python3"""
if sys.hexversion >= 0x3000000:
raise unittest.SkipTest('Module is not ported to python3')
def put_signal_file(path, filename):
"""Creates file, presence of which is a signal about some event."""
with open(os.path.join(path, filename), 'wb') as outfile:
outfile.write(b'%i' % time.time())

View File

@ -11,7 +11,6 @@ import shutil
import socket import socket
import string import string
import sys import sys
import threading
import time import time
import unittest import unittest
@ -62,13 +61,6 @@ class TestCore(unittest.TestCase):
"""Test case, which runs in main pybitmessage thread""" """Test case, which runs in main pybitmessage thread"""
addr = 'BM-2cVvkzJuQDsQHLqxRXc6HZGPLZnkBLzEZY' addr = 'BM-2cVvkzJuQDsQHLqxRXc6HZGPLZnkBLzEZY'
def tearDown(self):
"""Reset possible unexpected settings after test"""
knownnodes.addKnownNode(1, Peer('127.0.0.1', 8444), is_self=True)
BMConfigParser().remove_option('bitmessagesettings', 'dontconnect')
BMConfigParser().remove_option('bitmessagesettings', 'onionservicesonly')
BMConfigParser().set('bitmessagesettings', 'socksproxytype', 'none')
def test_msgcoding(self): def test_msgcoding(self):
"""test encoding and decoding (originally from helper_msgcoding)""" """test encoding and decoding (originally from helper_msgcoding)"""
msg_data = { msg_data = {
@ -278,36 +270,6 @@ class TestCore(unittest.TestCase):
return return
self.fail('Failed to connect to at least 3 nodes within 360 sec') self.fail('Failed to connect to at least 3 nodes within 360 sec')
def test_udp(self):
"""check default udp setting and presence of Announcer thread"""
self.assertTrue(
BMConfigParser().safeGetBoolean('bitmessagesettings', 'udp'))
for thread in threading.enumerate():
if thread.name == 'Announcer': # find Announcer thread
break
else:
return self.fail('No Announcer thread found')
for _ in range(20): # wait for UDP socket
for sock in BMConnectionPool().udpSockets.values():
thread.announceSelf()
break
else:
time.sleep(1)
continue
break
else:
self.fail('UDP socket is not started')
for _ in range(20):
if state.discoveredPeers:
peer = state.discoveredPeers.keys()[0]
self.assertEqual(peer.port, 8444)
break
time.sleep(1)
else:
self.fail('No self in discovered peers')
@staticmethod @staticmethod
def _decode_msg(data, pattern): def _decode_msg(data, pattern):
proto = BMProto() proto = BMProto()

View File

@ -5,13 +5,9 @@ Tests using API.
import base64 import base64
import json import json
import time import time
import xmlrpclib # nosec
try: # nosec from test_process import TestProcessProto, TestProcessShutdown
from xmlrpclib import ServerProxy, ProtocolError
except ImportError:
from xmlrpc.client import ServerProxy, ProtocolError
from .test_process import TestProcessProto, TestProcessShutdown
class TestAPIProto(TestProcessProto): class TestAPIProto(TestProcessProto):
@ -23,7 +19,7 @@ class TestAPIProto(TestProcessProto):
"""Setup XMLRPC proxy for pybitmessage API""" """Setup XMLRPC proxy for pybitmessage API"""
super(TestAPIProto, cls).setUpClass() super(TestAPIProto, cls).setUpClass()
cls.addresses = [] cls.addresses = []
cls.api = ServerProxy( cls.api = xmlrpclib.ServerProxy(
"http://username:password@127.0.0.1:8442/") "http://username:password@127.0.0.1:8442/")
for _ in range(5): for _ in range(5):
if cls._get_readline('.api_started'): if cls._get_readline('.api_started'):
@ -69,8 +65,8 @@ class TestAPI(TestAPIProto):
def test_user_password(self): def test_user_password(self):
"""Trying to connect with wrong username/password""" """Trying to connect with wrong username/password"""
api_wrong = ServerProxy("http://test:wrong@127.0.0.1:8442/") api_wrong = xmlrpclib.ServerProxy("http://test:wrong@127.0.0.1:8442/")
with self.assertRaises(ProtocolError): with self.assertRaises(xmlrpclib.ProtocolError):
api_wrong.clientStatus() api_wrong.clientStatus()
def test_connection(self): def test_connection(self):

View File

@ -5,7 +5,9 @@ import os
import unittest import unittest
from hashlib import sha256 from hashlib import sha256
from pybitmessage.pyelliptic import ECCBlind, ECCBlindChain, OpenSSL from pybitmessage.pyelliptic.eccblind import ECCBlind
from pybitmessage.pyelliptic.eccblindchain import ECCBlindChain
from pybitmessage.pyelliptic.openssl import OpenSSL
# pylint: disable=protected-access # pylint: disable=protected-access
@ -34,12 +36,12 @@ class TestBlindSig(unittest.TestCase):
# (3) Signature Generation # (3) Signature Generation
signature_blinded = signer_obj.blind_sign(msg_blinded) signature_blinded = signer_obj.blind_sign(msg_blinded)
assert isinstance(signature_blinded, bytes) assert isinstance(signature_blinded, str)
self.assertEqual(len(signature_blinded), 32) self.assertEqual(len(signature_blinded), 32)
# (4) Extraction # (4) Extraction
signature = requester_obj.unblind(signature_blinded) signature = requester_obj.unblind(signature_blinded)
assert isinstance(signature, bytes) assert isinstance(signature, str)
self.assertEqual(len(signature), 65) self.assertEqual(len(signature), 65)
self.assertNotEqual(signature, signature_blinded) self.assertNotEqual(signature, signature_blinded)
@ -55,7 +57,7 @@ class TestBlindSig(unittest.TestCase):
x = OpenSSL.BN_new() x = OpenSSL.BN_new()
y = OpenSSL.BN_new() y = OpenSSL.BN_new()
OpenSSL.EC_POINT_get_affine_coordinates( OpenSSL.EC_POINT_get_affine_coordinates(
obj.group, obj.Q, x, y, 0) obj.group, obj.Q, x, y, None)
self.assertEqual(OpenSSL.BN_is_odd(y), self.assertEqual(OpenSSL.BN_is_odd(y),
OpenSSL.BN_is_odd_compatible(y)) OpenSSL.BN_is_odd_compatible(y))
@ -82,7 +84,7 @@ class TestBlindSig(unittest.TestCase):
self.assertEqual(OpenSSL.BN_cmp(y0, y1), 0) self.assertEqual(OpenSSL.BN_cmp(y0, y1), 0)
self.assertEqual(OpenSSL.BN_cmp(x0, x1), 0) self.assertEqual(OpenSSL.BN_cmp(x0, x1), 0)
self.assertEqual(OpenSSL.EC_POINT_cmp(obj.group, randompoint, self.assertEqual(OpenSSL.EC_POINT_cmp(obj.group, randompoint,
secondpoint, 0), 0) secondpoint, None), 0)
finally: finally:
OpenSSL.BN_free(x0) OpenSSL.BN_free(x0)
OpenSSL.BN_free(x1) OpenSSL.BN_free(x1)
@ -161,7 +163,7 @@ class TestBlindSig(unittest.TestCase):
output.extend(pubkey) output.extend(pubkey)
output.extend(signature) output.extend(signature)
signer_obj = child_obj signer_obj = child_obj
verifychain = ECCBlindChain(ca=ca.pubkey(), chain=bytes(output)) verifychain = ECCBlindChain(ca=ca.pubkey(), chain=str(output))
self.assertTrue(verifychain.verify(msg=msg, value=1)) self.assertTrue(verifychain.verify(msg=msg, value=1))
def test_blind_sig_chain_wrong_ca(self): # pylint: disable=too-many-locals def test_blind_sig_chain_wrong_ca(self): # pylint: disable=too-many-locals

View File

@ -2,8 +2,12 @@
Various tests for config Various tests for config
""" """
import os
import unittest import unittest
import tempfile
from pybitmessage.bmconfigparser import BMConfigParser from pybitmessage.bmconfigparser import BMConfigParser
from test_process import TestProcessProto
class TestConfig(unittest.TestCase): class TestConfig(unittest.TestCase):
@ -34,3 +38,32 @@ class TestConfig(unittest.TestCase):
BMConfigParser().safeGetInt('nonexistent', 'nonexistent'), 0) BMConfigParser().safeGetInt('nonexistent', 'nonexistent'), 0)
self.assertEqual( self.assertEqual(
BMConfigParser().safeGetInt('nonexistent', 'nonexistent', 42), 42) BMConfigParser().safeGetInt('nonexistent', 'nonexistent', 42), 42)
class TestProcessConfig(TestProcessProto):
"""A test case for keys.dat"""
home = tempfile.mkdtemp()
def test_config_defaults(self):
"""Test settings in the generated config"""
self._stop_process()
self._kill_process()
config = BMConfigParser()
config.read(os.path.join(self.home, 'keys.dat'))
self.assertEqual(config.safeGetInt(
'bitmessagesettings', 'settingsversion'), 10)
self.assertEqual(config.safeGetInt(
'bitmessagesettings', 'port'), 8444)
# don't connect
self.assertTrue(config.safeGetBoolean(
'bitmessagesettings', 'dontconnect'))
# API disabled
self.assertFalse(config.safeGetBoolean(
'bitmessagesettings', 'apienabled'))
# extralowdifficulty is false
self.assertEqual(config.safeGetInt(
'bitmessagesettings', 'defaultnoncetrialsperbyte'), 1000)
self.assertEqual(config.safeGetInt(
'bitmessagesettings', 'defaultpayloadlengthextrabytes'), 1000)

View File

@ -1,38 +0,0 @@
"""
Various tests for config
"""
import os
import tempfile
from pybitmessage.bmconfigparser import BMConfigParser
from .test_process import TestProcessProto
class TestProcessConfig(TestProcessProto):
"""A test case for keys.dat"""
home = tempfile.mkdtemp()
def test_config_defaults(self):
"""Test settings in the generated config"""
config = BMConfigParser()
self._stop_process()
self._kill_process()
config.read(os.path.join(self.home, 'keys.dat'))
self.assertEqual(config.safeGetInt(
'bitmessagesettings', 'settingsversion'), 10)
self.assertEqual(config.safeGetInt(
'bitmessagesettings', 'port'), 8444)
# don't connect
self.assertTrue(config.safeGetBoolean(
'bitmessagesettings', 'dontconnect'))
# API disabled
self.assertFalse(config.safeGetBoolean(
'bitmessagesettings', 'apienabled'))
# extralowdifficulty is false
self.assertEqual(config.safeGetInt(
'bitmessagesettings', 'defaultnoncetrialsperbyte'), 1000)
self.assertEqual(config.safeGetInt(
'bitmessagesettings', 'defaultpayloadlengthextrabytes'), 1000)

View File

@ -6,10 +6,8 @@ import hashlib
import unittest import unittest
from abc import ABCMeta, abstractmethod from abc import ABCMeta, abstractmethod
from binascii import hexlify, unhexlify from binascii import hexlify, unhexlify
from pybitmessage.pyelliptic import arithmetic from pybitmessage.pyelliptic import arithmetic
try: try:
from Crypto.Hash import RIPEMD from Crypto.Hash import RIPEMD
except ImportError: except ImportError:
@ -23,21 +21,14 @@ sample_pubsigningkey = unhexlify(
sample_pubencryptionkey = unhexlify( sample_pubencryptionkey = unhexlify(
'044597d59177fc1d89555d38915f581b5ff2286b39d022ca0283d2bdd5c36be5d3c' '044597d59177fc1d89555d38915f581b5ff2286b39d022ca0283d2bdd5c36be5d3c'
'e7b9b97792327851a562752e4b79475d1f51f5a71352482b241227f45ed36a9') 'e7b9b97792327851a562752e4b79475d1f51f5a71352482b241227f45ed36a9')
sample_privsigningkey = \ sample_privatesigningkey = \
'93d0b61371a54b53df143b954035d612f8efa8a3ed1cf842c2186bfd8f876665' '93d0b61371a54b53df143b954035d612f8efa8a3ed1cf842c2186bfd8f876665'
sample_privencryptionkey = \ sample_privateencryptionkey = \
'4b0b73a54e19b059dc274ab69df095fe699f43b17397bca26fdf40f4d7400a3a' '4b0b73a54e19b059dc274ab69df095fe699f43b17397bca26fdf40f4d7400a3a'
sample_ripe = b'003cd097eb7f35c87b5dc8b4538c22cb55312a9f' sample_ripe = '003cd097eb7f35c87b5dc8b4538c22cb55312a9f'
# stream: 1, version: 2 # stream: 1, version: 2
sample_address = 'BM-onkVu1KKL2UaUss5Upg9vXmqd3esTmV79' sample_address = 'BM-onkVu1KKL2UaUss5Upg9vXmqd3esTmV79'
sample_factor = 66858749573256452658262553961707680376751171096153613379801854825275240965733
# G * sample_factor
sample_point = (
33567437183004486938355437500683826356288335339807546987348409590129959362313,
94730058721143827257669456336351159718085716196507891067256111928318063085006
)
_sha = hashlib.new('sha512') _sha = hashlib.new('sha512')
_sha.update(sample_pubsigningkey + sample_pubencryptionkey) _sha.update(sample_pubsigningkey + sample_pubencryptionkey)
@ -78,20 +69,14 @@ class TestCrypto(RIPEMD160TestCase, unittest.TestCase):
class TestAddresses(unittest.TestCase): class TestAddresses(unittest.TestCase):
"""Test addresses manipulations""" """Test addresses manipulations"""
def test_base10_multiply(self):
"""Test arithmetic.base10_multiply"""
self.assertEqual(
sample_point,
arithmetic.base10_multiply(arithmetic.G, sample_factor))
def test_privtopub(self): def test_privtopub(self):
"""Generate public keys and check the result""" """Generate public keys and check the result"""
self.assertEqual( self.assertEqual(
arithmetic.privtopub(sample_privsigningkey).encode(), arithmetic.privtopub(sample_privatesigningkey),
hexlify(sample_pubsigningkey) hexlify(sample_pubsigningkey)
) )
self.assertEqual( self.assertEqual(
arithmetic.privtopub(sample_privencryptionkey).encode(), arithmetic.privtopub(sample_privateencryptionkey),
hexlify(sample_pubencryptionkey) hexlify(sample_pubencryptionkey)
) )

View File

@ -5,7 +5,7 @@ Testing the logger configuration
import os import os
import tempfile import tempfile
from .test_process import TestProcessProto from test_process import TestProcessProto
class TestLogger(TestProcessProto): class TestLogger(TestProcessProto):

View File

@ -3,10 +3,6 @@ Test for network group
""" """
import unittest import unittest
from .common import skip_python3
skip_python3()
class TestNetworkGroup(unittest.TestCase): class TestNetworkGroup(unittest.TestCase):
""" """

View File

@ -3,12 +3,9 @@ Tests for openclpow module
""" """
import hashlib import hashlib
import unittest import unittest
from struct import pack, unpack from struct import pack, unpack
from .common import skip_python3
skip_python3() # noqa:E402
from pybitmessage import openclpow from pybitmessage import openclpow

View File

@ -49,6 +49,6 @@ class TestOpenSSL(unittest.TestCase):
c = OpenSSL.malloc(0, OpenSSL.BN_num_bytes(a)) c = OpenSSL.malloc(0, OpenSSL.BN_num_bytes(a))
OpenSSL.BN_bn2binpad(a, b, OpenSSL.BN_num_bytes(n)) OpenSSL.BN_bn2binpad(a, b, OpenSSL.BN_num_bytes(n))
OpenSSL.BN_bn2bin(a, c) OpenSSL.BN_bn2bin(a, c)
if b.raw != c.raw.rjust(OpenSSL.BN_num_bytes(n), b'\x00'): if b.raw != c.raw.rjust(OpenSSL.BN_num_bytes(n), chr(0)):
bad += 1 bad += 1
self.assertEqual(bad, 0) self.assertEqual(bad, 0)

View File

@ -12,10 +12,13 @@ import unittest
import psutil import psutil
from .common import cleanup, put_signal_file, skip_python3 from common import cleanup
skip_python3() def put_signal_file(path, filename):
"""Creates file, presence of which is a signal about some event."""
with open(os.path.join(path, filename), 'wb') as outfile:
outfile.write(str(time.time()))
class TestProcessProto(unittest.TestCase): class TestProcessProto(unittest.TestCase):
@ -195,7 +198,6 @@ class TestProcess(TestProcessProto):
"""Check PyBitmessage process name""" """Check PyBitmessage process name"""
self.assertEqual(self.process.name(), 'PyBitmessage') self.assertEqual(self.process.name(), 'PyBitmessage')
@unittest.skipIf(psutil.version_info < (4, 0), 'psutil is too old')
def test_home(self): def test_home(self):
"""Ensure BITMESSAGE_HOME is used by process""" """Ensure BITMESSAGE_HOME is used by process"""
self.assertEqual( self.assertEqual(
@ -205,7 +207,7 @@ class TestProcess(TestProcessProto):
"""Check that pybitmessage listens on port 8444""" """Check that pybitmessage listens on port 8444"""
for c in self.process.connections(): for c in self.process.connections():
if c.status == 'LISTEN': if c.status == 'LISTEN':
self.assertEqual(c.laddr[1], 8444) self.assertEqual(c.laddr.port, 8444)
break break
def test_files(self): def test_files(self):

View File

@ -4,10 +4,6 @@ Tests for common protocol functions
import unittest import unittest
from .common import skip_python3
skip_python3()
class TestProtocol(unittest.TestCase): class TestProtocol(unittest.TestCase):
"""Main protocol test case""" """Main protocol test case"""

View File

@ -15,7 +15,7 @@ class TestRandomTrackingDict(unittest.TestCase):
@staticmethod @staticmethod
def randString(): def randString():
"""helper function for tests, generates a random string""" """helper function for tests, generates a random string"""
retval = '' retval = b''
for _ in range(32): for _ in range(32):
retval += chr(random.randint(0, 255)) retval += chr(random.randint(0, 255))
return retval return retval

View File

@ -6,4 +6,3 @@ Depends: openssl, python-setuptools
Recommends: apparmor, python-msgpack, python-qt4, python-stem, tor Recommends: apparmor, python-msgpack, python-qt4, python-stem, tor
Suggests: python-pyopencl, python-jsonrpclib, python-defusedxml, python-qrcode Suggests: python-pyopencl, python-jsonrpclib, python-defusedxml, python-qrcode
Suite: bionic Suite: bionic
Setup-Env-Vars: DEB_BUILD_OPTIONS=nocheck

View File

@ -1,22 +0,0 @@
#!/usr/bin/env python
"""Custom tests runner script for tox and python3"""
import random # noseq
import sys
import unittest
def unittest_discover():
"""Explicit test suite creation"""
if sys.hexversion >= 0x3000000:
from pybitmessage import pathmagic
pathmagic.setup()
loader = unittest.defaultTestLoader
# randomize the order of tests in test cases
loader.sortTestMethodsUsing = lambda a, b: random.randint(-1, 1)
# pybitmessage symlink may disappear on Windows
return loader.discover('src.tests')
if __name__ == "__main__":
result = unittest.TextTestRunner(verbosity=2).run(unittest_discover())
sys.exit(not result.wasSuccessful())

34
tox.ini
View File

@ -1,34 +0,0 @@
[tox]
envlist = reset,py{27,37,38},stats
skip_missing_interpreters = true
[testenv]
setenv =
BITMESSAGE_HOME = {envtmpdir}
PYTHONWARNINGS = all
deps = -rrequirements.txt
commands =
python checkdeps.py
coverage run -a src/bitmessagemain.py -t
coverage run -a -m tests
[testenv:reset]
commands = coverage erase
[testenv:stats]
commands =
coverage report
coverage xml
[coverage:run]
source = src
omit =
*/lib*
tests.py
*/tests/*
src/version.py
*/__init__.py
src/fallback/umsgpack/*
[coverage:report]
ignore_errors = true