Compare commits

..

1 Commits

Author SHA1 Message Date
cis-kuldeep 1c6d4702c0 Added flatpak build manifests with split dependencies 2021-04-27 20:37:46 +05:30
10 changed files with 198 additions and 71 deletions

3
.gitmodules vendored Normal file
View File

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

View File

@ -0,0 +1,57 @@
{
"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

@ -0,0 +1,48 @@
{
"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" : "../../"
}
]
}
]
}

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

View File

@ -1,6 +1,7 @@
"""
Improved version of asyncore dispatcher
"""
# pylint: disable=attribute-defined-outside-init
import socket
import threading
import time
@ -30,7 +31,6 @@ class AdvancedDispatcher(asyncore.dispatcher):
def __init__(self, sock=None):
if not hasattr(self, '_map'):
asyncore.dispatcher.__init__(self, sock)
self.connectedAt = 0
self.close_reason = None
self.read_buf = bytearray()
self.write_buf = bytearray()
@ -42,7 +42,6 @@ class AdvancedDispatcher(asyncore.dispatcher):
self.readLock = threading.RLock()
self.writeLock = threading.RLock()
self.processingLock = threading.RLock()
self.uploadChunk = self.downloadChunk = 0
def append_write_buf(self, data):
"""Append binary data to the end of stream write buffer."""

View File

