Compare commits

...

68 Commits

Author SHA1 Message Date
Andreas Schneider
62f7eaf156 misc: Updated the changelog. 2010-09-05 17:57:48 +02:00
Andreas Schneider
2462b0fbc7 build: Increase version number. 2010-09-05 17:54:03 +02:00
Andreas Schneider
c05666245c build: Fixed a wrong if statement.
(cherry picked from commit 461dde231c)
2010-09-05 13:13:01 +02:00
Andreas Schneider
6db13f776f build: Fixed build with gcc 3.4.
The -fvisibility=hidden flag is broken in gcc 3.4. This fixes the build
on CentOS, bug #74.
2010-09-05 13:00:51 +02:00
Andreas Schneider
0980117c52 build: Fixed checking for printf function on Windows. 2010-09-02 11:50:59 +02:00
Andreas Schneider
3d66164545 poll: Fixed the Windows build on Vista and newer. 2010-09-01 23:31:06 +02:00
Aris Adamantiadis
c087e8704d Fixes bug #99
returns error when no cryptographic context is available
2010-08-28 23:38:53 +02:00
Andreas Schneider
e5801287da poll: Fixed the ssh_poll_(init/cleanup) functions. 2010-08-25 23:12:27 +02:00
Andreas Schneider
5b9d92c36f poll: Fixed the usage of WSAPoll() on Windows.
This should fix ticket #101.
2010-08-25 23:12:27 +02:00
Andreas Schneider
edc6b2cef2 poll: Added a cleanup function to free the ws2_32 library. 2010-08-25 23:12:26 +02:00
Aris Adamantiadis
9590a643ab Fixed "@deprecated" in doxygen 2010-08-20 12:59:42 +02:00
Aris Adamantiadis
bec9bc1222 Changed SSH_SUCCESS to SSH_OK 2010-08-20 12:58:48 +02:00
Aris Adamantiadis
b3067e362c Obsoletes ssh_auth_list, comment ssh_userauth_list
Conflicts:

	libssh/auth.c
2010-08-19 19:53:16 +02:00
Andreas Schneider
5f99fed07c build: Fixed some mingw warnings. 2010-07-24 21:36:00 +02:00
Andreas Schneider
9973de535e priv: Fixed a mingw build bug. 2010-07-24 10:10:33 +02:00
Aris Adamantiadis
a7d9f4addd Correctly handle failed opened channels 2010-07-19 22:50:15 +02:00
Aris Adamantiadis
a4f4fa3058 Fixed keepalive problem on older openssh servers 2010-07-16 23:04:54 +02:00
Aris Adamantiadis
a9c4877d84 New example for port forwarding 2010-07-16 22:45:12 +02:00
Andreas Schneider
284466632e build: InstallRequiredSystemLibraries isn't needed. 2010-07-16 08:58:32 +02:00
Andreas Schneider
aa8381999a build: Fixed the NSIS build. 2010-07-13 17:49:01 +02:00
Andreas Schneider
ac54a26c5d build: Fixed the Windows build.
We have to include stdio.h for the printf function before we can do
anything.
2010-07-13 17:27:52 +02:00
Andreas Schneider
fd53ebc7b6 build: Define values for printf functions. 2010-07-13 17:25:48 +02:00
Andreas Schneider
df2436b4a6 build: Don't test for big endian on Windows.
Visual Studio 2010 has problems running the test.
2010-07-13 16:08:43 +02:00
Andreas Schneider
7029d2f4b8 build: Fixed the Windows preprocessor macros and defines. 2010-07-13 15:10:19 +02:00
Andreas Schneider
3c9c358385 build: Set a default zlib search path for windows. 2010-07-13 14:03:54 +02:00
Andreas Schneider
82d1627cad build: Set a default openssl search path for windows. 2010-07-13 14:03:25 +02:00
Andreas Schneider
641e89b14a build: Fixed typo. 2010-07-13 13:25:20 +02:00
Andreas Schneider
3a61d55f27 build: Added a check for NSIS. 2010-07-13 13:19:06 +02:00
Andreas Schneider
c4d1d8b684 build: Increase version numbers. 2010-07-13 10:15:22 +02:00
Andreas Schneider
10e27f26be build: Updated ChangeLog. 2010-07-12 09:48:22 +02:00
Andreas Schneider
9791bc3eeb poll: Added poll constants for Windows.
WSAPoll uses different constanst values as the POSIX implementation,
what else ...
2010-07-09 09:46:57 +02:00
Andreas Schneider
4ad7828797 options: Added option to bind a client to an ip address.
Thanks to Donatello Boccaforno <donatello.boccaforno@gmail.com>.
2010-07-07 12:40:49 +02:00
Aris Adamantiadis
af8315b9ce Fixed ssh_socket_poll behaviour 2010-07-07 10:00:09 +02:00
Andreas Schneider
94fdcf7a2a socket: Fixed ssh_socket_poll().
If we don't have date to read or write, leave ssh_socket_poll().
2010-07-06 23:18:16 +02:00
Andreas Schneider
59a95fc3a7 poll: FD_SETSIZE is only for the count value of FD_SET on Windows. 2010-07-06 00:40:19 +02:00
Andreas Schneider
c1729c36d9 socket: Fixed a prototype. 2010-06-25 16:20:38 +02:00
Andreas Schneider
23efab0f8f socket: Fixed conflicting types. 2010-06-24 20:05:10 +02:00
Andreas Schneider
e50752a925 poll: Another attempt to get bsd_poll() working correctly. 2010-06-24 09:17:39 +02:00
Andreas Schneider
fd45c1b36b poll: Fixed building with poll-emulation on UNIX. 2010-06-24 09:16:58 +02:00
Andreas Schneider
5080671581 agent: Use the our poll typedef. 2010-06-24 09:14:07 +02:00
Andreas Schneider
e67fafd60f poll: Added a comment to the bsd_poll() implementation. 2010-06-22 14:45:08 +02:00
Andreas Schneider
a2a98fb5bc poll: Handle FD_SETSIZE in bsd_poll(). 2010-06-22 14:44:54 +02:00
Andreas Schneider
e2480fbaba poll: Fixed a comparsion. 2010-06-22 14:43:09 +02:00
Andreas Schneider
23e6b36209 poll: Fixed a typo. 2010-06-21 15:41:58 +02:00
Andreas Schneider
541b38b772 poll: Check if maxfd has been set. 2010-06-20 21:16:29 +02:00
Andreas Schneider
a85a4cc192 connect: Fixed some socket build warnings on windows. 2010-06-18 12:43:12 +02:00
Andreas Schneider
54ef77123a server: Fixed types and checks of fd's. 2010-06-17 13:36:14 +02:00
Andreas Schneider
4c679fd8a6 poll: Fixed type of the fd variables and use SSH_INVALID_SOCKET. 2010-06-17 13:35:40 +02:00
Andreas Schneider
21d918c68a client: Fixed fd type and checks. 2010-06-17 13:33:52 +02:00
Andreas Schneider
544fc28e6b channel: Fixed the type of the max fd variable in ssh_channel_select(). 2010-06-17 13:32:14 +02:00
Andreas Schneider
601081ebb6 agent: Use ssh_poll in agent code. 2010-06-17 13:31:35 +02:00
Andreas Schneider
22d975a24b socket: Fixed checks for max fd. 2010-06-17 13:18:23 +02:00
Andreas Schneider
aeb9f3e389 poll: Fixed brackets. 2010-06-17 12:02:06 +02:00
Andreas Schneider
d3a4e01137 poll: Fixed another wrong invalid fd check in bsd_poll. 2010-06-17 11:49:28 +02:00
Andreas Schneider
a1b9ae5048 poll: Some code cleanup for easier debugging. 2010-06-17 11:23:58 +02:00
Andreas Schneider
a375ebe29b poll: Fixed a malfunction with wrong max fd value check. 2010-06-17 11:23:50 +02:00
Andreas Schneider
b2f49a6a93 config: Use ssh log and error functions for problems. 2010-06-03 16:46:17 +02:00
Andreas Schneider
99fb5987ce socket: Fixed signed values which could be seen as an unary operator. 2010-06-02 10:14:53 +02:00
Andreas Schneider
be389dd644 socket: According to execle(2) environ shouldn't be const. 2010-06-01 21:47:15 +02:00
Andreas Schneider
a6a7922dbd Update Changelog. 2010-05-31 19:36:32 +02:00
Aris Adamantiadis
608e81bc00 Fix warning for snprintf 2010-05-31 11:52:36 +03:00
Aris Adamantiadis
7e17838c0b Fix unclean null termination in ~ expending 2010-05-31 11:50:52 +03:00
Andreas Schneider
84f6945a9c Increased version numbers. 2010-05-30 11:26:11 +02:00
Andreas Schneider
3ae187dbe7 misc: Make sure the expanded string is null-terminated. 2010-05-30 11:00:38 +02:00
Andreas Schneider
26989ab001 session: Fixed setting up default identity files. 2010-05-28 10:47:37 +02:00
Andreas Schneider
5b2e39cd79 options: Make sure that we have always have default options set. 2010-05-21 10:21:03 +02:00
Andreas Schneider
13af149ef9 options: Set the local username if still not set. 2010-05-21 10:19:06 +02:00
Andreas Schneider
3453cafd95 keyfiles: Fixed possible problem with known_hosts path. 2010-05-21 10:03:13 +02:00
31 changed files with 705 additions and 211 deletions

View File

@@ -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 "6")
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.3")
set(LIBRARY_SOVERSION "4")
# where to look first for cmake modules, before ${CMAKE_ROOT}/Modules/ is checked

View File

@@ -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 "6")
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")

View File

@@ -1,6 +1,29 @@
ChangeLog
==========
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().

View File

@@ -17,9 +17,25 @@ 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)
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)
# HEADER FILES
check_include_file(argp.h HAVE_ARGP_H)
@@ -39,18 +55,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 +69,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 +135,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)

View 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)

View File

@@ -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)

View File

@@ -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

View File

@@ -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 */

View File

@@ -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
View 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;
}

View File

@@ -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 6
#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 {
@@ -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 {

View File

@@ -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);

View File

@@ -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"

View File

@@ -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;

View File

@@ -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);

View File

@@ -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;

View File

@@ -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 */
@@ -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;
}
@@ -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 {

View File

@@ -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().
*/
@@ -1594,7 +1596,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 +1647,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 +1697,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 +2152,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 +2162,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 +2230,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);

View File

@@ -481,7 +481,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 +498,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 +512,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 +522,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;
}

View File

@@ -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;

View File

@@ -390,6 +390,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 +431,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 +494,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);
}
}

View File

@@ -831,8 +831,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) {

View File

@@ -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

View File

@@ -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;
}
}
@@ -1550,7 +1550,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 +1567,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 +1686,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;
}

View File

@@ -554,7 +554,7 @@ char *ssh_path_expand_tilde(const char *d) {
if (lh > 0) {
memcpy(r, h, lh);
}
memcpy(r + lh, p, ld);
memcpy(r + lh, p, ld + 1);
return r;
}
@@ -634,6 +634,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);
}

View File

@@ -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
@@ -397,6 +400,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 +1073,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 {

View File

@@ -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) {

View File

@@ -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));
@@ -284,7 +284,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);

View File

@@ -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;
}

View File

@@ -29,6 +29,7 @@
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>

View File

@@ -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,22 @@ 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 != SSH_INVALID_SOCKET) {
*max_fd = s->fd + 1;
}
}
@@ -440,7 +449,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) {
@@ -487,13 +496,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 +558,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) {