Python3.7 works on Windows Platofrm now.

pull/111/head
Apex Liu 2018-09-22 02:12:53 +08:00
parent 2e0c5b16fb
commit 7943f50212
14 changed files with 3519 additions and 1077 deletions

2
.gitignore vendored
View File

@ -43,6 +43,7 @@ __pycache__
/external/mongoose /external/mongoose
/external/openssl /external/openssl
/external/python /external/python
/external/libssh
/external/libssh-win-static/include/libssh /external/libssh-win-static/include/libssh
/external/libssh-win-static/src /external/libssh-win-static/src
/external/libssh-win-static/lib /external/libssh-win-static/lib
@ -99,3 +100,4 @@ xcuserdata
profile profile
*.moved-aside *.moved-aside
/server/share/tmp /server/share/tmp
/build.sh

View File

@ -2,10 +2,12 @@
rem ============================================ rem ============================================
rem 请调整以下路径,以适配您自己的的系统环境。 rem 请调整以下路径,以适配您自己的的系统环境。
rem 注意必须使用Pyhont 3.432位版本 rem 注意必须使用Pyhont 3.732位版本
rem 可以从这里下载:
rem https://www.python.org/ftp/python/3.7.0/python-3.7.0.exe
rem ============================================ rem ============================================
SET PYEXEC=C:\Program Files\Python\python.exe SET PYEXEC=C:\Program Files\Python\python.exe
"%PYEXEC%" -B build/build.py %1 %2 %3 %4 %5 "%PYEXEC%" -B build/build.py %1 %2 %3 %4 %5

View File

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="Encoding"> <component name="Encoding">
<file url="file://$PROJECT_DIR$/../build.bat" charset="GBK" />
<file url="PROJECT" charset="UTF-8" /> <file url="PROJECT" charset="UTF-8" />
</component> </component>
</project> </project>

View File

@ -128,6 +128,7 @@ def do_opt(opt):
elif 'external' == opt['name']: elif 'external' == opt['name']:
script = 'build-external.py' script = 'build-external.py'
arg = '%s %s' % (ctx.target_path, opt['bits'])
elif 'server' == opt['name']: elif 'server' == opt['name']:
script = 'build-server.py' script = 'build-server.py'

View File