@ -1,7 +1,7 @@
"""
Class BMProto defines bitmessage's network protocol workflow.
Bitmessage Protocol
"""
# pylint: disable=attribute-defined-outside-init, too-few-public-methods
import base64
import hashlib
import logging
@ -66,8 +66,6 @@ class BMProto(AdvancedDispatcher, ObjectTracker):
self.pendingUpload = RandomTrackingDict()
# canonical identifier of network group
self.network_group = None
# userAgent initialization
self.userAgent = ''
def bm_proto_reset(self):
"""Reset the bitmessage object parser"""
@ -102,7 +100,7 @@ class BMProto(AdvancedDispatcher, ObjectTracker):
length=protocol.Header.size, expectBytes=self.payloadLength)
return True
def state_bm_command(self): # pylint: disable=too-many-branches
def state_bm_command(self): # pylint: disable=too-many-branches
"""Process incoming command"""
self.payload = self.read_buf[:self.payloadLength]
if self.checksum != hashlib.sha512(self.payload).digest()[0:4]:
@ -187,6 +185,7 @@ class BMProto(AdvancedDispatcher, ObjectTracker):
return Node(services, host, port)
# pylint: disable=too-many-branches, too-many-statements
def decode_payload_content(self, pattern="v"):
"""
Decode the payload depending on pattern:
@ -202,8 +201,8 @@ class BMProto(AdvancedDispatcher, ObjectTracker):
0-9 = length of the next item
, = end of array
"""
# pylint: disable=too-many-branches,too-many-statements
# pylint: disable=inconsistent-return-statements
def decode_simple(self, char="v"):
"""Decode the payload using one char pattern"""
if char == "v":
@ -222,7 +221,6 @@ class BMProto(AdvancedDispatcher, ObjectTracker):
self.payloadOffset += 8
return struct.unpack(">Q", self.payload[
self.payloadOffset - 8:self.payloadOffset])[0]
return None
size = None
isArray = False
@ -256,11 +254,10 @@ class BMProto(AdvancedDispatcher, ObjectTracker):
])
parserStack[-2][4] = len(parserStack[-2][3])
else:
j = 0
for j in range(
parserStack[-1][4], len(parserStack[-1][3])):
for j in range(parserStack[-1][4], len(parserStack[-1][3])):
if parserStack[-1][3][j] not in "lL0123456789":
break
# pylint: disable=undefined-loop-variable
parserStack.append([
size, size, isArray,
parserStack[-1][3][parserStack[-1][4]:j + 1], 0, []
@ -271,8 +268,7 @@ class BMProto(AdvancedDispatcher, ObjectTracker):
elif i == "s":
# if parserStack[-2][2]:
# parserStack[-1][5].append(self.payload[
# self.payloadOffset:self.payloadOffset
# + parserStack[-1][0]])
# self.payloadOffset:self.payloadOffset + parserStack[-1][0]])
# else:
parserStack[-1][5] = self.payload[
self.payloadOffset:self.payloadOffset + parserStack[-1][0]]
@ -343,10 +339,6 @@ class BMProto(AdvancedDispatcher, ObjectTracker):
return True
def _command_inv(self, dandelion=False):
"""
Common inv announce implementation:
both inv and dinv depending on *dandelion* kwarg
"""
items = self.decode_payload_content("l32s")
if len(items) > MAX_OBJECT_COUNT:
@ -384,11 +376,10 @@ class BMProto(AdvancedDispatcher, ObjectTracker):
nonce, expiresTime, objectType, version, streamNumber,
self.payload, self.payloadOffset)
payload_len = len(self.payload) - self.payloadOffset
if payload_len > MAX_OBJECT_PAYLOAD_SIZE:
if len(self.payload) - self.payloadOffset > MAX_OBJECT_PAYLOAD_SIZE:
logger.info(
'The payload length of this object is too large'
' (%d bytes). Ignoring it.', payload_len)
'The payload length of this object is too large (%d bytes).'
' Ignoring it.', len(self.payload) - self.payloadOffset)
raise BMProtoExcessiveDataError()
try:
@ -443,8 +434,9 @@ class BMProto(AdvancedDispatcher, ObjectTracker):
def bm_command_addr(self):
"""Incoming addresses, process them"""
# not using services
for seenTime, stream, _, ip, port in self._decode_addr():
# pylint: disable=redefined-outer-name
addresses = self._decode_addr()
for seenTime, stream, _, ip, port in addresses:
ip = str(ip)
if (
stream not in state.streamsInWhichIAmParticipating
@ -454,7 +446,8 @@ class BMProto(AdvancedDispatcher, ObjectTracker):
continue
decodedIP = protocol.checkIPAddress(ip)
if (
decodedIP and time.time() - seenTime > 0
decodedIP
and time.time() - seenTime > 0
and seenTime > time.time() - ADDRESS_ALIVE
and port > 0
):
@ -482,8 +475,7 @@ class BMProto(AdvancedDispatcher, ObjectTracker):
self.append_write_buf(protocol.CreatePacket('pong'))
return True
@staticmethod
def bm_command_pong():
def bm_command_pong(self): # pylint: disable=no-self-use
"""
Incoming pong.
Ignore it. PyBitmessage pings connections after about 5 minutes
@ -553,9 +545,9 @@ class BMProto(AdvancedDispatcher, ObjectTracker):
length=self.payloadLength, expectBytes=0)
return False
# pylint: disable=too-many-return-statements
def peerValidityChecks(self):
"""Check the validity of the peer"""
# pylint: disable=too-many-return-statements
if self.remoteProtocolVersion < 3:
self.append_write_buf(protocol.assembleErrorMessage(
errorText="Your is using an old protocol. Closing connection.",
@ -570,8 +562,7 @@ class BMProto(AdvancedDispatcher, ObjectTracker):
" compared to mine. Closing connection.", fatal=2))
logger.info(
"%s's time is too far in the future (%s seconds)."
" Closing connection to it.",
self.destination, self.timeOffset)
" Closing connection to it.", self.destination, self.timeOffset)
BMProto.timeOffsetWrongCount += 1
return False
elif self.timeOffset < -MAX_TIME_OFFSET:
@ -579,9 +570,8 @@ class BMProto(AdvancedDispatcher, ObjectTracker):
errorText="Your time is too far in the past compared to mine."
" Closing connection.", fatal=2))
logger.info(
"%s's time is too far in the past"
" (timeOffset %s seconds). Closing connection to it.",
self.destination, self.timeOffset)
"%s's time is too far in the past (timeOffset %s seconds)."
" Closing connection to it.", self.destination, self.timeOffset)
BMProto.timeOffsetWrongCount += 1
return False
else:
@ -594,8 +584,7 @@ class BMProto(AdvancedDispatcher, ObjectTracker):
'Closed connection to %s because there is no overlapping'
' interest in streams.', self.destination)
return False
if connectionpool.BMConnectionPool().inboundConnections.get(
self.destination):
if self.destination in connectionpool.BMConnectionPool().inboundConnections:
try:
if not protocol.checkSocksIP(self.destination.host):
self.append_write_buf(protocol.assembleErrorMessage(
@ -605,7 +594,7 @@ class BMProto(AdvancedDispatcher, ObjectTracker):
'Closed connection to %s because we are already'
' connected to that IP.', self.destination)
return False
except: # TODO: exception types
except Exception:
pass
if not self.isOutbound:
# incoming from a peer we're connected to as outbound,
@ -625,7 +614,8 @@ class BMProto(AdvancedDispatcher, ObjectTracker):
'Closed connection to %s due to server full'
' or duplicate inbound/outbound.', self.destination)
return False
if connectionpool.BMConnectionPool().isAlreadyConnected(self.nonce):
if connectionpool.BMConnectionPool().isAlreadyConnected(
self.nonce):
self.append_write_buf(protocol.assembleErrorMessage(
errorText="I'm connected to myself. Closing connection.",
fatal=2))
@ -638,7 +628,7 @@ class BMProto(AdvancedDispatcher, ObjectTracker):
@staticmethod
def stopDownloadingObject(hashId, forwardAnyway=False):
"""Stop downloading object *hashId*"""
"""Stop downloading an object"""
for connection in connectionpool.BMConnectionPool().connections():
try:
del connection.objectsNewToMe[hashId]
@ -668,8 +658,7 @@ class BMProto(AdvancedDispatcher, ObjectTracker):
except AttributeError:
try:
logger.debug(
'%s:%i: closing',
self.destination.host, self.destination.port)
'%(host)s:%(port)i: closing', self.destination._asdict())
except AttributeError:
logger.debug('Disconnected socket closing')
AdvancedDispatcher.handle_close(self)

View File

@ -61,9 +61,9 @@ class Proxy(AdvancedDispatcher):
@proxy.setter
def proxy(self, address):
"""Set proxy IP and port"""
if (not isinstance(address, tuple) or len(address) < 2
or not isinstance(address[0], str)
or not isinstance(address[1], int)):
if (not isinstance(address, tuple) or len(address) < 2 or
not isinstance(address[0], str) or
not isinstance(address[1], int)):
raise ValueError
self.__class__._proxy = address
@ -113,6 +113,7 @@ class Proxy(AdvancedDispatcher):
self.destination = address
self.isOutbound = True
self.fullyEstablished = False
self.connectedAt = 0
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
if BMConfigParser().safeGetBoolean(
"bitmessagesettings", "socksauthentication"):
@ -144,5 +145,6 @@ class Proxy(AdvancedDispatcher):
def state_proxy_handshake_done(self):
"""Handshake is complete at this point"""
# pylint: disable=attribute-defined-outside-init
self.connectedAt = time.time()
return False

View File

@ -51,6 +51,7 @@ class TCPConnection(BMProto, TLSDispatcher):
self.verackSent = False
self.streams = [0]
self.fullyEstablished = False
self.connectedAt = 0
self.skipUntil = 0
if address is None and sock is not None:
self.destination = Peer(*sock.getpeername())

View File

@ -16,6 +16,7 @@ logger = logging.getLogger('default')
_DISCONNECTED_SSL = frozenset((ssl.SSL_ERROR_EOF,))
# sslProtocolVersion
if sys.version_info >= (2, 7, 13):
# this means TLSv1 or higher
# in the future change to
@ -26,16 +27,14 @@ elif sys.version_info >= (2, 7, 9):
# SSLv2 and 3 are excluded with an option after context is created
sslProtocolVersion = ssl.PROTOCOL_SSLv23
else:
# this means TLSv1, there is no way to set "TLSv1 or higher"
# or "TLSv1.2" in < 2.7.9
# this means TLSv1, there is no way to set "TLSv1 or higher" or
# "TLSv1.2" in < 2.7.9
sslProtocolVersion = ssl.PROTOCOL_TLSv1
# ciphers
if (
ssl.OPENSSL_VERSION_NUMBER >= 0x10100000
and not ssl.OPENSSL_VERSION.startswith(b"LibreSSL")
):
if ssl.OPENSSL_VERSION_NUMBER >= 0x10100000 and not \
ssl.OPENSSL_VERSION.startswith("LibreSSL"):
sslProtocolCiphers = "AECDH-AES256-SHA@SECLEVEL=0"
else:
sslProtocolCiphers = "AECDH-AES256-SHA"
@ -48,10 +47,16 @@ class TLSDispatcher(AdvancedDispatcher):
def __init__(self, _=None, sock=None, certfile=None, keyfile=None,
server_side=False, ciphers=sslProtocolCiphers):
self.want_read = self.want_write = True
self.certfile = certfile or os.path.join(
paths.codePath(), 'sslkeys', 'cert.pem')
self.keyfile = keyfile or os.path.join(
paths.codePath(), 'sslkeys', 'key.pem')
if certfile is None:
self.certfile = os.path.join(
paths.codePath(), 'sslkeys', 'cert.pem')
else:
self.certfile = certfile
if keyfile is None:
self.keyfile = os.path.join(
paths.codePath(), 'sslkeys', 'key.pem')
else:
self.keyfile = keyfile
self.server_side = server_side
self.ciphers = ciphers
self.tlsStarted = False
@ -61,6 +66,7 @@ class TLSDispatcher(AdvancedDispatcher):
def state_tls_init(self):
"""Prepare sockets for TLS handshake"""
# pylint: disable=attribute-defined-outside-init
self.isSSL = True
self.tlsStarted = True
# Once the connection has been established,
@ -90,6 +96,8 @@ class TLSDispatcher(AdvancedDispatcher):
self.want_read = self.want_write = True
self.set_state("tls_handshake")
return False
# if hasattr(self.socket, "context"):
# self.socket.context.set_ecdh_curve("secp256k1")
@staticmethod
def state_tls_handshake():
@ -104,9 +112,9 @@ class TLSDispatcher(AdvancedDispatcher):
try:
if self.tlsStarted and not self.tlsDone and not self.write_buf:
return self.want_write
return AdvancedDispatcher.writable(self)
except AttributeError:
pass
return AdvancedDispatcher.writable(self)
return AdvancedDispatcher.writable(self)
def readable(self):
"""Handle readable check for TLS-enabled sockets"""
@ -118,14 +126,14 @@ class TLSDispatcher(AdvancedDispatcher):
return self.want_read
# prior to TLS handshake,
# receiveDataThread should emulate synchronous behaviour
if not self.fullyEstablished and (
elif not self.fullyEstablished and (
self.expectBytes == 0 or not self.write_buf_empty()):
return False
return AdvancedDispatcher.readable(self)
except AttributeError:
pass
return AdvancedDispatcher.readable(self)
return AdvancedDispatcher.readable(self)
def handle_read(self):
def handle_read(self): # pylint: disable=inconsistent-return-statements
"""
Handle reads for sockets during TLS handshake. Requires special
treatment as during the handshake, buffers must remain empty
@ -134,20 +142,29 @@ class TLSDispatcher(AdvancedDispatcher):
try:
# wait for write buffer flush
if self.tlsStarted and not self.tlsDone and not self.write_buf:
# logger.debug(
# "%s:%i TLS handshaking (read)", self.destination.host,
# self.destination.port)
self.tls_handshake()
else:
AdvancedDispatcher.handle_read(self)
# logger.debug(
# "%s:%i Not TLS handshaking (read)", self.destination.host,
# self.destination.port)
return AdvancedDispatcher.handle_read(self)
except AttributeError:
AdvancedDispatcher.handle_read(self)
return AdvancedDispatcher.handle_read(self)
except ssl.SSLError as err:
self.close_reason = "SSL Error in handle_read"
if err.errno == ssl.SSL_ERROR_WANT_READ:
return
if err.errno not in _DISCONNECTED_SSL:
logger.info("SSL Error: %s", err)
self.close_reason = "SSL Error in handle_read"
elif err.errno in _DISCONNECTED_SSL:
self.handle_close()
return
logger.info("SSL Error: %s", err)
self.handle_close()
return
def handle_write(self):
def handle_write(self): # pylint: disable=inconsistent-return-statements
"""
Handle writes for sockets during TLS handshake. Requires special
treatment as during the handshake, buffers must remain empty
@ -156,18 +173,27 @@ class TLSDispatcher(AdvancedDispatcher):
try:
# wait for write buffer flush
if self.tlsStarted and not self.tlsDone and not self.write_buf:
# logger.debug(
# "%s:%i TLS handshaking (write)", self.destination.host,
# self.destination.port)
self.tls_handshake()
else:
AdvancedDispatcher.handle_write(self)
# logger.debug(
# "%s:%i Not TLS handshaking (write)", self.destination.host,
# self.destination.port)
return AdvancedDispatcher.handle_write(self)
except AttributeError:
AdvancedDispatcher.handle_write(self)
return AdvancedDispatcher.handle_write(self)
except ssl.SSLError as err:
if err.errno == ssl.SSL_ERROR_WANT_WRITE:
return
if err.errno not in _DISCONNECTED_SSL:
logger.info("SSL Error: %s", err)
self.close_reason = "SSL Error in handle_write"
if err.errno == ssl.SSL_ERROR_WANT_WRITE:
return 0
elif err.errno in _DISCONNECTED_SSL:
self.handle_close()
return 0
logger.info("SSL Error: %s", err)
self.handle_close()
return
def tls_handshake(self):
"""Perform TLS handshake and handle its stages"""

View File

@ -28,6 +28,7 @@ class UDPSocket(BMProto): # pylint: disable=too-many-instance-attributes
# .. todo:: sort out streams
self.streams = [1]
self.fullyEstablished = True
self.connectedAt = 0
self.skipUntil = 0
if sock is None:
if host is None: