Browse Source

Merge branch 'Release_2.1'

pull/4/head
heck 4 years ago
parent
commit
b1400519ff
  1. 38
      .gitignore
  2. 6
      DEPENDENCIES
  3. 4
      Makefile
  4. 4
      README.rst
  5. 31
      build-windows/pEpPythonAdapter.sln
  6. 112
      build-windows/pEpPythonAdapter.vcxproj
  7. 6
      build-windows/packages.config
  8. 2
      docs/source/install.rst
  9. 39
      make.mak
  10. 5
      setup.cfg
  11. 85
      setup.py
  12. 107
      src/pEp/__init__.py
  13. 141
      src/pEp/_pEp/pEpmodule.cc
  14. 4
      src/pEp/_pEp/pEpmodule.hh
  15. 1
      src/pEp/_pEp/str_attr.hh
  16. 2
      test/README.md
  17. 129
      test/data/keys/inquisitor-0xA4728718_full_expired.priv.asc
  18. 58
      test/start_sync.py
  19. 101
      test/sync_handshake.py
  20. 4
      test/sync_test.py

38
.gitignore

@ -1,5 +1,37 @@
syntax: glob
ws/
pEp.egg-info/
dist/
build/
.pythonhist
.gnupg
.lldb
.so
.pEp_management.db*
.python_history
__pycache__/
test/Laptop/
test/Library/
test/Phone/
test/TestInbox/
test/Backup/
test/lib/
test/imap_settings.py
venv/
build-windows/Debug/
build-windows/Release/
build-windows/packages/
build-windows/.vs/
build-windows/pEpPythonAdapter.vcxproj.*
launch.json
settings.json
# Default ignored files
.idea/
docs/build/
.eggs/
.tox/
=======
# Build config
local.conf
@ -42,9 +74,9 @@ __pycache__/
.idea
.spyproject
*.code-workspace
tags
ws
# platform artifacts
.DS_store
/src/pEp/_pEp.cpython-38-darwin.so

6
DEPENDENCIES

@ -0,0 +1,6 @@
# 1st Party Dependencies
## Prefer git tags instead of SHA hashes when possible.
libpEpAdapter=Release_2.1.17
pEpEngine=Release_2.1.23
sequoia=365d00a08bec6a5a48d48a7c7893d78c27092b59

4
Makefile

@ -1,7 +1,7 @@
include Makefile.conf
.PHONY: all compile compile-inplace dist dist-egg dist-whl install install-user venv envtest install-test test develop docs clean clean-all clean-docs
all: dist
all: install
# Build
# =====
@ -57,8 +57,6 @@ envtest:
install-test: compile
pip3 install .[test]
# TODO: maybe use setup.py test?
# --forked, because every test needs a separate process, see PYADPT-100
test:
pytest

4
README.rst

@ -5,8 +5,8 @@ Python adapter for the `pEpEngine <https://pep.foundation/dev/repos/pEpEngine/>`
Documentation
-------------
Please find the documentation in the ``docs`` directory.
The build instructions can be found in ``docs/source/install.rst``.
These build instruction also cover how to generate the complete documentation using sphinx.
Issues
------

31
build-windows/pEpPythonAdapter.sln

@ -0,0 +1,31 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.31005.135
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pEpPythonAdapter", "pEpPythonAdapter.vcxproj", "{F7D4314B-C7BA-4117-9AE7-AC5C1492153D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{F7D4314B-C7BA-4117-9AE7-AC5C1492153D}.Debug|x64.ActiveCfg = Debug|x64
{F7D4314B-C7BA-4117-9AE7-AC5C1492153D}.Debug|x64.Build.0 = Debug|x64
{F7D4314B-C7BA-4117-9AE7-AC5C1492153D}.Debug|x86.ActiveCfg = Debug|Win32
{F7D4314B-C7BA-4117-9AE7-AC5C1492153D}.Debug|x86.Build.0 = Debug|Win32
{F7D4314B-C7BA-4117-9AE7-AC5C1492153D}.Release|x64.ActiveCfg = Release|x64
{F7D4314B-C7BA-4117-9AE7-AC5C1492153D}.Release|x64.Build.0 = Release|x64
{F7D4314B-C7BA-4117-9AE7-AC5C1492153D}.Release|x86.ActiveCfg = Release|Win32
{F7D4314B-C7BA-4117-9AE7-AC5C1492153D}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {B63BC9BA-EF76-4FB4-9126-29CBFAD9092C}
EndGlobalSection
EndGlobal

112
build-windows/pEpPythonAdapter.vcxproj

@ -0,0 +1,112 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<ProjectGuid>{F7D4314B-C7BA-4117-9AE7-AC5C1492153D}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Makefile</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Makefile</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Makefile</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Makefile</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<NMakeBuildCommandLine>nmake /F "$(ProjectDir)..\make.mak" debug</NMakeBuildCommandLine>
<NMakeOutput>
</NMakeOutput>
<NMakePreprocessorDefinitions>WIN32;_DEBUG;_DLL;$(NMakePreprocessorDefinitions)</NMakePreprocessorDefinitions>
<NMakeCleanCommandLine>nmake /F "$(ProjectDir)..\make.mak" clean</NMakeCleanCommandLine>
<SourcePath>$(VC_SourcePath);$(ProjectDir)..</SourcePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<NMakeBuildCommandLine>make.cmd</NMakeBuildCommandLine>
<NMakeOutput>pEpPythonAdapter.exe</NMakeOutput>
<NMakePreprocessorDefinitions>_DEBUG;$(NMakePreprocessorDefinitions)</NMakePreprocessorDefinitions>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<NMakeBuildCommandLine>nmake /F "$(ProjectDir)..\make.mak" release</NMakeBuildCommandLine>
<NMakeOutput>
</NMakeOutput>
<NMakePreprocessorDefinitions>WIN32;NDEBUG;_DLL;$(NMakePreprocessorDefinitions)</NMakePreprocessorDefinitions>
<NMakeCleanCommandLine>nmake /F "$(ProjectDir)..\make.mak" clean</NMakeCleanCommandLine>
<SourcePath>$(VC_SourcePath);$(ProjectDir)..</SourcePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<NMakeBuildCommandLine>make.cmd</NMakeBuildCommandLine>
<NMakeOutput>pEpPythonAdapter.exe</NMakeOutput>
<NMakePreprocessorDefinitions>NDEBUG;$(NMakePreprocessorDefinitions)</NMakePreprocessorDefinitions>
</PropertyGroup>
<ItemDefinitionGroup>
</ItemDefinitionGroup>
<ItemGroup>
<None Include="..\make.mak" />
<None Include="..\setup.py" />
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="packages\boost.1.72.0.0\build\boost.targets" Condition="Exists('packages\boost.1.72.0.0\build\boost.targets')" />
<Import Project="packages\boost_locale-vc142.1.72.0.0\build\boost_locale-vc142.targets" Condition="Exists('packages\boost_locale-vc142.1.72.0.0\build\boost_locale-vc142.targets')" />
<Import Project="packages\boost_python38-vc142.1.72.0.0\build\boost_python38-vc142.targets" Condition="Exists('packages\boost_python38-vc142.1.72.0.0\build\boost_python38-vc142.targets')" />
</ImportGroup>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('packages\boost.1.72.0.0\build\boost.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\boost.1.72.0.0\build\boost.targets'))" />
<Error Condition="!Exists('packages\boost_locale-vc142.1.72.0.0\build\boost_locale-vc142.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\boost_locale-vc142.1.72.0.0\build\boost_locale-vc142.targets'))" />
<Error Condition="!Exists('packages\boost_python38-vc142.1.72.0.0\build\boost_python38-vc142.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\boost_python38-vc142.1.72.0.0\build\boost_python38-vc142.targets'))" />
</Target>
</Project>