@ -41,15 +41,12 @@ class BuilderBase:
def _build_mongoose(self, file_name): def _build_mongoose(self, file_name):
cc.e("this is a pure-virtual function.") cc.e("this is a pure-virtual function.")
# def build_openssl(self): def build_openssl(self):
# file_name = 'openssl-{}.zip'.format(env.ver_openssl) file_name = 'openssl-{}.zip'.format(env.ver_ossl)
# _alt_ver = '_'.join(env.ver_openssl.split('.')) self._build_openssl(file_name)
# if not utils.download_file('openssl source tarball', 'https://github.com/openssl/openssl/archive/OpenSSL_{}.zip'.format(_alt_ver), PATH_DOWNLOAD, file_name):
# return def _build_openssl(self, file_name):
# self._build_openssl(file_name) cc.e("this is a pure-virtual function.")
#
# def _build_openssl(self, file_name):
# cc.e("this is a pure-virtual function.")
def build_libuv(self): def build_libuv(self):
file_name = 'libuv-{}.zip'.format(env.ver_libuv) file_name = 'libuv-{}.zip'.format(env.ver_libuv)
@ -102,12 +99,13 @@ class BuilderWin(BuilderBase):
super().__init__() super().__init__()
def _init_path(self): def _init_path(self):
# self.OPENSSL_PATH_SRC = os.path.join(PATH_EXTERNAL, 'openssl') self.OPENSSL_PATH_SRC = os.path.join(PATH_EXTERNAL, 'openssl')
self.JSONCPP_PATH_SRC = os.path.join(PATH_EXTERNAL, 'jsoncpp') self.JSONCPP_PATH_SRC = os.path.join(PATH_EXTERNAL, 'jsoncpp')
self.MONGOOSE_PATH_SRC = os.path.join(PATH_EXTERNAL, 'mongoose') self.MONGOOSE_PATH_SRC = os.path.join(PATH_EXTERNAL, 'mongoose')
self.MBEDTLS_PATH_SRC = os.path.join(PATH_EXTERNAL, 'mbedtls') self.MBEDTLS_PATH_SRC = os.path.join(PATH_EXTERNAL, 'mbedtls')
self.LIBUV_PATH_SRC = os.path.join(PATH_EXTERNAL, 'libuv') self.LIBUV_PATH_SRC = os.path.join(PATH_EXTERNAL, 'libuv')
self.LIBSSH_PATH_SRC = os.path.join(PATH_EXTERNAL, 'libssh-win-static') # self.LIBSSH_PATH_SRC = os.path.join(PATH_EXTERNAL, 'libssh-win-static')
self.LIBSSH_PATH_SRC = os.path.join(PATH_EXTERNAL, 'libssh')
# self._prepare_python_header() # self._prepare_python_header()
@ -119,68 +117,84 @@ class BuilderWin(BuilderBase):
return return
cc.v('') cc.v('')
if os.path.exists(os.path.join(env.path_py_inc, 'Python.h')): # if os.path.exists(os.path.join(env.path_py_inc, 'Python.h')):
cc.e('can not locate python development include path, make sure miniconda installed.') # cc.e('can not locate python development include path, make sure miniconda installed.')
# return
# cc.v('')
# utils.copy_ex(env.path_py_inc, os.path.join(PATH_EXTERNAL, 'python', 'include'))
_header_path = None
for p in sys.path:
if os.path.exists(os.path.join(p, 'include', 'Python.h')):
_header_path = os.path.join(p, 'include')
if _header_path is None:
cc.e('\ncan not locate python development include path in:')
for p in sys.path:
cc.e(' ', p)
raise RuntimeError()
utils.copy_ex(_header_path, os.path.join(PATH_EXTERNAL, 'python', 'include'))
def _build_openssl(self, file_name):
cc.n('build openssl static library from source code... ', end='')
_alt_ver = '_'.join(env.ver_ossl.split('.'))
if not utils.download_file('openssl source tarball', 'https://github.com/openssl/openssl/archive/OpenSSL_{}.zip'.format(_alt_ver), PATH_DOWNLOAD, file_name):
return
_chk_output = [
os.path.join(self.OPENSSL_PATH_SRC, 'out32', 'libeay32.lib'),
os.path.join(self.OPENSSL_PATH_SRC, 'out32', 'ssleay32.lib'),
os.path.join(self.OPENSSL_PATH_SRC, 'inc32', 'openssl', 'opensslconf.h'),
]
need_build = False
for f in _chk_output:
if not os.path.exists(f):
need_build = True
break
if not need_build:
cc.w('already exists, skip.')
return return
cc.v('') cc.v('')
# _header_path = None cc.n('prepare openssl source code...')
# for p in sys.path: _alt_ver = '_'.join(env.ver_ossl.split('.'))
# if os.path.exists(os.path.join(p, 'include', 'pyctype.h')): if not os.path.exists(self.OPENSSL_PATH_SRC):
# _header_path = os.path.join(p, 'include') utils.unzip(os.path.join(PATH_DOWNLOAD, file_name), PATH_EXTERNAL)
# if _header_path is None: os.rename(os.path.join(PATH_EXTERNAL, 'openssl-OpenSSL_{}'.format(_alt_ver)), self.OPENSSL_PATH_SRC)
# cc.e('\ncan not locate python development include path in:') if not os.path.exists(self.OPENSSL_PATH_SRC):
# for p in sys.path: raise RuntimeError('can not prepare openssl source code.')
# cc.e(' ', p) else:
# raise RuntimeError() cc.w('already exists, skip.')
# utils.copy_ex(_header_path, os.path.join(PATH_EXTERNAL, 'python', 'include')) os.chdir(self.OPENSSL_PATH_SRC)
utils.copy_ex(env.path_py_inc, os.path.join(PATH_EXTERNAL, 'python', 'include')) os.system('""{}" Configure VC-WIN32"'.format(env.perl))
os.system(r'ms\do_nasm')
os.system(r'"{}\VC\bin\vcvars32.bat" && nmake -f ms\nt.mak'.format(env.visual_studio_path))
# def _build_openssl(self, file_name): for f in _chk_output:
# cc.n('build openssl static library from source code... ', end='') if not os.path.exists(f):
# _chk_output = [ raise RuntimeError('build openssl static library from source code failed.')
# os.path.join(self.OPENSSL_PATH_SRC, 'out32', 'libeay32.lib'),
# os.path.join(self.OPENSSL_PATH_SRC, 'out32', 'ssleay32.lib'),
# os.path.join(self.OPENSSL_PATH_SRC, 'inc32', 'openssl', 'opensslconf.h'),
# ]
#
# need_build = False
# for f in _chk_output:
# if not os.path.exists(f):
# need_build = True
# break
#
# if not need_build:
# cc.w('already exists, skip.')
# return
# cc.v('')
#
# cc.n('prepare openssl source code...')
# _alt_ver = '_'.join(env.ver_openssl.split('.'))
# if not os.path.exists(self.OPENSSL_PATH_SRC):
# utils.unzip(os.path.join(PATH_DOWNLOAD, file_name), PATH_EXTERNAL)
# os.rename(os.path.join(PATH_EXTERNAL, 'openssl-OpenSSL_{}'.format(_alt_ver)), self.OPENSSL_PATH_SRC)
# if not os.path.exists(self.OPENSSL_PATH_SRC):
# raise RuntimeError('can not prepare openssl source code.')
# else:
# cc.w('already exists, skip.')
#
# os.chdir(self.OPENSSL_PATH_SRC)
# os.system('""{}" Configure VC-WIN32"'.format(env.perl))
# os.system(r'ms\do_nasm')
# os.system(r'"{}\VC\bin\vcvars32.bat" && nmake -f ms\nt.mak'.format(env.visual_studio_path))
#
# for f in _chk_output:
# if not os.path.exists(f):
# raise RuntimeError('build openssl static library from source code failed.')
def _build_libssh(self, file_name): def _build_libssh(self, file_name):
cc.n('build libssh static library from source code... ', end='') cc.n('build libssh static library from source code... ', end='')
out_file = os.path.join(self.LIBSSH_PATH_SRC, 'lib', 'libsshMT.lib')
if not os.path.exists(self.LIBSSH_PATH_SRC):
cc.v('')
utils.unzip(os.path.join(PATH_DOWNLOAD, file_name), PATH_EXTERNAL)
os.rename(os.path.join(PATH_EXTERNAL, 'libssh-{}'.format(env.ver_libssh)), self.LIBSSH_PATH_SRC)
cc.n('fix libssh source code... ', end='')
utils.ensure_file_exists(os.path.join(PATH_EXTERNAL, 'fix-external', 'libssh', 'src', 'sftp.c'))
utils.copy_file(os.path.join(PATH_EXTERNAL, 'fix-external', 'libssh', 'src'), os.path.join(self.LIBSSH_PATH_SRC, 'src'), 'sftp.c')
out_file_lib = os.path.join(self.LIBSSH_PATH_SRC, 'lib', ctx.target_path, 'ssh.lib')
out_file_dll = os.path.join(self.LIBSSH_PATH_SRC, 'lib', ctx.target_path, 'ssh.dll')
need_build = False need_build = False
if not os.path.exists(out_file): if not (os.path.exists(out_file_lib) and (os.path.exists(out_file_dll))):
need_build = True need_build = True
if not need_build: if not need_build:
@ -188,30 +202,43 @@ class BuilderWin(BuilderBase):
return return
cc.v('') cc.v('')
cc.n('prepare libssh source code... ', end='') # cc.n('prepare libssh source code... ', end='')
_include = os.path.join(self.LIBSSH_PATH_SRC, 'include', 'libssh') # _include = os.path.join(self.LIBSSH_PATH_SRC, 'include', 'libssh')
_src = os.path.join(self.LIBSSH_PATH_SRC, 'src') # _src = os.path.join(self.LIBSSH_PATH_SRC, 'src')
#
# if not os.path.exists(_include) or not os.path.exists(_src):
# utils.unzip(os.path.join(PATH_DOWNLOAD, file_name), PATH_EXTERNAL)
# # os.rename(os.path.join(PATH_EXTERNAL, 'openssl-OpenSSL_{}'.format(_alt_ver)), self.OPENSSL_PATH_SRC)
#
# _unzipped_path = os.path.join(PATH_EXTERNAL, 'libssh-{}'.format(env.ver_libssh))
#
# utils.copy_ex(os.path.join(_unzipped_path, 'include', 'libssh'), _include)
# utils.copy_ex(os.path.join(_unzipped_path, 'src'), _src)
#
# utils.remove(_unzipped_path)
#
# if not os.path.exists(_include) or not os.path.exists(_src):
# raise RuntimeError('\ncan not prepare libssh source code.')
# else:
# cc.w('already exists, skip.')
if not os.path.exists(_include) or not os.path.exists(_src): cc.w('\nOnce the libssh.sln generated, press Enter to continue or Q to quit...', end='')
utils.unzip(os.path.join(PATH_DOWNLOAD, file_name), PATH_EXTERNAL) try:
# os.rename(os.path.join(PATH_EXTERNAL, 'openssl-OpenSSL_{}'.format(_alt_ver)), self.OPENSSL_PATH_SRC) x = env.input()
except EOFError:
_unzipped_path = os.path.join(PATH_EXTERNAL, 'libssh-{}'.format(env.ver_libssh)) x = 'q'
if x == 'q':
utils.copy_ex(os.path.join(_unzipped_path, 'include', 'libssh'), _include) return
utils.copy_ex(os.path.join(_unzipped_path, 'src'), _src)
utils.remove(_unzipped_path)
if not os.path.exists(_include) or not os.path.exists(_src):
raise RuntimeError('\ncan not prepare libssh source code.')
else:
cc.w('already exists, skip.')
cc.i('build libssh...') cc.i('build libssh...')
sln_file = os.path.join(self.LIBSSH_PATH_SRC, 'libssh.vs2015.sln') sln_file = os.path.join(self.LIBSSH_PATH_SRC, 'build', 'libssh.sln')
utils.msvc_build(sln_file, 'libssh', ctx.target_path, ctx.bits_path, False) utils.msvc_build(sln_file, 'ssh_shared', ctx.target_path, 'win32', False)
utils.ensure_file_exists(out_file) utils.ensure_file_exists(os.path.join(self.LIBSSH_PATH_SRC, 'build', 'src', ctx.target_path, 'ssh.lib'))
utils.ensure_file_exists(os.path.join(self.LIBSSH_PATH_SRC, 'build', 'src', ctx.target_path, 'ssh.dll'))
utils.copy_file(os.path.join(self.LIBSSH_PATH_SRC, 'build', 'src', ctx.target_path), os.path.join(self.LIBSSH_PATH_SRC, 'lib', ctx.target_path), 'ssh.lib')
utils.copy_file(os.path.join(self.LIBSSH_PATH_SRC, 'build', 'src', ctx.target_path), os.path.join(self.LIBSSH_PATH_SRC, 'lib', ctx.target_path), 'ssh.dll')
utils.ensure_file_exists(out_file_lib)
utils.ensure_file_exists(out_file_dll)
def _build_jsoncpp(self, file_name): def _build_jsoncpp(self, file_name):
cc.n('prepare jsoncpp source code... ', end='') cc.n('prepare jsoncpp source code... ', end='')
@ -245,8 +272,8 @@ class BuilderWin(BuilderBase):
# fix source file # fix source file
utils.ensure_file_exists(os.path.join(PATH_EXTERNAL, 'fix-external', 'mbedtls', 'include', 'mbedtls', 'config.h')) utils.ensure_file_exists(os.path.join(PATH_EXTERNAL, 'fix-external', 'mbedtls', 'include', 'mbedtls', 'config.h'))
utils.copy_file(os.path.join(PATH_EXTERNAL, 'fix-external', 'mbedtls', 'include', 'mbedtls'), os.path.join(self.MBEDTLS_PATH_SRC, 'include', 'mbedtls'), 'config.h') utils.copy_file(os.path.join(PATH_EXTERNAL, 'fix-external', 'mbedtls', 'include', 'mbedtls'), os.path.join(self.MBEDTLS_PATH_SRC, 'include', 'mbedtls'), 'config.h')
utils.ensure_file_exists(os.path.join(PATH_EXTERNAL, 'fix-external', 'mbedtls', 'library', 'rsa.c')) # utils.ensure_file_exists(os.path.join(PATH_EXTERNAL, 'fix-external', 'mbedtls', 'library', 'rsa.c'))
utils.copy_file(os.path.join(PATH_EXTERNAL, 'fix-external', 'mbedtls', 'library'), os.path.join(self.MBEDTLS_PATH_SRC, 'library'), 'rsa.c') # utils.copy_file(os.path.join(PATH_EXTERNAL, 'fix-external', 'mbedtls', 'library'), os.path.join(self.MBEDTLS_PATH_SRC, 'library'), 'rsa.c')
def _build_libuv(self, file_name): def _build_libuv(self, file_name):
cc.n('prepare libuv source code... ', end='') cc.n('prepare libuv source code... ', end='')
@ -272,7 +299,7 @@ class BuilderLinux(BuilderBase):
def _init_path(self): def _init_path(self):
self.PATH_TMP = os.path.join(PATH_EXTERNAL, 'linux', 'tmp') self.PATH_TMP = os.path.join(PATH_EXTERNAL, 'linux', 'tmp')
self.PATH_RELEASE = os.path.join(PATH_EXTERNAL, 'linux', 'release') self.PATH_RELEASE = os.path.join(PATH_EXTERNAL, 'linux', 'release')
# self.OPENSSL_PATH_SRC = os.path.join(self.PATH_TMP, 'openssl-{}'.format(env.ver_openssl)) # self.OPENSSL_PATH_SRC = os.path.join(self.PATH_TMP, 'openssl-{}'.format(env.ver_ossl))
self.LIBUV_PATH_SRC = os.path.join(self.PATH_TMP, 'libuv-{}'.format(env.ver_libuv)) self.LIBUV_PATH_SRC = os.path.join(self.PATH_TMP, 'libuv-{}'.format(env.ver_libuv))
self.MBEDTLS_PATH_SRC = os.path.join(self.PATH_TMP, 'mbedtls-mbedtls-{}'.format(env.ver_mbedtls)) self.MBEDTLS_PATH_SRC = os.path.join(self.PATH_TMP, 'mbedtls-mbedtls-{}'.format(env.ver_mbedtls))
self.LIBSSH_PATH_SRC = os.path.join(self.PATH_TMP, 'libssh-{}'.format(env.ver_libssh)) self.LIBSSH_PATH_SRC = os.path.join(self.PATH_TMP, 'libssh-{}'.format(env.ver_libssh))
@ -322,8 +349,8 @@ class BuilderLinux(BuilderBase):
else: else:
cc.w('already exists, skip.') cc.w('already exists, skip.')
# def _build_openssl(self, file_name): def _build_openssl(self, file_name):
# pass # we do not need build openssl anymore, because first time run build.sh we built Python, it include openssl. pass # we do not need build openssl anymore, because first time run build.sh we built Python, it include openssl.
def _build_libuv(self, file_name): def _build_libuv(self, file_name):
if not os.path.exists(self.LIBUV_PATH_SRC): if not os.path.exists(self.LIBUV_PATH_SRC):
@ -570,8 +597,8 @@ class BuilderMacOS(BuilderBase):
else: else:
cc.w('already exists, skip.') cc.w('already exists, skip.')
# def _build_openssl(self, file_name): def _build_openssl(self, file_name):
# # we do not need build openssl anymore, because first time run build.sh we built Python, it include openssl. pass # we do not need build openssl anymore, because first time run build.sh we built Python, it include openssl.
# #
# if not os.path.exists(self.OPENSSL_PATH_SRC): # if not os.path.exists(self.OPENSSL_PATH_SRC):
# os.system('tar -zxvf "{}/{}" -C "{}"'.format(PATH_DOWNLOAD, file_name, self.PATH_TMP)) # os.system('tar -zxvf "{}/{}" -C "{}"'.format(PATH_DOWNLOAD, file_name, self.PATH_TMP))
@ -797,7 +824,7 @@ def main():
builder.build_jsoncpp() builder.build_jsoncpp()
builder.build_mongoose() builder.build_mongoose()
# builder.build_openssl() builder.build_openssl()
builder.build_libuv() builder.build_libuv()
builder.build_mbedtls() builder.build_mbedtls()
builder.build_libssh() builder.build_libssh()

