mirror of
https://git.libssh.org/projects/libssh.git
synced 2026-02-05 04:40:31 +09:00
Compare commits
96 Commits
release-0-
...
v0-4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
75dc5939ed | ||
|
|
4d85f7b1e5 | ||
|
|
b7db87c817 | ||
|
|
eb49bf4bfd | ||
|
|
f6c31db3fc | ||
|
|
bef014b7a9 | ||
|
|
e6d17ccc15 | ||
|
|
0b0a2d85d0 | ||
|
|
8d7245f54b | ||
|
|
0b1f8a2b0c | ||
|
|
8d676c77b1 | ||
|
|
b1a65dd25f | ||
|
|
e78cc89b52 | ||
|
|
f6586576fb | ||
|
|
3797ca0ec6 | ||
|
|
bfe59d0cdd | ||
|
|
4362d76416 | ||
|
|
da3b2d68a3 | ||
|
|
4638b353d5 | ||
|
|
a9f3a2f103 | ||
|
|
59f0293576 | ||
|
|
7a314d9149 | ||
|
|
a13c9d4182 | ||
|
|
93f79c62ef | ||
|
|
31fdb4ecf6 | ||
|
|
0b564c358f | ||
|
|
fb24e68edd | ||
|
|
b5f095d0b4 | ||
|
|
62f7eaf156 | ||
|
|
2462b0fbc7 | ||
|
|
c05666245c | ||
|
|
6db13f776f | ||
|
|
0980117c52 | ||
|
|
3d66164545 | ||
|
|
c087e8704d | ||
|
|
e5801287da | ||
|
|
5b9d92c36f | ||
|
|
edc6b2cef2 | ||
|
|
9590a643ab | ||
|
|
bec9bc1222 | ||
|
|
b3067e362c | ||
|
|
5f99fed07c | ||
|
|
9973de535e | ||
|
|
a7d9f4addd | ||
|
|
a4f4fa3058 | ||
|
|
a9c4877d84 | ||
|
|
284466632e | ||
|
|
aa8381999a | ||
|
|
ac54a26c5d | ||
|
|
fd53ebc7b6 | ||
|
|
df2436b4a6 | ||
|
|
7029d2f4b8 | ||
|
|
3c9c358385 | ||
|
|
82d1627cad | ||
|
|
641e89b14a | ||
|
|
3a61d55f27 | ||
|
|
c4d1d8b684 | ||
|
|
10e27f26be | ||
|
|
9791bc3eeb | ||
|
|
4ad7828797 | ||
|
|
af8315b9ce | ||
|
|
94fdcf7a2a | ||
|
|
59a95fc3a7 | ||
|
|
c1729c36d9 | ||
|
|
23efab0f8f | ||
|
|
e50752a925 | ||
|
|
fd45c1b36b | ||
|
|
5080671581 | ||
|
|
e67fafd60f | ||
|
|
a2a98fb5bc | ||
|
|
e2480fbaba | ||
|
|
23e6b36209 | ||
|
|
541b38b772 | ||
|
|
a85a4cc192 | ||
|
|
54ef77123a | ||
|
|
4c679fd8a6 | ||
|
|
21d918c68a | ||
|
|
544fc28e6b | ||
|
|
601081ebb6 | ||
|
|
22d975a24b | ||
|
|
aeb9f3e389 | ||
|
|
d3a4e01137 | ||
|
|
a1b9ae5048 | ||
|
|
a375ebe29b | ||
|
|
b2f49a6a93 | ||
|
|
99fb5987ce | ||
|
|
be389dd644 | ||
|
|
a6a7922dbd | ||
|
|
608e81bc00 | ||
|
|
7e17838c0b | ||
|
|
84f6945a9c | ||
|
|
3ae187dbe7 | ||
|
|
26989ab001 | ||
|
|
5b2e39cd79 | ||
|
|
13af149ef9 | ||
|
|
3453cafd95 |
@@ -8,7 +8,7 @@ set(APPLICATION_NAME ${PROJECT_NAME})
|
||||
|
||||
set(APPLICATION_VERSION_MAJOR "0")
|
||||
set(APPLICATION_VERSION_MINOR "4")
|
||||
set(APPLICATION_VERSION_PATCH "3")
|
||||
set(APPLICATION_VERSION_PATCH "8")
|
||||
|
||||
set(APPLICATION_VERSION "${APPLICATION_VERSION_MAJOR}.${APPLICATION_VERSION_MINOR}.${APPLICATION_VERSION_PATCH}")
|
||||
|
||||
@@ -19,7 +19,7 @@ set(APPLICATION_VERSION "${APPLICATION_VERSION_MAJOR}.${APPLICATION_VERSION_MINO
|
||||
# Increment AGE. Set REVISION to 0
|
||||
# If the source code was changed, but there were no interface changes:
|
||||
# Increment REVISION.
|
||||
set(LIBRARY_VERSION "4.1.0")
|
||||
set(LIBRARY_VERSION "4.1.4")
|
||||
set(LIBRARY_SOVERSION "4")
|
||||
|
||||
# where to look first for cmake modules, before ${CMAKE_ROOT}/Modules/ is checked
|
||||
@@ -30,6 +30,7 @@ set(CMAKE_MODULE_PATH
|
||||
# add definitions
|
||||
include(DefineCMakeDefaults)
|
||||
include(DefineCompilerFlags)
|
||||
include(DefinePlatformDefaults)
|
||||
include(DefineInstallationPaths)
|
||||
include(DefineOptions.cmake)
|
||||
include(CPackConfig.cmake)
|
||||
|
||||
@@ -13,7 +13,7 @@ set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/COPYING")
|
||||
### versions
|
||||
set(CPACK_PACKAGE_VERSION_MAJOR "0")
|
||||
set(CPACK_PACKAGE_VERSION_MINOR "4")
|
||||
set(CPACK_PACKAGE_VERSION_PATCH "3")
|
||||
set(CPACK_PACKAGE_VERSION_PATCH "8")
|
||||
set(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}")
|
||||
|
||||
|
||||
@@ -22,16 +22,21 @@ set(CPACK_SOURCE_GENERATOR "TGZ")
|
||||
set(CPACK_SOURCE_IGNORE_FILES "~$;[.]swp$;/[.]svn/;/[.]git/;.gitignore;/build/;tags;cscope.*")
|
||||
set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}")
|
||||
|
||||
if (WIN32)
|
||||
set(CPACK_GENERATOR "ZIP")
|
||||
|
||||
### nsis generator
|
||||
set(CPACK_GENERATOR "NSIS")
|
||||
### nsis generator
|
||||
find_package(NSIS)
|
||||
if (HAVE_NSIS)
|
||||
set(CPACK_GENERATOR "${CPACK_GENERATOR};NSIS")
|
||||
set(CPACK_NSIS_DISPLAY_NAME "The SSH Library")
|
||||
set(CPACK_NSIS_COMPRESSOR "/SOLID zlib")
|
||||
set(CPACK_NSIS_MENU_LINKS "http://www.libssh.org/" "libssh homepage")
|
||||
endif (HAVE_NSIS)
|
||||
endif (WIN32)
|
||||
|
||||
set(CPACK_PACKAGE_INSTALL_DIRECTORY "libssh")
|
||||
|
||||
set(CPACK_NSIS_DISPLAY_NAME "The SSH Library")
|
||||
set(CPACK_NSIS_COMPRESSOR "/SOLID zlib")
|
||||
set(CPACK_NSIS_MENU_LINKS "http://www.libssh.org/" "libssh homepage")
|
||||
|
||||
set(CPACK_PACKAGE_FILE_NAME ${APPLICATION_NAME}-${CPACK_PACKAGE_VERSION})
|
||||
|
||||
set(CPACK_COMPONENT_LIBRARIES_DISPLAY_NAME "Libraries")
|
||||
|
||||
41
ChangeLog
41
ChangeLog
@@ -1,6 +1,47 @@
|
||||
ChangeLog
|
||||
==========
|
||||
|
||||
version 0.4.8 (released 2011-01-15)
|
||||
* Fixed memory leaks in session signing.
|
||||
* Fixed memory leak in ssh_print_hexa.
|
||||
* Fixed problem with ssh_connect w/ timeout and fd > 1024.
|
||||
* Fixed some warnings on OS/2.
|
||||
* Fixed installation path for OS/2.
|
||||
|
||||
version 0.4.7 (released 2010-12-28)
|
||||
* Fixed a possible memory leak in ssh_get_user_home().
|
||||
* Fixed a memory leak in sftp_xstat.
|
||||
* Fixed uninitialized fd->revents member.
|
||||
* Fixed timout value in ssh_channel_accept().
|
||||
* Fixed length checks in ssh_analyze_banner().
|
||||
* Fixed a possible data overread and crash bug.
|
||||
* Fixed setting max_fd which breaks ssh_select().
|
||||
* Fixed some pedantic build warnings.
|
||||
* Fixed a memory leak with session->bindaddr.
|
||||
|
||||
version 0.4.6 (released 2010-09-03)
|
||||
* Added a cleanup function to free the ws2_32 library.
|
||||
* Fixed build with gcc 3.4.
|
||||
* Fixed the Windows build on Vista and newer.
|
||||
* Fixed the usage of WSAPoll() on Windows.
|
||||
* Fixed "@deprecated" in doxygen
|
||||
* Fixed some mingw warnings.
|
||||
* Fixed handling of opened channels.
|
||||
* Fixed keepalive problem on older openssh servers.
|
||||
* Fixed testing for big endian on Windows.
|
||||
* Fixed the Windows preprocessor macros and defines.
|
||||
|
||||
version 0.4.5 (released 2010-07-13)
|
||||
* Added option to bind a client to an ip address.
|
||||
* Fixed the ssh socket polling function.
|
||||
* Fixed Windows related bugs in bsd_poll().
|
||||
* Fixed serveral build warnings.
|
||||
|
||||
version 0.4.4 (released 2010-06-01)
|
||||
* Fixed a bug in the expand function for escape sequences.
|
||||
* Fixed a bug in the tilde expand function.
|
||||
* Fixed a bug in setting the options.
|
||||
|
||||
version 0.4.3 (released 2010-05-18)
|
||||
* Added global/keepalive responses.
|
||||
* Added runtime detection of WSAPoll().
|
||||
|
||||
@@ -17,14 +17,31 @@ set(SYSCONFDIR ${SYSCONF_INSTALL_DIR})
|
||||
set(BINARYDIR ${CMAKE_BINARY_DIR})
|
||||
set(SOURCEDIR ${CMAKE_SOURCE_DIR})
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCC)
|
||||
check_c_compiler_flag("-fvisibility=hidden" WITH_VISIBILITY_HIDDEN)
|
||||
endif(CMAKE_COMPILER_IS_GNUCC)
|
||||
function(COMPILER_DUMPVERSION _OUTPUT_VERSION)
|
||||
execute_process(
|
||||
COMMAND
|
||||
${CMAKE_C_COMPILER} ${CMAKE_C_COMPILER_ARG1} -dumpversion
|
||||
OUTPUT_VARIABLE _COMPILER_VERSION
|
||||
)
|
||||
|
||||
string(REGEX REPLACE "([0-9])\\.([0-9])(\\.[0-9])?" "\\1\\2"
|
||||
_COMPILER_VERSION "${_COMPILER_VERSION}")
|
||||
|
||||
set(${_OUTPUT_VERSION} ${_COMPILER_VERSION} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCC AND NOT MINGW AND NOT OS2)
|
||||
compiler_dumpversion(GNUCC_VERSION)
|
||||
if (NOT GNUCC_VERSION EQUAL 34)
|
||||
check_c_compiler_flag("-fvisibility=hidden" WITH_VISIBILITY_HIDDEN)
|
||||
endif (NOT GNUCC_VERSION EQUAL 34)
|
||||
endif(CMAKE_COMPILER_IS_GNUCC AND NOT MINGW AND NOT OS2)
|
||||
|
||||
# HEADER FILES
|
||||
check_include_file(argp.h HAVE_ARGP_H)
|
||||
check_include_file(pty.h HAVE_PTY_H)
|
||||
check_include_file(terminos.h HAVE_TERMIOS_H)
|
||||
check_include_file(termios.h HAVE_TERMIOS_H)
|
||||
|
||||
if (WIN32)
|
||||
check_include_files("winsock2.h;ws2tcpip.h;wspiapi.h" HAVE_WSPIAPI_H)
|
||||
if (NOT HAVE_WSPIAPI_H)
|
||||
@@ -39,18 +56,6 @@ if (WIN32)
|
||||
set(HAVE_GETHOSTBYNAME TRUE)
|
||||
endif (HAVE_WSPIAPI_H OR HAVE_WS2TCPIP_H)
|
||||
|
||||
check_function_exists(vsnprintf HAVE_VSNPRINTF)
|
||||
if(NOT HAVE_VSNPRINTF)
|
||||
check_function_exists(_vsnprintf_s HAVE__VSNPRINTF_S)
|
||||
check_function_exists(_vsnprintf HAVE__VSNPRINTF)
|
||||
endif(NOT HAVE_VSNPRINTF)
|
||||
check_function_exists(snprintf HAVE_SNPRINTF)
|
||||
if(NOT HAVE_SNPRINTF)
|
||||
check_function_exists(_snprintf HAVE__SNPRINTF)
|
||||
check_function_exists(_snprintf_s HAVE__SNPRINTF_S)
|
||||
endif(NOT HAVE_SNPRINTF)
|
||||
check_function_exists(strncpy HAVE_STRNCPY)
|
||||
|
||||
set(HAVE_SELECT TRUE)
|
||||
endif (WIN32)
|
||||
|
||||
@@ -65,6 +70,17 @@ check_include_file(openssl/des.h HAVE_OPENSSL_DES_H)
|
||||
|
||||
# FUNCTIONS
|
||||
|
||||
check_function_exists(strncpy HAVE_STRNCPY)
|
||||
check_function_exists(vsnprintf HAVE_VSNPRINTF)
|
||||
check_function_exists(snprintf HAVE_SNPRINTF)
|
||||
|
||||
if (WIN32)
|
||||
check_function_exists(_vsnprintf_s HAVE__VSNPRINTF_S)
|
||||
check_function_exists(_vsnprintf HAVE__VSNPRINTF)
|
||||
check_function_exists(_snprintf HAVE__SNPRINTF)
|
||||
check_function_exists(_snprintf_s HAVE__SNPRINTF_S)
|
||||
endif (WIN32)
|
||||
|
||||
if (UNIX)
|
||||
# libsocket (Solaris)
|
||||
check_library_exists(socket getaddrinfo "" HAVE_LIBSOCKET)
|
||||
@@ -120,4 +136,6 @@ if (WITH_DEBUG_CALLTRACE)
|
||||
endif (WITH_DEBUG_CALLTRACE)
|
||||
|
||||
# ENDIAN
|
||||
test_big_endian(WORDS_BIGENDIAN)
|
||||
if (NOT WIN32)
|
||||
test_big_endian(WORDS_BIGENDIAN)
|
||||
endif (NOT WIN32)
|
||||
|
||||
@@ -1,4 +1,15 @@
|
||||
if (UNIX)
|
||||
if (WIN32)
|
||||
# Same same
|
||||
set(BIN_INSTALL_DIR "bin" CACHE PATH "-")
|
||||
set(SBIN_INSTALL_DIR "." CACHE PATH "-")
|
||||
set(LIB_INSTALL_DIR "lib" CACHE PATH "-")
|
||||
set(INCLUDE_INSTALL_DIR "include" CACHE PATH "-")
|
||||
set(PLUGIN_INSTALL_DIR "plugins" CACHE PATH "-")
|
||||
set(HTML_INSTALL_DIR "doc/HTML" CACHE PATH "-")
|
||||
set(ICON_INSTALL_DIR "." CACHE PATH "-")
|
||||
set(SOUND_INSTALL_DIR "." CACHE PATH "-")
|
||||
set(LOCALE_INSTALL_DIR "lang" CACHE PATH "-")
|
||||
elseif (UNIX OR OS2)
|
||||
IF (NOT APPLICATION_NAME)
|
||||
MESSAGE(STATUS "${PROJECT_NAME} is used as APPLICATION_NAME")
|
||||
SET(APPLICATION_NAME ${PROJECT_NAME})
|
||||
@@ -90,18 +101,4 @@ if (UNIX)
|
||||
"${SHARE_INSTALL_PREFIX}/info"
|
||||
CACHE PATH "The ${APPLICATION_NAME} info install dir (default prefix/info)"
|
||||
)
|
||||
endif (UNIX)
|
||||
|
||||
if (WIN32)
|
||||
# Same same
|
||||
set(BIN_INSTALL_DIR "bin" CACHE PATH "-")
|
||||
set(SBIN_INSTALL_DIR "." CACHE PATH "-")
|
||||
set(LIB_INSTALL_DIR "lib" CACHE PATH "-")
|
||||
set(INCLUDE_INSTALL_DIR "include" CACHE PATH "-")
|
||||
set(PLUGIN_INSTALL_DIR "plugins" CACHE PATH "-")
|
||||
set(HTML_INSTALL_DIR "doc/HTML" CACHE PATH "-")
|
||||
set(ICON_INSTALL_DIR "." CACHE PATH "-")
|
||||
set(SOUND_INSTALL_DIR "." CACHE PATH "-")
|
||||
set(LOCALE_INSTALL_DIR "lang" CACHE PATH "-")
|
||||
endif (WIN32)
|
||||
|
||||
endif ()
|
||||
|
||||
25
cmake/Modules/DefinePlatformDefaults.cmake
Normal file
25
cmake/Modules/DefinePlatformDefaults.cmake
Normal file
@@ -0,0 +1,25 @@
|
||||
# Set system vars
|
||||
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
set(LINUX TRUE)
|
||||
endif(CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
|
||||
set(FREEBSD TRUE)
|
||||
endif (CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
|
||||
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "OpenBSD")
|
||||
set(OPENBSD TRUE)
|
||||
endif (CMAKE_SYSTEM_NAME MATCHES "OpenBSD")
|
||||
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "NetBSD")
|
||||
set(NETBSD TRUE)
|
||||
endif (CMAKE_SYSTEM_NAME MATCHES "NetBSD")
|
||||
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "(Solaris|SunOS)")
|
||||
set(SOLARIS TRUE)
|
||||
endif (CMAKE_SYSTEM_NAME MATCHES "(Solaris|SunOS)")
|
||||
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "OS2")
|
||||
set(OS2 TRUE)
|
||||
endif (CMAKE_SYSTEM_NAME MATCHES "OS2")
|
||||
31
cmake/Modules/FindNSIS.cmake
Normal file
31
cmake/Modules/FindNSIS.cmake
Normal file
@@ -0,0 +1,31 @@
|
||||
# - Try to find NSIS
|
||||
# Once done this will define
|
||||
#
|
||||
# NSIS_FOUND - system has NSIS
|
||||
# NSIS_MAKE - NSIS creator executable
|
||||
#
|
||||
# Copyright (c) 2010 Andreas Schneider <mail@cynapses.org>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the New
|
||||
# BSD license.
|
||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||
#
|
||||
|
||||
if (NSIS_MAKE)
|
||||
# in cache already
|
||||
set(NSIS_FOUND TRUE)
|
||||
elseif (NSIS_MAKE)
|
||||
find_program(NSIS_MAKE
|
||||
NAMES
|
||||
makensis
|
||||
PATHS
|
||||
${_NSIS_DIR}
|
||||
${_NSIS_DIR}/Bin
|
||||
$ENV{PROGRAMFILES}/NSIS
|
||||
)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(NSIS DEFAULT_MSG NSIS_MAKE)
|
||||
|
||||
mark_as_advanced(NSIS_MAKE)
|
||||
endif (NSIS_MAKE)
|
||||
@@ -18,6 +18,10 @@ if (OPENSSL_LIBRARIES AND OPENSSL_INCLUDE_DIRS)
|
||||
# in cache already
|
||||
set(OPENSSL_FOUND TRUE)
|
||||
else (OPENSSL_LIBRARIES AND OPENSSL_INCLUDE_DIRS)
|
||||
if (WIN32)
|
||||
set(_OPENSSL_DIR $ENV{PROGRAMFILES}/OpenSSL)
|
||||
endif (WIN32)
|
||||
|
||||
# use pkg-config to get the directories and then use these values
|
||||
# in the FIND_PATH() and FIND_LIBRARY() calls
|
||||
if (${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} EQUAL 4)
|
||||
@@ -48,6 +52,7 @@ else (OPENSSL_LIBRARIES AND OPENSSL_INCLUDE_DIRS)
|
||||
find_library(SSL_LIBRARY
|
||||
NAMES
|
||||
ssl
|
||||
ssl_dl
|
||||
libssl
|
||||
PATHS
|
||||
${_OPENSSL_DIR}/lib
|
||||
@@ -97,6 +102,7 @@ else (OPENSSL_LIBRARIES AND OPENSSL_INCLUDE_DIRS)
|
||||
find_library(CRYPTO_LIBRARY
|
||||
NAMES
|
||||
crypto
|
||||
crypto_dl
|
||||
libcrypto
|
||||
eay
|
||||
eay32
|
||||
|
||||
@@ -18,6 +18,9 @@ if (ZLIB_LIBRARIES AND ZLIB_INCLUDE_DIRS)
|
||||
# in cache already
|
||||
set(ZLIB_FOUND TRUE)
|
||||
else (ZLIB_LIBRARIES AND ZLIB_INCLUDE_DIRS)
|
||||
if (WIN32)
|
||||
set(_ZLIB_DIR $ENV{PROGRAMFILES}/GnuWin32)
|
||||
endif (WIN32)
|
||||
|
||||
find_path(ZLIB_INCLUDE_DIR
|
||||
NAMES
|
||||
|
||||
@@ -37,27 +37,36 @@
|
||||
|
||||
/*************************** FUNCTIONS ***************************/
|
||||
|
||||
/* Define to 1 if you have the `vsnprintf' function. */
|
||||
#cmakedefine HAVE_VSNPRINTF
|
||||
|
||||
/* Define to 1 if you have the `_vsnprintf' function. */
|
||||
#cmakedefine HAVE__VSNPRINTF
|
||||
|
||||
/* Define to 1 if you have the `_vsnprintf_s' function. */
|
||||
#cmakedefine HAVE__VSNPRINTF_S
|
||||
|
||||
/* Define to 1 if you have the `snprintf' function. */
|
||||
#cmakedefine HAVE_SNPRINTF
|
||||
#cmakedefine HAVE_SNPRINTF 1
|
||||
|
||||
/* Define to 1 if you have the `_snprintf' function. */
|
||||
#cmakedefine HAVE__SNPRINTF
|
||||
#cmakedefine HAVE__SNPRINTF 1
|
||||
|
||||
/* Define to 1 if you have the `_snprintf_s' function. */
|
||||
#cmakedefine HAVE__SNPRINTF_S
|
||||
#cmakedefine HAVE__SNPRINTF_S 1
|
||||
|
||||
/* Define to 1 if you have the `vsnprintf' function. */
|
||||
#cmakedefine HAVE_VSNPRINTF 1
|
||||
|
||||
/* Define to 1 if you have the `_vsnprintf' function. */
|
||||
#cmakedefine HAVE__VSNPRINTF 1
|
||||
|
||||
/* Define to 1 if you have the `_vsnprintf_s' function. */
|
||||
#cmakedefine HAVE__VSNPRINTF_S 1
|
||||
|
||||
/* Define to 1 if you have the `snprintf' function. */
|
||||
#cmakedefine HAVE_SNPRINTF 1
|
||||
|
||||
/* Define to 1 if you have the `_snprintf' function. */
|
||||
#cmakedefine HAVE__SNPRINTF 1
|
||||
|
||||
/* Define to 1 if you have the `_snprintf_s' function. */
|
||||
#cmakedefine HAVE__SNPRINTF_S 1
|
||||
|
||||
|
||||
/* Define to 1 if you have the `strncpy' function. */
|
||||
#cmakedefine HAVE_STRNCPY
|
||||
#cmakedefine HAVE_STRNCPY 1
|
||||
|
||||
/* Define to 1 if you have the `cfmakeraw' function. */
|
||||
#cmakedefine HAVE_CFMAKERAW 1
|
||||
@@ -116,17 +125,3 @@
|
||||
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
|
||||
significant byte first (like Motorola and SPARC, unlike Intel). */
|
||||
#cmakedefine WORDS_BIGENDIAN 1
|
||||
|
||||
/************************* MS Windows ***************************/
|
||||
|
||||
#ifdef _WIN32
|
||||
# ifdef _MSC_VER
|
||||
/* On Microsoft compilers define inline to __inline on all others use inline */
|
||||
# undef inline
|
||||
# define inline __inline
|
||||
|
||||
# undef strdup
|
||||
# define strdup _strdup
|
||||
# endif // _MSC_VER
|
||||
#endif /* _WIN32 */
|
||||
|
||||
|
||||
1520
doc/doxy.config.in
1520
doc/doxy.config.in
File diff suppressed because it is too large
Load Diff
@@ -15,11 +15,14 @@ add_executable(libssh_scp libssh_scp.c ${examples_SRCS})
|
||||
add_executable(scp_download scp_download.c ${examples_SRCS})
|
||||
add_executable(samplessh sample.c ${examples_SRCS})
|
||||
add_executable(exec exec.c ${examples_SRCS})
|
||||
add_executable(sshnetcat sshnetcat.c ${examples_SRCS})
|
||||
|
||||
target_link_libraries(libssh_scp ${LIBSSH_SHARED_LIBRARY})
|
||||
target_link_libraries(scp_download ${LIBSSH_SHARED_LIBRARY})
|
||||
target_link_libraries(samplessh ${LIBSSH_SHARED_LIBRARY})
|
||||
target_link_libraries(exec ${LIBSSH_SHARED_LIBRARY})
|
||||
target_link_libraries(sshnetcat ${LIBSSH_SHARED_LIBRARY})
|
||||
|
||||
|
||||
include_directories(
|
||||
${LIBSSH_PUBLIC_INCLUDE_DIRS}
|
||||
|
||||
247
examples/sshnetcat.c
Normal file
247
examples/sshnetcat.c
Normal file
@@ -0,0 +1,247 @@
|
||||
/*
|
||||
Copyright 2010 Aris Adamantiadis
|
||||
|
||||
This file is part of the SSH Library
|
||||
|
||||
You are free to copy this file, modify it in any way, consider it being public
|
||||
domain. This does not apply to the rest of the library though, but it is
|
||||
allowed to cut-and-paste working code from this file to any license of
|
||||
program.
|
||||
The goal is to show the API in action. It's not a reference on how terminal
|
||||
clients must be made or how a client should react.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include <sys/select.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <errno.h>
|
||||
#include <libssh/callbacks.h>
|
||||
#include <libssh/libssh.h>
|
||||
#include <libssh/sftp.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "examples_common.h"
|
||||
char *host;
|
||||
const char *desthost="localhost";
|
||||
const char *port="22";
|
||||
|
||||
#ifdef WITH_PCAP
|
||||
#include <libssh/pcap.h>
|
||||
char *pcap_file=NULL;
|
||||
#endif
|
||||
|
||||
static void usage(){
|
||||
fprintf(stderr,"Usage : sshnetcat [user@]host forwarded_host forwarded_port\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static int opts(int argc, char **argv){
|
||||
int i;
|
||||
while((i=getopt(argc,argv,"P:"))!=-1){
|
||||
switch(i){
|
||||
#ifdef WITH_PCAP
|
||||
case 'P':
|
||||
pcap_file=optarg;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
fprintf(stderr,"unknown option %c\n",optopt);
|
||||
usage();
|
||||
}
|
||||
}
|
||||
if(optind < argc)
|
||||
host=argv[optind++];
|
||||
if(optind < argc)
|
||||
desthost=argv[optind++];
|
||||
if(optind < argc)
|
||||
port=argv[optind++];
|
||||
if(host==NULL)
|
||||
usage();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void select_loop(ssh_session session,ssh_channel channel){
|
||||
fd_set fds;
|
||||
struct timeval timeout;
|
||||
char buffer[4096];
|
||||
/* channels will be set to the channels to poll.
|
||||
* outchannels will contain the result of the poll
|
||||
*/
|
||||
ssh_channel channels[2], outchannels[2];
|
||||
int lus;
|
||||
int eof=0;
|
||||
int maxfd;
|
||||
int ret;
|
||||
while(channel){
|
||||
do{
|
||||
FD_ZERO(&fds);
|
||||
if(!eof)
|
||||
FD_SET(0,&fds);
|
||||
timeout.tv_sec=30;
|
||||
timeout.tv_usec=0;
|
||||
FD_SET(ssh_get_fd(session),&fds);
|
||||
maxfd=ssh_get_fd(session)+1;
|
||||
channels[0]=channel; // set the first channel we want to read from
|
||||
channels[1]=NULL;
|
||||
ret=ssh_select(channels,outchannels,maxfd,&fds,&timeout);
|
||||
if(ret==EINTR)
|
||||
continue;
|
||||
if(FD_ISSET(0,&fds)){
|
||||
lus=read(0,buffer,sizeof(buffer));
|
||||
if(lus)
|
||||
channel_write(channel,buffer,lus);
|
||||
else {
|
||||
eof=1;
|
||||
channel_send_eof(channel);
|
||||
}
|
||||
}
|
||||
if(channel && channel_is_closed(channel)){
|
||||
ssh_log(session,SSH_LOG_RARE,"exit-status : %d\n",channel_get_exit_status(channel));
|
||||
|
||||
channel_free(channel);
|
||||
channel=NULL;
|
||||
channels[0]=NULL;
|
||||
}
|
||||
if(outchannels[0]){
|
||||
while(channel && channel_is_open(channel) && channel_poll(channel,0)){
|
||||
lus=channel_read(channel,buffer,sizeof(buffer),0);
|
||||
if(lus==-1){
|
||||
fprintf(stderr, "Error reading channel: %s\n",
|
||||
ssh_get_error(session));
|
||||
return;
|
||||
}
|
||||
if(lus==0){
|
||||
ssh_log(session,SSH_LOG_RARE,"EOF received\n");
|
||||
ssh_log(session,SSH_LOG_RARE,"exit-status : %d\n",channel_get_exit_status(channel));
|
||||
|
||||
channel_free(channel);
|
||||
channel=channels[0]=NULL;
|
||||
} else
|
||||
write(1,buffer,lus);
|
||||
}
|
||||
while(channel && channel_is_open(channel) && channel_poll(channel,1)){ /* stderr */
|
||||
lus=channel_read(channel,buffer,sizeof(buffer),1);
|
||||
if(lus==-1){
|
||||
fprintf(stderr, "Error reading channel: %s\n",
|
||||
ssh_get_error(session));
|
||||
return;
|
||||
}
|
||||
if(lus==0){
|
||||
ssh_log(session,SSH_LOG_RARE,"EOF received\n");
|
||||
ssh_log(session,SSH_LOG_RARE,"exit-status : %d\n",channel_get_exit_status(channel));
|
||||
channel_free(channel);
|
||||
channel=channels[0]=NULL;
|
||||
} else
|
||||
write(2,buffer,lus);
|
||||
}
|
||||
}
|
||||
if(channel && channel_is_closed(channel)){
|
||||
channel_free(channel);
|
||||
channel=NULL;
|
||||
}
|
||||
} while (ret==EINTR || ret==SSH_EINTR);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static void forwarding(ssh_session session){
|
||||
ssh_channel channel;
|
||||
int r;
|
||||
channel=channel_new(session);
|
||||
r=channel_open_forward(channel,desthost,atoi(port),"localhost",22);
|
||||
if(r<0) {
|
||||
printf("error forwarding port : %s\n",ssh_get_error(session));
|
||||
return;
|
||||
}
|
||||
select_loop(session,channel);
|
||||
}
|
||||
|
||||
static int client(ssh_session session){
|
||||
int auth=0;
|
||||
char *banner;
|
||||
int state;
|
||||
|
||||
if (ssh_options_set(session, SSH_OPTIONS_HOST ,host) < 0)
|
||||
return -1;
|
||||
ssh_options_parse_config(session, NULL);
|
||||
|
||||
if(ssh_connect(session)){
|
||||
fprintf(stderr,"Connection failed : %s\n",ssh_get_error(session));
|
||||
return -1;
|
||||
}
|
||||
state=verify_knownhost(session);
|
||||
if (state != 0)
|
||||
return -1;
|
||||
ssh_userauth_none(session, NULL);
|
||||
banner=ssh_get_issue_banner(session);
|
||||
if(banner){
|
||||
printf("%s\n",banner);
|
||||
free(banner);
|
||||
}
|
||||
auth=authenticate_console(session);
|
||||
if(auth != SSH_AUTH_SUCCESS){
|
||||
return -1;
|
||||
}
|
||||
ssh_log(session, SSH_LOG_FUNCTIONS, "Authentication success");
|
||||
forwarding(session);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef WITH_PCAP
|
||||
ssh_pcap_file pcap;
|
||||
void set_pcap(ssh_session session);
|
||||
void set_pcap(ssh_session session){
|
||||
if(!pcap_file)
|
||||
return;
|
||||
pcap=ssh_pcap_file_new();
|
||||
if(ssh_pcap_file_open(pcap,pcap_file) == SSH_ERROR){
|
||||
printf("Error opening pcap file\n");
|
||||
ssh_pcap_file_free(pcap);
|
||||
pcap=NULL;
|
||||
return;
|
||||
}
|
||||
ssh_set_pcap_file(session,pcap);
|
||||
}
|
||||
|
||||
void cleanup_pcap(void);
|
||||
void cleanup_pcap(){
|
||||
ssh_pcap_file_free(pcap);
|
||||
pcap=NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
int main(int argc, char **argv){
|
||||
ssh_session session;
|
||||
|
||||
session = ssh_new();
|
||||
|
||||
if(ssh_options_getopt(session, &argc, argv)) {
|
||||
fprintf(stderr, "error parsing command line :%s\n",
|
||||
ssh_get_error(session));
|
||||
usage();
|
||||
}
|
||||
opts(argc,argv);
|
||||
#ifdef WITH_PCAP
|
||||
set_pcap(session);
|
||||
#endif
|
||||
client(session);
|
||||
|
||||
ssh_disconnect(session);
|
||||
ssh_free(session);
|
||||
#ifdef WITH_PCAP
|
||||
cleanup_pcap();
|
||||
#endif
|
||||
|
||||
ssh_finalize();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -33,6 +33,11 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @addtogroup ssh_session
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief SSH authentication callback.
|
||||
*
|
||||
@@ -110,4 +115,6 @@ LIBSSH_API int ssh_set_callbacks(ssh_session session, ssh_callbacks cb);
|
||||
}
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /*_SSH_CALLBACK_H */
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
#endif
|
||||
#endif
|
||||
#else
|
||||
#if __GNUC__ >= 4
|
||||
#if __GNUC__ >= 4 && !defined(__OS2__)
|
||||
#define LIBSSH_API __attribute__((visibility("default")))
|
||||
#else
|
||||
#define LIBSSH_API
|
||||
@@ -79,7 +79,7 @@
|
||||
/* libssh version */
|
||||
#define LIBSSH_VERSION_MAJOR 0
|
||||
#define LIBSSH_VERSION_MINOR 4
|
||||
#define LIBSSH_VERSION_MICRO 3
|
||||
#define LIBSSH_VERSION_MICRO 8
|
||||
|
||||
#define LIBSSH_VERSION_INT SSH_VERSION_INT(LIBSSH_VERSION_MAJOR, \
|
||||
LIBSSH_VERSION_MINOR, \
|
||||
@@ -119,10 +119,16 @@ typedef struct ssh_string_struct* ssh_string;
|
||||
|
||||
/* Socket type */
|
||||
#ifdef _WIN32
|
||||
#define socket_t SOCKET
|
||||
#else
|
||||
#ifndef socket_t
|
||||
typedef SOCKET socket_t;
|
||||
#endif /* socket_t */
|
||||
#else /* _WIN32 */
|
||||
#ifndef socket_t
|
||||
typedef int socket_t;
|
||||
#endif
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#define SSH_INVALID_SOCKET ((socket_t) -1)
|
||||
|
||||
/* the offsets of methods */
|
||||
enum ssh_kex_types_e {
|
||||
@@ -165,7 +171,7 @@ enum ssh_requests_e {
|
||||
SSH_REQUEST_CHANNEL_OPEN,
|
||||
SSH_REQUEST_CHANNEL,
|
||||
SSH_REQUEST_SERVICE,
|
||||
SSH_REQUEST_GLOBAL,
|
||||
SSH_REQUEST_GLOBAL
|
||||
};
|
||||
|
||||
enum ssh_channel_type_e {
|
||||
@@ -183,7 +189,7 @@ enum ssh_channel_requests_e {
|
||||
SSH_CHANNEL_REQUEST_SHELL,
|
||||
SSH_CHANNEL_REQUEST_ENV,
|
||||
SSH_CHANNEL_REQUEST_SUBSYSTEM,
|
||||
SSH_CHANNEL_REQUEST_WINDOW_CHANGE,
|
||||
SSH_CHANNEL_REQUEST_WINDOW_CHANGE
|
||||
};
|
||||
|
||||
/* status flags */
|
||||
@@ -197,7 +203,7 @@ enum ssh_server_known_e {
|
||||
SSH_SERVER_KNOWN_OK,
|
||||
SSH_SERVER_KNOWN_CHANGED,
|
||||
SSH_SERVER_FOUND_OTHER,
|
||||
SSH_SERVER_FILE_NOT_FOUND,
|
||||
SSH_SERVER_FILE_NOT_FOUND
|
||||
};
|
||||
|
||||
#ifndef MD5_DIGEST_LEN
|
||||
@@ -265,7 +271,8 @@ enum ssh_options_e {
|
||||
SSH_OPTIONS_CIPHERS_S_C,
|
||||
SSH_OPTIONS_COMPRESSION_C_S,
|
||||
SSH_OPTIONS_COMPRESSION_S_C,
|
||||
SSH_OPTIONS_PROXYCOMMAND
|
||||
SSH_OPTIONS_PROXYCOMMAND,
|
||||
SSH_OPTIONS_BINDADDR
|
||||
};
|
||||
|
||||
enum {
|
||||
|
||||
@@ -38,6 +38,45 @@ typedef struct ssh_pollfd_struct {
|
||||
short revents; /* returned events */
|
||||
} ssh_pollfd_t;
|
||||
|
||||
typedef unsigned long int nfds_t;
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#ifndef POLLRDNORM
|
||||
#define POLLRDNORM 0x0100
|
||||
#endif
|
||||
#ifndef POLLRDBAND
|
||||
#define POLLRDBAND 0x0200
|
||||
#endif
|
||||
#ifndef POLLIN
|
||||
#define POLLIN (POLLRDNORM | POLLRDBAND)
|
||||
#endif
|
||||
#ifndef POLLPRI
|
||||
#define POLLPRI 0x0400
|
||||
#endif
|
||||
|
||||
#ifndef POLLWRNORM
|
||||
#define POLLWRNORM 0x0010
|
||||
#endif
|
||||
#ifndef POLLOUT
|
||||
#define POLLOUT (POLLWRNORM)
|
||||
#endif
|
||||
#ifndef POLLWRBAND
|
||||
#define POLLWRBAND 0x0020
|
||||
#endif
|
||||
|
||||
#ifndef POLLERR
|
||||
#define POLLERR 0x0001
|
||||
#endif
|
||||
#ifndef POLLHUP
|
||||
#define POLLHUP 0x0002
|
||||
#endif
|
||||
#ifndef POLLNVAL
|
||||
#define POLLNVAL 0x0004
|
||||
#endif
|
||||
|
||||
#else /* _WIN32 */
|
||||
|
||||
/* poll.c */
|
||||
#ifndef POLLIN
|
||||
#define POLLIN 0x001 /* There is data to read. */
|
||||
@@ -72,11 +111,11 @@ typedef struct ssh_pollfd_struct {
|
||||
#define POLLWRBAND 0x200 /* mapped to write fds_set */
|
||||
#endif
|
||||
|
||||
|
||||
typedef unsigned long int nfds_t;
|
||||
#endif /* WIN32 */
|
||||
#endif /* HAVE_POLL */
|
||||
|
||||
void ssh_poll_init(void);
|
||||
void ssh_poll_cleanup(void);
|
||||
int ssh_poll(ssh_pollfd_t *fds, nfds_t nfds, int timeout);
|
||||
typedef struct ssh_poll_ctx_struct *ssh_poll_ctx;
|
||||
typedef struct ssh_poll_handle_struct *ssh_poll_handle;
|
||||
@@ -92,7 +131,7 @@ typedef struct ssh_poll_handle_struct *ssh_poll_handle;
|
||||
* @return 0 on success, < 0 if you removed the poll object from
|
||||
* it's poll context.
|
||||
*/
|
||||
typedef int (*ssh_poll_callback)(ssh_poll_handle p, int fd, int revents,
|
||||
typedef int (*ssh_poll_callback)(ssh_poll_handle p, socket_t fd, int revents,
|
||||
void *userdata);
|
||||
|
||||
|
||||
|
||||
@@ -32,57 +32,72 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#ifdef _WIN32
|
||||
|
||||
/** Imitate define of inttypes.h */
|
||||
#define PRIdS "Id"
|
||||
/* Imitate define of inttypes.h */
|
||||
# ifndef PRIdS
|
||||
# define PRIdS "Id"
|
||||
# endif
|
||||
|
||||
#define strcasecmp _stricmp
|
||||
#define strncasecmp _strnicmp
|
||||
#define strtoull _strtoui64
|
||||
#define isblank(ch) ((ch) == ' ' || (ch) == '\t' || (ch) == '\n' || (ch) == '\r')
|
||||
# ifdef _MSC_VER
|
||||
# include <stdio.h>
|
||||
|
||||
#if _MSC_VER >= 1400
|
||||
#define strdup _strdup
|
||||
#endif
|
||||
#define usleep(X) Sleep(((X)+1000)/1000)
|
||||
/* On Microsoft compilers define inline to __inline on all others use inline */
|
||||
# undef inline
|
||||
# define inline __inline
|
||||
|
||||
#undef strtok_r
|
||||
#define strtok_r strtok_s
|
||||
# undef strdup
|
||||
# define strdup _strdup
|
||||
|
||||
#ifndef HAVE_SNPRINTF
|
||||
#ifdef HAVE__SNPRINTF_S
|
||||
#define snprintf(d, n, ...) _snprintf_s((d), (n), _TRUNCATE, __VA_ARGS__)
|
||||
#else
|
||||
#ifdef HAVE__SNPRINTF
|
||||
#define snprintf _snprintf
|
||||
#else
|
||||
#error "no snprintf compatible function found"
|
||||
#endif /* HAVE__SNPRINTF */
|
||||
#endif /* HAVE__SNPRINTF_S */
|
||||
#endif /* HAVE_SNPRINTF */
|
||||
# define strcasecmp _stricmp
|
||||
# define strncasecmp _strnicmp
|
||||
# define strtoull _strtoui64
|
||||
# define isblank(ch) ((ch) == ' ' || (ch) == '\t' || (ch) == '\n' || (ch) == '\r')
|
||||
|
||||
#ifndef HAVE_VSNPRINTF
|
||||
#ifdef HAVE__VSNPRINTF_S
|
||||
#define vsnprintf(s, n, f, v) _vsnprintf_s((s), (n), _TRUNCATE, (f), (v))
|
||||
#else
|
||||
#ifdef HAVE__VSNPRINTF
|
||||
#define vsnprintf _vsnprintf
|
||||
#else /* HAVE_VSNPRINTF */
|
||||
#error "No vsnprintf compatible function found"
|
||||
#endif /* HAVE__VSNPRINTF */
|
||||
#endif /* HAVE__VSNPRINTF_S */
|
||||
#endif /* HAVE_VSNPRINTF */
|
||||
# define usleep(X) Sleep(((X)+1000)/1000)
|
||||
|
||||
#ifndef HAVE_STRNCPY
|
||||
#define strncpy(d, s, n) strncpy_s((d), (n), (s), _TRUNCATE)
|
||||
#endif
|
||||
#else /* _MSC_VER */
|
||||
# undef strtok_r
|
||||
# define strtok_r strtok_s
|
||||
|
||||
# if defined(HAVE__SNPRINTF_S)
|
||||
# undef snprintf
|
||||
# define snprintf(d, n, ...) _snprintf_s((d), (n), _TRUNCATE, __VA_ARGS__)
|
||||
# else /* HAVE__SNPRINTF_S */
|
||||
# if defined(HAVE__SNPRINTF)
|
||||
# undef snprintf
|
||||
# define snprintf _snprintf
|
||||
# else /* HAVE__SNPRINTF */
|
||||
# if !defined(HAVE_SNPRINTF)
|
||||
# error "no snprintf compatible function found"
|
||||
# endif /* HAVE_SNPRINTF */
|
||||
# endif /* HAVE__SNPRINTF */
|
||||
# endif /* HAVE__SNPRINTF_S */
|
||||
|
||||
# if defined(HAVE__VSNPRINTF_S)
|
||||
# undef vsnprintf
|
||||
# define vsnprintf(s, n, f, v) _vsnprintf_s((s), (n), _TRUNCATE, (f), (v))
|
||||
# else /* HAVE__VSNPRINTF_S */
|
||||
# if defined(HAVE__VSNPRINTF)
|
||||
# undef vsnprintf
|
||||
# define vsnprintf _vsnprintf
|
||||
# else
|
||||
# if !defined(HAVE_VSNPRINTF)
|
||||
# error "No vsnprintf compatible function found"
|
||||
# endif /* HAVE_VSNPRINTF */
|
||||
# endif /* HAVE__VSNPRINTF */
|
||||
# endif /* HAVE__VSNPRINTF_S */
|
||||
|
||||
# ifndef HAVE_STRNCPY
|
||||
# define strncpy(d, s, n) strncpy_s((d), (n), (s), _TRUNCATE)
|
||||
# endif
|
||||
# endif /* _MSC_VER */
|
||||
|
||||
#else /* _WIN32 */
|
||||
|
||||
#include <unistd.h>
|
||||
#define PRIdS "zd"
|
||||
|
||||
#endif /* _MSC_VER */
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#include "libssh/libssh.h"
|
||||
#include "libssh/callbacks.h"
|
||||
|
||||
@@ -102,7 +102,7 @@ struct ssh_session_struct {
|
||||
#endif
|
||||
char *username;
|
||||
char *host;
|
||||
char *bindaddr; /* TODO: check if needed */
|
||||
char *bindaddr; /* bind the client to an ip addr */
|
||||
char *xbanner; /* TODO: looks like it is not needed */
|
||||
struct ssh_list *identity;
|
||||
char *sshdir;
|
||||
|
||||
@@ -30,6 +30,7 @@ struct socket *ssh_socket_new(ssh_session session);
|
||||
void ssh_socket_free(struct socket *s);
|
||||
void ssh_socket_set_fd(struct socket *s, socket_t fd);
|
||||
socket_t ssh_socket_get_fd(struct socket *s);
|
||||
void ssh_socket_cleanup(void);
|
||||
#ifndef _WIN32
|
||||
int ssh_socket_unix(struct socket *s, const char *path);
|
||||
#endif
|
||||
@@ -38,7 +39,7 @@ int ssh_socket_read(struct socket *s, void *buffer, int len);
|
||||
int ssh_socket_write(struct socket *s,const void *buffer, int len);
|
||||
int ssh_socket_is_open(struct socket *s);
|
||||
int ssh_socket_fd_isset(struct socket *s, fd_set *set);
|
||||
void ssh_socket_fd_set(struct socket *s, fd_set *set, int *fd_max);
|
||||
void ssh_socket_fd_set(struct socket *s, fd_set *set, socket_t *max_fd);
|
||||
int ssh_socket_completeread(struct socket *s, void *buffer, uint32_t len);
|
||||
int ssh_socket_completewrite(struct socket *s, const void *buffer, uint32_t len);
|
||||
int ssh_socket_wait_for_data(struct socket *s, ssh_session session, uint32_t len);
|
||||
|
||||
@@ -41,7 +41,6 @@
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <poll.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
@@ -54,6 +53,7 @@
|
||||
#include "libssh/buffer.h"
|
||||
#include "libssh/session.h"
|
||||
#include "libssh/keys.h"
|
||||
#include "libssh/poll.h"
|
||||
|
||||
/* macro to check for "agent failure" message */
|
||||
#define agent_failed(x) \
|
||||
@@ -85,8 +85,8 @@ static size_t atomicio(struct socket *s, void *buf, size_t n, int do_read) {
|
||||
char *b = buf;
|
||||
size_t pos = 0;
|
||||
ssize_t res;
|
||||
struct pollfd pfd;
|
||||
int fd = ssh_socket_get_fd(s);
|
||||
ssh_pollfd_t pfd;
|
||||
socket_t fd = ssh_socket_get_fd(s);
|
||||
|
||||
pfd.fd = fd;
|
||||
pfd.events = do_read ? POLLIN : POLLOUT;
|
||||
@@ -107,7 +107,7 @@ static size_t atomicio(struct socket *s, void *buf, size_t n, int do_read) {
|
||||
#else
|
||||
if (errno == EAGAIN) {
|
||||
#endif
|
||||
(void) poll(&pfd, 1, -1);
|
||||
(void) ssh_poll(&pfd, 1, -1);
|
||||
continue;
|
||||
}
|
||||
return 0;
|
||||
|
||||
@@ -170,24 +170,33 @@ static int wait_auth_status(ssh_session session, int kbdint) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief retrieves available authentication methods for this session
|
||||
* @deprecated
|
||||
* @see ssh_userauth_list
|
||||
*/
|
||||
int ssh_auth_list(ssh_session session) {
|
||||
if (session == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return session->auth_methods;
|
||||
return ssh_userauth_list(session, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief retrieves available authentication methods for this session
|
||||
* @param[in] session the SSH session
|
||||
* @param[in] username set to NULL
|
||||
* @returns A bitfield of values SSH_AUTH_METHOD_NONE, SSH_AUTH_METHOD_PASSWORD,
|
||||
SSH_AUTH_METHOD_PUBLICKEY, SSH_AUTH_METHOD_HOSTBASED,
|
||||
SSH_AUTH_METHOD_INTERACTIVE.
|
||||
@warning Other reserved flags may appear in future versions.
|
||||
*/
|
||||
int ssh_userauth_list(ssh_session session, const char *username) {
|
||||
if (session == NULL || username == NULL) {
|
||||
if (session == NULL) {
|
||||
return SSH_AUTH_ERROR;
|
||||
}
|
||||
|
||||
if (session->auth_methods == 0) {
|
||||
ssh_userauth_none(session, username);
|
||||
}
|
||||
|
||||
return ssh_auth_list(session);
|
||||
return session->auth_methods;
|
||||
}
|
||||
|
||||
/* use the "none" authentication question */
|
||||
@@ -217,7 +226,7 @@ int ssh_userauth_none(ssh_session session, const char *username) {
|
||||
|
||||
#ifdef WITH_SSH1
|
||||
if (session->version == 1) {
|
||||
ssh_userauth1_none(session, username);
|
||||
rc = ssh_userauth1_none(session, username);
|
||||
leave_function();
|
||||
return rc;
|
||||
}
|
||||
@@ -225,7 +234,7 @@ int ssh_userauth_none(ssh_session session, const char *username) {
|
||||
|
||||
if (username == NULL) {
|
||||
if (session->username == NULL) {
|
||||
if (ssh_options_set(session, SSH_OPTIONS_USER, NULL) < 0) {
|
||||
if (ssh_options_apply(session) < 0) {
|
||||
leave_function();
|
||||
return rc;
|
||||
}
|
||||
@@ -323,7 +332,7 @@ int ssh_userauth_offer_pubkey(ssh_session session, const char *username,
|
||||
|
||||
#ifdef WITH_SSH1
|
||||
if (session->version == 1) {
|
||||
ssh_userauth1_offer_pubkey(session, username, type, publickey);
|
||||
rc = ssh_userauth1_offer_pubkey(session, username, type, publickey);
|
||||
leave_function();
|
||||
return rc;
|
||||
}
|
||||
@@ -331,7 +340,7 @@ int ssh_userauth_offer_pubkey(ssh_session session, const char *username,
|
||||
|
||||
if (username == NULL) {
|
||||
if (session->username == NULL) {
|
||||
if (ssh_options_set(session, SSH_OPTIONS_USER, NULL) < 0) {
|
||||
if (ssh_options_apply(session) < 0) {
|
||||
leave_function();
|
||||
return rc;
|
||||
}
|
||||
@@ -443,7 +452,7 @@ int ssh_userauth_pubkey(ssh_session session, const char *username,
|
||||
|
||||
if (username == NULL) {
|
||||
if (session->username == NULL) {
|
||||
if (ssh_options_set(session, SSH_OPTIONS_USER, NULL) < 0) {
|
||||
if (ssh_options_apply(session) < 0) {
|
||||
leave_function();
|
||||
return rc;
|
||||
}
|
||||
@@ -561,7 +570,7 @@ int ssh_userauth_agent_pubkey(ssh_session session, const char *username,
|
||||
|
||||
if (username == NULL) {
|
||||
if (session->username == NULL) {
|
||||
if (ssh_options_set(session, SSH_OPTIONS_USER, NULL) < 0) {
|
||||
if (ssh_options_apply(session) < 0) {
|
||||
leave_function();
|
||||
return rc;
|
||||
}
|
||||
@@ -688,7 +697,7 @@ int ssh_userauth_password(ssh_session session, const char *username,
|
||||
|
||||
if (username == NULL) {
|
||||
if (session->username == NULL) {
|
||||
if (ssh_options_set(session, SSH_OPTIONS_USER, NULL) < 0) {
|
||||
if (ssh_options_apply(session) < 0) {
|
||||
leave_function();
|
||||
return rc;
|
||||
}
|
||||
@@ -777,7 +786,6 @@ error:
|
||||
*
|
||||
* @see ssh_userauth_kbdint()
|
||||
* @see ssh_userauth_password()
|
||||
* @see ssh_options_set()
|
||||
*/
|
||||
int ssh_userauth_autopubkey(ssh_session session, const char *passphrase) {
|
||||
struct ssh_iterator *it;
|
||||
@@ -1336,7 +1344,7 @@ int ssh_userauth_kbdint(ssh_session session, const char *user,
|
||||
/* first time we call. we must ask for a challenge */
|
||||
if (user == NULL) {
|
||||
if ((user = session->username) == NULL) {
|
||||
if (ssh_options_set(session, SSH_OPTIONS_USER, NULL) < 0) {
|
||||
if (ssh_options_apply(session) < 0) {
|
||||
leave_function();
|
||||
return SSH_AUTH_ERROR;
|
||||
} else {
|
||||
|
||||
@@ -35,38 +35,46 @@
|
||||
|
||||
#ifdef WITH_SSH1
|
||||
static int wait_auth1_status(ssh_session session) {
|
||||
enter_function();
|
||||
/* wait for a packet */
|
||||
if (packet_read(session) != SSH_OK) {
|
||||
leave_function();
|
||||
return SSH_AUTH_ERROR;
|
||||
}
|
||||
|
||||
if(packet_translate(session) != SSH_OK) {
|
||||
leave_function();
|
||||
return SSH_AUTH_ERROR;
|
||||
}
|
||||
|
||||
switch(session->in_packet.type) {
|
||||
case SSH_SMSG_SUCCESS:
|
||||
leave_function();
|
||||
return SSH_AUTH_SUCCESS;
|
||||
case SSH_SMSG_FAILURE:
|
||||
leave_function();
|
||||
return SSH_AUTH_DENIED;
|
||||
}
|
||||
|
||||
ssh_set_error(session, SSH_FATAL, "Was waiting for a SUCCESS or "
|
||||
"FAILURE, got %d", session->in_packet.type);
|
||||
|
||||
leave_function();
|
||||
return SSH_AUTH_ERROR;
|
||||
}
|
||||
|
||||
static int send_username(ssh_session session, const char *username) {
|
||||
ssh_string user = NULL;
|
||||
/* returns SSH_AUTH_SUCCESS or SSH_AUTH_DENIED */
|
||||
enter_function();
|
||||
if(session->auth_service_asked) {
|
||||
leave_function();
|
||||
return session->auth_service_asked;
|
||||
}
|
||||
|
||||
if (!username) {
|
||||
if(!(username = session->username)) {
|
||||
if (ssh_options_set(session, SSH_OPTIONS_USER, NULL) < 0) {
|
||||
leave_function();
|
||||
return session->auth_service_asked = SSH_AUTH_ERROR;
|
||||
} else {
|
||||
username = session->username;
|
||||
@@ -75,24 +83,30 @@ static int send_username(ssh_session session, const char *username) {
|
||||
}
|
||||
user = string_from_char(username);
|
||||
if (user == NULL) {
|
||||
leave_function();
|
||||
return SSH_AUTH_ERROR;
|
||||
}
|
||||
|
||||
if (buffer_add_u8(session->out_buffer, SSH_CMSG_USER) < 0) {
|
||||
string_free(user);
|
||||
leave_function();
|
||||
return SSH_AUTH_ERROR;
|
||||
}
|
||||
if (buffer_add_ssh_string(session->out_buffer, user) < 0) {
|
||||
string_free(user);
|
||||
leave_function();
|
||||
return SSH_AUTH_ERROR;
|
||||
}
|
||||
string_free(user);
|
||||
if (packet_send(session) != SSH_OK) {
|
||||
leave_function();
|
||||
return SSH_AUTH_ERROR;
|
||||
}
|
||||
|
||||
session->auth_service_asked = wait_auth1_status(session);
|
||||
|
||||
if(session->auth_service_asked != SSH_AUTH_ERROR)
|
||||
session->auth_methods=SSH_AUTH_METHOD_PASSWORD;
|
||||
leave_function();
|
||||
return session->auth_service_asked;
|
||||
}
|
||||
|
||||
|
||||
@@ -165,8 +165,10 @@ static int channel_open(ssh_channel channel, const char *type_c, int window,
|
||||
type_c, channel->local_channel);
|
||||
|
||||
if (packet_wait(session, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, 1) != SSH_OK) {
|
||||
leave_function();
|
||||
return -1;
|
||||
if(session->in_packet.type != SSH2_MSG_CHANNEL_OPEN_FAILURE) {
|
||||
leave_function();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
switch(session->in_packet.type) {
|
||||
@@ -555,7 +557,7 @@ static void channel_rcv_request(ssh_session session) {
|
||||
if(strcmp(request,"keepalive@openssh.com")==0){
|
||||
SAFE_FREE(request);
|
||||
ssh_log(session, SSH_LOG_PROTOCOL,"Responding to Openssh's keepalive");
|
||||
buffer_add_u8(session->out_buffer, SSH2_MSG_CHANNEL_SUCCESS);
|
||||
buffer_add_u8(session->out_buffer, SSH2_MSG_CHANNEL_FAILURE);
|
||||
buffer_add_u32(session->out_buffer, htonl(channel->remote_channel));
|
||||
packet_send(session);
|
||||
leave_function();
|
||||
@@ -794,7 +796,7 @@ void channel_free(ssh_channel channel) {
|
||||
*
|
||||
* @param channel The channel to send the eof to.
|
||||
*
|
||||
* @return SSH_SUCCESS on success\n
|
||||
* @return SSH_OK on success\n
|
||||
* SSH_ERROR on error\n
|
||||
*
|
||||
* @see channel_close()
|
||||
@@ -837,7 +839,7 @@ error:
|
||||
*
|
||||
* @param channel The channel to close.
|
||||
*
|
||||
* @return SSH_SUCCESS on success\n
|
||||
* @return SSH_OK on success\n
|
||||
* SSH_ERROR on error
|
||||
*
|
||||
* @see channel_free()
|
||||
@@ -1116,7 +1118,7 @@ error:
|
||||
*
|
||||
* @param row The number of rows.
|
||||
*
|
||||
* @return SSH_SUCCESS on success, SSH_ERROR on error.
|
||||
* @return SSH_OK on success, SSH_ERROR on error.
|
||||
*/
|
||||
int channel_request_pty_size(ssh_channel channel, const char *terminal,
|
||||
int col, int row) {
|
||||
@@ -1167,7 +1169,7 @@ error:
|
||||
*
|
||||
* @param channel The channel to send the request.
|
||||
*
|
||||
* @return SSH_SUCCESS on success, SSH_ERROR on error.
|
||||
* @return SSH_OK on success, SSH_ERROR on error.
|
||||
*
|
||||
* @see channel_request_pty_size()
|
||||
*/
|
||||
@@ -1228,7 +1230,7 @@ error:
|
||||
*
|
||||
* @param channel The channel to send the request.
|
||||
*
|
||||
* @returns SSH_SUCCESS on success, SSH_ERROR on error.
|
||||
* @returns SSH_OK on success, SSH_ERROR on error.
|
||||
*/
|
||||
int channel_request_shell(ssh_channel channel) {
|
||||
#ifdef WITH_SSH1
|
||||
@@ -1246,7 +1248,7 @@ int channel_request_shell(ssh_channel channel) {
|
||||
*
|
||||
* @param subsys The subsystem to request (for example "sftp").
|
||||
*
|
||||
* @return SSH_SUCCESS on success, SSH_ERROR on error.
|
||||
* @return SSH_OK on success, SSH_ERROR on error.
|
||||
*
|
||||
* @warning You normally don't have to call it for sftp, see sftp_new().
|
||||
*/
|
||||
@@ -1390,11 +1392,13 @@ static ssh_channel channel_accept(ssh_session session, int channeltype,
|
||||
iterator = iterator->next;
|
||||
}
|
||||
}
|
||||
if(t>0){
|
||||
#ifdef _WIN32
|
||||
Sleep(50); /* 50ms */
|
||||
Sleep(50); /* 50ms */
|
||||
#else
|
||||
nanosleep(&ts, NULL);
|
||||
nanosleep(&ts, NULL);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@@ -1594,7 +1598,7 @@ error:
|
||||
*
|
||||
* @param value The value to set.
|
||||
*
|
||||
* @return SSH_SUCCESS on success, SSH_ERROR on error.
|
||||
* @return SSH_OK on success, SSH_ERROR on error.
|
||||
*
|
||||
* @warning Some environement variables may be refused by security reasons.
|
||||
* */
|
||||
@@ -1645,7 +1649,7 @@ error:
|
||||
* @param cmd The command to execute
|
||||
* (e.g. "ls ~/ -al | grep -i reports").
|
||||
*
|
||||
* @return SSH_SUCCESS on success, SSH_ERROR on error.
|
||||
* @return SSH_OK on success, SSH_ERROR on error.
|
||||
*
|
||||
* @see channel_request_shell()
|
||||
*/
|
||||
@@ -1695,7 +1699,7 @@ error:
|
||||
* @param signal The signal to send (without SIG prefix)
|
||||
* (e.g. "TERM" or "KILL").
|
||||
*
|
||||
* @return SSH_SUCCESS on success, SSH_ERROR on error (including attempt to send signal via SSH-v1 session).
|
||||
* @return SSH_OK on success, SSH_ERROR on error (including attempt to send signal via SSH-v1 session).
|
||||
*
|
||||
*/
|
||||
int channel_request_send_signal(ssh_channel channel, const char *signal) {
|
||||
@@ -2150,7 +2154,7 @@ static int count_ptrs(ssh_channel *ptrs) {
|
||||
*
|
||||
* @param timeout Timeout as defined by select(2).
|
||||
*
|
||||
* @return SSH_SUCCESS operation successful\n
|
||||
* @return SSH_OK operation successful\n
|
||||
* SSH_EINTR select(2) syscall was interrupted, relaunch the function
|
||||
*/
|
||||
int channel_select(ssh_channel *readchans, ssh_channel *writechans,
|
||||
@@ -2160,7 +2164,7 @@ int channel_select(ssh_channel *readchans, ssh_channel *writechans,
|
||||
fd_set rset;
|
||||
fd_set wset;
|
||||
fd_set eset;
|
||||
int fdmax = -1;
|
||||
socket_t max_fd = SSH_INVALID_SOCKET;
|
||||
int rc;
|
||||
int i;
|
||||
|
||||
@@ -2228,24 +2232,24 @@ int channel_select(ssh_channel *readchans, ssh_channel *writechans,
|
||||
|
||||
for (i = 0; readchans[i] != NULL; i++) {
|
||||
if (!ssh_socket_fd_isset(readchans[i]->session->socket, &rset)) {
|
||||
ssh_socket_fd_set(readchans[i]->session->socket, &rset, &fdmax);
|
||||
ssh_socket_fd_set(readchans[i]->session->socket, &rset, &max_fd);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; writechans[i] != NULL; i++) {
|
||||
if (!ssh_socket_fd_isset(writechans[i]->session->socket, &wset)) {
|
||||
ssh_socket_fd_set(writechans[i]->session->socket, &wset, &fdmax);
|
||||
ssh_socket_fd_set(writechans[i]->session->socket, &wset, &max_fd);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; exceptchans[i] != NULL; i++) {
|
||||
if (!ssh_socket_fd_isset(exceptchans[i]->session->socket, &eset)) {
|
||||
ssh_socket_fd_set(exceptchans[i]->session->socket, &eset, &fdmax);
|
||||
ssh_socket_fd_set(exceptchans[i]->session->socket, &eset, &max_fd);
|
||||
}
|
||||
}
|
||||
|
||||
/* Here we go */
|
||||
rc = select(fdmax, &rset, &wset, &eset, timeout);
|
||||
rc = select(max_fd, &rset, &wset, &eset, timeout);
|
||||
/* Leave if select was interrupted */
|
||||
if (rc == EINTR) {
|
||||
SAFE_FREE(rchans);
|
||||
|
||||
@@ -110,26 +110,37 @@ static int ssh_analyze_banner(ssh_session session, int *ssh1, int *ssh2) {
|
||||
const char *banner = session->serverbanner;
|
||||
const char *openssh;
|
||||
|
||||
ssh_log(session, SSH_LOG_RARE, "Analyzing banner: %s", banner);
|
||||
|
||||
if (strncmp(banner, "SSH-", 4) != 0) {
|
||||
ssh_set_error(session, SSH_FATAL, "Protocol mismatch: %s", banner);
|
||||
return -1;
|
||||
if (banner == NULL) {
|
||||
ssh_set_error(session, SSH_FATAL, "Invalid banner");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Typical banners e.g. are:
|
||||
* SSH-1.5-blah
|
||||
* SSH-1.99-blah
|
||||
* SSH-2.0-blah
|
||||
*
|
||||
* SSH-1.5-openSSH_5.4
|
||||
* SSH-1.99-openSSH_3.0
|
||||
*
|
||||
* SSH-2.0-something
|
||||
* 012345678901234567890
|
||||
*/
|
||||
if (strlen(banner) < 6 ||
|
||||
strncmp(banner, "SSH-", 4) != 0) {
|
||||
ssh_set_error(session, SSH_FATAL, "Protocol mismatch: %s", banner);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ssh_log(session, SSH_LOG_RARE, "Analyzing banner: %s", banner);
|
||||
|
||||
switch(banner[4]) {
|
||||
case '1':
|
||||
*ssh1 = 1;
|
||||
if (banner[6] == '9') {
|
||||
*ssh2 = 1;
|
||||
} else {
|
||||
*ssh2 = 0;
|
||||
if (strlen(banner) > 6) {
|
||||
if (banner[6] == '9') {
|
||||
*ssh2 = 1;
|
||||
} else {
|
||||
*ssh2 = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case '2':
|
||||
@@ -143,13 +154,21 @@ static int ssh_analyze_banner(ssh_session session, int *ssh1, int *ssh2) {
|
||||
|
||||
openssh = strstr(banner, "OpenSSH");
|
||||
if (openssh != NULL) {
|
||||
int major, minor;
|
||||
major = strtol(openssh + 8, (char **) NULL, 10);
|
||||
minor = strtol(openssh + 10, (char **) NULL, 10);
|
||||
session->openssh = SSH_VERSION_INT(major, minor, 0);
|
||||
ssh_log(session, SSH_LOG_RARE,
|
||||
"We are talking to an OpenSSH server version: %d.%d (%x)",
|
||||
major, minor, session->openssh);
|
||||
int major, minor;
|
||||
|
||||
/*
|
||||
* The banner is typical:
|
||||
* OpenSSH_5.4
|
||||
* 012345678901234567890
|
||||
*/
|
||||
if (strlen(openssh) > 9) {
|
||||
major = strtol(openssh + 8, (char **) NULL, 10);
|
||||
minor = strtol(openssh + 10, (char **) NULL, 10);
|
||||
session->openssh = SSH_VERSION_INT(major, minor, 0);
|
||||
ssh_log(session, SSH_LOG_RARE,
|
||||
"We are talking to an OpenSSH client version: %d.%d (%x)",
|
||||
major, minor, session->openssh);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -481,7 +500,7 @@ int ssh_service_request(ssh_session session, const char *service) {
|
||||
int ssh_connect(ssh_session session) {
|
||||
int ssh1 = 0;
|
||||
int ssh2 = 0;
|
||||
int fd = -1;
|
||||
socket_t fd = SSH_INVALID_SOCKET;
|
||||
int ret;
|
||||
|
||||
if (session == NULL) {
|
||||
@@ -498,7 +517,7 @@ int ssh_connect(ssh_session session) {
|
||||
leave_function();
|
||||
return SSH_ERROR;
|
||||
}
|
||||
if (session->fd == -1 && session->host == NULL &&
|
||||
if (session->fd == SSH_INVALID_SOCKET && session->host == NULL &&
|
||||
session->ProxyCommand == NULL) {
|
||||
ssh_set_error(session, SSH_FATAL, "Hostname required");
|
||||
leave_function();
|
||||
@@ -512,7 +531,7 @@ int ssh_connect(ssh_session session) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
if (session->fd != -1) {
|
||||
if (session->fd != SSH_INVALID_SOCKET) {
|
||||
fd = session->fd;
|
||||
#ifndef _WIN32
|
||||
} else if (session->ProxyCommand != NULL) {
|
||||
@@ -522,7 +541,7 @@ int ssh_connect(ssh_session session) {
|
||||
fd = ssh_connect_host(session, session->host, session->bindaddr,
|
||||
session->port, session->timeout, session->timeout_usec);
|
||||
}
|
||||
if (fd < 0) {
|
||||
if (fd == SSH_INVALID_SOCKET) {
|
||||
leave_function();
|
||||
return SSH_ERROR;
|
||||
}
|
||||
@@ -554,8 +573,10 @@ int ssh_connect(ssh_session session) {
|
||||
/* Here we decide which version of the protocol to use. */
|
||||
if (ssh2 && session->ssh2) {
|
||||
session->version = 2;
|
||||
#ifdef WITH_SSH1
|
||||
} else if(ssh1 && session->ssh1) {
|
||||
session->version = 1;
|
||||
#endif
|
||||
} else {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"No version of SSH protocol usable (banner: %s)",
|
||||
@@ -610,6 +631,7 @@ int ssh_connect(ssh_session session) {
|
||||
|
||||
session->connected = 1;
|
||||
break;
|
||||
#ifdef WITH_SSH1
|
||||
case 1:
|
||||
if (ssh_get_kex1(session) < 0) {
|
||||
ssh_socket_close(session->socket);
|
||||
@@ -621,6 +643,7 @@ int ssh_connect(ssh_session session) {
|
||||
|
||||
session->connected = 1;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
leave_function();
|
||||
|
||||
@@ -283,10 +283,12 @@ static int ssh_config_parse_line(ssh_session session, const char *line,
|
||||
}
|
||||
break;
|
||||
case SOC_UNSUPPORTED:
|
||||
fprintf(stderr, "Unsupported option: %s, line: %d\n", keyword, count);
|
||||
ssh_log(session, SSH_LOG_RARE, "Unsupported option: %s, line: %d\n",
|
||||
keyword, count);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "ERROR - unimplemented opcode: %d\n", opcode);
|
||||
ssh_set_error(session, SSH_FATAL, "ERROR - unimplemented opcode: %d\n",
|
||||
opcode);
|
||||
SAFE_FREE(x);
|
||||
return -1;
|
||||
break;
|
||||
|
||||
@@ -67,10 +67,7 @@
|
||||
#include "libssh/socket.h"
|
||||
#include "libssh/channels.h"
|
||||
#include "libssh/session.h"
|
||||
|
||||
#ifndef HAVE_SELECT
|
||||
#error "Your system must have select()"
|
||||
#endif
|
||||
#include "libssh/poll.h"
|
||||
|
||||
#ifndef HAVE_GETADDRINFO
|
||||
#error "Your system must have getaddrinfo()"
|
||||
@@ -202,29 +199,35 @@ static int getai(ssh_session session, const char *host, int port, struct addrinf
|
||||
|
||||
static int ssh_connect_ai_timeout(ssh_session session, const char *host,
|
||||
int port, struct addrinfo *ai, long timeout, long usec, socket_t s) {
|
||||
struct timeval to;
|
||||
fd_set set;
|
||||
int timeout_ms;
|
||||
ssh_pollfd_t fds;
|
||||
int rc = 0;
|
||||
unsigned int len = sizeof(rc);
|
||||
|
||||
enter_function();
|
||||
|
||||
to.tv_sec = timeout;
|
||||
to.tv_usec = usec;
|
||||
/* I know we're losing some precision. But it's not like poll-like family
|
||||
* type of mechanisms are precise up to the microsecond.
|
||||
*/
|
||||
timeout_ms=timeout * 1000 + usec / 1000;
|
||||
|
||||
sock_set_nonblocking(s);
|
||||
|
||||
ssh_log(session, SSH_LOG_RARE, "Trying to connect to host: %s:%d with "
|
||||
"timeout %ld.%ld", host, port, timeout, usec);
|
||||
"timeout %d ms", host, port, timeout_ms);
|
||||
|
||||
/* The return value is checked later */
|
||||
connect(s, ai->ai_addr, ai->ai_addrlen);
|
||||
freeaddrinfo(ai);
|
||||
|
||||
FD_ZERO(&set);
|
||||
FD_SET(s, &set);
|
||||
fds.fd=s;
|
||||
fds.revents=0;
|
||||
fds.events=POLLOUT;
|
||||
#ifdef _WIN32
|
||||
fds.events |= POLLWRNORM;
|
||||
#endif
|
||||
rc = ssh_poll(&fds,1,timeout_ms);
|
||||
|
||||
rc = select(s + 1, NULL, &set, NULL, &to);
|
||||
if (rc == 0) {
|
||||
/* timeout */
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
@@ -236,7 +239,7 @@ static int ssh_connect_ai_timeout(ssh_session session, const char *host,
|
||||
|
||||
if (rc < 0) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Select error: %s", strerror(errno));
|
||||
"poll error: %s", strerror(errno));
|
||||
ssh_connect_socket_close(s);
|
||||
leave_function();
|
||||
return -1;
|
||||
@@ -390,6 +393,7 @@ int ssh_select(ssh_channel *channels, ssh_channel *outchannels, socket_t maxfd,
|
||||
fd_set *readfds, struct timeval *timeout) {
|
||||
struct timeval zerotime;
|
||||
fd_set localset, localset2;
|
||||
socket_t f;
|
||||
int rep;
|
||||
int set;
|
||||
int i;
|
||||
@@ -430,8 +434,8 @@ int ssh_select(ssh_channel *channels, ssh_channel *outchannels, socket_t maxfd,
|
||||
|
||||
/* Look into the localset for active fd */
|
||||
set = 0;
|
||||
for (i = 0; (i < maxfd) && !set; i++) {
|
||||
if (FD_ISSET(i, &localset)) {
|
||||
for (f = 0; (f < maxfd) && !set; f++) {
|
||||
if (FD_ISSET(f, &localset)) {
|
||||
set = 1;
|
||||
}
|
||||
}
|
||||
@@ -493,9 +497,9 @@ int ssh_select(ssh_channel *channels, ssh_channel *outchannels, socket_t maxfd,
|
||||
outchannels[j] = NULL;
|
||||
|
||||
FD_ZERO(&localset2);
|
||||
for (i = 0; i < maxfd; i++) {
|
||||
if (FD_ISSET(i, readfds) && FD_ISSET(i, &localset)) {
|
||||
FD_SET(i, &localset2);
|
||||
for (f = 0; f < maxfd; f++) {
|
||||
if (FD_ISSET(f, readfds) && FD_ISSET(i, &localset)) {
|
||||
FD_SET(f, &localset2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -222,6 +222,8 @@ void ssh_print_hexa(const char *descr, const unsigned char *what, size_t len) {
|
||||
return;
|
||||
}
|
||||
printf("%s: %s\n", descr, hexa);
|
||||
|
||||
free(hexa);
|
||||
}
|
||||
|
||||
int dh_generate_x(ssh_session session) {
|
||||
@@ -831,8 +833,11 @@ int ssh_get_pubkey_hash(ssh_session session, unsigned char **hash) {
|
||||
if (session == NULL || hash == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
*hash = NULL;
|
||||
if (session->current_crypto == NULL ||
|
||||
session->current_crypto->server_pubkey == NULL){
|
||||
ssh_set_error(session,SSH_FATAL,"No current cryptographic context");
|
||||
}
|
||||
|
||||
h = malloc(sizeof(unsigned char *) * MD5_DIGEST_LEN);
|
||||
if (h == NULL) {
|
||||
|
||||
@@ -65,6 +65,7 @@ int ssh_init(void) {
|
||||
int ssh_finalize(void) {
|
||||
ssh_regex_finalize();
|
||||
ssh_crypto_finalize();
|
||||
ssh_socket_cleanup();
|
||||
#ifdef HAVE_LIBGCRYPT
|
||||
gcry_control(GCRYCTL_TERM_SECMEM);
|
||||
#elif defined HAVE_LIBCRYPTO
|
||||
|
||||
@@ -450,6 +450,8 @@ int verify_existing_algo(int algo, const char *name){
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef WITH_SSH1
|
||||
|
||||
/* makes a STRING contating 3 strings : ssh-rsa1,e and n */
|
||||
/* this is a public key in openssh's format */
|
||||
static ssh_string make_rsa1_string(ssh_string e, ssh_string n){
|
||||
@@ -507,6 +509,7 @@ static int build_session_id1(ssh_session session, ssh_string servern,
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* returns 1 if the modulus of k1 is < than the one of k2 */
|
||||
static int modulus_smaller(ssh_public_key k1, ssh_public_key k2){
|
||||
bignum n1;
|
||||
@@ -796,4 +799,6 @@ error:
|
||||
return rc;
|
||||
}
|
||||
|
||||
#endif /* WITH_SSH1 */
|
||||
|
||||
/* vim: set ts=2 sw=2 et cindent: */
|
||||
|
||||
@@ -1077,7 +1077,7 @@ int ssh_try_publickey_from_file(ssh_session session, const char *keyfile,
|
||||
}
|
||||
|
||||
if (session->sshdir == NULL) {
|
||||
if (ssh_options_set(session, SSH_OPTIONS_SSH_DIR, NULL) < 0) {
|
||||
if (ssh_options_apply(session) < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -1145,7 +1145,7 @@ ssh_string try_publickey_from_file(ssh_session session, struct ssh_keys_struct k
|
||||
}
|
||||
|
||||
if (session->sshdir == NULL) {
|
||||
if (ssh_options_set(session, SSH_OPTIONS_SSH_DIR, NULL) < 0) {
|
||||
if (ssh_options_apply(session) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@@ -1457,6 +1457,7 @@ static int match_hashed_host(ssh_session session, const char *host,
|
||||
enter_function();
|
||||
|
||||
if (strncmp(sourcehash, "|1|", 3) != 0) {
|
||||
leave_function();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1550,7 +1551,6 @@ static int match_hashed_host(ssh_session session, const char *host,
|
||||
* if host key is accepted\n
|
||||
* SSH_SERVER_ERROR: Some error happened
|
||||
*
|
||||
* \see ssh_options_set()
|
||||
* \see ssh_get_pubkey_hash()
|
||||
*
|
||||
* \bug There is no current way to remove or modify an entry into the known
|
||||
@@ -1568,7 +1568,7 @@ int ssh_is_server_known(ssh_session session) {
|
||||
enter_function();
|
||||
|
||||
if (session->knownhosts == NULL) {
|
||||
if (ssh_options_set(session, SSH_OPTIONS_KNOWNHOSTS, NULL) < 0) {
|
||||
if (ssh_options_apply(session) < 0) {
|
||||
ssh_set_error(session, SSH_REQUEST_DENIED,
|
||||
"Can't find a known_hosts file");
|
||||
leave_function();
|
||||
@@ -1687,7 +1687,7 @@ int ssh_write_knownhost(ssh_session session) {
|
||||
}
|
||||
|
||||
if (session->knownhosts == NULL) {
|
||||
if (ssh_options_set(session, SSH_OPTIONS_KNOWNHOSTS, NULL) < 0) {
|
||||
if (ssh_options_apply(session) < 0) {
|
||||
ssh_set_error(session, SSH_FATAL, "Can't find a known_hosts file");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1308,6 +1308,9 @@ ssh_string ssh_do_sign(ssh_session session, ssh_buffer sigbuf,
|
||||
#endif
|
||||
sign->dsa_sign = NULL;
|
||||
break;
|
||||
default:
|
||||
signature_free(sign);
|
||||
return NULL;
|
||||
}
|
||||
#ifdef HAVE_LIBGCRYPT
|
||||
gcry_sexp_release(gcryhash);
|
||||
@@ -1463,6 +1466,9 @@ ssh_string ssh_sign_session_id(ssh_session session, ssh_private_key privatekey)
|
||||
#endif
|
||||
sign->dsa_sign = NULL;
|
||||
break;
|
||||
default:
|
||||
signature_free(sign);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBGCRYPT
|
||||
|
||||
@@ -129,9 +129,11 @@ char *ssh_get_user_home_dir(void) {
|
||||
|
||||
rc = getpwuid_r(getuid(), &pwd, buf, NSS_BUFLEN_PASSWD, &pwdbuf);
|
||||
if (rc != 0) {
|
||||
return NULL;
|
||||
szPath = getenv("HOME");
|
||||
return szPath ? strdup(szPath) : NULL;
|
||||
}
|
||||
|
||||
|
||||
szPath = strdup(pwd.pw_dir);
|
||||
|
||||
return szPath;
|
||||
@@ -504,7 +506,7 @@ int ssh_mkdir(const char *pathname, mode_t mode) {
|
||||
* @return The expanded directory, NULL on error.
|
||||
*/
|
||||
char *ssh_path_expand_tilde(const char *d) {
|
||||
char *h, *r;
|
||||
char *h = NULL, *r;
|
||||
const char *p;
|
||||
size_t ld;
|
||||
size_t lh = 0;
|
||||
@@ -548,13 +550,15 @@ char *ssh_path_expand_tilde(const char *d) {
|
||||
|
||||
r = malloc(ld + lh + 1);
|
||||
if (r == NULL) {
|
||||
SAFE_FREE(h);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (lh > 0) {
|
||||
memcpy(r, h, lh);
|
||||
}
|
||||
memcpy(r + lh, p, ld);
|
||||
SAFE_FREE(h);
|
||||
memcpy(r + lh, p, ld + 1);
|
||||
|
||||
return r;
|
||||
}
|
||||
@@ -634,6 +638,7 @@ char *ssh_path_expand_escape(ssh_session session, const char *s) {
|
||||
}
|
||||
l = strlen(buf);
|
||||
strcat(buf + l, x);
|
||||
buf[i] = '\0';
|
||||
SAFE_FREE(x);
|
||||
}
|
||||
|
||||
|
||||
@@ -187,6 +187,9 @@ int ssh_options_set_algo(ssh_session session, int algo,
|
||||
* set the hostname as the hostname is used as a key in
|
||||
* the known_host mechanism.
|
||||
*
|
||||
* - SSH_OPTIONS_BINDADDR:
|
||||
* The address to bind the client to (string).
|
||||
*
|
||||
* - SSH_OPTIONS_USER:
|
||||
* The username for authentication (string).\n
|
||||
* \n
|
||||
@@ -263,33 +266,6 @@ int ssh_options_set_algo(ssh_session session, int algo,
|
||||
* \n
|
||||
* See the corresponding numbers in libssh.h.
|
||||
*
|
||||
* - SSH_OPTTIONS_AUTH_CALLBACK:
|
||||
* Set a callback to use your own authentication function
|
||||
* (function pointer).
|
||||
*
|
||||
* - SSH_OPTTIONS_AUTH_USERDATA:
|
||||
* Set the user data passed to the authentication
|
||||
* function (generic pointer).
|
||||
*
|
||||
* - SSH_OPTTIONS_LOG_CALLBACK:
|
||||
* Set a callback to use your own logging function
|
||||
* (function pointer).
|
||||
*
|
||||
* - SSH_OPTTIONS_LOG_USERDATA:
|
||||
* Set the user data passed to the logging function
|
||||
* (generic pointer).
|
||||
*
|
||||
* - SSH_OPTTIONS_STATUS_CALLBACK:
|
||||
* Set a callback to show connection status in realtime
|
||||
* (function pointer).\n
|
||||
* \n
|
||||
* @code
|
||||
* fn(void *arg, float status)
|
||||
* @endcode
|
||||
* \n
|
||||
* During ssh_connect(), libssh will call the callback
|
||||
* with status from 0.0 to 1.0.
|
||||
*
|
||||
* - SSH_OPTTIONS_STATUS_ARG:
|
||||
* Set the status argument which should be passed to the
|
||||
* status callback (generic pointer).
|
||||
@@ -397,6 +373,18 @@ int ssh_options_set(ssh_session session, enum ssh_options_e type,
|
||||
session->fd = *x & 0xffff;
|
||||
}
|
||||
break;
|
||||
case SSH_OPTIONS_BINDADDR:
|
||||
if (value == NULL) {
|
||||
ssh_set_error_invalid(session, __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
q = strdup(value);
|
||||
if (q == NULL) {
|
||||
return -1;
|
||||
}
|
||||
SAFE_FREE(session->bindaddr);
|
||||
session->bindaddr = q;
|
||||
break;
|
||||
case SSH_OPTIONS_USER:
|
||||
SAFE_FREE(session->username);
|
||||
if (value == NULL) { /* set default username */
|
||||
@@ -1058,6 +1046,13 @@ int ssh_options_apply(ssh_session session) {
|
||||
}
|
||||
}
|
||||
|
||||
if (session->username == NULL) {
|
||||
rc = ssh_options_set(session, SSH_OPTIONS_USER, NULL);
|
||||
if (rc < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (session->knownhosts == NULL) {
|
||||
tmp = ssh_path_expand_escape(session, "%d/known_hosts");
|
||||
} else {
|
||||
|
||||
@@ -63,36 +63,69 @@ void ssh_poll_init(void) {
|
||||
return;
|
||||
}
|
||||
|
||||
void ssh_poll_cleanup(void) {
|
||||
return;
|
||||
}
|
||||
|
||||
int ssh_poll(ssh_pollfd_t *fds, nfds_t nfds, int timeout) {
|
||||
return poll((struct pollfd *) fds, nfds, timeout);
|
||||
}
|
||||
|
||||
#else /* HAVE_POLL */
|
||||
|
||||
typedef int (*poll_fn)(ssh_pollfd_t *, nfds_t, int);
|
||||
static poll_fn ssh_poll_emu;
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifndef STRICT
|
||||
#define STRICT
|
||||
#endif
|
||||
#endif /* STRICT */
|
||||
|
||||
#include <time.h>
|
||||
#include <windows.h>
|
||||
#include <winsock2.h>
|
||||
|
||||
#define WS2_LIBRARY "ws2_32.dll"
|
||||
typedef int (*poll_fn)(ssh_pollfd_t *, nfds_t, int);
|
||||
#if (_WIN32_WINNT < 0x0600)
|
||||
typedef struct ssh_pollfd_struct WSAPOLLFD;
|
||||
#endif
|
||||
|
||||
static poll_fn win_poll;
|
||||
typedef int (WSAAPI* WSAPoll_FunctionType)(WSAPOLLFD fdarray[],
|
||||
ULONG nfds,
|
||||
INT timeout
|
||||
);
|
||||
|
||||
static WSAPoll_FunctionType wsa_poll;
|
||||
|
||||
int win_poll(ssh_pollfd_t *fds, nfds_t nfds, int timeout) {
|
||||
if (wsa_poll) {
|
||||
return (wsa_poll)(fds, nfds, timeout);
|
||||
}
|
||||
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
|
||||
#define WS2_LIBRARY "ws2_32.dll"
|
||||
static HINSTANCE hlib;
|
||||
|
||||
#else
|
||||
#else /* _WIN32 */
|
||||
#include <sys/select.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
#endif /* _WIN32 */
|
||||
|
||||
|
||||
/*
|
||||
* This is a poll(2)-emulation using select for systems not providing a native
|
||||
* poll implementation.
|
||||
*
|
||||
* Keep in mind that select is terribly inefficient. The interface is simply not
|
||||
* meant to be used with maximum descriptor value greater, say, 32 or so. With
|
||||
* a value as high as 1024 on Linux you'll pay dearly in every single call.
|
||||
* poll() will be orders of magnitude faster.
|
||||
*/
|
||||
static int bsd_poll(ssh_pollfd_t *fds, nfds_t nfds, int timeout) {
|
||||
fd_set readfds, writefds, exceptfds;
|
||||
struct timeval tv, *ptv;
|
||||
@@ -110,10 +143,16 @@ static int bsd_poll(ssh_pollfd_t *fds, nfds_t nfds, int timeout) {
|
||||
FD_ZERO (&exceptfds);
|
||||
|
||||
/* compute fd_sets and find largest descriptor */
|
||||
for (max_fd = -1, i = 0; i < nfds; i++) {
|
||||
if (fds[i].fd < 0) {
|
||||
for (rc = -1, max_fd = 0, i = 0; i < nfds; i++) {
|
||||
if (fds[i].fd == SSH_INVALID_SOCKET) {
|
||||
continue;
|
||||
}
|
||||
#ifndef _WIN32
|
||||
if (fds[i].fd >= FD_SETSIZE) {
|
||||
rc = -1;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (fds[i].events & (POLLIN | POLLRDNORM)) {
|
||||
FD_SET (fds[i].fd, &readfds);
|
||||
@@ -124,15 +163,16 @@ static int bsd_poll(ssh_pollfd_t *fds, nfds_t nfds, int timeout) {
|
||||
if (fds[i].events & (POLLPRI | POLLRDBAND)) {
|
||||
FD_SET (fds[i].fd, &exceptfds);
|
||||
}
|
||||
if (fds[i].fd >= max_fd &&
|
||||
if (fds[i].fd > max_fd &&
|
||||
(fds[i].events & (POLLIN | POLLOUT | POLLPRI |
|
||||
POLLRDNORM | POLLRDBAND |
|
||||
POLLWRNORM | POLLWRBAND))) {
|
||||
max_fd = fds[i].fd;
|
||||
rc = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (max_fd == -1) {
|
||||
if (max_fd == SSH_INVALID_SOCKET || rc == -1) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
@@ -162,14 +202,16 @@ static int bsd_poll(ssh_pollfd_t *fds, nfds_t nfds, int timeout) {
|
||||
if (FD_ISSET(fds[i].fd, &readfds)) {
|
||||
int save_errno = errno;
|
||||
char data[64] = {0};
|
||||
int ret;
|
||||
|
||||
/* support for POLLHUP */
|
||||
ret = recv(fds[i].fd, data, 64, MSG_PEEK);
|
||||
#ifdef _WIN32
|
||||
if ((recv(fds[i].fd, data, 64, MSG_PEEK) == -1) &&
|
||||
if ((ret == -1) &&
|
||||
(errno == WSAESHUTDOWN || errno == WSAECONNRESET ||
|
||||
errno == WSAECONNABORTED || errno == WSAENETRESET)) {
|
||||
#else
|
||||
if ((recv(fds[i].fd, data, 64, MSG_PEEK) == -1) &&
|
||||
if ((ret == -1) &&
|
||||
(errno == ESHUTDOWN || errno == ECONNRESET ||
|
||||
errno == ECONNABORTED || errno == ENETRESET)) {
|
||||
#endif
|
||||
@@ -199,22 +241,33 @@ static int bsd_poll(ssh_pollfd_t *fds, nfds_t nfds, int timeout) {
|
||||
}
|
||||
|
||||
void ssh_poll_init(void) {
|
||||
poll_fn wsa_poll = NULL;
|
||||
ssh_poll_emu = bsd_poll;
|
||||
|
||||
#ifdef _WIN32
|
||||
hlib = LoadLibrary(WS2_LIBRARY);
|
||||
if (hlib != NULL) {
|
||||
wsa_poll = (poll_fn) GetProcAddress(hlib, "WSAPoll");
|
||||
wsa_poll = (WSAPoll_FunctionType) (void *) GetProcAddress(hlib, "WSAPoll");
|
||||
}
|
||||
#endif /* _WIN32 */
|
||||
|
||||
if (wsa_poll == NULL) {
|
||||
win_poll = bsd_poll;
|
||||
} else {
|
||||
win_poll = wsa_poll;
|
||||
if (wsa_poll != NULL) {
|
||||
ssh_poll_emu = bsd_poll;
|
||||
}
|
||||
}
|
||||
|
||||
void ssh_poll_cleanup(void) {
|
||||
ssh_poll_emu = bsd_poll;
|
||||
#ifdef _WIN32
|
||||
wsa_poll = NULL;
|
||||
|
||||
FreeLibrary(hlib);
|
||||
|
||||
hlib = NULL;
|
||||
#endif /* _WIN32 */
|
||||
}
|
||||
|
||||
int ssh_poll(ssh_pollfd_t *fds, nfds_t nfds, int timeout) {
|
||||
return win_poll(fds, nfds, timeout);
|
||||
return (ssh_poll_emu)(fds, nfds, timeout);
|
||||
}
|
||||
|
||||
#endif /* HAVE_POLL */
|
||||
@@ -389,7 +442,7 @@ void ssh_poll_ctx_free(ssh_poll_ctx ctx) {
|
||||
used = ctx->polls_used;
|
||||
for (i = 0; i < used; ) {
|
||||
ssh_poll_handle p = ctx->pollptrs[i];
|
||||
int fd = ctx->pollfds[i].fd;
|
||||
socket_t fd = ctx->pollfds[i].fd;
|
||||
|
||||
/* force poll object removal */
|
||||
if (p->cb(p, fd, POLLERR, p->cb_data) < 0) {
|
||||
@@ -437,7 +490,7 @@ static int ssh_poll_ctx_resize(ssh_poll_ctx ctx, size_t new_size) {
|
||||
* @return 0 on success, < 0 on error
|
||||
*/
|
||||
int ssh_poll_ctx_add(ssh_poll_ctx ctx, ssh_poll_handle p) {
|
||||
int fd;
|
||||
socket_t fd;
|
||||
|
||||
if (p->ctx != NULL) {
|
||||
/* already attached to a context */
|
||||
@@ -516,7 +569,7 @@ int ssh_poll_ctx_dopoll(ssh_poll_ctx ctx, int timeout) {
|
||||
i++;
|
||||
} else {
|
||||
ssh_poll_handle p = ctx->pollptrs[i];
|
||||
int fd = ctx->pollfds[i].fd;
|
||||
socket_t fd = ctx->pollfds[i].fd;
|
||||
int revents = ctx->pollfds[i].revents;
|
||||
|
||||
if (p->cb(p, fd, revents, p->cb_data) < 0) {
|
||||
|
||||
@@ -129,7 +129,7 @@ ssh_bind ssh_bind_new(void) {
|
||||
return NULL;
|
||||
}
|
||||
ZERO_STRUCTP(ptr);
|
||||
ptr->bindfd = -1;
|
||||
ptr->bindfd = SSH_INVALID_SOCKET;
|
||||
ptr->bindport= 22;
|
||||
ptr->log_verbosity = 0;
|
||||
|
||||
@@ -138,7 +138,7 @@ ssh_bind ssh_bind_new(void) {
|
||||
|
||||
int ssh_bind_listen(ssh_bind sshbind) {
|
||||
const char *host;
|
||||
int fd;
|
||||
socket_t fd;
|
||||
|
||||
if (ssh_init() < 0) {
|
||||
return -1;
|
||||
@@ -185,10 +185,10 @@ void ssh_bind_fd_toaccept(ssh_bind sshbind) {
|
||||
int ssh_bind_accept(ssh_bind sshbind, ssh_session session) {
|
||||
ssh_private_key dsa = NULL;
|
||||
ssh_private_key rsa = NULL;
|
||||
int fd = -1;
|
||||
socket_t fd = SSH_INVALID_SOCKET;
|
||||
int i;
|
||||
|
||||
if (sshbind->bindfd < 0) {
|
||||
if (sshbind->bindfd == SSH_INVALID_SOCKET) {
|
||||
ssh_set_error(sshbind, SSH_FATAL,
|
||||
"Can't accept new clients on a not bound socket.");
|
||||
return SSH_ERROR;
|
||||
@@ -219,7 +219,7 @@ int ssh_bind_accept(ssh_bind sshbind, ssh_session session) {
|
||||
}
|
||||
|
||||
fd = accept(sshbind->bindfd, NULL, NULL);
|
||||
if (fd < 0) {
|
||||
if (fd == SSH_INVALID_SOCKET) {
|
||||
ssh_set_error(sshbind, SSH_FATAL,
|
||||
"Accepting a new connection: %s",
|
||||
strerror(errno));
|
||||
@@ -246,6 +246,7 @@ int ssh_bind_accept(ssh_bind sshbind, ssh_session session) {
|
||||
if (sshbind->bindaddr == NULL)
|
||||
session->bindaddr = NULL;
|
||||
else {
|
||||
SAFE_FREE(session->bindaddr);
|
||||
session->bindaddr = strdup(sshbind->bindaddr);
|
||||
if (session->bindaddr == NULL) {
|
||||
privatekey_free(dsa);
|
||||
@@ -284,7 +285,7 @@ void ssh_bind_free(ssh_bind sshbind){
|
||||
close(sshbind->bindfd);
|
||||
#endif
|
||||
}
|
||||
sshbind->bindfd = -1;
|
||||
sshbind->bindfd = SSH_INVALID_SOCKET;
|
||||
|
||||
/* options */
|
||||
SAFE_FREE(sshbind->banner);
|
||||
|
||||
@@ -104,7 +104,7 @@ ssh_session ssh_new(void) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
id = strdup("SSH_DIR/id_rsa");
|
||||
id = strdup("%d/id_rsa");
|
||||
if (id == NULL) {
|
||||
goto err;
|
||||
}
|
||||
@@ -113,7 +113,7 @@ ssh_session ssh_new(void) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
id = strdup("SSH_DIR/id_dsa");
|
||||
id = strdup("%d/id_dsa");
|
||||
if (id == NULL) {
|
||||
goto err;
|
||||
}
|
||||
@@ -122,7 +122,7 @@ ssh_session ssh_new(void) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
id = strdup("SSH_DIR/identity");
|
||||
id = strdup("%d/identity");
|
||||
if (id == NULL) {
|
||||
goto err;
|
||||
}
|
||||
@@ -153,6 +153,7 @@ void ssh_free(ssh_session session) {
|
||||
|
||||
SAFE_FREE(session->serverbanner);
|
||||
SAFE_FREE(session->clientbanner);
|
||||
SAFE_FREE(session->bindaddr);
|
||||
SAFE_FREE(session->banner);
|
||||
#ifdef WITH_PCAP
|
||||
if(session->pcap_ctx){
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
@@ -3122,7 +3123,10 @@ static sftp_attributes sftp_xstat(sftp_session sftp, const char *path,
|
||||
}
|
||||
|
||||
if (msg->packet_type == SSH_FXP_ATTRS) {
|
||||
return sftp_parse_attr(sftp, msg->payload, 0);
|
||||
sftp_attributes attr = sftp_parse_attr(sftp, msg->payload, 0);
|
||||
sftp_message_free(msg);
|
||||
|
||||
return attr;
|
||||
} else if (msg->packet_type == SSH_FXP_STATUS) {
|
||||
status = parse_status_msg(msg);
|
||||
sftp_message_free(msg);
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
extern const char **environ;
|
||||
extern char **environ;
|
||||
#endif
|
||||
#include "libssh/priv.h"
|
||||
#include "libssh/socket.h"
|
||||
@@ -72,11 +72,20 @@ int ssh_socket_init(void) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ssh_poll_init();
|
||||
#endif
|
||||
ssh_poll_init();
|
||||
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
|
||||
/**
|
||||
* @brief Cleanup the socket system.
|
||||
*/
|
||||
void ssh_socket_cleanup(void) {
|
||||
ssh_poll_cleanup();
|
||||
}
|
||||
|
||||
/**
|
||||
* \internal
|
||||
* \brief creates a new Socket object
|
||||
*/
|
||||
@@ -87,7 +96,7 @@ struct socket *ssh_socket_new(ssh_session session) {
|
||||
if (s == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
s->fd = -1;
|
||||
s->fd = SSH_INVALID_SOCKET;
|
||||
s->last_errno = -1;
|
||||
s->session = session;
|
||||
s->in_buffer = buffer_new();
|
||||
@@ -129,20 +138,20 @@ int ssh_socket_unix(struct socket *s, const char *path) {
|
||||
snprintf(sunaddr.sun_path, sizeof(sunaddr.sun_path), "%s", path);
|
||||
|
||||
s->fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (s->fd < 0) {
|
||||
if (s->fd == SSH_INVALID_SOCKET) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fcntl(s->fd, F_SETFD, 1) == -1) {
|
||||
close(s->fd);
|
||||
s->fd = -1;
|
||||
s->fd = SSH_INVALID_SOCKET;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (connect(s->fd, (struct sockaddr *) &sunaddr,
|
||||
sizeof(sunaddr)) < 0) {
|
||||
close(s->fd);
|
||||
s->fd = -1;
|
||||
s->fd = SSH_INVALID_SOCKET;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -162,7 +171,7 @@ void ssh_socket_close(struct socket *s){
|
||||
close(s->fd);
|
||||
s->last_errno = errno;
|
||||
#endif
|
||||
s->fd=-1;
|
||||
s->fd = SSH_INVALID_SOCKET;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -184,7 +193,7 @@ socket_t ssh_socket_get_fd(struct socket *s) {
|
||||
* \brief returns nonzero if the socket is open
|
||||
*/
|
||||
int ssh_socket_is_open(struct socket *s) {
|
||||
return s->fd != -1;
|
||||
return s->fd != SSH_INVALID_SOCKET;
|
||||
}
|
||||
|
||||
/* \internal
|
||||
@@ -242,22 +251,25 @@ static int ssh_socket_unbuffered_write(struct socket *s, const void *buffer,
|
||||
* \brief returns nonzero if the current socket is in the fd_set
|
||||
*/
|
||||
int ssh_socket_fd_isset(struct socket *s, fd_set *set) {
|
||||
if(s->fd == -1) {
|
||||
if(s->fd == SSH_INVALID_SOCKET) {
|
||||
return 0;
|
||||
}
|
||||
return FD_ISSET(s->fd,set);
|
||||
}
|
||||
|
||||
/* \internal
|
||||
* \brief sets the current fd in a fd_set and updates the fd_max
|
||||
* \brief sets the current fd in a fd_set and updates the max_fd
|
||||
*/
|
||||
|
||||
void ssh_socket_fd_set(struct socket *s, fd_set *set, int *fd_max) {
|
||||
if (s->fd == -1)
|
||||
void ssh_socket_fd_set(struct socket *s, fd_set *set, socket_t *max_fd) {
|
||||
if (s->fd == SSH_INVALID_SOCKET)
|
||||
return;
|
||||
FD_SET(s->fd,set);
|
||||
if (s->fd >= *fd_max) {
|
||||
*fd_max = s->fd + 1;
|
||||
|
||||
if (s->fd >= 0 &&
|
||||
s->fd >= *max_fd &&
|
||||
s->fd != SSH_INVALID_SOCKET) {
|
||||
*max_fd = s->fd + 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -440,7 +452,7 @@ int ssh_socket_wait_for_data(struct socket *s, ssh_session session, uint32_t len
|
||||
if (ssh_socket_is_open(session->socket)) {
|
||||
r = ssh_socket_unbuffered_read(session->socket, buffer, sizeof(buffer));
|
||||
} else {
|
||||
r =- 1;
|
||||
r = -1;
|
||||
}
|
||||
|
||||
if (r <= 0) {
|
||||
@@ -480,6 +492,7 @@ int ssh_socket_poll(struct socket *s, int *writeable, int *except) {
|
||||
|
||||
fd->fd = s->fd;
|
||||
fd->events = 0;
|
||||
fd->revents = 0;
|
||||
|
||||
if (!s->data_to_read) {
|
||||
fd->events |= POLLIN;
|
||||
@@ -487,13 +500,15 @@ int ssh_socket_poll(struct socket *s, int *writeable, int *except) {
|
||||
if (!s->data_to_write) {
|
||||
fd->events |= POLLOUT;
|
||||
}
|
||||
|
||||
/* Make the call, and listen for errors */
|
||||
rc = ssh_poll(fd, 1, 0);
|
||||
if (rc < 0) {
|
||||
ssh_set_error(session, SSH_FATAL, "poll(): %s", strerror(errno));
|
||||
leave_function();
|
||||
return -1;
|
||||
/* do not do poll if fd->events is empty, we already know the response */
|
||||
if(fd->events != 0){
|
||||
/* Make the call, and listen for errors */
|
||||
rc = ssh_poll(fd, 1, 0);
|
||||
if (rc < 0) {
|
||||
ssh_set_error(session, SSH_FATAL, "poll(): %s", strerror(errno));
|
||||
leave_function();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!s->data_to_read) {
|
||||
@@ -547,7 +562,7 @@ int ssh_socket_nonblocking_flush(struct socket *s) {
|
||||
buffer_get_rest_len(s->out_buffer));
|
||||
} else {
|
||||
/* write failed */
|
||||
w =- 1;
|
||||
w = -1;
|
||||
}
|
||||
|
||||
if (w < 0) {
|
||||
|
||||
Reference in New Issue
Block a user