6
build-windows/packages.config

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="boost" version="1.72.0.0" targetFramework="native" />
<package id="boost_locale-vc142" version="1.72.0.0" targetFramework="native" />
<package id="boost_python38-vc142" version="1.72.0.0" targetFramework="native" />
</packages>

2
docs/source/install.rst

@ -9,7 +9,7 @@ system dependencies already installed:
* pEp-base (sequoia, libetpan, asn1c, yml2, pEpEngine, libpEpAdapter)
* boost-python
These `build instructions <https://dev.pep.foundation/Common%20Adapter%20Documentation/Adapter_Build_Instructions>`_ will get you all setup.
These `build instructions <https://dev.pep.foundation/Common%20Adapter%20Documentation/Adapter%20Build%20Instructions>`_ will get you all setup.
Additionally, there is a `build script <http://pep-security.lu/gitlab/juga/Internal-Deployment/-/blob/master/build-pep-stack.sh>`_
that executes these build instructions automatically (Debian and MacOS):

39
make.mak

@ -0,0 +1,39 @@
# build dirs
BUILD_DIR = $(ProjectDir)..\build
DIST_DIR = $(ProjectDir)..\dist
# create wheel and egg package in dist
dist: dist-whl dist-egg
# create wheel package in dist
dist-whl: compile
PY -3.8-32 setup.py bdist_wheel
# create egg package in dist
dist-egg: compile
PY -3.8-32 setup.py bdist_egg
# build the module into build
compile:
CD..
PY -3.8-32 setup.py build_ext --debug
# delete output directories
clean:
@if exist $(BUILD_DIR) rmdir /S /Q $(BUILD_DIR)
@if exist $(DIST_DIR) rmdir /S /Q $(DIST_DIR)
# create directories and build application
all: clean dist
# release build
release: clean
CD..
PY -3.8-32 setup.py build_ext
PY -3.8-32 setup.py bdist_wheel
#debug build
debug: clean
CD..
PY -3.8-32 setup.py build_ext --debug
PY -3.8-32 setup.py bdist_wheel

5
setup.cfg

@ -27,7 +27,7 @@ classifiers =
[options]
zip_safe = false
include_package_data = true
python_requires = >= 3.6
python_requires = >=3.8,<3.9
test_suite = tests
install_requires =
# deprecated/redundant with pyproject.toml, but lets keep both ways around for now
@ -40,4 +40,7 @@ setup_requires =
test =
pytest
pytest-forked
lxml
termcolor
doc = sphinx

85
setup.py

@ -40,55 +40,51 @@ class BuildExtCommand(build_ext):
self.prefix = getattr(self, "prefix=", None)
def windowsGetInstallLocation(self):
# Note: should be installed to 'C:\Program Files (x86)' while a 32-bit distro
# TODO: Try desktop adapter location first, then COM server
# FIXME: This is wrong, we should chase the COM server, not the Outlook Plugin (even if they're in the same place)
reg_path = "Software\\Microsoft\\Office\\Outlook\\Addins\\pEp"
KeyName = 'FileName'
reg_path = "SOFTWARE\\Classes\\TypeLib\\{564A4350-419E-47F1-B0DF-6FCCF0CD0BBC}\\1.0\\0\\win32"
KeyName = None
regKey = None
pEpLog("Registry Lookup:", reg_path, KeyName)
try:
regKey = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, reg_path, 0, winreg.KEY_READ)
# Keys: Description, FileName, FriendlyName, LoadBehavior
com_server, regtype = winreg.QueryValueEx(regKey, KeyName)
winreg.CloseKey(regKey)
except WindowsError:
pEpLog("Unknown Error")
com_server, _ = winreg.QueryValueEx(regKey, KeyName)
except WindowsError as error:
pEpLog("Error ocurred: " + error)
com_server = None
finally:
if winreg:
winreg.CloseKey(regKey)
# <install-base>\\bin\\COM_Server.exe
dirname = os.path.dirname
ret = dirname(dirname(com_server))
pEpLog("Value:", ret)
return ret
def get_build_info_winnt(self):
def windowsGetBoostDirs(self):
for dir in [f.path for f in os.scandir(join(os.getcwd(), 'build-windows', 'packages')) if f.is_dir()]:
if 'boost.' in dir or 'boost_python' in dir or 'boost_locale' in dir:
yield join(dir, 'lib', 'native'), join(dir, 'lib', 'native', 'include')
def get_build_info_win32(self):
home = environ.get('PER_USER_DIRECTORY') or environ.get('USERPROFILE')
sys_root = environ.get('SystemRoot')
profile_root = environ.get('AppData')
local_root = environ.get('LocalAppData')
inst_prefix = self.windowsGetInstallLocation()
sys_includes = [
join(inst_prefix, 'include'),
join(profile_root, 'pEp', 'include'),
join(local_root, 'pEp', 'include'),
join(sys_root, 'pEp', 'include'),
]
sys_libdirs = [
join(inst_prefix, 'bin'),
join(profile_root, 'pEp', 'bin'),
join(local_root, 'pEp', 'bin'),
join(sys_root, 'pEp', 'bin'),
]
join(inst_prefix),
] + [d[1] for d in self.windowsGetBoostDirs()]
sys_libdirs = [ join(inst_prefix, 'Debug')] if self.debug else [ join(inst_prefix, 'Release')]
sys_libdirs += [d[0] for d in self.windowsGetBoostDirs()]
libs = [
'pEpEngine',
'pEpAdapter',
'boost_python37-mt',
'boost_locale-mt'
'libpEpAdapter',
'boost_python38-vc142-mt-x32-1_72',
'boost_locale-vc142-mt-x32-1_72'
]
return (home, sys_includes, sys_libdirs, libs)
compile_flags = ['/std:c++14', '/permissive']
if self.debug:
pEpLog("debug mode")
compile_flags += ['/Od', '/Zi', '/DEBUG']
return (home, sys_includes, sys_libdirs, libs, compile_flags)
def get_build_info_darwin(self):
home = environ.get('PER_USER_DIRECTORY') or environ.get('HOME')
@ -104,7 +100,13 @@ class BuildExtCommand(build_ext):
'boost_python38-mt',
'boost_locale-mt'
]
return (home, sys_includes, sys_libdirs, libs)
compile_flags = ['-std=c++14', '-fpermissive']
if self.debug:
pEpLog("debug mode")
compile_flags += ['-O0', '-g', '-UNDEBUG']
return (home, sys_includes, sys_libdirs, libs, compile_flags)
def get_build_info_linux(self):
home = environ.get('PER_USER_DIRECTORY') or environ.get('HOME')
@ -123,7 +125,13 @@ class BuildExtCommand(build_ext):
'boost_python3',
'boost_locale'
]
return (home, sys_includes, sys_libdirs, libs)
compile_flags = ['-std=c++14', '-fpermissive']
if self.debug:
pEpLog("debug mode")
compile_flags += ['-O0', '-g', '-UNDEBUG']
return (home, sys_includes, sys_libdirs, libs, compile_flags)
def finalize_options(self):
build_ext.finalize_options(self)
@ -131,9 +139,10 @@ class BuildExtCommand(build_ext):
pEpLog("prefix: ", self.prefix)
pEpLog("sys.platform: ", sys.platform)
# get build information for platform
if sys.platform == 'winnt':
build_info = self.get_build_info_winnt()
if sys.platform == 'win32':
build_info = self.get_build_info_win32()
elif sys.platform == 'darwin':
build_info = self.get_build_info_darwin()
elif sys.platform == 'linux':
@ -142,7 +151,7 @@ class BuildExtCommand(build_ext):
pEpLog("Platform not supported:" + sys.platform)
exit()
(home, sys_includes, sys_libdirs, libs) = build_info
(home, sys_includes, sys_libdirs, libs, compile_flags) = build_info
# Build the Includes -I and Library paths -L
# Start empty
@ -161,12 +170,6 @@ class BuildExtCommand(build_ext):
includes += sys_includes
libdirs += sys_libdirs
# Compile flags
compile_flags = ['-std=c++14', '-fpermissive']
if self.debug:
pEpLog("debug mode")
compile_flags += ['-O0', '-g', '-UNDEBUG']
# Apply the build information
global module_pEp
module_pEp.include_dirs = includes
@ -183,7 +186,7 @@ class BuildExtCommand(build_ext):
build_ext.run(self)
if sys.platform == 'winnt':
if sys.platform == 'win32':
if sys.version_info[0] >= 3:
import winreg
else:

107
src/pEp/__init__.py

@ -14,9 +14,11 @@ try:
from .__version__ import version as __version__
except ImportError:
import warnings
warnings.warn("Error loading build-time defined __version__.py, trying setuptools now...")
try:
import setuptools_scm
__version__ = setuptools_scm.get_version()
del setuptools_scm
except Exception:
@ -30,18 +32,48 @@ from ._pEp import *
# with an underscore (of _pEp), but we dont want to import them into this module
import pEp._pEp
# 3rd party imports
from threading import Thread, Barrier
from time import sleep
# Executed on module import
def init():
print(init, "called")
# print(init, "called")
_pEp._init_after_main_module()
def start_sync() -> None:
"""starts the sync thread"""
set_sync_mode(SyncModes.Async)
def shutdown_sync() -> None:
"""call this to shut down the sync thread"""
set_sync_mode(SyncModes.Off)
def set_sync_mode(mode):
_pEp._set_sync_mode(mode)
if mode == SyncModes.Sync:
Sync.shutdown_sync()
if mode == SyncModes.Async:
Sync.start_sync()
if mode == SyncModes.Off:
Sync.shutdown_sync()
def is_sync_active() -> bool:
"""True if sync is active, False otherwise"""
return Sync.getInstance().is_alive()
def message_to_send(msg):
"""
message_to_send(msg)
override pEp.message_to_send(msg) with your own implementation
this callback is being called when a pp management message needs to be sent
GIL CAVEAT
"""
print("message_to_send() - default callback\n")
print("overwrite this method")
@ -54,10 +86,77 @@ def notify_handshake(me, partner, signal):
partner identity of communication partner
signal the handshake signal
overwrite this method with an implementation of a handshake dialog
GIL CAVEAT
"""
print("message_to_send() - default callback\n")
print("notify_handshake() - default callback\n")
print("overwrite this method")
class Sync(Thread):
__instance: 'Sync' = None
barr = Barrier(2)
def __init__(self):
if Sync.__instance != None:
raise Exception("singleton!")
else:
Sync.__instance = self
Thread.__init__(self)
@staticmethod
def getInstance() -> 'Sync':
if Sync.__instance == None:
Sync()
return Sync.__instance
def run(self):
"""
* Sync Thread
* NOPE 1. Execute registered startup function
register_sync_callbacks
* 2. Create session for the sync thread (registers: messageToSend, _inject_sync_event, _ensure_passphrase)
* 3. register_sync_callbacks() (registers: _notifyHandshake, _retrieve_next_sync_event)
* 4. Enter Sync Event Dispatching Loop (do_sync_protocol())
unregister_sync_callbacks
* 5. unregister_sync_callbacks()
* 6. Release the session
* NOPE 7. Execute registered shutdown function
"""
# TODO catch exception, and rethrow in start()
_pEp._register_sync_callbacks()
self.barr.wait()
while _pEp._do_protocol_step():
sleep(1)
_pEp._unregister_sync_callbacks()
def start(self):
"""
* (1. Done on init(): ensure session for the main thread
(registers: messageToSend, _inject_sync_event, _ensure_passphrase))
* 2. Start the sync thread
* 3. Defer execution until sync thread register_sync_callbacks() has returned
* 4. TODO: Throw pending exception from the sync thread
"""
Thread.start(self)
self.barr.wait()
# TODO: Throw exceptions from sync thread
# _pEp._notifyHandshake_sync_start()
# sleep(2)
@staticmethod
def start_sync():
if not Sync.getInstance().is_alive():
Sync.getInstance().start()
@staticmethod
def shutdown_sync():
if Sync.__instance:
if Sync.__instance.is_alive():
_pEp._inject_sync_shutdown()
Sync.__instance.join()
Sync.__instance = None
# _pEp._notifyHandshake_sync_stop()
init()

141
src/pEp/_pEp/pEpmodule.cc

@ -37,11 +37,20 @@ namespace pEp {
pEpLog("called");
}
// hidden init function, wrapped by hello_world.init()
// hidden init function, wrapped by _pEp.init()
void _init_after_main_module() {
pEpLog("called");
callback_dispatcher.add(_messageToSend, notifyHandshake, nullptr, nullptr);
Adapter::_messageToSend = CallbackDispatcher::messageToSend;
callback_dispatcher.add(_messageToSend, _notifyHandshake, nullptr, nullptr);
// Adapter::sync_initialize(
// Adapter::SyncModes::Off,
// CallbackDispatcher::messageToSend,
// CallbackDispatcher::notifyHandshake,
// true);
Adapter::sync_initialize(
Adapter::SyncModes::Off,
_messageToSend,
_notifyHandshake,
true);
}
@ -96,6 +105,7 @@ namespace pEp {
}
}
// TODO: GIL handling isnt really required here, i think
PEP_STATUS _messageToSend(::message *msg) {
pEpLog("called");
try {
@ -103,7 +113,7 @@ namespace pEp {
pEpLog("GIL Aquired");
object modref = import("pEp");
object funcref = modref.attr("message_to_send");
call<void>(funcref.ptr(), Message());
call<void>(funcref.ptr(), Message(msg));
PyGILState_Release(gil);
pEpLog("GIL released");
} catch (exception &e) {}
@ -111,14 +121,15 @@ namespace pEp {
return PEP_STATUS_OK;
}
PEP_STATUS notifyHandshake(pEp_identity *me, pEp_identity *partner, sync_handshake_signal signal) {
// TODO: GIL handling isnt really required here, i think
PEP_STATUS _notifyHandshake(pEp_identity *me, pEp_identity *partner, sync_handshake_signal signal) {
pEpLog("called");
try {
PyGILState_STATE gil = PyGILState_Ensure();
pEpLog("GIL Aquired");
object modref = import("pEp");
object funcref = modref.attr("notify_handshake");
call<void>(funcref.ptr(), me, partner, signal);
call<void>(funcref.ptr(), Identity(me), Identity(partner), signal);
PyGILState_Release(gil);
pEpLog("GIL released");
} catch (exception &e) {}
@ -126,13 +137,45 @@ namespace pEp {
return PEP_STATUS_OK;
}
bool _do_protocol_step() {
pEpLog("called");
SYNC_EVENT event = Adapter::_retrieve_next_sync_event(nullptr, 0);
if (event != NULL) {
::do_sync_protocol_step(Adapter::session(), (void *)&callback_dispatcher, event);
return true;
} else {
pEpLog("null event, signaling sync shutdown");
return false;
}
}
void _register_sync_callbacks() {
pEpLog("called");
Adapter::session();
PEP_STATUS status = ::register_sync_callbacks(Adapter::session(), nullptr, Adapter::_notifyHandshake, Adapter::_retrieve_next_sync_event);
_throw_status(status);
}
void start_sync() {
CallbackDispatcher::start_sync();
void _unregister_sync_callbacks() {
::unregister_sync_callbacks(Adapter::session());
// Adapter::session(release);
}
void shutdown_sync() {
CallbackDispatcher::stop_sync();
void _inject_sync_shutdown() {
pEpLog("injecting null event");
Adapter::_queue_sync_event(nullptr,nullptr);
}
// TODO: Integrate this (currently SEGFAULTING)
void _notifyHandshake_sync_start() {
pEpLog("all targets signal: SYNC_NOTIFY_START");
CallbackDispatcher::notifyHandshake(nullptr, nullptr, SYNC_NOTIFY_START);
}
// TODO: Integrate this (currently SEGFAULTING)
void _notifyHandshake_sync_stop() {
pEpLog("all targets signal: SYNC_NOTIFY_STOP");
CallbackDispatcher::notifyHandshake(nullptr, nullptr, SYNC_NOTIFY_STOP);
}
void debug_color(int ansi_color) {
@ -143,8 +186,8 @@ namespace pEp {
::leave_device_group(Adapter::session());
}
bool is_sync_active() {
return Adapter::is_sync_running();
void disable_all_sync_channels() {
::disable_all_sync_channels(Adapter::session());
}
void testfunc() {
@ -196,6 +239,35 @@ namespace pEp {
scope().attr("engine_version") = get_engine_version();
scope().attr("protocol_version") = get_protocol_version();
def("set_debug_log_enabled", &Adapter::pEpLog::set_enabled,
"Switch debug logging on/off");
def("_register_sync_callbacks", _register_sync_callbacks,
"");
def("_unregister_sync_callbacks", _unregister_sync_callbacks,
"");
def("_do_protocol_step", _do_protocol_step,
"");
def("_inject_sync_shutdown", _inject_sync_shutdown,
"");
def("_notifyHandshake_sync_start", _notifyHandshake_sync_start,
"");
def("_notifyHandshake_sync_stop", _notifyHandshake_sync_stop,
"");
def("_set_sync_mode", pEp::Adapter::set_sync_mode,
"");
enum_<pEp::Adapter::SyncModes>("SyncModes")
.value("Off", pEp::Adapter::SyncModes::Off)
.value("Async", pEp::Adapter::SyncModes::Async)
.value("Sync", pEp::Adapter::SyncModes::Sync);
def("passive_mode", config_passive_mode,
"do not attach pub keys to all messages");
@ -584,32 +656,6 @@ namespace pEp {
.value("SYNC_NOTIFY_SOLE", SYNC_NOTIFY_SOLE)
.value("SYNC_NOTIFY_IN_GROUP", SYNC_NOTIFY_IN_GROUP);
// auto user_interface_class = class_<UserInterface, UserInterface_callback, boost::noncopyable>(
// "UserInterface",
// "class MyUserInterface(UserInterface):\n"
// " def notifyHandshake(self, me, partner):\n"
// " ...\n"
// "\n"
// "p≡p User Interface class\n"
// "To be used as a mixin\n"
// )
// .def("notifyHandshake", &UserInterface::notifyHandshake,
// "notifyHandshake(self, me, partner)\n"
// "\n"
// " me own identity\n"
// " partner identity of communication partner\n"
// "\n"
// "overwrite this method with an implementation of a handshake dialog")
// .def("deliverHandshakeResult", &UserInterface::deliverHandshakeResult,
// boost::python::arg("identities")=object(),
// "deliverHandshakeResult(self, result, identities=None)\n"
// "\n"
// " result -1: cancel, 0: accepted, 1: rejected\n"
// " identities list of identities to share or None for all\n"
// "\n"
// "call to deliver the handshake result of the handshake dialog"
// );
def("deliver_handshake_result", &deliverHandshakeResult, boost::python::arg("identities")=object(),
"deliverHandshakeResult(self, result, identities=None)\n"
"\n"
@ -619,18 +665,6 @@ namespace pEp {
"call to deliver the handshake result of the handshake dialog"
);
def("start_sync", &start_sync,
"start_sync()\n"
"\n"
"starts the sync thread"
);
def("shutdown_sync", &shutdown_sync,
"shutdown_sync()\n"
"\n"
"call this from another thread to shut down the sync thread\n"
);
def("debug_color", &debug_color,
"for debug builds set ANSI color value");
@ -640,13 +674,12 @@ namespace pEp {
"call this for a grouped device, which should leave\n"
);
def("is_sync_active", &is_sync_active,
"is_sync_active()\n"
def("disable_all_sync_channels", &disable_all_sync_channels,
"disable_all_sync_channels()\n"
"\n"
"True if sync is active, False otherwise\n"
"Disable sync for all identities\n"
);
// codecs
call< object >(((object)(import("codecs").attr("register"))).ptr(), make_function(sync_search));
call< object >(((object)(import("codecs").attr("register"))).ptr(), make_function(distribution_search));

4
src/pEp/_pEp/pEpmodule.hh

@ -27,9 +27,9 @@ namespace pEp {
PEP_STATUS _messageToSend(::message *msg);
PEP_STATUS notifyHandshake(pEp_identity *me, pEp_identity *partner, sync_handshake_signal signal);
PEP_STATUS _notifyHandshake(pEp_identity *me, pEp_identity *partner, sync_handshake_signal signal);
} /* namespace PythonAdapter */
} /* namespace pEp */
#endif /* PEPMODULE_HH */
#endif /* PEPMODULE_HH */

1
src/pEp/_pEp/str_attr.hh

@ -12,6 +12,7 @@
#include <pEp/timestamp.h>
#include <pEp/stringlist.h>
#include <pEp/stringpair.h>
#include <pEp/platform.h>
namespace pEp {
namespace PythonAdapter {

2
test/README.md

@ -1,5 +1,7 @@
= Tests in this directory =
more doc under: https://dev.pep.foundation/Engine/Testing%20p%e2%89%a1p%20Sync
$ HOME=$PWD python3 basic_doctest.py -v
do some basic tests of p≡p

129
test/data/keys/inquisitor-0xA4728718_full_expired.priv.asc

@ -0,0 +1,129 @@
-----BEGIN PGP PRIVATE KEY BLOCK-----
lQVYBEdLUwABDAC2bTz7s8V9CDu/K3PtSXDvNCtx+84tdQEoNnmzQh9bkdnHWIzO
cscoO/YcJIQFJJ7WWdCudLLj+qaHS1t2EomW8ZRYe/HdIcIW/qO0ydGDShiJxEZN
4ZrNPz+BfEAhatbsN46z7DyzZjGHPPdIdLic2QAuDbv/z2/11ABDYa58vZINOp1r
pkmytOJps92K8hpY+PmfWTdNSWaNTCiQoel0MyyV/AgNLv/HUJRlN5QvqCQWqcAN
lHE5JmVZQK9wzlzs8T8pnoJJRPMG3GeiiMWMXjPUI01DdX+Fv69wkFavUOOV/JND
0nKl42xqajbkDL+Hc9veNlR4+hVykdVOlFgEY3x37wiI3gklHGoRZmex4MOL9+oB
LEiOARhtduG1w3bukOphhBfc1W4We12WIblKWfzRr/YhIgiNCD5rCL8kvcaFyKUe
3a9BQWayRewPmY8IdxcUHoKwhNS5a+52Aqgd/1ki+VvWRX3uTVAZA0rIiECGTioQ
MkSHr1F00bZ+1QEAEQEAAQAL/is5gfgf1fz0vPdki+DfBG/hPCQTZnx121LUaYy0
b6qqSeBGloJ6Rr89SejMLC3tyeb/PAeCJjsHknq/O8ojxU8rKZu3rozXaV46cr6t
DUQfA+Zsx72/ZYcZY+pB7w4b+xXYaisuoAlf/v9MzkjwQygC8Nx4q6GG3L/yPie5
Fvd+kYMp7s/phE/gNT+Xezhneh+3yqnboVNiP3beY0Q14ROD5p4ZLC03hCqNaMP8
4dNS804dZaCyGgvREbWOsqM3ef0rljKfTSLZ9eFoLU0CMw/dw764IXWnjEo4bkl6
ialKwjSyaPIShgjSMx/IcH2iYI6GcEXkzl6O+j8cn2Q62lEuQijQ0T1jn/Gq36kT
hRPcx3lumR9Dsc1CHyIuHZFWUy8+ZRoVKDSvv4EjjZN8YsqB7wLLvT5/yMI1wnku
ITPCn/TMMGNCzKuiIucC7T/Kj3yDsotpFX6RTRiq1H+Z3iN+Ml1Ih+D7CoJMUkBS
42JfwYhCLDhC6JCk2HAUQpzTywYAwUFFl3u8oR8PA/EYwBiS/UUm616hMTAOOM4u
uF9Iai75BW4mfLGd1mmqZknIAKmYYNN9A8IjvkA81/Y5wdyBo/oLOhQuewnou7Uf
zJ9R7IY8LWToc0LgOBjvxL3ucxYz1Ub1YJiaQxw9sm8L97H+HZCER0k3pDXNWvhB
yT7jrRlvOLIpU/EOTRx2SbWWyUXCM+b5MNzmk4sDxH/reIhhgbqfEjV7FeOAnaiB
F2zTz7JtEz94gS1KOXYJFrlMpzRrBgDxp/TrHBuJhAmPXn/WCnqVnNP1klAzD7l2
ecp6gSysNhyGkoC3vT84gL2Sz3VkAwd7tbb5CKQKqw/Bea4EJ2Ex4z4AopwH7c5X
LFTYWxFDlGNxf68Np7XiuMOOCTtpUkKR8oCY/TEPNdfnsdU3XiT7kJxo9Kt51Mra
YeCKiJeF2wd2KwezTAy9M0PCIDVx/CP05ZhAfV099Yb4CfjPsMQHUEcJOYBmY1VR
pveqg/9H2XZvrKcdsZ6+EsEFLyCzl0MGAJRBb5J6Y/il3aYw5Vijv7hSg5zsgMRx
JqqmOCLG+iDPhkuN4HAZgpED1zMA5SRgYjNKk3sFy6lkMHFi4hzi7gpXhksVSIQD
rZieSXOxCLzRp2lyJR03w/q2XbkcOYX8aHbtZHzmNvXHmqLo+PtE0gvHT6VFcuoX
FVNcN4yjMTGMmTNX+BHIUVYRmSOvqEx9QaHcDtJfCe55VwVvW1shu2c22QHnxF+H
eDSUEM61YphvIvB+tfEj60sqwU6BWZnYW9M2tDBMYWR5IENsYWlyZSBUcmV2ZWx5
YW4gPGlucXVpc2l0b3JAZGFydGhtYW1hLm9yZz6JAdQEEwEIAD4WIQSOjSOBrgZq
vh/uUJghupd8pHKHGAUCR0tTAAIbAwUJA8JnAAULCQgHAgYVCgkICwIEFgIDAQIe
AQIXgAAKCRAhupd8pHKHGOJxC/9qpPHanMKIJOPxLNr5Yp7AZhcOlzX7IXlp1hwt
m6MPXMRz76wDeDjQSlDUo80eOIaDmq6Q3yHL3XbaDBXoHsj5HO2F1oaQnNgByq6r
loOFjjQ4zcPp7Z6U3vKP++cE1CTTA/wZKsW5EDg2opd5BCq0MYj2H7KoisXLpM6N
k0zDWeZrdmewXvhNmlnf2r3e7N6FS3cReWiSQvFxVcNHYK3QEAb3JZe172kpf/ko
PQA24hIyjY+JjTLGFQ74WPSsXCo423s6Yjj80FtJOSwJQ+JgUfgKB6mv4adLDEN2
Lsbylumci9rv7VF3UWUWwgo4Fhwxr6O3bH7eTc4EjjWexB14hovRGmgNJBiyzAKs
i2QBAd+UY5Y5xaqh+Ed4zMpvs5HobuEPPf31sUVkt9J7HIbKPeDJkowQ8UO8AeS1
fEy+iacwlH/3Ve07xUyGDztnS/vQ6MBzIZm12bvedXALOqdXr61e+rx05Fww/Q0F
x98fBWUDan5vXKCvNSx3yzBodcedBVgER0tTAAEMAMW5zC5ogzpPKaIrnhLypB+I
7slHiF3kt8iGmgUePr9GVuRkLr2vWJz3+Tvd3L8UjXeNEdZ2z/fqxDD08pk3gY/f
/JhGQeNnvsZ4nsaVUnc3Xz640W6ufH+aJtgCW+Y+rvo0zLXZ+hlhcJ9FeroRODji
t5Pwu0tgBcjOpnPu/p1Vc+Yj145qw9HQR/sQ2tnj02m31/a8POf6efGRgIRhDMJ1
KeuVzLqsXEWJIOi651OOvtOG0tKOemxmm8cOqMqRBW7bVbSsqKcD0/7sQw6mprFW
YKp9WKKu+XM3sHTk2NZhKqAfyloZLnhgiC30LgQS9QMJdC4/QDfZY2srEKlod1tX
8Gj07E7P5PG/e6X+rjPKEoqJmTUxqjEAk8++yvPGQRncT8V9dEbpGU9zm7qmYdtZ
TjQFLHJ//mRcx2zqTSExoETg3IWgyt5e6bQypO+2xr5NC0Jf3Ubj7RhD6hHzPaSP
PyJ5ZxnyXAePsKPsDWJRVc2JYiMQTqBg9sCkZWccRQARAQABAAv8C8qN9NmKM9y7
Lp7bxST/qRrFJK81oGXOmPB/+FyqoMT80w9vYyP1DJ1UGWAcdS+wVQgOX4QD2HTB
YOsGmaEAAri4i0srTDioXZUdYNnQSmg8r5SddrSEm6ZxeRHA8bzcufKSn6ihW8ie
Cv19eWGkAO5yRKoHPVI7XhOGxSSkPfU13WxXQzi2N0mstTn21yYZOjV6tU3Z8vqS
sZd7+sj/1gvfJVuwUxSKxyHLmt1khKzfT+V7Jo/VGKhQ02DaK4RU2+u0JF6YM+mj
2FjjuqtYvtYVfMHESy/MkPdInNgddMdJRshwpvRxCELJtGYc6fonAHZKzcW7iZfL
ytKQ/kAET2GbJ3bmCHs8mEsrbGYNYipnX8G0M+SLxuECYL8ngfkMz02VRmZC0W3U
CfYg6+cfhymQnXJoRUPkiVjMA7zF57Z5Zqo9+QGGpy9wflU+7CD4uBMaZ71Oh1Lf
odVxL5oGph+IjvOErUIKCOUXsew9ZvxreJd/CTzB768mXheJs9lBBgDNsi3sGJP9
K7xrIxsulwWZbzr0T7o02PDkwyj8LuECwSvjvVqHRM+Xdw4GhaDVt7+cf0MoBxC4
dd7LYohP5wf2Bmp725gPuW/fdjq73OM/HHgzoZeRSyPFM0jcjM40nMAyTTyJDzID
Yyi1nU5qWd7o6STgfFnT0hslW+fs/h+mTD9/4MJh2g2xCgH3f3RHw04aSdPJI9At
rhenA/dp+sSa1H511B/tS+hpdW4uw5ooHfUqWAo0QjQSASP1/6lmYgUGAPYUofUK
A17OEdi+lqcFEpSuDp22d3EWt4doOde9bpshLb7olxEAa/+gyb5gufI0TS/TdHii
LlR6qhFCXOaY5b/ABgL5KuO14qOBEFcMPYm+MFRhG1PGUct3RW5WeMzQy3CIE+A3
nZP/8LaEJzjQNXBcS8ei2ID2k13VTn3KkMhgf7Gmw5xyxVF7o2JCFVVX0Iq9gcvi
ghPL3rrrOBotN/fJSEP3uIqEeCygqi4Gz0a5K0jy6Uir7s3n81SZDj+lQQX/U2lS
0YxQH3jxZwLNnC07CcZh+uSYxALb8SplVkm6B1rU3lsnmLf4I9h7JwIIK6tiBFiE
o44MrH9A9IEKUCIGqgfwcFJwItlqHTd3rkHKy/FOoVpa2cwyX5h+NbqNCjCGZgrl
c369/9L1c+qlz0Zush5Q/18hTwFjFrWqyBTil0Qh6qcsHQRVcSWm9SJQIwDA3i1q
BRlpoCih2r/ilZcc3M52vgCrmqMfRRkhzyiuEQE3kH4drMY9VuHJwsZSnpfX3VmJ
AbwEGAEIACYWIQSOjSOBrgZqvh/uUJghupd8pHKHGAUCR0tTAAIbDAUJA8JnAAAK
CRAhupd8pHKHGOjDC/4xEU1ewAMks7sMoCsgaYu0i7fyYo9FooItRTp1qUC3zJIh
QV9Wo7e0+1SX8ZAVSbjNIVTQC3P2SElTdtifejJdZa76KcCyMzbg6hI9ickU1il6
LGjPr5xXxrWUYGcS21XFgt7yk8L2FYzwMcUWG/ailn31zj3w9UGaEHK82+Wasbkn
YmobxQNcjbp1QZGatSUQHfA+yTBlxyDyvUR2riTUOhx6jX6HDQNiOauHZi0zRP0F
nMk7tHa4r+AQ0g/M4+t8aCsClj5ws7AiM9jU7YaX4VIC3r/H+pJGEmw6RNqGxHa/
MM399A9HWyrpP/LdMChxUGkUDc8VIs2XGw5j3VMNXcEYJhb4PDTqIJSaJ2SY/HxU
VzCp1re+HTPBUAYogWpD2dQdtrs8yqdNf4+OEZZOHYmErUsfCLFTh0qAD5WkL2Cj
Sl2KlL7y+s9YW5fHZSycu6/oLpUWccIAl3A1h/dLaO3Ukh2rDkJsjD1X5hLas96v
WGub8+IbexOlWL9VX02dBVgER0tTRwEMAMS1DPt9Y/bjUDIxBG7/1tN/5MdBeiU2
pvZVpIy34a2vNWFnUNUu7vPEUXoTu3ZJcQj8uBDzq3ikJ57O17gyFQYsIUbdJrVV
hsr4sh7mByR/fqq7G+CrJwzPtVcnszCilRnzK+3G/vYd4mW9vM8L58E4J8rc/Nlw
GUbqrKkbAP5oUNyRtUASgHgBnSnTWeGIbRVPjY6dt8TfpY9XEuh3ghs77jkyiknw
NTopYnaqeIDHQ/5BGmw1B0Fj1CbyJz+UiQ3QEpAvOmCrmE0hfyHiyhrpq+eewasL
4axBHLaFxYB5DyZ2ch+D4D4Nqbtxd5vWDR33yzgJT57WFrUrG9adyruxpfG9v6CR
UFkA+o9f+UI8E+Pr3s67rau1ZurZtjKuWgNt3yPE4Sb/JlwLTqK6F4QcXfDLbsav
YvuyX9juUhE63ApfOh3I0NAZIVt6u1/nRc9X8x2Ae8zLZbIhcswUd7IbzIgmqngq
+t5tw5fhQNaNUjvUGtNAdwltMu8FaJMYlQARAQABAAv9EOTNvyGXPsJqBk2AaHoP
fK2cu+IrN9v4PerADZfTSYPlLT7eydhUjFn9d2MPdAq9qvxtYINU5DEQ+Aoiq76d
YKDUoM3of6VfRLpULeQqk99hRQ95xvNcELUcCWau9IvaC1b/nFW9WuzZH0zK1Otc
VZNZk4okKxZ+DUGlX4aisLbLzw2yh9Su9N+KnGd67iw11iE1cpyoBkAA640aYh21
blpYzM/C4bPAFoUsYC2m2MSEWedEeiuZumt08n1UkpjSf+J+czamLAxOda09hhwl
TYjRSDRydH15JAXZFhlnuNKTNwVh4Bi7gRRI8+v1ZxQufVvnOPmhljAUOnDjEK76
5T9LarVEttGOBWYY6acZvE2Rx+Ax5bjsoD7+3P1O4f1XoapBJsJIYcb1xGLQxikG
n7Zf5es8+7HPgicQE/mv59ya91UaYeD7dSQrU/zzsr1zBRM8DTOar/xVCHJBCXNi
PAqFuYM/tJ4otde2MbGdEpYWHDFnLDrZ7emLyxOJuZcnBgDUJaOnNN4fD8/S9S/s
hM0a1iu4h58rbsDuOhiUDI/Yxql6xbZGDiHC8owgf7gSjb42KBh1eDX8ioZe7bUF
MPHJzfHw0Jsz8eyXtI4CQqmGNpeB9t3z5WoT/KPNMgo3ay0ZiiiYsvZ4SVR81/jD
9PM1MAvdsNnHN0eHv/QImoP8+4wbfCxxa+2pP/jLiDa+j2TvCRR+U1knsL5o7dya
7IrzjK/qQQjQ9TrGWWCvRt4HAz0f3fJyIYZJRwq+IVWvB8sGAO1eXunWbyU6bUMh
OagLWZhY3s9WsJEgv8u9sWGO+zMFGx62Q8DH1gEKJitbNURNzvu3BShdLb7fow1Z
MPxnhblHB7bwq7V/IHz0iX1apm3YaJmhDWlvBmNGRucopOU3Ow72kvPMEkuWb0Wr
Zxv57zgRbfcI5McgFrlxAxZ+yqpohwnVFJZmmvcEb83QX/CLfVYBiwb71kZ0GDUE
Tt2bjnBuPQWNtAjG2S2BbgK934nIxYY7RmRZWxmjObJAb4iVHwX/T8s55lWNjKam
jIHSdjKes8nXe3cDk51GWBu91IQpnwG5A8wGJJb/rZuIEKs1h3Fr06q4dVB6my6P
qlTdT5WL5Kqa7arlHQHbnkGpPhUi5K7od1KnHa1HjQHGqEVvlAAOQRZdp2bdzOO8
UbL6POh6P8QJzGBog/lTWxSsR9CvShD/3+MJe9hqSYtwo3DWHMjYSup68GJhF8qz
8lPf5s6+MfIReaBxogj/ELhvAjLDbJJcdezU5/e47LkEnxc9+BP15TmJA3IEGAEI
ACYWIQSOjSOBrgZqvh/uUJghupd8pHKHGAUCR0tTRwIbAgUJAeEzgAHACRAhupd8
pHKHGMD0IAQZAQgAHRYhBOEnUeYHkpl5OllbbeH52cCAwQuBBQJHS1NHAAoJEOH5
2cCAwQuBrcoMAKxYGeOOXJfDau0rXvyNxPHqTYgLJkzWipofizqjruP52w7vef/F
iVHOHhxRNaCMgKFhiBNzM7GVNlrBcXmgwkUo7PLhC+DVgSr0gkAdFQ01Ic/EjfyK
znxS49nxuziFfOM63BsBo7MNQB7eklDRsfz2OLgDB/SE3svv5A31QBTdYQpBZNZL
FhYDo+JQsZKx+YMsXoro7rBGcN1aF4ogyXYcaOm+DJp+ZwZUIi3/7wgRHdTOUwr7
PBTxlNLqBG0RdOvb2iKjxQmCY8kc4Se13CPuQvEKb4LOjlHsRp+N2GP0b6Rr7XPJ
o9YbBA6xo4ICrtaXCkJd6qMux96P7t6SWh4ZYvMGP2XOeHLGe8OiZjo6cEOsYvda
vmOZM0X+A814uNalEzcl027Q8NtcGW0oBn/C3AOKKR69fRzwBfZTY1E8G9kYNO9x
j+GBFwudjs7l/DSX71g1XQWkMpXNn8SoODh15UoIfjkR2Ic8LdpgYlTYsaapOxLo
ulFmyTJn6bRy028+C/9SwTIAmlGRP7rneycRdCOUmqN7dQJ5pcU6M9FQiqyLr4pv
oED7ambIC438ZelwkacPu0Uc+KFVqOUGwng5Ldz62smHnFwVn1BrasjhP+ilN3c9
iSHr8flQeVRU288ywKWXKV/VlHkND+sKGxDpWF53y3fFrKjukG7sIkd7k/RHtYv5
mMuYx9O2gcG8mnzP+zk9YBjgbeow+Se0SdlSnRIGXLl0mk2CfJKZp5hd+sMXq+Gw
78MBCBNv0cfQCfBfhPFbm44oDUgotFQliEBU1ey5fOUjtEOPpvvQzAA4KRK4BMd6
RHnJI657X9ffWiX900IggFYIC+yCTaKmm9LVMgPZ5KS/C+MdvZlkWzH8jv7gKFHP
1JV1c//vSuxq0khtAIkffl0KxLQBHoov8LcFsADafhnYUZFXASOsZOdv1sp5HqLr
kJmOk28sw0+6HrVXa4PItghG5jOVG1CgWaCCtC24zQj5zhXYfmh/aGIdBf1vPe9b
Zi5tJqJFwNBceGW3kZI=
=jOL5
-----END PGP PRIVATE KEY BLOCK-----

58
test/start_sync.py

@ -0,0 +1,58 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import pEp
import time
pEp.set_debug_log_enabled(True)
def msg2send(message):
print("MSG2SEND")
# print(message)
def handshake(me, partner, signal):
print("HANDSHAKE")
print(me.fpr)
print(partner.fpr)
print(signal)
pEp.message_to_send = msg2send
pEp.notify_handshake = handshake
alice = pEp.Identity("tedst@alice.com", "alice", "23")
pEp.myself(alice)
print(alice.fpr)
while True:
pEp.set_sync_mode(pEp.SyncModes.Async)
print("start_sync()")
pEp.start_sync()
print("Running...")
time.sleep(3)
print("shutdown_sync()")
pEp.shutdown_sync()
print("END")
time.sleep(3)
pEp.set_sync_mode(pEp.SyncModes.Sync)
print("start_sync()")
pEp.start_sync()
print("Running...")
time.sleep(3)
print("shutdown_sync()")
pEp.shutdown_sync()
print("END")
time.sleep(3)
pEp.set_sync_mode(pEp.SyncModes.Off)
print("start_sync()")
pEp.start_sync()
print("Running...")
time.sleep(3)
print("shutdown_sync()")
pEp.shutdown_sync()
print("END")
time.sleep(3)

101
test/sync_handshake.py

@ -112,37 +112,36 @@ def add_debug_info(msg):
return msg
class UserInterface(pEp.UserInterface):
def notifyHandshake(self, me, partner, signal):
print(colored(str(signal), "yellow"), end=" ")
output("on " + device_name + "" if not me.fpr else
"for identities " + str(me.fpr) + " " + str(partner.fpr))
if me.fpr and partner.fpr:
assert me.fpr != partner.fpr
if signal in (
pEp.sync_handshake_signal.SYNC_NOTIFY_INIT_ADD_OTHER_DEVICE,
pEp.sync_handshake_signal.SYNC_NOTIFY_INIT_ADD_OUR_DEVICE,
pEp.sync_handshake_signal.SYNC_NOTIFY_INIT_FORM_GROUP
):
if isinstance(end_on, list):
end_on.extend([
pEp.sync_handshake_signal.SYNC_NOTIFY_SOLE,
pEp.sync_handshake_signal.SYNC_NOTIFY_IN_GROUP,
])
sleep(.5) # user is reading message
try:
if not options.noanswer:
if options.reject:
self.deliverHandshakeResult(SYNC_HANDSHAKE_REJECTED)
else:
self.deliverHandshakeResult(SYNC_HANDSHAKE_ACCEPTED)
except NameError:
self.deliverHandshakeResult(SYNC_HANDSHAKE_ACCEPTED)
if signal in end_on:
global the_end
the_end = True
def this_notifyHandshake(me, partner, signal):
print(colored(str(signal), "yellow"), end=" ")
output("on " + device_name + "" if not me.fpr else
"for identities " + str(me.fpr) + " " + str(partner.fpr))
if me.fpr and partner.fpr:
assert me.fpr != partner.fpr
if signal in (
pEp.sync_handshake_signal.SYNC_NOTIFY_INIT_ADD_OTHER_DEVICE,
pEp.sync_handshake_signal.SYNC_NOTIFY_INIT_ADD_OUR_DEVICE,
pEp.sync_handshake_signal.SYNC_NOTIFY_INIT_FORM_GROUP
):
if isinstance(end_on, list):
end_on.extend([
pEp.sync_handshake_signal.SYNC_NOTIFY_SOLE,
pEp.sync_handshake_signal.SYNC_NOTIFY_IN_GROUP,
])
sleep(.5) # user is reading message
try:
if not options.noanswer:
if options.reject:
pEp.deliver_handshake_result(SYNC_HANDSHAKE_REJECTED)
else:
pEp.deliver_handshake_result(SYNC_HANDSHAKE_ACCEPTED)
except NameError:
pEp.deliver_handshake_result(SYNC_HANDSHAKE_ACCEPTED)
if signal in end_on:
global the_end
the_end = True
def shutdown_sync():
@ -153,6 +152,7 @@ def run(name, color=None, imap=False, own_ident=1, leave=False):
global device_name
device_name = name
pEp.notify_handshake = this_notifyHandshake
if color:
global output
@ -164,41 +164,34 @@ def run(name, color=None, imap=False, own_ident=1, leave=False):
elif color == "cyan":
pEp.debug_color(36)
if own_ident >= 2:
me2 = pEp.Identity("alice@pep.security", name + " of Alice Neuman", name)
pEp.myself(me2)
if own_ident == 3:
me3 = pEp.Identity("alice@pep.foundation", name + " of Alice Neuman", name)
pEp.myself(me3)
pEp.disable_all_sync_channels()
if imap:
import miniimap
import imap_settings
me = pEp.Identity(imap_settings.IMAP_EMAIL, name + " of " + imap_settings.IMAP_USER, name)
pEp.myself(me)
pEp.messageToSend = messageImapToSend
pEp.message_to_send = messageImapToSend
else:
me = pEp.Identity("alice@peptest.ch", name + " of Alice Neuman", name)
pEp.myself(me)
if own_ident >= 2:
me2 = pEp.Identity("alice@pep.security", name + " of Alice Neuman", name)
pEp.myself(me2)
if own_ident == 3:
me3 = pEp.Identity("alice@pep.foundation", name + " of Alice Neuman", name)
pEp.myself(me3)
pEp.messageToSend = messageToSend
pEp.message_to_send = messageToSend
if multithreaded:
from threading import Thread
def sync_thread():
print(colored("********* ", "yellow") + colored("sync_thread entered", color))
ui = UserInterface()
print(colored("********* ", "yellow") + colored("UserInterface object created", color))
pEp.do_sync_protocol()
print(colored("********* ", "yellow") + colored("leaving sync_thread", color))
sync = Thread(target=sync_thread)
sync.start()
print("Sync Start multi-threaded")
pEp.set_sync_mode(pEp.SyncModes.Async)
else:
pEp.script_is_implementing_sync()
sync = None
ui = UserInterface()
print("Sync Start single-threaded")
pEp.set_sync_mode(pEp.SyncModes.Sync);
try:
if leave:

4
test/sync_test.py

@ -36,8 +36,6 @@ def test_for(path, color=None, end_on=None, mt=False, imap=False, own_ident=1):
sync_handshake.run(path, color, imap, own_ident)
os.chdir(cwd)
def setup(path):
cwd = os.getcwd();
@ -213,7 +211,7 @@ if __name__ == "__main__":
# Phone runs with own_ident = 2
Phone = Process(target=test_for, args=("Phone", "red", end_on,
options.multithreaded, options.imap, 1))
options.multithreaded, options.imap, 2))
# others run with own_ident = 1
Laptop = Process(target=test_for, args=("Laptop", "green", end_on,

Loading…
Cancel
Save