View File

@ -12,12 +12,13 @@ from core.env import env
ctx = BuildContext() ctx = BuildContext()
MODULES_WIN = ['_bz2', '_ctypes', '_hashlib', '_lzma', '_overlapped', '_socket', '_sqlite3', '_ssl', 'select', 'sqlite3', 'unicodedata'] MODULES_WIN = ['_asyncio', '_bz2', '_ctypes', '_hashlib', '_lzma', '_overlapped', '_socket', '_sqlite3', '_ssl', 'select', 'sqlite3',
'libcrypto-1_1', 'libssl-1_1', 'unicodedata']
PY_LIB_REMOVE_WIN = ['ctypes/test', 'curses', 'dbm', 'distutils', 'email/test', 'ensurepip', 'idlelib', 'lib2to3', PY_LIB_REMOVE_WIN = ['ctypes/test', 'curses', 'dbm', 'distutils', 'email/test', 'ensurepip', 'idlelib', 'lib2to3',
'lib-dynload', 'pydoc_data', 'site-packages', 'sqlite3/test', 'test', 'tkinter', 'turtledemo', 'lib-dynload', 'pydoc_data', 'site-packages', 'sqlite3/test', 'test', 'tkinter', 'turtledemo',
'unittest', 'venv', 'wsgiref', 'dis.py', 'doctest.py', 'pdb.py', 'py_compile.py', 'pydoc.py', 'unittest', 'venv', 'wsgiref', 'dis.py', 'doctest.py', 'pdb.py', 'py_compile.py', 'pydoc.py',
'this.py', 'wave.py', 'webbrowser.py', 'zipapp.py'] 'this.py', 'wave.py', 'webbrowser.py', 'zipapp.py']
PY_LIB_REMOVE_LINUX = ['ctypes/test', 'curses', 'config-3.7m-x86_64-linux-gnu', 'dbm', 'distutils', 'ensurepip', 'idlelib', 'lib2to3', PY_LIB_REMOVE_LINUX = ['ctypes/test', 'curses', 'dbm', 'distutils', 'ensurepip', 'idlelib', 'lib2to3',
'lib-dynload', 'pydoc_data', 'site-packages', 'sqlite3/test', 'test', 'tkinter', 'turtledemo', 'unittest', 'venv', 'lib-dynload', 'pydoc_data', 'site-packages', 'sqlite3/test', 'test', 'tkinter', 'turtledemo', 'unittest', 'venv',
'wsgiref', 'dis.py', 'doctest.py', 'pdb.py', 'py_compile.py', 'pydoc_data', 'pydoc.py', 'this.py', 'wave.py', 'wsgiref', 'dis.py', 'doctest.py', 'pdb.py', 'py_compile.py', 'pydoc_data', 'pydoc.py', 'this.py', 'wave.py',
'webbrowser.py', 'zipapp.py'] 'webbrowser.py', 'zipapp.py']
@ -150,23 +151,24 @@ class PYSWin(PYSBase):
utils.makedirs(self.base_path) utils.makedirs(self.base_path)
cc.v('copy python core dll...') cc.v('copy python core dll...')
_win_system_path = os.path.join(os.getenv('SystemRoot'), 'system32') _exec_path = os.path.dirname(env.py_exec)
if ctx.bits == BITS_32 and ctx.host_os_is_win_x64: # _win_system_path = os.path.join(os.getenv('SystemRoot'), 'system32')
_win_system_path = os.path.join(os.getenv('SystemRoot'), 'SysWOW64') # if ctx.bits == BITS_32 and ctx.host_os_is_win_x64:
# _win_system_path = os.path.join(os.getenv('SystemRoot'), 'SysWOW64')
if not os.path.exists(_win_system_path): if not os.path.exists(_exec_path):
raise RuntimeError('can not locate windows system folder at:', _win_system_path) raise RuntimeError('can not locate python folder at:', _exec_path)
pydll = self._get_py_dll_name() pydll = self._get_py_dll_name()
shutil.copy(os.path.join(_win_system_path, pydll), os.path.join(self.base_path, pydll)) shutil.copy(os.path.join(_exec_path, pydll), os.path.join(self.base_path, pydll))
if ctx.py_ver == '34': if ctx.py_ver == '34':
msvcrdll = 'msvcr100.dll' msvcrdll = 'msvcr100.dll'
elif ctx.py_ver == '37': elif ctx.py_ver == '37':
msvcrdll = 'msvcr140.dll' msvcrdll = 'vcruntime140.dll'
else: else:
raise RuntimeError('unknown msvc runtime for this python version.') raise RuntimeError('unknown msvc runtime for this python version.')
shutil.copy(os.path.join(_win_system_path, msvcrdll), os.path.join(self.base_path, msvcrdll)) shutil.copy(os.path.join(_exec_path, msvcrdll), os.path.join(self.base_path, msvcrdll))
super()._copy_modules() super()._copy_modules()

View File

@ -49,6 +49,7 @@ class BuilderWin(BuilderBase):
utils.remove(out_file) utils.remove(out_file)
utils.msvc_build(sln_file, 'tpssh', ctx.target_path, ctx.bits_path, False) utils.msvc_build(sln_file, 'tpssh', ctx.target_path, ctx.bits_path, False)
utils.ensure_file_exists(out_file) utils.ensure_file_exists(out_file)
utils.copy_file(os.path.join(env.root_path, 'external', 'libssh', 'lib', ctx.target_path), os.path.join(env.root_path, 'out', 'server', ctx.bits_path, ctx.target_path), 'ssh.dll')
cc.n('build TELNET protocol ...') cc.n('build TELNET protocol ...')
sln_file = os.path.join(env.root_path, 'server', 'tp_core', 'protocol', 'telnet', 'tptelnet.vs2015.sln') sln_file = os.path.join(env.root_path, 'server', 'tp_core', 'protocol', 'telnet', 'tptelnet.vs2015.sln')

View File

@ -59,6 +59,7 @@ class BuildContext(object):
if self.host_os == 'windows': if self.host_os == 'windows':
self.host_os_is_win_x64 = 'PROGRAMFILES(X86)' in os.environ self.host_os_is_win_x64 = 'PROGRAMFILES(X86)' in os.environ
self.dist_path = ''
self.make_dist_path() self.make_dist_path()
def make_dist_path(self): def make_dist_path(self):

View File

@ -24,11 +24,15 @@ class Env(object):
self.root_path = os.path.abspath(os.path.join(_this_path, '..', '..', '..')) self.root_path = os.path.abspath(os.path.join(_this_path, '..', '..', '..'))
self.build_path = os.path.abspath(os.path.join(_this_path, '..', '..')) self.build_path = os.path.abspath(os.path.join(_this_path, '..', '..'))
self.builder_path = os.path.join(self.build_path, 'builder') self.builder_path = os.path.join(self.build_path, 'builder')
self.win32_tools_path = os.path.join(self.build_path, 'tools', 'win32')
self.is_py2 = sys.version_info[0] == 2 self.is_py2 = sys.version_info[0] == 2
self.is_py3 = sys.version_info[0] == 3 self.is_py3 = sys.version_info[0] == 3
if self.is_py2:
self.input = raw_input
else:
self.input = input
self.py_ver = platform.python_version_tuple() self.py_ver = platform.python_version_tuple()
self.py_ver_str = '%s%s' % (self.py_ver[0], self.py_ver[1]) self.py_ver_str = '%s%s' % (self.py_ver[0], self.py_ver[1])
self.py_ver_dot = '%s.%s' % (self.py_ver[0], self.py_ver[1]) self.py_ver_dot = '%s.%s' % (self.py_ver[0], self.py_ver[1])
@ -53,19 +57,9 @@ class Env(object):
self.is_win = True self.is_win = True
self.plat = 'windows' self.plat = 'windows'
self.is_win_x64 = 'PROGRAMFILES(X86)' in os.environ self.is_win_x64 = 'PROGRAMFILES(X86)' in os.environ
self.path_miniconda = os.path.abspath(os.path.dirname(self.py_exec))
self.path_ossl_inc = os.path.join(self.path_miniconda, 'Library', 'include')
self.path_ossl_lib = os.path.join(self.path_miniconda, 'Library', 'lib')
self.path_py_inc = os.path.join(self.path_miniconda, 'include')
self.path_py_lib = os.path.join(self.path_miniconda, 'libs')
elif _os == 'linux': elif _os == 'linux':
self.is_linux = True self.is_linux = True
self.plat = 'linux' self.plat = 'linux'
self.path_miniconda = os.path.abspath(os.path.join(os.path.dirname(self.py_exec), '..'))
self.path_ossl_inc = os.path.join(self.path_miniconda, 'include')
self.path_ossl_lib = os.path.join(self.path_miniconda, 'lib')
self.path_py_inc = os.path.join(self.path_miniconda, 'include', 'python{}m'.format(self.py_ver_dot))
self.path_py_lib = os.path.join(self.path_miniconda, 'lib')
elif _os == 'darwin': elif _os == 'darwin':
self.is_macos = True self.is_macos = True
self.plat = 'macos' self.plat = 'macos'
@ -77,16 +71,12 @@ class Env(object):
if not self._load_version(): if not self._load_version():
return False return False
if not os.path.exists(os.path.join(self.path_miniconda, 'conda-meta')):
cc.e('can not find conda, please install miniconda from https://conda.io/miniconda.html and try again.')
return False
return True return True
def _load_config(self, warn_miss_tool): def _load_config(self, warn_miss_tool):
_cfg_file = os.path.join(self.root_path, 'config.ini') _cfg_file = os.path.join(self.root_path, 'config.ini')
if not os.path.exists(_cfg_file): if not os.path.exists(_cfg_file):
cc.e('can not load configuration.\n\nplease copy `config.ini.in` into `config.ini` and modify it to fit your condition and try again.') cc.e('can not load configuration.\n\nplease copy `config.ini.in` to `config.ini` and modify it to fit your condition and try again.')
return False return False
_cfg = configparser.ConfigParser() _cfg = configparser.ConfigParser()

View File

@ -1,953 +0,0 @@
/*
* session.c - non-networking functions
*
* This file is part of the SSH Library
*
* Copyright (c) 2005-2013 by Aris Adamantiadis
*
* The SSH Library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or (at your
* option) any later version.
*
* The SSH Library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the SSH Library; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*/
#include "config.h"
#include <string.h>
#include <stdlib.h>
#include "libssh/priv.h"
#include "libssh/libssh.h"
#include "libssh/crypto.h"
#include "libssh/server.h"
#include "libssh/socket.h"
#ifdef WITH_SSH1
#include "libssh/ssh1.h"
#endif /* WITH_SSH1 */
#include "libssh/ssh2.h"
#include "libssh/agent.h"
#include "libssh/packet.h"
#include "libssh/session.h"
#include "libssh/misc.h"
#include "libssh/buffer.h"
#include "libssh/poll.h"
#define FIRST_CHANNEL 42 // why not ? it helps to find bugs.
/**
* @defgroup libssh_session The SSH session functions.
* @ingroup libssh
*
* Functions that manage a session.
*
* @{
*/
/**
* @brief Create a new ssh session.
*
* @returns A new ssh_session pointer, NULL on error.
*/
ssh_session ssh_new(void) {
ssh_session session;
char *id = NULL;
int rc;
session = malloc(sizeof (struct ssh_session_struct));
if (session == NULL) {
return NULL;
}
ZERO_STRUCTP(session);
session->next_crypto = crypto_new();
if (session->next_crypto == NULL) {
goto err;
}
session->socket = ssh_socket_new(session);
if (session->socket == NULL) {
goto err;
}
session->out_buffer = ssh_buffer_new();
if (session->out_buffer == NULL) {
goto err;
}
session->in_buffer=ssh_buffer_new();
if (session->in_buffer == NULL) {
goto err;
}
session->alive = 0;
session->auth_methods = 0;
ssh_set_blocking(session, 1);
session->maxchannel = FIRST_CHANNEL;
#ifndef _WIN32
session->agent = agent_new(session);
if (session->agent == NULL) {
goto err;
}
#endif /* _WIN32 */
/* OPTIONS */
session->opts.StrictHostKeyChecking = 1;
session->opts.port = 0;
session->opts.fd = -1;
session->opts.ssh2 = 1;
session->opts.compressionlevel=7;
#ifdef WITH_SSH1
session->opts.ssh1 = 1;
#else
session->opts.ssh1 = 0;
#endif
session->opts.identity = ssh_list_new();
if (session->opts.identity == NULL) {
goto err;
}
id = strdup("%d/id_ed25519");
if (id == NULL) {
goto err;
}
rc = ssh_list_append(session->opts.identity, id);
if (rc == SSH_ERROR) {
goto err;
}
#ifdef HAVE_ECC
id = strdup("%d/id_ecdsa");
if (id == NULL) {
goto err;
}
rc = ssh_list_append(session->opts.identity, id);
if (rc == SSH_ERROR) {
goto err;
}
#endif
id = strdup("%d/id_rsa");
if (id == NULL) {
goto err;
}
rc = ssh_list_append(session->opts.identity, id);
if (rc == SSH_ERROR) {
goto err;
}
id = strdup("%d/id_dsa");
if (id == NULL) {
goto err;
}
rc = ssh_list_append(session->opts.identity, id);
if (rc == SSH_ERROR) {
goto err;
}
id = strdup("%d/identity");
if (id == NULL) {
goto err;
}
rc = ssh_list_append(session->opts.identity, id);
if (rc == SSH_ERROR) {
goto err;
}
return session;
err:
free(id);
ssh_free(session);
return NULL;
}
/**
* @brief Deallocate a SSH session handle.
*
* @param[in] session The SSH session to free.
*
* @see ssh_disconnect()
* @see ssh_new()
*/
void ssh_free(ssh_session session) {
int i;
struct ssh_iterator *it;
if (session == NULL) {
return;
}
/*
* Delete all channels
*
* This needs the first thing we clean up cause if there is still an open
* channel we call ssh_channel_close() first. So we need a working socket
* and poll context for it.
*/
for (it = ssh_list_get_iterator(session->channels);
it != NULL;
it = ssh_list_get_iterator(session->channels)) {
ssh_channel_do_free(ssh_iterator_value(ssh_channel,it));
ssh_list_remove(session->channels, it);
}
ssh_list_free(session->channels);
session->channels = NULL;
#ifdef WITH_PCAP
if (session->pcap_ctx) {
ssh_pcap_context_free(session->pcap_ctx);
session->pcap_ctx = NULL;
}
#endif
ssh_socket_free(session->socket);
session->socket = NULL;
if (session->default_poll_ctx) {
ssh_poll_ctx_free(session->default_poll_ctx);
}
ssh_buffer_free(session->in_buffer);
ssh_buffer_free(session->out_buffer);
session->in_buffer = session->out_buffer = NULL;
if (session->in_hashbuf != NULL) {
ssh_buffer_free(session->in_hashbuf);
}
if (session->out_hashbuf != NULL) {
ssh_buffer_free(session->out_hashbuf);
}
crypto_free(session->current_crypto);
crypto_free(session->next_crypto);
#ifndef _WIN32
agent_free(session->agent);
#endif /* _WIN32 */
ssh_key_free(session->srv.dsa_key);
session->srv.dsa_key = NULL;
ssh_key_free(session->srv.rsa_key);
session->srv.rsa_key = NULL;
ssh_key_free(session->srv.ecdsa_key);
session->srv.ecdsa_key = NULL;
ssh_key_free(session->srv.ed25519_key);
session->srv.ed25519_key = NULL;
if (session->ssh_message_list) {
ssh_message msg;
for (msg = ssh_list_pop_head(ssh_message, session->ssh_message_list);
msg != NULL;
msg = ssh_list_pop_head(ssh_message, session->ssh_message_list)) {
ssh_message_free(msg);
}
ssh_list_free(session->ssh_message_list);
}
if (session->packet_callbacks) {
ssh_list_free(session->packet_callbacks);
}
/* options */
if (session->opts.identity) {
char *id;
for (id = ssh_list_pop_head(char *, session->opts.identity);
id != NULL;
id = ssh_list_pop_head(char *, session->opts.identity)) {
SAFE_FREE(id);
}
ssh_list_free(session->opts.identity);
}
#ifndef _WIN32
ssh_agent_state_free (session->agent_state);
#endif
session->agent_state = NULL;
SAFE_FREE(session->auth_auto_state);
SAFE_FREE(session->serverbanner);
SAFE_FREE(session->clientbanner);
SAFE_FREE(session->banner);
SAFE_FREE(session->opts.bindaddr);
SAFE_FREE(session->opts.custombanner);
SAFE_FREE(session->opts.username);
SAFE_FREE(session->opts.host);
SAFE_FREE(session->opts.sshdir);
SAFE_FREE(session->opts.knownhosts);
SAFE_FREE(session->opts.ProxyCommand);
SAFE_FREE(session->opts.gss_server_identity);
SAFE_FREE(session->opts.gss_client_identity);
for (i = 0; i < 10; i++) {
if (session->opts.wanted_methods[i]) {
SAFE_FREE(session->opts.wanted_methods[i]);
}
}
/* burn connection, it could contain sensitive data */
BURN_BUFFER(session, sizeof(struct ssh_session_struct));
SAFE_FREE(session);
}
/**
* @brief get the client banner
*
* @param[in] session The SSH session
*
* @return Returns the client banner string or NULL.
*/
const char* ssh_get_clientbanner(ssh_session session) {
if (session == NULL) {
return NULL;
}
return session->clientbanner;
}
/**
* @brief get the server banner
*
* @param[in] session The SSH session
*
* @return Returns the server banner string or NULL.
*/
const char* ssh_get_serverbanner(ssh_session session) {
if(!session) {
return NULL;
}
return session->serverbanner;
}
/**
* @brief get the name of the current key exchange algorithm.
*
* @param[in] session The SSH session
*
* @return Returns the key exchange algorithm string or NULL.
*/
const char* ssh_get_kex_algo(ssh_session session) {
if ((session == NULL) ||
(session->current_crypto == NULL)) {
return NULL;
}
switch (session->current_crypto->kex_type) {
case SSH_KEX_DH_GROUP1_SHA1:
return "diffie-hellman-group1-sha1";
case SSH_KEX_DH_GROUP14_SHA1:
return "diffie-hellman-group14-sha1";
case SSH_KEX_ECDH_SHA2_NISTP256:
return "ecdh-sha2-nistp256";
case SSH_KEX_CURVE25519_SHA256_LIBSSH_ORG:
return "curve25519-sha256@libssh.org";
default:
break;
}
return NULL;
}
/**
* @brief get the name of the input cipher for the given session.
*
* @param[in] session The SSH session.
*
* @return Returns cipher name or NULL.
*/
const char* ssh_get_cipher_in(ssh_session session) {
if ((session != NULL) &&
(session->current_crypto != NULL) &&
(session->current_crypto->in_cipher != NULL)) {
return session->current_crypto->in_cipher->name;
}
return NULL;
}
/**
* @brief get the name of the output cipher for the given session.
*
* @param[in] session The SSH session.
*
* @return Returns cipher name or NULL.
*/
const char* ssh_get_cipher_out(ssh_session session) {
if ((session != NULL) &&
(session->current_crypto != NULL) &&
(session->current_crypto->out_cipher != NULL)) {
return session->current_crypto->out_cipher->name;
}
return NULL;
}
/**
* @brief get the name of the input HMAC algorithm for the given session.
*
* @param[in] session The SSH session.
*
* @return Returns HMAC algorithm name or NULL if unknown.
*/
const char* ssh_get_hmac_in(ssh_session session) {
if ((session != NULL) &&
(session->current_crypto != NULL)) {
return ssh_hmac_type_to_string(session->current_crypto->in_hmac);
}
return NULL;
}
/**
* @brief get the name of the output HMAC algorithm for the given session.
*
* @param[in] session The SSH session.
*
* @return Returns HMAC algorithm name or NULL if unknown.
*/
const char* ssh_get_hmac_out(ssh_session session) {
if ((session != NULL) &&
(session->current_crypto != NULL)) {
return ssh_hmac_type_to_string(session->current_crypto->out_hmac);
}
return NULL;
}
/**
* @brief Disconnect impolitely from a remote host by closing the socket.
*
* Suitable if you forked and want to destroy this session.
*
* @param[in] session The SSH session to disconnect.
*/
void ssh_silent_disconnect(ssh_session session) {
if (session == NULL) {
return;
}
ssh_socket_close(session->socket);
session->alive = 0;
ssh_disconnect(session);
}
/**
* @brief Set the session in blocking/nonblocking mode.
*
* @param[in] session The ssh session to change.
*
* @param[in] blocking Zero for nonblocking mode.
*/
void ssh_set_blocking(ssh_session session, int blocking) {
if (session == NULL) {
return;
}
session->flags &= ~SSH_SESSION_FLAG_BLOCKING;
session->flags |= blocking ? SSH_SESSION_FLAG_BLOCKING : 0;
}
/**
* @brief Return the blocking mode of libssh
* @param[in] session The SSH session
* @returns 0 if the session is nonblocking,
* @returns 1 if the functions may block.
*/
int ssh_is_blocking(ssh_session session){
return (session->flags&SSH_SESSION_FLAG_BLOCKING) ? 1 : 0;
}
/* Waits until the output socket is empty */
static int ssh_flush_termination(void *c){
ssh_session session = c;
if (ssh_socket_buffered_write_bytes(session->socket) == 0 ||
session->session_state == SSH_SESSION_STATE_ERROR)
return 1;
else
return 0;
}
/**
* @brief Blocking flush of the outgoing buffer
* @param[in] session The SSH session
* @param[in] timeout Set an upper limit on the time for which this function
* will block, in milliseconds. Specifying -1
* means an infinite timeout. This parameter is passed to
* the poll() function.
* @returns SSH_OK on success, SSH_AGAIN if timeout occurred,
* SSH_ERROR otherwise.
*/
int ssh_blocking_flush(ssh_session session, int timeout){
int rc;
if (session == NULL) {
return SSH_ERROR;
}
rc = ssh_handle_packets_termination(session, timeout,
ssh_flush_termination, session);
if (rc == SSH_ERROR) {
return rc;
}
if (!ssh_flush_termination(session)) {
rc = SSH_AGAIN;
}
return rc;
}
/**
* @brief Check if we are connected.
*
* @param[in] session The session to check if it is connected.
*
* @return 1 if we are connected, 0 if not.
*/
int ssh_is_connected(ssh_session session) {
if (session == NULL) {
return 0;
}
return session->alive;
}
/**
* @brief Get the fd of a connection.
*
* In case you'd need the file descriptor of the connection to the server/client.
*
* @param[in] session The ssh session to use.
*
* @return The file descriptor of the connection, or -1 if it is
* not connected
*/
socket_t ssh_get_fd(ssh_session session) {
if (session == NULL) {
return -1;
}
return ssh_socket_get_fd_in(session->socket);
}
/**
* @brief Tell the session it has data to read on the file descriptor without
* blocking.
*
* @param[in] session The ssh session to use.
*/
void ssh_set_fd_toread(ssh_session session) {
if (session == NULL) {
return;
}
ssh_socket_set_read_wontblock(session->socket);
}
/**
* @brief Tell the session it may write to the file descriptor without blocking.
*
* @param[in] session The ssh session to use.
*/
void ssh_set_fd_towrite(ssh_session session) {
if (session == NULL) {
return;
}
ssh_socket_set_write_wontblock(session->socket);
}
/**
* @brief Tell the session it has an exception to catch on the file descriptor.
*
* \param[in] session The ssh session to use.
*/
void ssh_set_fd_except(ssh_session session) {
if (session == NULL) {
return;
}
ssh_socket_set_except(session->socket);
}
/**
* @internal
*
* @brief Poll the current session for an event and call the appropriate
* callbacks. This function will not loop until the timeout is expired.
*
* This will block until one event happens.
*
* @param[in] session The session handle to use.
*
* @param[in] timeout Set an upper limit on the time for which this function
* will block, in milliseconds. Specifying SSH_TIMEOUT_INFINITE
* (-1) means an infinite timeout.
* Specifying SSH_TIMEOUT_USER means to use the timeout
* specified in options. 0 means poll will return immediately.
* This parameter is passed to the poll() function.
*
* @return SSH_OK on success, SSH_ERROR otherwise.
*/
int ssh_handle_packets(ssh_session session, int timeout) {
ssh_poll_handle spoll_in,spoll_out;
ssh_poll_ctx ctx;
int tm = timeout;
int rc;
if (session == NULL || session->socket == NULL) {
return SSH_ERROR;
}
spoll_in = ssh_socket_get_poll_handle_in(session->socket);
spoll_out = ssh_socket_get_poll_handle_out(session->socket);
ssh_poll_add_events(spoll_in, POLLIN);
ctx = ssh_poll_get_ctx(spoll_in);
if (!ctx) {
ctx = ssh_poll_get_default_ctx(session);
ssh_poll_ctx_add(ctx, spoll_in);
if (spoll_in != spoll_out) {
ssh_poll_ctx_add(ctx, spoll_out);
}
}
if (timeout == SSH_TIMEOUT_USER) {
if (ssh_is_blocking(session))
tm = ssh_make_milliseconds(session->opts.timeout,
session->opts.timeout_usec);
else
tm = 0;
}
rc = ssh_poll_ctx_dopoll(ctx, tm);
if (rc == SSH_ERROR) {
session->session_state = SSH_SESSION_STATE_ERROR;
}
return rc;
}
/**
* @internal
*
* @brief Poll the current session for an event and call the appropriate
* callbacks.
*
* This will block until termination function returns true, or timeout expired.
*
* @param[in] session The session handle to use.
*
* @param[in] timeout Set an upper limit on the time for which this function
* will block, in milliseconds. Specifying SSH_TIMEOUT_INFINITE
* (-1) means an infinite timeout.
* Specifying SSH_TIMEOUT_USER means to use the timeout
* specified in options. 0 means poll will return immediately.
* SSH_TIMEOUT_DEFAULT uses blocking parameters of the session.
* This parameter is passed to the poll() function.
*
* @param[in] fct Termination function to be used to determine if it is
* possible to stop polling.
* @param[in] user User parameter to be passed to fct termination function.
* @return SSH_OK on success, SSH_ERROR otherwise.
*/
int ssh_handle_packets_termination(ssh_session session,
int timeout,
ssh_termination_function fct,
void *user)
{
struct ssh_timestamp ts;
int ret = SSH_OK;
int tm;
if (timeout == SSH_TIMEOUT_USER) {
if (ssh_is_blocking(session)) {
timeout = ssh_make_milliseconds(session->opts.timeout,
session->opts.timeout_usec);
} else {
timeout = SSH_TIMEOUT_NONBLOCKING;
}
} else if (timeout == SSH_TIMEOUT_DEFAULT) {
if (ssh_is_blocking(session)) {
// Apex.
// timeout = SSH_TIMEOUT_INFINITE;
timeout = ssh_make_milliseconds(session->opts.timeout,
session->opts.timeout_usec);
} else {
timeout = SSH_TIMEOUT_NONBLOCKING;
}
}
/* avoid unnecessary syscall for the SSH_TIMEOUT_NONBLOCKING case */
if (timeout != SSH_TIMEOUT_NONBLOCKING) {
ssh_timestamp_init(&ts);
}
tm = timeout;
while(!fct(user)) {
ret = ssh_handle_packets(session, tm);
if (ret == SSH_ERROR) {
break;
}
if (ssh_timeout_elapsed(&ts,timeout)) {
ret = fct(user) ? SSH_OK : SSH_AGAIN;
break;
}
tm = ssh_timeout_update(&ts, timeout);
}
return ret;
}
/**
* @brief Get session status
*
* @param session The ssh session to use.
*
* @returns A bitmask including SSH_CLOSED, SSH_READ_PENDING, SSH_WRITE_PENDING
* or SSH_CLOSED_ERROR which respectively means the session is closed,
* has data to read on the connection socket and session was closed
* due to an error.
*/
int ssh_get_status(ssh_session session) {
int socketstate;
int r = 0;
if (session == NULL) {
return 0;
}
socketstate = ssh_socket_get_status(session->socket);
if (session->session_state == SSH_SESSION_STATE_DISCONNECTED) {
r |= SSH_CLOSED;
}
if (socketstate & SSH_READ_PENDING) {
r |= SSH_READ_PENDING;
}
if (socketstate & SSH_WRITE_PENDING) {
r |= SSH_WRITE_PENDING;
}
if ((session->session_state == SSH_SESSION_STATE_DISCONNECTED &&
(socketstate & SSH_CLOSED_ERROR)) ||
session->session_state == SSH_SESSION_STATE_ERROR) {
r |= SSH_CLOSED_ERROR;
}
return r;
}
/**
* @brief Get poll flags for an external mainloop
*
* @param session The ssh session to use.
*
* @returns A bitmask including SSH_READ_PENDING or SSH_WRITE_PENDING.
* For SSH_READ_PENDING, your invocation of poll() should include
* POLLIN. For SSH_WRITE_PENDING, your invocation of poll() should
* include POLLOUT.
*/
int ssh_get_poll_flags(ssh_session session)
{
if (session == NULL) {
return 0;
}
return ssh_socket_get_poll_flags (session->socket);
}
/**
* @brief Get the disconnect message from the server.
*
* @param[in] session The ssh session to use.
*
* @return The message sent by the server along with the
* disconnect, or NULL in which case the reason of the
* disconnect may be found with ssh_get_error.
*
* @see ssh_get_error()
*/
const char *ssh_get_disconnect_message(ssh_session session) {
if (session == NULL) {
return NULL;
}
if (session->session_state != SSH_SESSION_STATE_DISCONNECTED) {
ssh_set_error(session, SSH_REQUEST_DENIED,
"Connection not closed yet");
} else if(!session->discon_msg) {
ssh_set_error(session, SSH_FATAL,
"Connection correctly closed but no disconnect message");
} else {
return session->discon_msg;
}
return NULL;
}
/**
* @brief Get the protocol version of the session.
*
* @param session The ssh session to use.
*
* @return 1 or 2, for ssh1 or ssh2, < 0 on error.
*/
int ssh_get_version(ssh_session session) {
if (session == NULL) {
return -1;
}
return session->version;
}
/**
* @internal
* @brief Callback to be called when the socket received an exception code.
* @param user is a pointer to session
*/
void ssh_socket_exception_callback(int code, int errno_code, void *user){
ssh_session session=(ssh_session)user;
SSH_LOG(SSH_LOG_RARE,"Socket exception callback: %d (%d)",code, errno_code);
session->session_state = SSH_SESSION_STATE_ERROR;
if (errno_code == 0 && code == SSH_SOCKET_EXCEPTION_EOF) {
ssh_set_error(session, SSH_FATAL, "Socket error: disconnected");
} else {
ssh_set_error(session, SSH_FATAL, "Socket error: %s", strerror(errno_code));
}
session->ssh_connection_callback(session);
}
/**
* @brief Send a message that should be ignored
*
* @param[in] session The SSH session
* @param[in] data Data to be sent
*
* @return SSH_OK on success, SSH_ERROR otherwise.
*/
int ssh_send_ignore (ssh_session session, const char *data) {
#ifdef WITH_SSH1
const int type = session->version == 1 ? SSH_MSG_IGNORE : SSH2_MSG_IGNORE;
#else /* WITH_SSH1 */
const int type = SSH2_MSG_IGNORE;
#endif /* WITH_SSH1 */
int rc;
if (ssh_socket_is_open(session->socket)) {
rc = ssh_buffer_pack(session->out_buffer,
"bs",
type,
data);
if (rc != SSH_OK){
ssh_set_error_oom(session);
goto error;
}
packet_send(session);
ssh_handle_packets(session, 0);
}
return SSH_OK;
error:
ssh_buffer_reinit(session->out_buffer);
return SSH_ERROR;
}
/**
* @brief Send a debug message
*
* @param[in] session The SSH session
* @param[in] message Data to be sent
* @param[in] always_display Message SHOULD be displayed by the server. It
* SHOULD NOT be displayed unless debugging
* information has been explicitly requested.
*
* @return SSH_OK on success, SSH_ERROR otherwise.
*/
int ssh_send_debug (ssh_session session, const char *message, int always_display) {
int rc;
if (ssh_socket_is_open(session->socket)) {
#ifdef WITH_SSH1
if (session->version == 1) {
rc = ssh_buffer_pack(session->out_buffer,
"bs",
SSH_MSG_DEBUG,
message);
} else
#endif /* WITH_SSH1 */
{
rc = ssh_buffer_pack(session->out_buffer,
"bbsd",
SSH2_MSG_DEBUG,
always_display != 0 ? 1 : 0,
message,
0); /* empty language tag */
}
if (rc != SSH_OK) {
ssh_set_error_oom(session);
goto error;
}
packet_send(session);
ssh_handle_packets(session, 0);
}
return SSH_OK;
error:
ssh_buffer_reinit(session->out_buffer);
return SSH_ERROR;
}
/**
* @brief Set the session data counters.
*
* This functions sets the counter structures to be used to calculate data
* which comes in and goes out through the session at different levels.
*
* @code
* struct ssh_counter_struct scounter = {
* .in_bytes = 0,
* .out_bytes = 0,
* .in_packets = 0,
* .out_packets = 0
* };
*
* struct ssh_counter_struct rcounter = {
* .in_bytes = 0,
* .out_bytes = 0,
* .in_packets = 0,
* .out_packets = 0
* };
*
* ssh_set_counters(session, &scounter, &rcounter);
* @endcode
*
* @param[in] session The SSH session.
*
* @param[in] scounter Counter for byte data handled by the session sockets.
*
* @param[in] rcounter Counter for byte and packet data handled by the session,
* prior compression and SSH overhead.
*/
void ssh_set_counters(ssh_session session, ssh_counter scounter,
ssh_counter rcounter) {
if (session != NULL) {
session->socket_counter = scounter;
session->raw_counter = rcounter;
}
}
/** @} */
/* vim: set ts=4 sw=4 et cindent: */

3368
external/fix-external/libssh/src/sftp.c vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,7 @@
openssl = 1.0.2p,1000210f openssl = 1.0.2p,1000210f
libuv = 1.23.0 libuv = 1.23.0
mbedtls = 2.12.0 mbedtls = 2.12.0
libssh = 0.7.5 libssh = 0.8.2
jsoncpp = 0.10.6 jsoncpp = 0.10.6
mongoose = 6.12 mongoose = 6.12

View File

@ -1,2 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<module classpath="CMake" type="CPP_MODULE" version="4" /> <module classpath="CMake" type="CPP_MODULE" version="4" />

View File

@ -11,9 +11,9 @@
#ifdef EX_OS_WIN32 #ifdef EX_OS_WIN32
# ifdef EX_DEBUG # ifdef EX_DEBUG
# pragma comment(lib, "libsshMTd.lib") # pragma comment(lib, "..\\..\\..\\..\\external\\libssh\\lib\\debug\\ssh.lib")
# else # else
# pragma comment(lib, "libsshMT.lib") # pragma comment(lib, "..\\..\\..\\..\\external\\libssh\\lib\\release\\ssh.lib")
# endif # endif
# pragma comment(lib, "libeay32.lib") # pragma comment(lib, "libeay32.lib")
# pragma comment(lib, "ws2_32.lib") # pragma comment(lib, "ws2_32.lib")