Compare commits

...

37 Commits

Author SHA1 Message Date
Andreas Schneider
789df0b7d0 Bump version to 0.8.4
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-16 09:25:01 +02:00
Andreas Schneider
66a222a73c Bump ABI to 4.7.1
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 60037f3275)
2018-10-16 09:25:01 +02:00
Anderson Toshiyuki Sasaki
09a7638575 CVE-2018-10933: Add tests for packet filtering
Created the test torture_packet_filter.c which tests if packets are
being correctly filtered.

Fixes T101

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-16 09:19:40 +02:00
Anderson Toshiyuki Sasaki
203818608a CVE-2018-10933: Introduced packet filtering
The packet filter checks required states for the incoming packets and
reject them if they arrived in the wrong state.

Fixes T101

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-16 09:19:40 +02:00
Anderson Toshiyuki Sasaki
f8c452cbef CVE-2018-10933: Check channel state when OPEN_FAILURE arrives
When a SSH2_MSG_OPEN_FAILURE arrives, the channel state is checked
to be in SSH_CHANNEL_STATE_OPENING.

Fixes T101

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-16 09:19:40 +02:00
Anderson Toshiyuki Sasaki
adeaa69cc5 CVE-2018-10933: Check channel state when OPEN_CONFIRMATION arrives
When a SSH2_MSG_OPEN_CONFIRMATION arrives, the channel state is checked
to be in SSH_CHANNEL_STATE_OPENING.

Fixes T101

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-16 09:19:40 +02:00
Anderson Toshiyuki Sasaki
72bce5ece7 CVE-2018-10933: Set correct state after sending MIC
After sending the client token, the auth state is set as
SSH_AUTH_STATE_GSSAPI_MIC_SENT.  Then this can be expected to be the
state when a USERAUTH_FAILURE or USERAUTH_SUCCESS arrives.

Fixes T101

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-16 09:19:40 +02:00
Anderson Toshiyuki Sasaki
7819621fc2 CVE-2018-10933: Introduce SSH_AUTH_STATE_AUTH_NONE_SENT
The introduced auth state allows to identify when a request without
authentication information was sent.

Fixes T101

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-16 09:19:40 +02:00
Anderson Toshiyuki Sasaki
fcfba0d8aa CVE-2018-10933: Introduce SSH_AUTH_STATE_PASSWORD_AUTH_SENT
The introduced auth state allows to identify when authentication using
password was tried.

Fixes T101

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-16 09:19:40 +02:00
Anderson Toshiyuki Sasaki
b166ac4749 CVE-2018-10933: Introduced new auth states
Introduced the states SSH_AUTH_STATE_PUBKEY_OFFER_SENT and
SSH_AUTH_STATE_PUBKEY_AUTH_SENT to know when SSH2_MSG_USERAUTH_PK_OK and
SSH2_MSG_USERAUTH_SUCCESS should be expected.

Fixes T101

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-16 09:19:40 +02:00
Tilo Eckert
160a416ef6 chacha: remove re-declared type
re-declaring typedefs are not supported by some compilers

Signed-off-by: Tilo Eckert <tilo.eckert@flam.de>
(cherry picked from commit d13517e922)
2018-10-13 22:09:18 +02:00
Tilo Eckert
59071bc4c5 knownhosts: Fix invalid read of known_hosts token
Fixes invalid read introduced by commit 21962d.
Accessing tokens[4] for a known_hosts line of
three tokens led to randomly rejected host keys.

This commit completely removes the check because
the optional comments field may contain whitespace.

Signed-off-by: Tilo Eckert <tilo.eckert@flam.de>
(cherry picked from commit 45058285fc)
2018-10-13 22:09:16 +02:00
Andreas Schneider
2ae63251d3 init: Only add DllMain if we create a shared library
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit f747e46f33)
2018-10-09 11:40:54 +02:00
Andreas Schneider
eefae820b5 cmake: Always build position independent code
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
2018-10-02 15:26:52 +02:00
Anderson Toshiyuki Sasaki
0792fb37b0 messages: Fixed possible memory leak in ssh_message_queue
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit cc513c4c9a)
2018-09-27 15:39:20 +02:00
Anderson Toshiyuki Sasaki
e23c28a82b examples: Add null checks in libssh_scp.c
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 31202822a7)
2018-09-27 15:39:20 +02:00
Anderson Toshiyuki Sasaki
7291b50420 examples: Fix libssh_scp.c code style
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 6118628424)
2018-09-27 15:39:20 +02:00
Anderson Toshiyuki Sasaki
c1d61617fb examples: Fix possible memory leak in libssh_scp.c
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 00e5ef1b3c)
2018-09-27 15:39:20 +02:00
Anderson Toshiyuki Sasaki
488fb47c32 tests: Add frees to avoid memory leak errors
The added frees are unnecessary, but the static analyser does not know.

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 6eef4b4a3c)
2018-09-27 15:39:20 +02:00
Anderson Toshiyuki Sasaki
721132696c tests: Replace ssh_buffer_free() with SSH_BUFFER_FREE()
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 79e907402e)
2018-09-27 15:39:20 +02:00
Anderson Toshiyuki Sasaki
ee034e0484 tests: Replace ssh_string_free() with SSH_STRING_FREE()
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit ca7da823c3)
2018-09-27 15:39:20 +02:00
Anderson Toshiyuki Sasaki
d56c8fdfc6 tests: Replace ssh_key_free() with SSH_KEY_FREE()
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 2eaa23a20e)
2018-09-27 15:39:20 +02:00
Anderson Toshiyuki Sasaki
4269b62153 tests: Use SSH_STRING_FREE_CHAR
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 143b5e2e50)
2018-09-27 15:39:20 +02:00
Anderson Toshiyuki Sasaki
c6c63030c5 include: Add SSH_KEY_FREE
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 11d480134c)
2018-09-27 15:39:20 +02:00
Alberto Aguirre
afa5dbb8b1 sftpserver: allocate packet on sftp_server_new
Ensure sftp_server_new allocates the packet and payload as
sftp_packet_read now expects the packet and payload to be
pre-allocated.

Similarly, ensure sftp_get_client_message does not free the packet.

Signed-off-by: Alberto Aguirre <albaguirre@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 14f5624ff5)
2018-09-25 16:42:08 +02:00
David Wedderwille
bd7e8295e2 connector: Add checks if file descriptor is a socket
Fixes T104

Signed-off-by: David Wedderwille <davidwe@posteo.de>
(cherry picked from commit 9adc2d36eb)
2018-09-25 16:41:31 +02:00
Andreas Schneider
933d9c6b07 socket: Pass MSG_NOSIGNAL to send()
This avoid that we get a SIGPIPE.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 1e5e09563a)
2018-09-25 16:41:31 +02:00
Andreas Schneider
0f0eb05e03 socket: Return ssize_t for ssh_socket_unbuffered_write()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 35bf5334b8)
2018-09-25 16:41:31 +02:00
Andreas Schneider
171a950a80 socket: Reformat ssh_socket_write()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit a7604c7d6e)
2018-09-25 16:41:31 +02:00
Andreas Schneider
b1b1da0f97 socket: Reformat ssh_socket_unbuffered_write()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit c5cadaa982)
2018-09-25 16:41:31 +02:00
Andreas Schneider
7453038d74 socket: Return ssize_t for ssh_socket_unbuffered_read()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit caf50270c6)
2018-09-25 16:41:31 +02:00
Andreas Schneider
29ef92a95e socket: Reformat ssh_socket_pollcallback()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit b7a29c7ffd)
2018-09-25 16:41:31 +02:00
Andreas Schneider
6650685758 socket: Reformat ssh_socket_unbuffered_read()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 491a42d046)
2018-09-25 16:41:31 +02:00
Andreas Schneider
bdca6b7efa connect: Fix build warning on Windows
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 642a1b1aa4)
2018-09-25 16:41:31 +02:00
Andreas Schneider
97b2a61d74 config: Fix building without globbing support
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit f709c3ac58)
2018-09-25 16:41:31 +02:00
Andreas Schneider
781ce47dea include: Do not declare ssh_channel_new() twice
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit ae2b9a3bde)
2018-09-25 16:41:31 +02:00
Andreas Schneider
277ee932d6 cmake: Add -Wattributs for configure checks
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 1d7520b68a)
2018-09-25 16:41:31 +02:00
39 changed files with 2754 additions and 656 deletions

View File

@@ -10,7 +10,7 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules")
include(DefineCMakeDefaults)
include(DefineCompilerFlags)
project(libssh VERSION 0.8.3 LANGUAGES C)
project(libssh VERSION 0.8.4 LANGUAGES C)
# global needed variable
set(APPLICATION_NAME ${PROJECT_NAME})
@@ -22,7 +22,7 @@ set(APPLICATION_NAME ${PROJECT_NAME})
# Increment AGE. Set REVISION to 0
# If the source code was changed, but there were no interface changes:
# Increment REVISION.
set(LIBRARY_VERSION "4.7.0")
set(LIBRARY_VERSION "4.7.1")
set(LIBRARY_SOVERSION "4")
# where to look first for cmake modules, before ${CMAKE_ROOT}/Modules/ is checked

View File

@@ -1,6 +1,12 @@
ChangeLog
==========
version 0.8.4 (released 2018-10-16)
* Fixed CVE-2018-10933
* Fixed building without globbing support
* Fixed possible memory leaks
* Avoid SIGPIPE on sockets
version 0.8.3 (released 2018-09-21)
* Added support for rsa-sha2
* Added support to parse private keys in openssh container format

View File

@@ -273,6 +273,13 @@ int main(void) {
# For detecting attributes we need to treat warnings as
# errors
if (UNIX)
# Get warnings for attributs
check_c_compiler_flag("-Wattributs" REQUIRED_FLAGS_WERROR)
if (REQUIRED_FLAGS_WERROR)
set(CMAKE_REQUIRED_FLAGS "-Wattributes")
endif()
# Turn warnings into errors
check_c_compiler_flag("-Werror" REQUIRED_FLAGS_WERROR)
if (REQUIRED_FLAGS_WERROR)
set(CMAKE_REQUIRED_FLAGS "-Werror")

View File

@@ -16,3 +16,6 @@ set(CMAKE_COLOR_MAKEFILE ON)
# Create the compile command database for clang by default
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
# Always build with -fPIC
set(CMAKE_POSITION_INDEPENDENT_CODE ON)

View File

@@ -25,148 +25,230 @@ program.
static char **sources;
static int nsources;
static char *destination;
static int verbosity=0;
static int verbosity = 0;
struct location {
int is_ssh;
char *user;
char *host;
char *path;
ssh_session session;
ssh_scp scp;
FILE *file;
int is_ssh;
char *user;
char *host;
char *path;
ssh_session session;
ssh_scp scp;
FILE *file;
};
enum {
READ,
WRITE
READ,
WRITE
};
static void usage(const char *argv0){
fprintf(stderr,"Usage : %s [options] [[user@]host1:]file1 ... \n"
" [[user@]host2:]destination\n"
"sample scp client - libssh-%s\n",
// "Options :\n",
// " -r : use RSA to verify host public key\n",
argv0,
ssh_version(0));
exit(0);
static void usage(const char *argv0) {
fprintf(stderr, "Usage : %s [options] [[user@]host1:]file1 ... \n"
" [[user@]host2:]destination\n"
"sample scp client - libssh-%s\n",
// "Options :\n",
// " -r : use RSA to verify host public key\n",
argv0,
ssh_version(0));
exit(0);
}
static int opts(int argc, char **argv){
int i;
while((i=getopt(argc,argv,"v"))!=-1){
switch(i){
case 'v':
verbosity++;
break;
default:
fprintf(stderr,"unknown option %c\n",optopt);
static int opts(int argc, char **argv) {
int i;
while((i = getopt(argc, argv, "v")) != -1) {
switch(i) {
case 'v':
verbosity++;
break;
default:
fprintf(stderr, "unknown option %c\n", optopt);
usage(argv[0]);
return -1;
}
}
nsources = argc - optind - 1;
if (nsources < 1) {
usage(argv[0]);
return -1;
}
}
nsources=argc-optind-1;
if(nsources < 1){
usage(argv[0]);
return -1;
}
sources=malloc((nsources + 1) * sizeof(char *));
if(sources == NULL)
return -1;
for(i=0;i<nsources;++i){
sources[i] = argv[optind];
optind++;
}
sources[i]=NULL;
destination=argv[optind];
return 0;
sources = malloc((nsources + 1) * sizeof(char *));
if (sources == NULL) {
return -1;
}
for(i = 0; i < nsources; ++i) {
sources[i] = argv[optind];
optind++;
}
sources[i] = NULL;
destination = argv[optind];
return 0;
}
static struct location *parse_location(char *loc){
struct location *location;
char *ptr;
static void location_free(struct location *loc)
{
if (loc) {
if (loc->path) {
free(loc->path);
}
loc->path = NULL;
if (loc->is_ssh) {
if (loc->host) {
free(loc->host);
}
loc->host = NULL;
if (loc->user) {
free(loc->user);
}
loc->user = NULL;
if (loc->host) {
free(loc->host);
}
loc->host = NULL;
}
free(loc);
}
}
location = malloc(sizeof(struct location));
if (location == NULL) {
return NULL;
}
memset(location, 0, sizeof(struct location));
static struct location *parse_location(char *loc) {
struct location *location;
char *ptr;
location->host=location->user=NULL;
ptr=strchr(loc,':');
if(ptr != NULL){
location->is_ssh=1;
location->path=strdup(ptr+1);
*ptr='\0';
ptr=strchr(loc,'@');
if(ptr != NULL){
location->host=strdup(ptr+1);
*ptr='\0';
location->user=strdup(loc);
location = malloc(sizeof(struct location));
if (location == NULL) {
return NULL;
}
memset(location, 0, sizeof(struct location));
location->host = location->user = NULL;
ptr = strchr(loc, ':');
if (ptr != NULL) {
location->is_ssh = 1;
location->path = strdup(ptr+1);
*ptr = '\0';
ptr = strchr(loc, '@');
if (ptr != NULL) {
location->host = strdup(ptr+1);
*ptr = '\0';
location->user = strdup(loc);
} else {
location->host = strdup(loc);
}
} else {
location->host=strdup(loc);
location->is_ssh = 0;
location->path = strdup(loc);
}
} else {
location->is_ssh=0;
location->path=strdup(loc);
}
return location;
return location;
}
static int open_location(struct location *loc, int flag){
if(loc->is_ssh && flag==WRITE){
loc->session=connect_ssh(loc->host,loc->user,verbosity);
if(!loc->session){
fprintf(stderr,"Couldn't connect to %s\n",loc->host);
return -1;
static void close_location(struct location *loc) {
int rc;
if (loc) {
if (loc->is_ssh) {
if (loc->scp) {
rc = ssh_scp_close(loc->scp);
if (rc == SSH_ERROR) {
fprintf(stderr,
"Error closing scp: %s\n",
ssh_get_error(loc->session));
}
ssh_scp_free(loc->scp);
loc->scp = NULL;
}
if (loc->session) {
ssh_disconnect(loc->session);
ssh_free(loc->session);
loc->session = NULL;
}
} else {
if (loc->file) {
fclose(loc->file);
loc->file = NULL;
}
}
}
loc->scp=ssh_scp_new(loc->session,SSH_SCP_WRITE,loc->path);
if(!loc->scp){
fprintf(stderr,"error : %s\n",ssh_get_error(loc->session));
return -1;
}
static int open_location(struct location *loc, int flag) {
if (loc->is_ssh && flag == WRITE) {
loc->session = connect_ssh(loc->host, loc->user, verbosity);
if (!loc->session) {
fprintf(stderr, "Couldn't connect to %s\n", loc->host);
return -1;
}
loc->scp = ssh_scp_new(loc->session, SSH_SCP_WRITE, loc->path);
if (!loc->scp) {
fprintf(stderr, "error : %s\n", ssh_get_error(loc->session));
ssh_disconnect(loc->session);
ssh_free(loc->session);
loc->session = NULL;
return -1;
}
if (ssh_scp_init(loc->scp) == SSH_ERROR) {
fprintf(stderr, "error : %s\n", ssh_get_error(loc->session));
ssh_scp_free(loc->scp);
loc->scp = NULL;
ssh_disconnect(loc->session);
ssh_free(loc->session);
loc->session = NULL;
return -1;
}
return 0;
} else if (loc->is_ssh && flag == READ) {
loc->session = connect_ssh(loc->host, loc->user, verbosity);
if (!loc->session) {
fprintf(stderr, "Couldn't connect to %s\n", loc->host);
return -1;
}
loc->scp = ssh_scp_new(loc->session, SSH_SCP_READ, loc->path);
if (!loc->scp) {
fprintf(stderr, "error : %s\n", ssh_get_error(loc->session));
ssh_disconnect(loc->session);
ssh_free(loc->session);
loc->session = NULL;
return -1;
}
if (ssh_scp_init(loc->scp) == SSH_ERROR) {
fprintf(stderr, "error : %s\n", ssh_get_error(loc->session));
ssh_scp_free(loc->scp);
loc->scp = NULL;
ssh_disconnect(loc->session);
ssh_free(loc->session);
loc->session = NULL;
return -1;
}
return 0;
} else {
loc->file = fopen(loc->path, flag == READ ? "r":"w");
if (!loc->file) {
if (errno == EISDIR) {
if (chdir(loc->path)) {
fprintf(stderr,
"Error changing directory to %s: %s\n",
loc->path, strerror(errno));
return -1;
}
return 0;
}
fprintf(stderr,
"Error opening %s: %s\n",
loc->path, strerror(errno));
return -1;
}
return 0;
}
if(ssh_scp_init(loc->scp)==SSH_ERROR){
fprintf(stderr,"error : %s\n",ssh_get_error(loc->session));
ssh_scp_free(loc->scp);
loc->scp = NULL;
return -1;
}
return 0;
} else if(loc->is_ssh && flag==READ){
loc->session=connect_ssh(loc->host, loc->user,verbosity);
if(!loc->session){
fprintf(stderr,"Couldn't connect to %s\n",loc->host);
return -1;
}
loc->scp=ssh_scp_new(loc->session,SSH_SCP_READ,loc->path);
if(!loc->scp){
fprintf(stderr,"error : %s\n",ssh_get_error(loc->session));
return -1;
}
if(ssh_scp_init(loc->scp)==SSH_ERROR){
fprintf(stderr,"error : %s\n",ssh_get_error(loc->session));
ssh_scp_free(loc->scp);
loc->scp = NULL;
return -1;
}
return 0;
} else {
loc->file=fopen(loc->path,flag==READ ? "r":"w");
if(!loc->file){
if(errno==EISDIR){
if(chdir(loc->path)){
fprintf(stderr,"Error changing directory to %s: %s\n",loc->path,strerror(errno));
return -1;
}
return 0;
}
fprintf(stderr,"Error opening %s: %s\n",loc->path,strerror(errno));
return -1;
}
return 0;
}
return -1;
return -1;
}
/** @brief copies files from source location to destination
@@ -174,155 +256,197 @@ static int open_location(struct location *loc, int flag){
* @param dest destination location
* @param recursive Copy also directories
*/
static int do_copy(struct location *src, struct location *dest, int recursive){
int size;
socket_t fd;
struct stat s;
int w,r;
char buffer[16384];
int total=0;
int mode;
char *filename = NULL;
/* recursive mode doesn't work yet */
(void)recursive;
/* Get the file name and size*/
if(!src->is_ssh){
fd = fileno(src->file);
if (fd < 0) {
fprintf(stderr, "Invalid file pointer, error: %s\n", strerror(errno));
return -1;
}
r = fstat(fd, &s);
if (r < 0) {
return -1;
}
size=s.st_size;
mode = s.st_mode & ~S_IFMT;
filename=ssh_basename(src->path);
} else {
size=0;
do {
r=ssh_scp_pull_request(src->scp);
if(r==SSH_SCP_REQUEST_NEWDIR){
ssh_scp_deny_request(src->scp,"Not in recursive mode");
continue;
}
if(r==SSH_SCP_REQUEST_NEWFILE){
size=ssh_scp_request_get_size(src->scp);
filename=strdup(ssh_scp_request_get_filename(src->scp));
mode=ssh_scp_request_get_permissions(src->scp);
//ssh_scp_accept_request(src->scp);
break;
}
if(r==SSH_ERROR){
fprintf(stderr,"Error: %s\n",ssh_get_error(src->session));
static int do_copy(struct location *src, struct location *dest, int recursive) {
int size;
socket_t fd;
struct stat s;
int w, r;
char buffer[16384];
int total = 0;
int mode;
char *filename = NULL;
/* recursive mode doesn't work yet */
(void)recursive;
/* Get the file name and size*/
if (!src->is_ssh) {
fd = fileno(src->file);
if (fd < 0) {
fprintf(stderr,
"Invalid file pointer, error: %s\n",
strerror(errno));
return -1;
}
r = fstat(fd, &s);
if (r < 0) {
return -1;
}
size = s.st_size;
mode = s.st_mode & ~S_IFMT;
filename = ssh_basename(src->path);
} else {
size = 0;
do {
r = ssh_scp_pull_request(src->scp);
if (r == SSH_SCP_REQUEST_NEWDIR) {
ssh_scp_deny_request(src->scp, "Not in recursive mode");
continue;
}
if (r == SSH_SCP_REQUEST_NEWFILE) {
size = ssh_scp_request_get_size(src->scp);
filename = strdup(ssh_scp_request_get_filename(src->scp));
mode = ssh_scp_request_get_permissions(src->scp);
//ssh_scp_accept_request(src->scp);
break;
}
if (r == SSH_ERROR) {
fprintf(stderr,
"Error: %s\n",
ssh_get_error(src->session));
ssh_string_free_char(filename);
return -1;
}
} while(r != SSH_SCP_REQUEST_NEWFILE);
}
return -1;
}
} while(r != SSH_SCP_REQUEST_NEWFILE);
}
if(dest->is_ssh){
r=ssh_scp_push_file(dest->scp,src->path, size, mode);
// snprintf(buffer,sizeof(buffer),"C0644 %d %s\n",size,src->path);
if(r==SSH_ERROR){
fprintf(stderr,"error: %s\n",ssh_get_error(dest->session));
ssh_string_free_char(filename);
ssh_scp_free(dest->scp);
dest->scp = NULL;
return -1;
}
} else {
if(!dest->file){
dest->file=fopen(filename,"w");
if(!dest->file){
fprintf(stderr,"Cannot open %s for writing: %s\n",filename,strerror(errno));
if(src->is_ssh)
ssh_scp_deny_request(src->scp,"Cannot open local file");
ssh_string_free_char(filename);
return -1;
}
}
if(src->is_ssh){
ssh_scp_accept_request(src->scp);
}
}
do {
if(src->is_ssh){
r=ssh_scp_read(src->scp,buffer,sizeof(buffer));
if(r==SSH_ERROR){
fprintf(stderr,"Error reading scp: %s\n",ssh_get_error(src->session));
ssh_string_free_char(filename);
return -1;
}
if(r==0)
break;
} else {
r=fread(buffer,1,sizeof(buffer),src->file);
if(r==0)
break;
if(r<0){
fprintf(stderr,"Error reading file: %s\n",strerror(errno));
ssh_string_free_char(filename);
return -1;
}
}
if(dest->is_ssh){
w=ssh_scp_write(dest->scp,buffer,r);
if(w == SSH_ERROR){
fprintf(stderr,"Error writing in scp: %s\n",ssh_get_error(dest->session));
ssh_scp_free(dest->scp);
dest->scp=NULL;
ssh_string_free_char(filename);
return -1;
}
} else {
w=fwrite(buffer,r,1,dest->file);
if(w<=0){
fprintf(stderr,"Error writing in local file: %s\n",strerror(errno));
ssh_string_free_char(filename);
return -1;
}
}
total+=r;
if (dest->is_ssh) {
r = ssh_scp_push_file(dest->scp, src->path, size, mode);
// snprintf(buffer, sizeof(buffer), "C0644 %d %s\n", size, src->path);
if (r == SSH_ERROR) {
fprintf(stderr,
"error: %s\n",
ssh_get_error(dest->session));
ssh_string_free_char(filename);
ssh_scp_free(dest->scp);
dest->scp = NULL;
return -1;
}
} else {
if (!dest->file) {
dest->file = fopen(filename, "w");
if (!dest->file) {
fprintf(stderr,
"Cannot open %s for writing: %s\n",
filename, strerror(errno));
if (src->is_ssh) {
ssh_scp_deny_request(src->scp, "Cannot open local file");
}
ssh_string_free_char(filename);
return -1;
}
}
if (src->is_ssh) {
ssh_scp_accept_request(src->scp);
}
}
} while(total < size);
ssh_string_free_char(filename);
printf("wrote %d bytes\n",total);
return 0;
do {
if (src->is_ssh) {
r = ssh_scp_read(src->scp, buffer, sizeof(buffer));
if (r == SSH_ERROR) {
fprintf(stderr,
"Error reading scp: %s\n",
ssh_get_error(src->session));
ssh_string_free_char(filename);
return -1;
}
if (r == 0) {
break;
}
} else {
r = fread(buffer, 1, sizeof(buffer), src->file);
if (r == 0) {
break;
}
if (r < 0) {
fprintf(stderr,
"Error reading file: %s\n",
strerror(errno));
ssh_string_free_char(filename);
return -1;
}
}
if (dest->is_ssh) {
w = ssh_scp_write(dest->scp, buffer, r);
if (w == SSH_ERROR) {
fprintf(stderr,
"Error writing in scp: %s\n",
ssh_get_error(dest->session));
ssh_scp_free(dest->scp);
dest->scp = NULL;
ssh_string_free_char(filename);
return -1;
}
} else {
w = fwrite(buffer, r, 1, dest->file);
if (w <= 0) {
fprintf(stderr,
"Error writing in local file: %s\n",
strerror(errno));
ssh_string_free_char(filename);
return -1;
}
}
total += r;
} while(total < size);
ssh_string_free_char(filename);
printf("wrote %d bytes\n", total);
return 0;
}
int main(int argc, char **argv){
struct location *dest, *src;
int i;
int r;
if(opts(argc,argv)<0)
return EXIT_FAILURE;
dest=parse_location(destination);
if(open_location(dest,WRITE)<0)
return EXIT_FAILURE;
for(i=0;i<nsources;++i){
src=parse_location(sources[i]);
if(open_location(src,READ)<0){
return EXIT_FAILURE;
int main(int argc, char **argv) {
struct location *dest, *src;
int i;
int r;
if (opts(argc, argv) < 0) {
r = EXIT_FAILURE;
goto end;
}
if(do_copy(src,dest,0) < 0){
break;
dest = parse_location(destination);
if (dest == NULL) {
r = EXIT_FAILURE;
goto end;
}
}
if (dest->is_ssh && dest->scp != NULL) {
r=ssh_scp_close(dest->scp);
if(r == SSH_ERROR){
fprintf(stderr,"Error closing scp: %s\n",ssh_get_error(dest->session));
ssh_scp_free(dest->scp);
dest->scp=NULL;
return -1;
}
} else {
fclose(dest->file);
dest->file=NULL;
}
ssh_disconnect(dest->session);
ssh_finalize();
return 0;
if (open_location(dest, WRITE) < 0) {
location_free(dest);
r = EXIT_FAILURE;
goto end;
}
for (i = 0; i < nsources; ++i) {
src = parse_location(sources[i]);
if (src == NULL) {
r = EXIT_FAILURE;
goto close_dest;
}
if (open_location(src, READ) < 0) {
location_free(src);
r = EXIT_FAILURE;
goto close_dest;
}
if (do_copy(src, dest, 0) < 0) {
close_location(src);
location_free(src);
break;
}
close_location(src);
location_free(src);
}
r = 0;
close_dest:
close_location(dest);
location_free(dest);
end:
return r;
}

View File

@@ -76,6 +76,14 @@ enum ssh_auth_state_e {
SSH_AUTH_STATE_GSSAPI_TOKEN,
/** We have sent the MIC and expecting to be authenticated */
SSH_AUTH_STATE_GSSAPI_MIC_SENT,
/** We have offered a pubkey to check if it is supported */
SSH_AUTH_STATE_PUBKEY_OFFER_SENT,
/** We have sent pubkey and signature expecting to be authenticated */
SSH_AUTH_STATE_PUBKEY_AUTH_SENT,
/** We have sent a password expecting to be authenticated */
SSH_AUTH_STATE_PASSWORD_AUTH_SENT,
/** We have sent a request without auth information (method 'none') */
SSH_AUTH_STATE_AUTH_NONE_SENT,
};
/** @internal

View File

@@ -92,7 +92,6 @@ SSH_PACKET_CALLBACK(channel_rcv_close);
SSH_PACKET_CALLBACK(channel_rcv_request);
SSH_PACKET_CALLBACK(channel_rcv_data);
ssh_channel ssh_channel_new(ssh_session session);
int channel_default_bufferize(ssh_channel channel, void *data, int len,
int is_stderr);
int ssh_channel_flush(ssh_channel channel);

View File

@@ -79,7 +79,7 @@
/* libssh version */
#define LIBSSH_VERSION_MAJOR 0
#define LIBSSH_VERSION_MINOR 8
#define LIBSSH_VERSION_MICRO 3
#define LIBSSH_VERSION_MICRO 4
#define LIBSSH_VERSION_INT SSH_VERSION_INT(LIBSSH_VERSION_MAJOR, \
LIBSSH_VERSION_MINOR, \
@@ -630,6 +630,8 @@ typedef int (*ssh_auth_callback) (const char *prompt, char *buf, size_t len,
int echo, int verify, void *userdata);
LIBSSH_API ssh_key ssh_key_new(void);
#define SSH_KEY_FREE(x) \
do { if ((x) != NULL) { ssh_key_free(x); x = NULL; } } while(0)
LIBSSH_API void ssh_key_free (ssh_key key);
LIBSSH_API enum ssh_keytypes_e ssh_key_type(const ssh_key key);
LIBSSH_API const char *ssh_key_type_to_char(enum ssh_keytypes_e type);

View File

@@ -43,6 +43,12 @@ enum ssh_packet_state_e {
PACKET_STATE_PROCESSING
};
enum ssh_packet_filter_result_e {
SSH_PACKET_UNKNOWN,
SSH_PACKET_ALLOWED,
SSH_PACKET_DENIED
};
int ssh_packet_send(ssh_session session);
SSH_PACKET_CALLBACK(ssh_packet_unimplemented);

View File

@@ -1 +1 @@
4.7.0
4.7.1

View File

@@ -0,0 +1,415 @@
_ssh_log
buffer_free
buffer_get
buffer_get_len
buffer_new
channel_accept_x11
channel_change_pty_size
channel_close
channel_forward_accept
channel_forward_cancel
channel_forward_listen
channel_free
channel_get_exit_status
channel_get_session
channel_is_closed
channel_is_eof
channel_is_open
channel_new
channel_open_forward
channel_open_session
channel_poll
channel_read
channel_read_buffer
channel_read_nonblocking
channel_request_env
channel_request_exec
channel_request_pty
channel_request_pty_size
channel_request_send_signal
channel_request_sftp
channel_request_shell
channel_request_subsystem
channel_request_x11
channel_select
channel_send_eof
channel_set_blocking
channel_write
channel_write_stderr
privatekey_free
privatekey_from_file
publickey_free
publickey_from_file
publickey_from_privatekey
publickey_to_string
sftp_async_read
sftp_async_read_begin
sftp_attributes_free
sftp_canonicalize_path
sftp_chmod
sftp_chown
sftp_client_message_free
sftp_client_message_get_data
sftp_client_message_get_filename
sftp_client_message_get_flags
sftp_client_message_get_submessage
sftp_client_message_get_type
sftp_client_message_set_filename
sftp_close
sftp_closedir
sftp_dir_eof
sftp_extension_supported
sftp_extensions_get_count
sftp_extensions_get_data
sftp_extensions_get_name
sftp_file_set_blocking
sftp_file_set_nonblocking
sftp_free
sftp_fstat
sftp_fstatvfs
sftp_fsync
sftp_get_client_message
sftp_get_error
sftp_handle
sftp_handle_alloc
sftp_handle_remove
sftp_init
sftp_lstat
sftp_mkdir
sftp_new
sftp_new_channel
sftp_open
sftp_opendir
sftp_read
sftp_readdir
sftp_readlink
sftp_rename
sftp_reply_attr
sftp_reply_data
sftp_reply_handle
sftp_reply_name
sftp_reply_names
sftp_reply_names_add
sftp_reply_status
sftp_rewind
sftp_rmdir
sftp_seek
sftp_seek64
sftp_send_client_message
sftp_server_init
sftp_server_new
sftp_server_version
sftp_setstat
sftp_stat
sftp_statvfs
sftp_statvfs_free
sftp_symlink
sftp_tell
sftp_tell64
sftp_unlink
sftp_utimes
sftp_write
ssh_accept
ssh_add_channel_callbacks
ssh_auth_list
ssh_basename
ssh_bind_accept
ssh_bind_accept_fd
ssh_bind_fd_toaccept
ssh_bind_free
ssh_bind_get_fd
ssh_bind_listen
ssh_bind_new
ssh_bind_options_set
ssh_bind_set_blocking
ssh_bind_set_callbacks
ssh_bind_set_fd
ssh_blocking_flush
ssh_buffer_add_data
ssh_buffer_free
ssh_buffer_get
ssh_buffer_get_data
ssh_buffer_get_len
ssh_buffer_new
ssh_buffer_reinit
ssh_channel_accept_forward
ssh_channel_accept_x11
ssh_channel_cancel_forward
ssh_channel_change_pty_size
ssh_channel_close
ssh_channel_free
ssh_channel_get_exit_status
ssh_channel_get_session
ssh_channel_is_closed
ssh_channel_is_eof
ssh_channel_is_open
ssh_channel_listen_forward
ssh_channel_new
ssh_channel_open_auth_agent
ssh_channel_open_forward
ssh_channel_open_reverse_forward
ssh_channel_open_session
ssh_channel_open_x11
ssh_channel_poll
ssh_channel_poll_timeout
ssh_channel_read
ssh_channel_read_nonblocking
ssh_channel_read_timeout
ssh_channel_request_auth_agent
ssh_channel_request_env
ssh_channel_request_exec
ssh_channel_request_pty
ssh_channel_request_pty_size
ssh_channel_request_send_break
ssh_channel_request_send_exit_signal
ssh_channel_request_send_exit_status
ssh_channel_request_send_signal
ssh_channel_request_sftp
ssh_channel_request_shell
ssh_channel_request_subsystem
ssh_channel_request_x11
ssh_channel_select
ssh_channel_send_eof
ssh_channel_set_blocking
ssh_channel_set_counter
ssh_channel_window_size
ssh_channel_write
ssh_channel_write_stderr
ssh_clean_pubkey_hash
ssh_connect
ssh_connector_free
ssh_connector_new
ssh_connector_set_in_channel
ssh_connector_set_in_fd
ssh_connector_set_out_channel
ssh_connector_set_out_fd
ssh_copyright
ssh_dirname
ssh_disconnect
ssh_dump_knownhost
ssh_event_add_connector
ssh_event_add_fd
ssh_event_add_session
ssh_event_dopoll
ssh_event_free
ssh_event_new
ssh_event_remove_connector
ssh_event_remove_fd
ssh_event_remove_session
ssh_execute_message_callbacks
ssh_finalize
ssh_forward_accept
ssh_forward_cancel
ssh_forward_listen
ssh_free
ssh_get_cipher_in
ssh_get_cipher_out
ssh_get_clientbanner
ssh_get_disconnect_message
ssh_get_error
ssh_get_error_code
ssh_get_fd
ssh_get_fingerprint_hash
ssh_get_hexa
ssh_get_hmac_in
ssh_get_hmac_out
ssh_get_issue_banner
ssh_get_kex_algo
ssh_get_log_callback
ssh_get_log_level
ssh_get_log_userdata
ssh_get_openssh_version
ssh_get_poll_flags
ssh_get_pubkey
ssh_get_pubkey_hash
ssh_get_publickey
ssh_get_publickey_hash
ssh_get_random
ssh_get_server_publickey
ssh_get_serverbanner
ssh_get_status
ssh_get_version
ssh_getpass
ssh_gssapi_get_creds
ssh_gssapi_set_creds
ssh_handle_key_exchange
ssh_init
ssh_is_blocking
ssh_is_connected
ssh_is_server_known
ssh_key_cmp
ssh_key_free
ssh_key_is_private
ssh_key_is_public
ssh_key_new
ssh_key_type
ssh_key_type_from_name
ssh_key_type_to_char
ssh_known_hosts_parse_line
ssh_knownhosts_entry_free
ssh_log
ssh_message_auth_interactive_request
ssh_message_auth_kbdint_is_response
ssh_message_auth_password
ssh_message_auth_pubkey
ssh_message_auth_publickey
ssh_message_auth_publickey_state
ssh_message_auth_reply_pk_ok
ssh_message_auth_reply_pk_ok_simple
ssh_message_auth_reply_success
ssh_message_auth_set_methods
ssh_message_auth_user
ssh_message_channel_request_channel
ssh_message_channel_request_command
ssh_message_channel_request_env_name
ssh_message_channel_request_env_value
ssh_message_channel_request_open_destination
ssh_message_channel_request_open_destination_port
ssh_message_channel_request_open_originator
ssh_message_channel_request_open_originator_port
ssh_message_channel_request_open_reply_accept
ssh_message_channel_request_pty_height
ssh_message_channel_request_pty_pxheight
ssh_message_channel_request_pty_pxwidth
ssh_message_channel_request_pty_term
ssh_message_channel_request_pty_width
ssh_message_channel_request_reply_success
ssh_message_channel_request_subsystem
ssh_message_channel_request_x11_auth_cookie
ssh_message_channel_request_x11_auth_protocol
ssh_message_channel_request_x11_screen_number
ssh_message_channel_request_x11_single_connection
ssh_message_free
ssh_message_get
ssh_message_global_request_address
ssh_message_global_request_port
ssh_message_global_request_reply_success
ssh_message_reply_default
ssh_message_retrieve
ssh_message_service_reply_success
ssh_message_service_service
ssh_message_subtype
ssh_message_type
ssh_mkdir
ssh_new
ssh_options_copy
ssh_options_get
ssh_options_get_port
ssh_options_getopt
ssh_options_parse_config
ssh_options_set
ssh_pcap_file_close
ssh_pcap_file_free
ssh_pcap_file_new
ssh_pcap_file_open
ssh_pki_copy_cert_to_privkey
ssh_pki_export_privkey_base64
ssh_pki_export_privkey_file
ssh_pki_export_privkey_to_pubkey
ssh_pki_export_pubkey_base64
ssh_pki_export_pubkey_file
ssh_pki_generate
ssh_pki_import_cert_base64
ssh_pki_import_cert_file
ssh_pki_import_privkey_base64
ssh_pki_import_privkey_file
ssh_pki_import_pubkey_base64
ssh_pki_import_pubkey_file
ssh_pki_key_ecdsa_name
ssh_print_hash
ssh_print_hexa
ssh_privatekey_type
ssh_publickey_to_file
ssh_remove_channel_callbacks
ssh_scp_accept_request
ssh_scp_close
ssh_scp_deny_request
ssh_scp_free
ssh_scp_init
ssh_scp_leave_directory
ssh_scp_new
ssh_scp_pull_request
ssh_scp_push_directory
ssh_scp_push_file
ssh_scp_push_file64
ssh_scp_read
ssh_scp_request_get_filename
ssh_scp_request_get_permissions
ssh_scp_request_get_size
ssh_scp_request_get_size64
ssh_scp_request_get_warning
ssh_scp_write
ssh_select
ssh_send_debug
ssh_send_ignore
ssh_send_keepalive
ssh_server_init_kex
ssh_service_request
ssh_session_export_known_hosts_entry
ssh_session_has_known_hosts_entry
ssh_session_is_known_server
ssh_session_update_known_hosts
ssh_set_agent_channel
ssh_set_agent_socket
ssh_set_auth_methods
ssh_set_blocking
ssh_set_callbacks
ssh_set_channel_callbacks
ssh_set_counters
ssh_set_fd_except
ssh_set_fd_toread
ssh_set_fd_towrite
ssh_set_log_callback
ssh_set_log_level
ssh_set_log_userdata
ssh_set_message_callback
ssh_set_pcap_file
ssh_set_server_callbacks
ssh_silent_disconnect
ssh_string_burn
ssh_string_copy
ssh_string_data
ssh_string_fill
ssh_string_free
ssh_string_free_char
ssh_string_from_char
ssh_string_get_char
ssh_string_len
ssh_string_new
ssh_string_to_char
ssh_threads_get_noop
ssh_threads_get_pthread
ssh_threads_set_callbacks
ssh_try_publickey_from_file
ssh_userauth_agent
ssh_userauth_agent_pubkey
ssh_userauth_autopubkey
ssh_userauth_gssapi
ssh_userauth_kbdint
ssh_userauth_kbdint_getanswer
ssh_userauth_kbdint_getinstruction
ssh_userauth_kbdint_getname
ssh_userauth_kbdint_getnanswers
ssh_userauth_kbdint_getnprompts
ssh_userauth_kbdint_getprompt
ssh_userauth_kbdint_setanswer
ssh_userauth_list
ssh_userauth_none
ssh_userauth_offer_pubkey
ssh_userauth_password
ssh_userauth_privatekey_file
ssh_userauth_pubkey
ssh_userauth_publickey
ssh_userauth_publickey_auto
ssh_userauth_try_publickey
ssh_version
ssh_write_knownhost
string_burn
string_copy
string_data
string_fill
string_free
string_from_char
string_len
string_new
string_to_char

View File

@@ -85,6 +85,10 @@ static int ssh_auth_response_termination(void *user) {
case SSH_AUTH_STATE_GSSAPI_REQUEST_SENT:
case SSH_AUTH_STATE_GSSAPI_TOKEN:
case SSH_AUTH_STATE_GSSAPI_MIC_SENT:
case SSH_AUTH_STATE_PUBKEY_AUTH_SENT:
case SSH_AUTH_STATE_PUBKEY_OFFER_SENT:
case SSH_AUTH_STATE_PASSWORD_AUTH_SENT:
case SSH_AUTH_STATE_AUTH_NONE_SENT:
return 0;
default:
return 1;
@@ -167,6 +171,10 @@ static int ssh_userauth_get_response(ssh_session session) {
case SSH_AUTH_STATE_GSSAPI_REQUEST_SENT:
case SSH_AUTH_STATE_GSSAPI_TOKEN:
case SSH_AUTH_STATE_GSSAPI_MIC_SENT:
case SSH_AUTH_STATE_PUBKEY_OFFER_SENT:
case SSH_AUTH_STATE_PUBKEY_AUTH_SENT:
case SSH_AUTH_STATE_PASSWORD_AUTH_SENT:
case SSH_AUTH_STATE_AUTH_NONE_SENT:
case SSH_AUTH_STATE_NONE:
/* not reached */
rc = SSH_AUTH_ERROR;
@@ -312,24 +320,30 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_success) {
SSH_PACKET_CALLBACK(ssh_packet_userauth_pk_ok) {
int rc;
SSH_LOG(SSH_LOG_TRACE, "Received SSH_USERAUTH_PK_OK/INFO_REQUEST/GSSAPI_RESPONSE");
if (session->auth.state == SSH_AUTH_STATE_KBDINT_SENT) {
/* Assuming we are in keyboard-interactive context */
SSH_LOG(SSH_LOG_TRACE,
"keyboard-interactive context, assuming SSH_USERAUTH_INFO_REQUEST");
rc = ssh_packet_userauth_info_request(session,type,packet,user);
#ifdef WITH_GSSAPI
} else if (session->auth.state == SSH_AUTH_STATE_GSSAPI_REQUEST_SENT) {
rc = ssh_packet_userauth_gssapi_response(session, type, packet, user);
#endif
} else {
session->auth.state = SSH_AUTH_STATE_PK_OK;
SSH_LOG(SSH_LOG_TRACE, "Assuming SSH_USERAUTH_PK_OK");
rc = SSH_PACKET_USED;
}
"Received SSH_USERAUTH_PK_OK/INFO_REQUEST/GSSAPI_RESPONSE");
return rc;
if (session->auth.state == SSH_AUTH_STATE_KBDINT_SENT) {
/* Assuming we are in keyboard-interactive context */
SSH_LOG(SSH_LOG_TRACE,
"keyboard-interactive context, "
"assuming SSH_USERAUTH_INFO_REQUEST");
rc = ssh_packet_userauth_info_request(session,type,packet,user);
#ifdef WITH_GSSAPI
} else if (session->auth.state == SSH_AUTH_STATE_GSSAPI_REQUEST_SENT) {
rc = ssh_packet_userauth_gssapi_response(session, type, packet, user);
#endif
} else if (session->auth.state == SSH_AUTH_STATE_PUBKEY_OFFER_SENT) {
session->auth.state = SSH_AUTH_STATE_PK_OK;
SSH_LOG(SSH_LOG_TRACE, "Assuming SSH_USERAUTH_PK_OK");
rc = SSH_PACKET_USED;
} else {
session->auth.state = SSH_AUTH_STATE_ERROR;
SSH_LOG(SSH_LOG_TRACE, "SSH_USERAUTH_PK_OK received in wrong state");
rc = SSH_PACKET_USED;
}
return rc;
}
/**
@@ -416,7 +430,7 @@ int ssh_userauth_none(ssh_session session, const char *username) {
}
session->auth.current_method = SSH_AUTH_METHOD_NONE;
session->auth.state = SSH_AUTH_STATE_NONE;
session->auth.state = SSH_AUTH_STATE_AUTH_NONE_SENT;
session->pending_call_state = SSH_PENDING_CALL_AUTH_NONE;
rc = ssh_packet_send(session);
if (rc == SSH_ERROR) {
@@ -553,7 +567,7 @@ int ssh_userauth_try_publickey(ssh_session session,
ssh_string_free(pubkey_s);
session->auth.current_method = SSH_AUTH_METHOD_PUBLICKEY;
session->auth.state = SSH_AUTH_STATE_NONE;
session->auth.state = SSH_AUTH_STATE_PUBKEY_OFFER_SENT;
session->pending_call_state = SSH_PENDING_CALL_AUTH_OFFER_PUBKEY;
rc = ssh_packet_send(session);
if (rc == SSH_ERROR) {
@@ -701,7 +715,7 @@ int ssh_userauth_publickey(ssh_session session,
}
session->auth.current_method = SSH_AUTH_METHOD_PUBLICKEY;
session->auth.state = SSH_AUTH_STATE_NONE;
session->auth.state = SSH_AUTH_STATE_PUBKEY_AUTH_SENT;
session->pending_call_state = SSH_PENDING_CALL_AUTH_PUBKEY;
rc = ssh_packet_send(session);
if (rc == SSH_ERROR) {
@@ -797,7 +811,7 @@ static int ssh_userauth_agent_publickey(ssh_session session,
}
session->auth.current_method = SSH_AUTH_METHOD_PUBLICKEY;
session->auth.state = SSH_AUTH_STATE_NONE;
session->auth.state = SSH_AUTH_STATE_PUBKEY_AUTH_SENT;
session->pending_call_state = SSH_PENDING_CALL_AUTH_AGENT;
rc = ssh_packet_send(session);
if (rc == SSH_ERROR) {
@@ -1258,7 +1272,7 @@ int ssh_userauth_password(ssh_session session,
}
session->auth.current_method = SSH_AUTH_METHOD_PASSWORD;
session->auth.state = SSH_AUTH_STATE_NONE;
session->auth.state = SSH_AUTH_STATE_PASSWORD_AUTH_SENT;
session->pending_call_state = SSH_PENDING_CALL_AUTH_PASSWORD;
rc = ssh_packet_send(session);
if (rc == SSH_ERROR) {

View File

@@ -171,6 +171,15 @@ SSH_PACKET_CALLBACK(ssh_packet_channel_open_conf){
"Received a CHANNEL_OPEN_CONFIRMATION for channel %d:%d",
channel->local_channel,
channel->remote_channel);
if (channel->state != SSH_CHANNEL_STATE_OPENING) {
SSH_LOG(SSH_LOG_RARE,
"SSH2_MSG_CHANNEL_OPEN_CONFIRMATION received in incorrect "
"channel state %d",
channel->state);
goto error;
}
SSH_LOG(SSH_LOG_PROTOCOL,
"Remote window : %lu, maxpacket : %lu",
(long unsigned int) channel->remote_window,
@@ -211,6 +220,14 @@ SSH_PACKET_CALLBACK(ssh_packet_channel_open_fail){
return SSH_PACKET_USED;
}
if (channel->state != SSH_CHANNEL_STATE_OPENING) {
SSH_LOG(SSH_LOG_RARE,
"SSH2_MSG_CHANNEL_OPEN_FAILURE received in incorrect channel "
"state %d",
channel->state);
goto error;
}
ssh_set_error(session, SSH_REQUEST_DENIED,
"Channel opening failure: channel %u error (%lu) %s",
channel->local_channel,
@@ -219,6 +236,10 @@ SSH_PACKET_CALLBACK(ssh_packet_channel_open_fail){
SAFE_FREE(error);
channel->state=SSH_CHANNEL_STATE_OPEN_DENIED;
return SSH_PACKET_USED;
error:
ssh_set_error(session, SSH_FATAL, "Invalid packet");
return SSH_PACKET_USED;
}
static int ssh_channel_open_termination(void *c){

View File

@@ -462,7 +462,7 @@ static int ssh_config_parse_line(ssh_session session, const char *line,
p = ssh_config_get_str_tok(&s, NULL);
if (p && *parsing) {
#ifdef HAVE_GLOB
#if defined(HAVE_GLOB) && defined(HAVE_GLOB_GL_FLAGS_MEMBER)
local_parse_glob(session, p, parsing, seen);
#else
local_parse_file(session, p, parsing, seen);

View File

@@ -220,7 +220,12 @@ static int ssh_connect_ai_timeout(ssh_session session, const char *host,
static int set_tcp_nodelay(socket_t socket)
{
int opt = 1;
return setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt));
return setsockopt(socket,
IPPROTO_TCP,
TCP_NODELAY,
(void *)&opt,
sizeof(opt));
}
/**

View File

@@ -26,6 +26,10 @@
#include "libssh/callbacks.h"
#include "libssh/session.h"
#include <stdlib.h>
#include <errno.h>
#include <stdbool.h>
#include <sys/stat.h>
#define CHUNKSIZE 4096
#ifdef _WIN32
@@ -40,6 +44,9 @@
# undef unlink
# define unlink _unlink
# endif /* HAVE_IO_H */
#else
# include <sys/types.h>
# include <sys/socket.h>
#endif
struct ssh_connector_struct {
@@ -51,6 +58,8 @@ struct ssh_connector_struct {
socket_t in_fd;
socket_t out_fd;
bool fd_is_socket;
ssh_poll_handle in_poll;
ssh_poll_handle out_poll;
@@ -76,6 +85,13 @@ static int ssh_connector_channel_write_wontblock_cb(ssh_session session,
ssh_channel channel,
size_t bytes,
void *userdata);
static ssize_t ssh_connector_fd_read(ssh_connector connector,
void *buffer,
uint32_t len);
static ssize_t ssh_connector_fd_write(ssh_connector connector,
const void *buffer,
uint32_t len);
static bool ssh_connector_fd_is_socket(socket_t socket);
ssh_connector ssh_connector_new(ssh_session session)
{
@@ -91,6 +107,8 @@ ssh_connector ssh_connector_new(ssh_session session)
connector->in_fd = SSH_INVALID_SOCKET;
connector->out_fd = SSH_INVALID_SOCKET;
connector->fd_is_socket = false;
ssh_callbacks_init(&connector->in_channel_cb);
ssh_callbacks_init(&connector->out_channel_cb);
@@ -167,12 +185,14 @@ int ssh_connector_set_out_channel(ssh_connector connector,
void ssh_connector_set_in_fd(ssh_connector connector, socket_t fd)
{
connector->in_fd = fd;
connector->fd_is_socket = ssh_connector_fd_is_socket(fd);
connector->in_channel = NULL;
}
void ssh_connector_set_out_fd(ssh_connector connector, socket_t fd)
{
connector->out_fd = fd;
connector->fd_is_socket = ssh_connector_fd_is_socket(fd);
connector->out_channel = NULL;
}
@@ -223,9 +243,9 @@ static void ssh_connector_reset_pollevents(ssh_connector connector)
static void ssh_connector_fd_in_cb(ssh_connector connector)
{
unsigned char buffer[CHUNKSIZE];
int r;
int toread = CHUNKSIZE;
int w;
uint32_t toread = CHUNKSIZE;
ssize_t r;
ssize_t w;
int total = 0;
int rc;
@@ -239,7 +259,7 @@ static void ssh_connector_fd_in_cb(ssh_connector connector)
toread = MIN(size, CHUNKSIZE);
}
r = read(connector->in_fd, buffer, toread);
r = ssh_connector_fd_read(connector, buffer, toread);
if (r < 0) {
ssh_connector_except(connector, connector->in_fd);
return;
@@ -277,7 +297,7 @@ static void ssh_connector_fd_in_cb(ssh_connector connector)
* bytes
*/
while (total != r) {
w = write(connector->out_fd, buffer + total, r - total);
w = ssh_connector_fd_write(connector, buffer + total, r - total);
if (w < 0){
ssh_connector_except(connector, connector->out_fd);
return;
@@ -319,7 +339,7 @@ static void ssh_connector_fd_out_cb(ssh_connector connector){
} else if(r>0) {
/* loop around write in case the write blocks even for CHUNKSIZE bytes */
while (total != r){
w = write(connector->out_fd, buffer + total, r - total);
w = ssh_connector_fd_write(connector, buffer + total, r - total);
if (w < 0){
ssh_connector_except(connector, connector->out_fd);
return;
@@ -451,7 +471,7 @@ static int ssh_connector_channel_data_cb(ssh_session session,
ssh_connector_except_channel(connector, connector->out_channel);
}
} else if (connector->out_fd != SSH_INVALID_SOCKET) {
w = write(connector->out_fd, data, len);
w = ssh_connector_fd_write(connector, data, len);
if (w < 0)
ssh_connector_except(connector, connector->out_fd);
} else {
@@ -634,3 +654,96 @@ int ssh_connector_remove_event(ssh_connector connector) {
return SSH_OK;
}
/**
* @internal
*
* @brief Check the file descriptor to check if it is a Windows socket handle.
*
*/
static bool ssh_connector_fd_is_socket(socket_t s)
{
#ifdef _WIN32
struct sockaddr_storage ss;
int len = sizeof(struct sockaddr_storage);
int rc;
rc = getsockname(s, (struct sockaddr *)&ss, &len);
if (rc == 0) {
return true;
}
SSH_LOG(SSH_LOG_TRACE,
"Error %i in getsockname() for fd %d",
WSAGetLastError(),
s);
return false;
#else
struct stat sb;
int rc;
rc = fstat(s, &sb);
if (rc != 0) {
SSH_LOG(SSH_LOG_TRACE,
"error %i in fstat() for fd %d",
errno,
s);
return false;
}
/* The descriptor is a socket */
if (S_ISSOCK(sb.st_mode)) {
return true;
}
return false;
#endif /* _WIN32 */
}
/**
* @internal
*
* @brief read len bytes from socket into buffer
*
*/
static ssize_t ssh_connector_fd_read(ssh_connector connector,
void *buffer,
uint32_t len)
{
ssize_t nread = -1;
if (connector->fd_is_socket) {
nread = recv(connector->in_fd,buffer, len, 0);
} else {
nread = read(connector->in_fd,buffer, len);
}
return nread;
}
/**
* @internal
*
* @brief brief writes len bytes from buffer to socket
*
*/
static ssize_t ssh_connector_fd_write(ssh_connector connector,
const void *buffer,
uint32_t len)
{
ssize_t bwritten = -1;
int flags = 0;
#ifdef MSG_NOSIGNAL
flags |= MSG_NOSIGNAL;
#endif
if (connector->fd_is_socket) {
bwritten = send(connector->out_fd,buffer, len, flags);
} else {
bwritten = write(connector->out_fd, buffer, len);
}
return bwritten;
}

View File

@@ -10,8 +10,6 @@ Public domain.
#include "libssh/chacha.h"
typedef unsigned int uint32_t;
typedef struct chacha_ctx chacha_ctx;
#define U8C(v) (v##U)

View File

@@ -960,8 +960,8 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_token_client){
}
if (maj_stat == GSS_S_COMPLETE) {
session->auth.state = SSH_AUTH_STATE_NONE;
ssh_gssapi_send_mic(session);
session->auth.state = SSH_AUTH_STATE_GSSAPI_MIC_SENT;
}
return SSH_PACKET_USED;

View File

@@ -224,7 +224,7 @@ int ssh_finalize(void) {
#ifdef _WIN32
#ifdef _MSC_VER
#if defined(_MSC_VER) && !defined(LIBSSH_STATIC)
/* Library constructor and destructor */
BOOL WINAPI DllMain(HINSTANCE hinstDLL,
DWORD fdwReason,
@@ -249,7 +249,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL,
return TRUE;
}
#endif /* _MSC_VER */
#endif /* _MSC_VER && !LIBSSH_STATIC */
#endif /* _WIN32 */

View File

@@ -131,17 +131,13 @@ static char **ssh_get_knownhost_line(FILE **file, const char *filename,
return NULL;
}
if(!tokens[0] || !tokens[1] || !tokens[2]) {
if(tokens[0] == NULL || tokens[1] == NULL || tokens[2] == NULL) {
/* it should have at least 3 tokens */
tokens_free(tokens);
continue;
}
*found_type = tokens[1];
if (tokens[3] || tokens[4]) {
tokens_free(tokens);
continue;
}
return tokens;
}

View File

@@ -430,6 +430,13 @@ void ssh_message_queue(ssh_session session, ssh_message message){
}
if (session->ssh_message_list != NULL) {
ssh_list_append(session->ssh_message_list, message);
} else {
/* If the message list couldn't be allocated, the message can't be
* enqueued */
ssh_message_reply_default(message);
ssh_set_error_oom(session);
ssh_message_free(message);
return;
}
}
}

View File

@@ -128,6 +128,797 @@ static ssh_packet_callback default_packet_handlers[]= {
ssh_packet_channel_failure, // SSH2_MSG_CHANNEL_FAILURE 100
};
/** @internal
* @brief check if the received packet is allowed for the current session state
* @param session current ssh_session
* @returns SSH_PACKET_ALLOWED if the packet is allowed; SSH_PACKET_DENIED
* if the packet arrived in wrong state; SSH_PACKET_UNKNOWN if the packet type
* is unknown
*/
static enum ssh_packet_filter_result_e ssh_packet_incoming_filter(ssh_session session)
{
enum ssh_packet_filter_result_e rc;
#ifdef DEBUG_PACKET
SSH_LOG(SSH_LOG_PACKET, "Filtering packet type %d",
session->in_packet.type);
#endif
switch(session->in_packet.type) {
case SSH2_MSG_DISCONNECT: // 1
/*
* States required:
* - None
*
* Transitions:
* - session->socket->state = SSH_SOCKET_CLOSED
* - session->session_state = SSH_SESSION_STATE_ERROR
* */
/* Always allowed */
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_IGNORE: // 2
/*
* States required:
* - None
*
* Transitions:
* - None
* */
/* Always allowed */
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_UNIMPLEMENTED: // 3
/*
* States required:
* - None
*
* Transitions:
* - None
* */
/* Always allowed */
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_DEBUG: // 4
/*
* States required:
* - None
*
* Transitions:
* - None
* */
/* Always allowed */
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_SERVICE_REQUEST: // 5
/* Server only */
/*
* States required:
* - session->session_state == SSH_SESSION_STATE_AUTHENTICATING
* or session->session_state == SSH_SESSION_STATE_AUTHENTICATED
* - session->dh_handshake_state == DH_STATE_FINISHED
*
* Transitions:
* - None
* */
/* If this is a client, reject the message */
if (session->client) {
rc = SSH_PACKET_DENIED;
break;
}
if ((session->session_state != SSH_SESSION_STATE_AUTHENTICATING) &&
(session->session_state != SSH_SESSION_STATE_AUTHENTICATED))
{
rc = SSH_PACKET_DENIED;
break;
}
if (session->dh_handshake_state != DH_STATE_FINISHED) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_SERVICE_ACCEPT: // 6
/*
* States required:
* - session->session_state == SSH_SESSION_STATE_AUTHENTICATING
* or session->session_state == SSH_SESSION_STATE_AUTHENTICATED
* - session->dh_handshake_state == DH_STATE_FINISHED
* - session->auth.service_state == SSH_AUTH_SERVICE_SENT
*
* Transitions:
* - auth.service_state = SSH_AUTH_SERVICE_ACCEPTED
* */
if ((session->session_state != SSH_SESSION_STATE_AUTHENTICATING) &&
(session->session_state != SSH_SESSION_STATE_AUTHENTICATED))
{
rc = SSH_PACKET_DENIED;
break;
}
if (session->dh_handshake_state != DH_STATE_FINISHED) {
rc = SSH_PACKET_DENIED;
break;
}
/* TODO check if only auth service can be requested */
if (session->auth.service_state != SSH_AUTH_SERVICE_SENT) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_EXT_INFO: // 7
/*
* States required:
* - session_state == SSH_SESSION_STATE_AUTHENTICATING
* - dh_handshake_state == DH_STATE_FINISHED
*
* Transitions:
* - None
* */
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATING) {
rc = SSH_PACKET_DENIED;
break;
}
if (session->dh_handshake_state != DH_STATE_FINISHED) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_KEXINIT: // 20
/*
* States required:
* - session_state == SSH_SESSION_STATE_AUTHENTICATED
* or session_state == SSH_SESSION_STATE_INITIAL_KEX
* - dh_handshake_state == DH_STATE_INIT
* or dh_handshake_state == DH_STATE_FINISHED (re-exchange)
*
* Transitions:
* - session->dh_handshake_state = DH_STATE_INIT
* - session->session_state = SSH_SESSION_STATE_KEXINIT_RECEIVED
*
* On server:
* - session->session_state = SSH_SESSION_STATE_DH
* */
if ((session->session_state != SSH_SESSION_STATE_AUTHENTICATED) &&
(session->session_state != SSH_SESSION_STATE_INITIAL_KEX))
{
rc = SSH_PACKET_DENIED;
break;
}
if ((session->dh_handshake_state != DH_STATE_INIT) &&
(session->dh_handshake_state != DH_STATE_FINISHED))
{
rc = SSH_PACKET_DENIED;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_NEWKEYS: // 21
/*
* States required:
* - session_state == SSH_SESSION_STATE_DH
* - dh_handshake_state == DH_STATE_NEWKEYS_SENT
*
* Transitions:
* - session->dh_handshake_state = DH_STATE_FINISHED
* - session->session_state = SSH_SESSION_STATE_AUTHENTICATING
* if session->flags & SSH_SESSION_FLAG_AUTHENTICATED
* - session->session_state = SSH_SESSION_STATE_AUTHENTICATED
* */
/* If DH has not been started, reject message */
if (session->session_state != SSH_SESSION_STATE_DH) {
rc = SSH_PACKET_DENIED;
break;
}
/* Only allowed if dh_handshake_state is in NEWKEYS_SENT state */
if (session->dh_handshake_state != DH_STATE_NEWKEYS_SENT) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_KEXDH_INIT: // 30
// SSH2_MSG_KEX_ECDH_INIT: // 30
// SSH2_MSG_ECMQV_INIT: // 30
// SSH2_MSG_KEX_DH_GEX_REQUEST_OLD: // 30
/* Server only */
/*
* States required:
* - session_state == SSH_SESSION_STATE_DH
* - dh_handshake_state == DH_STATE_INIT
*
* Transitions:
* - session->dh_handshake_state = DH_STATE_INIT_SENT
* then calls dh_handshake_server which triggers:
* - session->dh_handhsake_state = DH_STATE_NEWKEYS_SENT
* */
if (session->session_state != SSH_SESSION_STATE_DH) {
rc = SSH_PACKET_DENIED;
break;
}
/* Only allowed if dh_handshake_state is in initial state */
if (session->dh_handshake_state != DH_STATE_INIT) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_KEXDH_REPLY: // 31
// SSH2_MSG_KEX_ECDH_REPLY: // 31
// SSH2_MSG_ECMQV_REPLY: // 31
// SSH2_MSG_KEX_DH_GEX_GROUP: // 31
/*
* States required:
* - session_state == SSH_SESSION_STATE_DH
* - dh_handshake_state == DH_STATE_INIT_SENT
*
* Transitions:
* - session->dh_handhsake_state = DH_STATE_NEWKEYS_SENT
* */
if (session->session_state != SSH_SESSION_STATE_DH) {
rc = SSH_PACKET_DENIED;
break;
}
if (session->dh_handshake_state != DH_STATE_INIT_SENT) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_KEX_DH_GEX_INIT: // 32
/* TODO Not filtered */
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_KEX_DH_GEX_REPLY: // 33
/* TODO Not filtered */
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_KEX_DH_GEX_REQUEST: // 34
/* TODO Not filtered */
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_USERAUTH_REQUEST: // 50
/* Server only */
/*
* States required:
* - session_state == SSH_SESSION_STATE_AUTHENTICATING
* - dh_hanshake_state == DH_STATE_FINISHED
*
* Transitions:
* - if authentication was successful:
* - session_state = SSH_SESSION_STATE_AUTHENTICATED
* */
/* If this is a client, reject the message */
if (session->client) {
rc = SSH_PACKET_DENIED;
break;
}
if (session->dh_handshake_state != DH_STATE_FINISHED) {
rc = SSH_PACKET_DENIED;
break;
}
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATING) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_USERAUTH_FAILURE: // 51
/*
* States required:
* - session_state == SSH_SESSION_STATE_AUTHENTICATING
* - dh_hanshake_state == DH_STATE_FINISHED
* - session->auth.state == SSH_AUTH_STATE_KBDINT_SENT
* or session->auth.state == SSH_AUTH_STATE_PUBKEY_OFFER_SENT
* or session->auth.state == SSH_AUTH_STATE_PUBKEY_AUTH_SENT
* or session->auth.state == SSH_AUTH_STATE_PASSWORD_AUTH_SENT
* or session->auth.state == SSH_AUTH_STATE_GSSAPI_MIC_SENT
*
* Transitions:
* - if unpacking failed:
* - session->auth.state = SSH_AUTH_ERROR
* - if failure was partial:
* - session->auth.state = SSH_AUTH_PARTIAL
* - else:
* - session->auth.state = SSH_AUTH_STATE_FAILED
* */
/* If this is a server, reject the message */
if (session->server) {
rc = SSH_PACKET_DENIED;
break;
}
if (session->dh_handshake_state != DH_STATE_FINISHED) {
rc = SSH_PACKET_DENIED;
break;
}
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATING) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_USERAUTH_SUCCESS: // 52
/*
* States required:
* - session_state == SSH_SESSION_STATE_AUTHENTICATING
* - dh_hanshake_state == DH_STATE_FINISHED
* - session->auth.state == SSH_AUTH_STATE_KBDINT_SENT
* or session->auth.state == SSH_AUTH_STATE_PUBKEY_AUTH_SENT
* or session->auth.state == SSH_AUTH_STATE_PASSWORD_AUTH_SENT
* or session->auth.state == SSH_AUTH_STATE_GSSAPI_MIC_SENT
* or session->auth.state == SSH_AUTH_STATE_AUTH_NONE_SENT
*
* Transitions:
* - session->auth.state = SSH_AUTH_STATE_SUCCESS
* - session->session_state = SSH_SESSION_STATE_AUTHENTICATED
* - session->flags |= SSH_SESSION_FLAG_AUTHENTICATED
* - sessions->auth.current_method = SSH_AUTH_METHOD_UNKNOWN
* */
/* If this is a server, reject the message */
if (session->server) {
rc = SSH_PACKET_DENIED;
break;
}
if (session->dh_handshake_state != DH_STATE_FINISHED) {
rc = SSH_PACKET_DENIED;
break;
}
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATING) {
rc = SSH_PACKET_DENIED;
break;
}
if ((session->auth.state != SSH_AUTH_STATE_KBDINT_SENT) &&
(session->auth.state != SSH_AUTH_STATE_PUBKEY_AUTH_SENT) &&
(session->auth.state != SSH_AUTH_STATE_PASSWORD_AUTH_SENT) &&
(session->auth.state != SSH_AUTH_STATE_GSSAPI_MIC_SENT) &&
(session->auth.state != SSH_AUTH_STATE_AUTH_NONE_SENT))
{
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_USERAUTH_BANNER: // 53
/*
* States required:
* - session_state == SSH_SESSION_STATE_AUTHENTICATING
*
* Transitions:
* - None
* */
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATING) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_USERAUTH_PK_OK: // 60
// SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ: // 60
// SSH2_MSG_USERAUTH_INFO_REQUEST: // 60
// SSH2_MSG_USERAUTH_GSSAPI_RESPONSE: // 60
/*
* States required:
* - session_state == SSH_SESSION_STATE_AUTHENTICATING
* - session->auth.state == SSH_AUTH_STATE_KBDINT_SENT
* or
* session->auth.state == SSH_AUTH_STATE_GSSAPI_REQUEST_SENT
* or
* session->auth.state == SSH_AUTH_STATE_PUBKEY_OFFER_SENT
*
* Transitions:
* Depending on the current state, the message is treated
* differently:
* - session->auth.state == SSH_AUTH_STATE_KBDINT_SENT
* - session->auth.state = SSH_AUTH_STATE_INFO
* - session->auth.state == SSH_AUTH_STATE_GSSAPI_REQUEST_SENT
* - session->auth.state = SSH_AUTH_STATE_GSSAPI_TOKEN
* - session->auth.state == SSH_AUTH_STATE_PUBKEY_OFFER_SENT
* - session->auth.state = SSH_AUTH_STATE_PK_OK
* */
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATING) {
rc = SSH_PACKET_DENIED;
break;
}
if ((session->auth.state != SSH_AUTH_STATE_KBDINT_SENT) &&
(session->auth.state != SSH_AUTH_STATE_PUBKEY_OFFER_SENT) &&
(session->auth.state != SSH_AUTH_STATE_GSSAPI_REQUEST_SENT))
{
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_USERAUTH_INFO_RESPONSE: // 61
// SSH2_MSG_USERAUTH_GSSAPI_TOKEN: // 61
/*
* States required:
* - session_state == SSH_SESSION_STATE_AUTHENTICATING
* - session_state->auth.state == SSH_SESSION_STATE_GSSAPI_TOKEN
* or
* session_state->auth.state == SSH_SESSION_STATE_INFO
*
* Transitions:
* - None
* */
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATING) {
rc = SSH_PACKET_DENIED;
break;
}
if ((session->auth.state != SSH_AUTH_STATE_INFO) &&
(session->auth.state != SSH_AUTH_STATE_GSSAPI_TOKEN))
{
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE: // 63
/* TODO Not filtered */
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_USERAUTH_GSSAPI_ERROR: // 64
/* TODO Not filtered */
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_USERAUTH_GSSAPI_ERRTOK: // 65
/* TODO Not filtered */
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_USERAUTH_GSSAPI_MIC: // 66
/* Server only */
/*
* States required:
* - session_state == SSH_SESSION_STATE_AUTHENTICATING
* - session->gssapi->state == SSH_GSSAPI_STATE_RCV_MIC
*
* Transitions:
* Depending on the result of the verification, the states are
* changed:
* - SSH_AUTH_SUCCESS:
* - session->session_state = SSH_SESSION_STATE_AUTHENTICATED
* - session->flags != SSH_SESSION_FLAG_AUTHENTICATED
* - SSH_AUTH_PARTIAL:
* - None
* - any other case:
* - None
* */
/* If this is a client, reject the message */
if (session->client) {
rc = SSH_PACKET_DENIED;
break;
}
if (session->dh_handshake_state != DH_STATE_FINISHED) {
rc = SSH_PACKET_DENIED;
break;
}
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATING) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_GLOBAL_REQUEST: // 80
/*
* States required:
* - session_state == SSH_SESSION_STATE_AUTHENTICATED
*
* Transitions:
* - None
* */
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_REQUEST_SUCCESS: // 81
/*
* States required:
* - session_state == SSH_SESSION_STATE_AUTHENTICATED
* - session->global_req_state == SSH_CHANNEL_REQ_STATE_PENDING
*
* Transitions:
* - session->global_req_state == SSH_CHANNEL_REQ_STATE_ACCEPTED
* */
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) {
rc = SSH_PACKET_DENIED;
break;
}
if (session->global_req_state != SSH_CHANNEL_REQ_STATE_PENDING) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_REQUEST_FAILURE: // 82
/*
* States required:
* - session_state == SSH_SESSION_STATE_AUTHENTICATED
* - session->global_req_state == SSH_CHANNEL_REQ_STATE_PENDING
*
* Transitions:
* - session->global_req_state == SSH_CHANNEL_REQ_STATE_DENIED
* */
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) {
rc = SSH_PACKET_DENIED;
break;
}
if (session->global_req_state != SSH_CHANNEL_REQ_STATE_PENDING) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_CHANNEL_OPEN: // 90
/*
* States required:
* - session_state == SSH_SESSION_STATE_AUTHENTICATED
*
* Transitions:
* - None
* */
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_CHANNEL_OPEN_CONFIRMATION: // 91
/*
* States required:
* - session_state == SSH_SESSION_STATE_AUTHENTICATED
*
* Transitions:
* - channel->state = SSH_CHANNEL_STATE_OPEN
* - channel->flags &= ~SSH_CHANNEL_FLAG_NOT_BOUND
* */
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_CHANNEL_OPEN_FAILURE: // 92
/*
* States required:
* - session_state == SSH_SESSION_STATE_AUTHENTICATED
*
* Transitions:
* - channel->state = SSH_CHANNEL_STATE_OPEN_DENIED
* */
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_CHANNEL_WINDOW_ADJUST: // 93
/*
* States required:
* - session_state == SSH_SESSION_STATE_AUTHENTICATED
*
* Transitions:
* - None
* */
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_CHANNEL_DATA: // 94
/*
* States required:
* - session_state == SSH_SESSION_STATE_AUTHENTICATED
*
* Transitions:
* - None
* */
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_CHANNEL_EXTENDED_DATA: // 95
/*
* States required:
* - session_state == SSH_SESSION_STATE_AUTHENTICATED
*
* Transitions:
* - None
* */
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_CHANNEL_EOF: // 96
/*
* States required:
* - session_state == SSH_SESSION_STATE_AUTHENTICATED
*
* Transitions:
* - None
* */
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_CHANNEL_CLOSE: // 97
/*
* States required:
* - session_state == SSH_SESSION_STATE_AUTHENTICATED
*
* Transitions:
* - channel->state = SSH_CHANNEL_STATE_CLOSED
* - channel->flags |= SSH_CHANNEL_FLAG_CLOSED_REMOTE
* */
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_CHANNEL_REQUEST: // 98
/*
* States required:
* - session_state == SSH_SESSION_STATE_AUTHENTICATED
*
* Transitions:
* - Depends on the request
* */
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_CHANNEL_SUCCESS: // 99
/*
* States required:
* - session_state == SSH_SESSION_STATE_AUTHENTICATED
* - channel->request_state == SSH_CHANNEL_REQ_STATE_PENDING
*
* Transitions:
* - channel->request_state = SSH_CHANNEL_REQ_STATE_ACCEPTED
* */
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
case SSH2_MSG_CHANNEL_FAILURE: // 100
/*
* States required:
* - session_state == SSH_SESSION_STATE_AUTHENTICATED
* - channel->request_state == SSH_CHANNEL_REQ_STATE_PENDING
*
* Transitions:
* - channel->request_state = SSH_CHANNEL_REQ_STATE_DENIED
* */
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) {
rc = SSH_PACKET_DENIED;
break;
}
rc = SSH_PACKET_ALLOWED;
break;
default:
/* Unknown message, do not filter */
rc = SSH_PACKET_UNKNOWN;
goto end;
}
end:
#ifdef DEBUG_PACKET
if (rc == SSH_PACKET_DENIED) {
SSH_LOG(SSH_LOG_PACKET, "REJECTED packet type %d: ",
session->in_packet.type);
}
if (rc == SSH_PACKET_UNKNOWN) {
SSH_LOG(SSH_LOG_PACKET, "UNKNOWN packet type %d",
session->in_packet.type);
}
#endif
return rc;
}
/* in nonblocking mode, socket_read will read as much as it can, and return */
/* SSH_OK if it has read at least len bytes, otherwise, SSH_AGAIN. */
/* in blocking mode, it will read at least len bytes and will block until it's ok. */
@@ -158,6 +949,7 @@ int ssh_packet_socket_callback(const void *data, size_t receivedlen, void *user)
uint32_t packet_len, compsize, payloadsize;
uint8_t padding;
size_t processed = 0; /* number of byte processed from the callback */
enum ssh_packet_filter_result_e filter_result;
if(session->current_crypto != NULL) {
current_macsize = hmac_digest_len(session->current_crypto->in_hmac);
@@ -345,8 +1137,21 @@ int ssh_packet_socket_callback(const void *data, size_t receivedlen, void *user)
"packet: read type %hhd [len=%d,padding=%hhd,comp=%d,payload=%d]",
session->in_packet.type, packet_len, padding, compsize, payloadsize);
/* Execute callbacks */
ssh_packet_process(session, session->in_packet.type);
/* Check if the packet is expected */
filter_result = ssh_packet_incoming_filter(session);
switch(filter_result) {
case SSH_PACKET_ALLOWED:
/* Execute callbacks */
ssh_packet_process(session, session->in_packet.type);
break;
case SSH_PACKET_DENIED:
goto error;
case SSH_PACKET_UNKNOWN:
ssh_packet_send_unimplemented(session, session->recv_seq - 1);
break;
}
session->packet_state = PACKET_STATE_INIT;
if (processed < receivedlen) {
/* Handle a potential packet left in socket buffer */

View File

@@ -211,10 +211,31 @@ sftp_session sftp_server_new(ssh_session session, ssh_channel chan){
return NULL;
}
sftp->read_packet = calloc(1, sizeof(struct sftp_packet_struct));
if (sftp->read_packet == NULL) {
goto error;
}
sftp->read_packet->payload = ssh_buffer_new();
if (sftp->read_packet->payload == NULL) {
goto error;
}
sftp->session = session;
sftp->channel = chan;
return sftp;
error:
ssh_set_error_oom(session);
if (sftp->read_packet != NULL) {
if (sftp->read_packet->payload != NULL) {
ssh_buffer_free(sftp->read_packet->payload);
}
SAFE_FREE(sftp->read_packet);
}
SAFE_FREE(sftp);
return NULL;
}
int sftp_server_init(sftp_session sftp){

View File

@@ -232,8 +232,6 @@ sftp_client_message sftp_get_client_message(sftp_session sftp) {
return NULL;
}
sftp_packet_free(packet);
return msg;
}

View File

@@ -93,9 +93,12 @@ struct ssh_socket_struct {
static int sockets_initialized = 0;
static int ssh_socket_unbuffered_read(ssh_socket s, void *buffer, uint32_t len);
static int ssh_socket_unbuffered_write(ssh_socket s, const void *buffer,
uint32_t len);
static ssize_t ssh_socket_unbuffered_read(ssh_socket s,
void *buffer,
uint32_t len);
static ssize_t ssh_socket_unbuffered_write(ssh_socket s,
const void *buffer,
uint32_t len);
/**
* \internal
@@ -216,13 +219,18 @@ void ssh_socket_set_callbacks(ssh_socket s, ssh_socket_callbacks callbacks){
* @return 0 on success, < 0 when the poll object has been removed
* from its poll context.
*/
int ssh_socket_pollcallback(struct ssh_poll_handle_struct *p, socket_t fd,
int revents, void *v_s) {
int ssh_socket_pollcallback(struct ssh_poll_handle_struct *p,
socket_t fd,
int revents,
void *v_s)
{
ssh_socket s = (ssh_socket)v_s;
char buffer[MAX_BUF_SIZE];
int r;
ssize_t nread;
int rc;
int err = 0;
socklen_t errlen = sizeof(err);
/* Do not do anything if this socket was already closed */
if (!ssh_socket_is_open(s)) {
return -1;
@@ -236,16 +244,18 @@ int ssh_socket_pollcallback(struct ssh_poll_handle_struct *p, socket_t fd,
/* Check if we are in a connecting state */
if (s->state == SSH_SOCKET_CONNECTING) {
s->state = SSH_SOCKET_ERROR;
r = getsockopt(fd, SOL_SOCKET, SO_ERROR, (char *)&err, &errlen);
if (r < 0) {
rc = getsockopt(fd, SOL_SOCKET, SO_ERROR, (char *)&err, &errlen);
if (rc < 0) {
err = errno;
}
s->last_errno = err;
ssh_socket_close(s);
if (s->callbacks && s->callbacks->connected) {
s->callbacks->connected(SSH_SOCKET_CONNECTED_ERROR, err,
if (s->callbacks != NULL && s->callbacks->connected != NULL) {
s->callbacks->connected(SSH_SOCKET_CONNECTED_ERROR,
err,
s->callbacks->userdata);
}
return -1;
}
/* Then we are in a more standard kind of error */
@@ -254,56 +264,62 @@ int ssh_socket_pollcallback(struct ssh_poll_handle_struct *p, socket_t fd,
}
if ((revents & POLLIN) && s->state == SSH_SOCKET_CONNECTED) {
s->read_wontblock = 1;
r = ssh_socket_unbuffered_read(s, buffer, sizeof(buffer));
if (r < 0) {
nread = ssh_socket_unbuffered_read(s, buffer, sizeof(buffer));
if (nread < 0) {
if (p != NULL) {
ssh_poll_remove_events(p, POLLIN);
}
if (s->callbacks && s->callbacks->exception) {
if (s->callbacks != NULL && s->callbacks->exception != NULL) {
s->callbacks->exception(SSH_SOCKET_EXCEPTION_ERROR,
s->last_errno, s->callbacks->userdata);
s->last_errno,
s->callbacks->userdata);
/* p may have been freed, so don't use it
* anymore in this function */
p = NULL;
return -2;
}
}
if (r == 0) {
if (nread == 0) {
if (p != NULL) {
ssh_poll_remove_events(p, POLLIN);
}
if (p != NULL) {
ssh_poll_remove_events(p, POLLIN);
}
if (s->callbacks && s->callbacks->exception) {
if (s->callbacks != NULL && s->callbacks->exception != NULL) {
s->callbacks->exception(SSH_SOCKET_EXCEPTION_EOF,
0, s->callbacks->userdata);
0,
s->callbacks->userdata);
/* p may have been freed, so don't use it
* anymore in this function */
p = NULL;
return -2;
}
}
if (r > 0) {
if (s->session->socket_counter != NULL) {
s->session->socket_counter->in_bytes += r;
}
/* Bufferize the data and then call the callback */
r = ssh_buffer_add_data(s->in_buffer, buffer, r);
if (r < 0) {
return -1;
}
if (s->callbacks && s->callbacks->data) {
do {
r = s->callbacks->data(ssh_buffer_get(s->in_buffer),
ssh_buffer_get_len(s->in_buffer),
s->callbacks->userdata);
ssh_buffer_pass_bytes(s->in_buffer, r);
} while ((r > 0) && (s->state == SSH_SOCKET_CONNECTED));
/* p may have been freed, so don't use it
* anymore in this function */
p = NULL;
}
if (s->session->socket_counter != NULL) {
s->session->socket_counter->in_bytes += nread;
}
/* Bufferize the data and then call the callback */
rc = ssh_buffer_add_data(s->in_buffer, buffer, nread);
if (rc < 0) {
return -1;
}
if (s->callbacks != NULL && s->callbacks->data != NULL) {
do {
nread = s->callbacks->data(ssh_buffer_get(s->in_buffer),
ssh_buffer_get_len(s->in_buffer),
s->callbacks->userdata);
ssh_buffer_pass_bytes(s->in_buffer, nread);
} while ((nread > 0) && (s->state == SSH_SOCKET_CONNECTED));
/* p may have been freed, so don't use it
* anymore in this function */
p = NULL;
}
}
#ifdef _WIN32
@@ -311,6 +327,8 @@ int ssh_socket_pollcallback(struct ssh_poll_handle_struct *p, socket_t fd,
#else
if (revents & POLLOUT) {
#endif
uint32_t len;
/* First, POLLOUT is a sign we may be connected */
if (s->state == SSH_SOCKET_CONNECTING) {
SSH_LOG(SSH_LOG_PACKET, "Received POLLOUT in connecting state");
@@ -318,26 +336,32 @@ int ssh_socket_pollcallback(struct ssh_poll_handle_struct *p, socket_t fd,
if (p != NULL) {
ssh_poll_set_events(p, POLLOUT | POLLIN);
}
r = ssh_socket_set_blocking(ssh_socket_get_fd_in(s));
if (r < 0) {
rc = ssh_socket_set_blocking(ssh_socket_get_fd_in(s));
if (rc < 0) {
return -1;
}
if (s->callbacks && s->callbacks->connected) {
s->callbacks->connected(SSH_SOCKET_CONNECTED_OK, 0,
if (s->callbacks != NULL && s->callbacks->connected != NULL) {
s->callbacks->connected(SSH_SOCKET_CONNECTED_OK,
0,
s->callbacks->userdata);
}
return 0;
}
/* So, we can write data */
s->write_wontblock=1;
s->write_wontblock = 1;
if (p != NULL) {
ssh_poll_remove_events(p, POLLOUT);
}
/* If buffered data is pending, write it */
if (ssh_buffer_get_len(s->out_buffer) > 0) {
len = ssh_buffer_get_len(s->out_buffer);
if (len > 0) {
ssh_socket_nonblocking_flush(s);
} else if (s->callbacks && s->callbacks->controlflow) {
} else if (s->callbacks != NULL && s->callbacks->controlflow != NULL) {
/* Otherwise advertise the upper level that write can be done */
SSH_LOG(SSH_LOG_TRACE,"sending control flow event");
s->callbacks->controlflow(SSH_SOCKET_FLOW_WRITEWONTBLOCK,
@@ -345,8 +369,13 @@ int ssh_socket_pollcallback(struct ssh_poll_handle_struct *p, socket_t fd,
}
/* TODO: Find a way to put back POLLOUT when buffering occurs */
}
/* Return -1 if one of the poll handlers disappeared */
return (s->poll_in == NULL || s->poll_out == NULL) ? -1 : 0;
if (s->poll_in == NULL || s->poll_out == NULL) {
return -1;
}
return 0;
}
/** @internal
@@ -524,60 +553,73 @@ int ssh_socket_is_open(ssh_socket s) {
/** \internal
* \brief read len bytes from socket into buffer
*/
static int ssh_socket_unbuffered_read(ssh_socket s, void *buffer, uint32_t len) {
int rc = -1;
static ssize_t ssh_socket_unbuffered_read(ssh_socket s,
void *buffer,
uint32_t len)
{
ssize_t rc = -1;
if (s->data_except) {
return -1;
}
if(s->fd_is_socket)
rc = recv(s->fd_in,buffer, len, 0);
else
rc = read(s->fd_in,buffer, len);
if (s->data_except) {
return -1;
}
if (s->fd_is_socket) {
rc = recv(s->fd_in,buffer, len, 0);
} else {
rc = read(s->fd_in,buffer, len);
}
#ifdef _WIN32
s->last_errno = WSAGetLastError();
s->last_errno = WSAGetLastError();
#else
s->last_errno = errno;
s->last_errno = errno;
#endif
s->read_wontblock = 0;
s->read_wontblock = 0;
if (rc < 0) {
s->data_except = 1;
}
if (rc < 0) {
s->data_except = 1;
}
return rc;
return rc;
}
/** \internal
* \brief writes len bytes from buffer to socket
*/
static int ssh_socket_unbuffered_write(ssh_socket s, const void *buffer,
uint32_t len) {
int w = -1;
static ssize_t ssh_socket_unbuffered_write(ssh_socket s,
const void *buffer,
uint32_t len)
{
ssize_t w = -1;
int flags = 0;
if (s->data_except) {
return -1;
}
if (s->fd_is_socket)
w = send(s->fd_out,buffer, len, 0);
else
w = write(s->fd_out, buffer, len);
#ifdef _WIN32
s->last_errno = WSAGetLastError();
#else
s->last_errno = errno;
#ifdef MSG_NOSIGNAL
flags |= MSG_NOSIGNAL;
#endif
s->write_wontblock = 0;
/* Reactive the POLLOUT detector in the poll multiplexer system */
if(s->poll_out){
SSH_LOG(SSH_LOG_PACKET, "Enabling POLLOUT for socket");
ssh_poll_set_events(s->poll_out,ssh_poll_get_events(s->poll_out) | POLLOUT);
}
if (w < 0) {
s->data_except = 1;
}
return w;
if (s->data_except) {
return -1;
}
if (s->fd_is_socket) {
w = send(s->fd_out, buffer, len, flags);
} else {
w = write(s->fd_out, buffer, len);
}
#ifdef _WIN32
s->last_errno = WSAGetLastError();
#else
s->last_errno = errno;
#endif
s->write_wontblock = 0;
/* Reactive the POLLOUT detector in the poll multiplexer system */
if (s->poll_out) {
SSH_LOG(SSH_LOG_PACKET, "Enabling POLLOUT for socket");
ssh_poll_set_events(s->poll_out,ssh_poll_get_events(s->poll_out) | POLLOUT);
}
if (w < 0) {
s->data_except = 1;
}
return w;
}
/** \internal
@@ -636,67 +678,78 @@ int ssh_socket_write(ssh_socket s, const void *buffer, int len) {
* \brief starts a nonblocking flush of the output buffer
*
*/
int ssh_socket_nonblocking_flush(ssh_socket s) {
ssh_session session = s->session;
uint32_t len;
int w;
int ssh_socket_nonblocking_flush(ssh_socket s)
{
ssh_session session = s->session;
uint32_t len;
if (!ssh_socket_is_open(s)) {
session->alive = 0;
if(s->callbacks && s->callbacks->exception){
s->callbacks->exception(
SSH_SOCKET_EXCEPTION_ERROR,
s->last_errno,s->callbacks->userdata);
}else{
ssh_set_error(session, SSH_FATAL,
"Writing packet: error on socket (or connection closed): %s",
strerror(s->last_errno));
if (!ssh_socket_is_open(s)) {
session->alive = 0;
if (s->callbacks && s->callbacks->exception) {
s->callbacks->exception(SSH_SOCKET_EXCEPTION_ERROR,
s->last_errno,
s->callbacks->userdata);
} else {
ssh_set_error(session,
SSH_FATAL,
"Writing packet: error on socket (or connection "
"closed): %s",
strerror(s->last_errno));
}
return SSH_ERROR;
}
return SSH_ERROR;
}
len = ssh_buffer_get_len(s->out_buffer);
if (!s->write_wontblock && s->poll_out && len > 0) {
/* force the poll system to catch pollout events */
ssh_poll_add_events(s->poll_out, POLLOUT);
len = ssh_buffer_get_len(s->out_buffer);
if (!s->write_wontblock && s->poll_out && len > 0) {
/* force the poll system to catch pollout events */
ssh_poll_add_events(s->poll_out, POLLOUT);
return SSH_AGAIN;
}
if (s->write_wontblock && len > 0) {
w = ssh_socket_unbuffered_write(s, ssh_buffer_get(s->out_buffer), len);
if (w < 0) {
session->alive = 0;
ssh_socket_close(s);
if(s->callbacks && s->callbacks->exception){
s->callbacks->exception(
SSH_SOCKET_EXCEPTION_ERROR,
s->last_errno,s->callbacks->userdata);
}else{
ssh_set_error(session, SSH_FATAL,
"Writing packet: error on socket (or connection closed): %s",
strerror(s->last_errno));
}
return SSH_ERROR;
return SSH_AGAIN;
}
ssh_buffer_pass_bytes(s->out_buffer, w);
if (s->session->socket_counter != NULL) {
s->session->socket_counter->out_bytes += w;
if (s->write_wontblock && len > 0) {
ssize_t bwritten;
bwritten = ssh_socket_unbuffered_write(s,
ssh_buffer_get(s->out_buffer),
len);
if (bwritten < 0) {
session->alive = 0;
ssh_socket_close(s);
if (s->callbacks && s->callbacks->exception) {
s->callbacks->exception(SSH_SOCKET_EXCEPTION_ERROR,
s->last_errno,
s->callbacks->userdata);
} else {
ssh_set_error(session,
SSH_FATAL,
"Writing packet: error on socket (or connection "
"closed): %s",
strerror(s->last_errno));
}
return SSH_ERROR;
}
ssh_buffer_pass_bytes(s->out_buffer, bwritten);
if (s->session->socket_counter != NULL) {
s->session->socket_counter->out_bytes += bwritten;
}
}
}
/* Is there some data pending? */
len = ssh_buffer_get_len(s->out_buffer);
if (s->poll_out && len > 0) {
/* force the poll system to catch pollout events */
ssh_poll_add_events(s->poll_out, POLLOUT);
/* Is there some data pending? */
len = ssh_buffer_get_len(s->out_buffer);
if (s->poll_out && len > 0) {
/* force the poll system to catch pollout events */
ssh_poll_add_events(s->poll_out, POLLOUT);
return SSH_AGAIN;
}
return SSH_AGAIN;
}
/* all data written */
return SSH_OK;
/* all data written */
return SSH_OK;
}
void ssh_socket_set_write_wontblock(ssh_socket s) {

View File

@@ -534,8 +534,8 @@ static void torture_auth_cert(void **state) {
rc = ssh_userauth_publickey(session, NULL, privkey);
assert_int_equal(rc, SSH_AUTH_SUCCESS);
ssh_key_free(privkey);
ssh_key_free(cert);
SSH_KEY_FREE(privkey);
SSH_KEY_FREE(cert);
}
static void torture_auth_agent_cert(void **state) {

View File

@@ -35,6 +35,9 @@ target_compile_options(torture_knownhosts_parsing PRIVATE ${DEFAULT_C_COMPILE_FL
add_cmocka_test(torture_hashes torture_hashes.c ${TEST_TARGET_LIBRARIES})
target_compile_options(torture_hashes PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
add_cmocka_test(torture_packet_filter torture_packet_filter.c ${TORTURE_LIBRARY})
target_compile_options(torture_packet_filter PRIVATE ${DEFAULT_C_COMPILE_FLAGS})
if (CMAKE_USE_PTHREADS_INIT)
add_cmocka_test(torture_rand torture_rand.c ${TEST_TARGET_LIBRARIES})
target_compile_options(torture_rand PRIVATE ${DEFAULT_C_COMPILE_FLAGS})

View File

@@ -22,7 +22,7 @@ static int setup(void **state) {
}
static int teardown(void **state) {
ssh_buffer_free(*state);
SSH_BUFFER_FREE(*state);
return 0;
}
@@ -125,9 +125,9 @@ static void torture_ssh_buffer_get_ssh_string(void **state) {
for(l=0;l<k;++l){
ssh_string str = ssh_buffer_get_ssh_string(buffer);
assert_null(str);
ssh_string_free(str);
SSH_STRING_FREE(str);
}
ssh_buffer_free(buffer);
SSH_BUFFER_FREE(buffer);
}
}
}
@@ -161,7 +161,7 @@ static void torture_ssh_buffer_add_format(void **state) {
assert_int_equal(len, sizeof(verif) - 1);
assert_memory_equal(ssh_buffer_get(buffer), verif, sizeof(verif) -1);
ssh_string_free(s);
SSH_STRING_FREE(s);
}
static void torture_ssh_buffer_get_format(void **state) {

View File

@@ -170,21 +170,21 @@ static void torture_config_from_file(void **state) {
assert_non_null(v);
assert_string_equal(v, PROXYCMD);
ssh_string_free_char(v);
SSH_STRING_FREE_CHAR(v);
ret = ssh_options_get(session, SSH_OPTIONS_IDENTITY, &v);
assert_true(ret == 0);
assert_non_null(v);
assert_string_equal(v, ID_FILE);
ssh_string_free_char(v);
SSH_STRING_FREE_CHAR(v);
ret = ssh_options_get(session, SSH_OPTIONS_USER, &v);
assert_true(ret == 0);
assert_non_null(v);
assert_string_equal(v, USERNAME);
ssh_string_free_char(v);
SSH_STRING_FREE_CHAR(v);
assert_string_equal(session->opts.wanted_methods[SSH_KEX], KEXALGORITHMS);
@@ -223,14 +223,14 @@ static void torture_config_glob(void **state) {
assert_non_null(v);
assert_string_equal(v, PROXYCMD);
ssh_string_free_char(v);
SSH_STRING_FREE_CHAR(v);
ret = ssh_options_get(session, SSH_OPTIONS_IDENTITY, &v);
assert_true(ret == 0);
assert_non_null(v);
assert_string_equal(v, ID_FILE);
ssh_string_free_char(v);
SSH_STRING_FREE_CHAR(v);
#endif /* HAVE_GLOB */
}

View File

@@ -41,88 +41,91 @@ static int setup_rsa_key(void **state)
static int teardown(void **state)
{
ssh_key_free(*state);
SSH_KEY_FREE(*state);
return 0;
}
static void torture_md5_hash(void **state)
{
ssh_key pubkey = *state;
unsigned char *hash = NULL;
char *hash = NULL;
char *hexa = NULL;
size_t hlen;
int rc = 0;
rc = ssh_get_publickey_hash(pubkey, SSH_PUBLICKEY_HASH_MD5, &hash, &hlen);
rc = ssh_get_publickey_hash(pubkey, SSH_PUBLICKEY_HASH_MD5,
(unsigned char **)&hash, &hlen);
assert_true(rc == 0);
hexa = ssh_get_hexa(hash, hlen);
ssh_string_free_char((char *)hash);
hexa = ssh_get_hexa((unsigned char *)hash, hlen);
SSH_STRING_FREE_CHAR(hash);
assert_string_equal(hexa,
"50:15:a0:9b:92:bf:33:1c:01:c5:8c:fe:18:fa:ce:78");
ssh_string_free_char(hexa);
SSH_STRING_FREE_CHAR(hexa);
}
static void torture_sha1_hash(void **state)
{
ssh_key pubkey = *state;
unsigned char *hash = NULL;
char *hash = NULL;
char *sha1 = NULL;
int rc = 0;
size_t hlen;
rc = ssh_get_publickey_hash(pubkey, SSH_PUBLICKEY_HASH_SHA1, &hash, &hlen);
rc = ssh_get_publickey_hash(pubkey, SSH_PUBLICKEY_HASH_SHA1,
(unsigned char **)&hash, &hlen);
assert_true(rc == 0);
sha1 = ssh_get_b64_unpadded(hash, hlen);
ssh_string_free_char((char *)hash);
sha1 = ssh_get_b64_unpadded((unsigned char *)hash, hlen);
SSH_STRING_FREE_CHAR(hash);
assert_string_equal(sha1, "6wP+houujQmxLBiFugTcoeoODCM");
ssh_string_free_char(sha1);
SSH_STRING_FREE_CHAR(sha1);
}
static void torture_sha256_hash(void **state)
{
ssh_key pubkey = *state;
unsigned char *hash = NULL;
char *hash = NULL;
char *sha256 = NULL;
int rc = 0;
size_t hlen;
rc = ssh_get_publickey_hash(pubkey, SSH_PUBLICKEY_HASH_SHA256, &hash, &hlen);
rc = ssh_get_publickey_hash(pubkey, SSH_PUBLICKEY_HASH_SHA256,
(unsigned char **)&hash, &hlen);
assert_true(rc == 0);
sha256 = ssh_get_b64_unpadded(hash, hlen);
ssh_string_free_char((char *)hash);
sha256 = ssh_get_b64_unpadded((unsigned char *)hash, hlen);
SSH_STRING_FREE_CHAR(hash);
assert_string_equal(sha256, "jXstVLLe84fSDo1kEYGn6iumnPCSorhaiWxnJz8VTII");
ssh_string_free_char(sha256);
SSH_STRING_FREE_CHAR(sha256);
}
static void torture_sha256_fingerprint(void **state)
{
ssh_key pubkey = *state;
unsigned char *hash = NULL;
char *hash = NULL;
char *sha256 = NULL;
int rc = 0;
size_t hlen;
rc = ssh_get_publickey_hash(pubkey,
SSH_PUBLICKEY_HASH_SHA256,
&hash,
(unsigned char **)&hash,
&hlen);
assert_true(rc == 0);
sha256 = ssh_get_fingerprint_hash(SSH_PUBLICKEY_HASH_SHA256,
hash,
(unsigned char *)hash,
hlen);
ssh_string_free_char(discard_const(hash));
SSH_STRING_FREE_CHAR(hash);
assert_string_equal(sha256,
"SHA256:jXstVLLe84fSDo1kEYGn6iumnPCSorhaiWxnJz8VTII");
ssh_string_free_char(sha256);
SSH_STRING_FREE_CHAR(sha256);
}
int torture_run_tests(void) {

View File

@@ -111,7 +111,7 @@ static void torture_pubkey_from_file(void **state) {
assert_true(rc == 0);
ssh_string_free(pubkey);
SSH_STRING_FREE(pubkey);
/* test if it returns 1 if pubkey doesn't exist */
unlink(LIBSSH_RSA_TESTKEY ".pub");
@@ -119,11 +119,17 @@ static void torture_pubkey_from_file(void **state) {
rc = ssh_try_publickey_from_file(session, LIBSSH_RSA_TESTKEY, &pubkey, &type);
assert_true(rc == 1);
/* This free is unnecessary, but the static analyser does not know */
SSH_STRING_FREE(pubkey);
/* test if it returns -1 if privkey doesn't exist */
unlink(LIBSSH_RSA_TESTKEY);
rc = ssh_try_publickey_from_file(session, LIBSSH_RSA_TESTKEY, &pubkey, &type);
assert_true(rc == -1);
/* This free is unnecessary, but the static analyser does not know */
SSH_STRING_FREE(pubkey);
}
static int torture_read_one_line(const char *filename, char *buffer, size_t len) {
@@ -210,8 +216,8 @@ static void torture_pubkey_generate_from_privkey(void **state) {
assert_string_equal(pubkey_line_orig, pubkey_line_new);
ssh_string_free(pubkey_orig);
ssh_string_free(pubkey_new);
SSH_STRING_FREE(pubkey_orig);
SSH_STRING_FREE(pubkey_new);
}
/**

View File

@@ -560,7 +560,7 @@ static void torture_bind_options_import_key(void **state)
/* set invalid key */
rc = ssh_bind_options_set(bind, SSH_BIND_OPTIONS_IMPORT_KEY, key);
assert_int_equal(rc, -1);
ssh_key_free(key);
SSH_KEY_FREE(key);
/* set rsa key */
base64_key = torture_get_testkey(SSH_KEYTYPE_RSA, 0, 0);

View File

@@ -0,0 +1,502 @@
/*
* This file is part of the SSH Library
*
* Copyright (c) 2018 by Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
*
* The SSH Library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or (at your
* option) any later version.
*
* The SSH Library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the SSH Library; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*/
/*
* This test checks if the messages accepted by the packet filter were intented
* to be accepted.
*
* The process consists in 2 steps:
* - Try the filter with a message type in an arbitrary state
* - If the message is accepted by the filter, check if the message is in the
* set of accepted states.
*
* Only the values selected by the flag (COMPARE_*) are considered.
* */
#include "config.h"
#define LIBSSH_STATIC
#include "torture.h"
#include "libssh/priv.h"
#include "libssh/libssh.h"
#include "libssh/session.h"
#include "libssh/auth.h"
#include "libssh/ssh2.h"
#include "libssh/packet.h"
#include "packet.c"
#define COMPARE_SESSION_STATE 1
#define COMPARE_ROLE (1 << 1)
#define COMPARE_DH_STATE (1 << 2)
#define COMPARE_AUTH_STATE (1 << 3)
#define COMPARE_GLOBAL_REQ_STATE (1 << 4)
#define COMPARE_CURRENT_METHOD (1 << 5)
#define SESSION_STATE_COUNT 11
#define DH_STATE_COUNT 4
#define AUTH_STATE_COUNT 15
#define GLOBAL_REQ_STATE_COUNT 5
#define MESSAGE_COUNT 100 // from 1 to 100
#define ROLE_CLIENT 0
#define ROLE_SERVER 1
/*
* This is the list of currently unfiltered message types.
* Only unrecognized types should be in this list.
* */
static uint8_t unfiltered[] = {
8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
22, 23, 24, 25, 26, 27, 28, 29,
35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
54, 55, 56, 57, 58, 59,
62,
67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
83, 84, 85, 86, 87, 88, 89,
};
typedef struct global_state_st {
/* If the bit in this flag is zero, the corresponding state is not
* considered, working as a wildcard (meaning any value is accepted) */
uint32_t flags;
uint8_t role;
enum ssh_session_state_e session;
enum ssh_dh_state_e dh;
enum ssh_auth_state_e auth;
enum ssh_channel_request_state_e global_req;
} global_state;
static int cmp_state(const void *e1, const void *e2)
{
global_state *s1 = (global_state *) e1;
global_state *s2 = (global_state *) e2;
/* Compare role (client == 0 or server == 1)*/
if (s1->role < s2->role) {
return -1;
}
else if (s1->role > s2->role) {
return 1;
}
/* Compare session state */
if (s1->session < s2->session) {
return -1;
}
else if (s1->session > s2->session) {
return 1;
}
/* Compare DH state */
if (s1->dh < s2->dh) {
return -1;
}
else if (s1->dh > s2->dh) {
return 1;
}
/* Compare auth */
if (s1->auth < s2->auth) {
return -1;
}
else if (s1->auth > s2->auth) {
return 1;
}
/* Compare global_req */
if (s1->global_req < s2->global_req) {
return -1;
}
else if (s1->global_req > s2->global_req) {
return 1;
}
/* If all equal, they are equal */
return 0;
}
static int cmp_state_search(const void *key, const void *array_element)
{
global_state *s1 = (global_state *) key;
global_state *s2 = (global_state *) array_element;
int result = 0;
if (s2->flags & COMPARE_ROLE) {
/* Compare role (client == 0 or server == 1)*/
if (s1->role < s2->role) {
return -1;
}
else if (s1->role > s2->role) {
return 1;
}
}
if (s2->flags & COMPARE_SESSION_STATE) {
/* Compare session state */
if (s1->session < s2->session) {
result = -1;
goto end;
}
else if (s1->session > s2->session) {
result = 1;
goto end;
}
}
if (s2->flags & COMPARE_DH_STATE) {
/* Compare DH state */
if (s1->dh < s2->dh) {
result = -1;
goto end;
}
else if (s1->dh > s2->dh) {
result = 1;
goto end;
}
}
if (s2->flags & COMPARE_AUTH_STATE) {
/* Compare auth */
if (s1->auth < s2->auth) {
result = -1;
goto end;
}
else if (s1->auth > s2->auth) {
result = 1;
goto end;
}
}
if (s2->flags & COMPARE_GLOBAL_REQ_STATE) {
/* Compare global_req */
if (s1->global_req < s2->global_req) {
result = -1;
goto end;
}
else if (s1->global_req > s2->global_req) {
result = 1;
goto end;
}
}
end:
return result;
}
static int is_state_accepted(global_state *tested, global_state *accepted,
int accepted_len)
{
global_state *found = NULL;
found = bsearch(tested, accepted, accepted_len, sizeof(global_state),
cmp_state_search);
if (found != NULL) {
return 1;
}
return 0;
}
static int cmp_uint8(const void *i, const void *j)
{
uint8_t e1 = *((uint8_t *)i);
uint8_t e2 = *((uint8_t *)j);
if (e1 < e2) {
return -1;
}
else if (e1 > e2) {
return 1;
}
return 0;
}
static int check_unfiltered(uint8_t msg_type)
{
uint8_t *found;
found = bsearch(&msg_type, unfiltered, sizeof(unfiltered)/sizeof(uint8_t),
sizeof(uint8_t), cmp_uint8);
if (found != NULL) {
return 1;
}
return 0;
}
static void torture_packet_filter_check_unfiltered(void **state)
{
ssh_session session;
int role_c;
int auth_c;
int session_c;
int dh_c;
int global_req_c;
uint8_t msg_type;
enum ssh_packet_filter_result_e rc;
int in_unfiltered;
session = ssh_new();
for (msg_type = 1; msg_type <= MESSAGE_COUNT; msg_type++) {
session->in_packet.type = msg_type;
for (role_c = 0; role_c < 2; role_c++) {
session->server = role_c;
for (session_c = 0; session_c < SESSION_STATE_COUNT; session_c++) {
session->session_state = session_c;
for (dh_c = 0; dh_c < DH_STATE_COUNT; dh_c++) {
session->dh_handshake_state = dh_c;
for (auth_c = 0; auth_c < AUTH_STATE_COUNT; auth_c++) {
session->auth.state = auth_c;
for (global_req_c = 0;
global_req_c < GLOBAL_REQ_STATE_COUNT;
global_req_c++)
{
session->global_req_state = global_req_c;
rc = ssh_packet_incoming_filter(session);
if (rc == SSH_PACKET_UNKNOWN) {
in_unfiltered = check_unfiltered(msg_type);
if (!in_unfiltered) {
fprintf(stderr, "Message type %d UNFILTERED "
"in state: role %d, session %d, dh %d, auth %d\n",
msg_type, role_c, session_c, dh_c, auth_c);
}
assert_int_equal(in_unfiltered, 1);
}
else {
in_unfiltered = check_unfiltered(msg_type);
if (in_unfiltered) {
fprintf(stderr, "Message type %d NOT UNFILTERED "
"in state: role %d, session %d, dh %d, auth %d\n",
msg_type, role_c, session_c, dh_c, auth_c);
}
assert_int_equal(in_unfiltered, 0);
}
}
}
}
}
}
}
ssh_free(session);
}
static int check_message_in_all_states(global_state accepted[],
int accepted_count, uint8_t msg_type)
{
ssh_session session;
int role_c;
int auth_c;
int session_c;
int dh_c;
int global_req_c;
enum ssh_packet_filter_result_e rc;
int in_accepted;
global_state key;
session = ssh_new();
/* Sort the accepted array so that the elements can be searched using
* bsearch */
qsort(accepted, accepted_count, sizeof(global_state), cmp_state);
session->in_packet.type = msg_type;
for (role_c = 0; role_c < 2; role_c++) {
session->server = role_c;
key.role = role_c;
for (session_c = 0; session_c < SESSION_STATE_COUNT; session_c++) {
session->session_state = session_c;
key.session = session_c;
for (dh_c = 0; dh_c < DH_STATE_COUNT; dh_c++) {
session->dh_handshake_state = dh_c;
key.dh = dh_c;
for (auth_c = 0; auth_c < AUTH_STATE_COUNT; auth_c++) {
session->auth.state = auth_c;
key.auth = auth_c;
for (global_req_c = 0;
global_req_c < GLOBAL_REQ_STATE_COUNT;
global_req_c++)
{
session->global_req_state = global_req_c;
key.global_req = global_req_c;
rc = ssh_packet_incoming_filter(session);
if (rc == SSH_PACKET_ALLOWED) {
in_accepted = is_state_accepted(&key, accepted,
accepted_count);
if (!in_accepted) {
fprintf(stderr, "Message type %d ALLOWED "
"in state: role %d, session %d, dh %d, auth %d\n",
msg_type, role_c, session_c, dh_c, auth_c);
}
assert_int_equal(in_accepted, 1);
}
else if (rc == SSH_PACKET_DENIED) {
in_accepted = is_state_accepted(&key, accepted, accepted_count);
if (in_accepted) {
fprintf(stderr, "Message type %d DENIED "
"in state: role %d, session %d, dh %d, auth %d\n",
msg_type, role_c, session_c, dh_c, auth_c);
}
assert_int_equal(in_accepted, 0);
}
else {
fprintf(stderr, "Message type %d UNFILTERED "
"in state: role %d, session %d, dh %d, auth %d\n",
msg_type, role_c, session_c, dh_c, auth_c);
}
}
}
}
}
}
ssh_free(session);
return 0;
}
static void torture_packet_filter_check_auth_success(void **state)
{
int rc;
global_state accepted[] = {
{
.flags = (COMPARE_SESSION_STATE |
COMPARE_ROLE |
COMPARE_AUTH_STATE |
COMPARE_DH_STATE),
.role = ROLE_CLIENT,
.session = SSH_SESSION_STATE_AUTHENTICATING,
.dh = DH_STATE_FINISHED,
.auth = SSH_AUTH_STATE_PUBKEY_AUTH_SENT,
},
{
.flags = (COMPARE_SESSION_STATE |
COMPARE_ROLE |
COMPARE_AUTH_STATE |
COMPARE_DH_STATE),
.role = ROLE_CLIENT,
.session = SSH_SESSION_STATE_AUTHENTICATING,
.dh = DH_STATE_FINISHED,
.auth = SSH_AUTH_STATE_PASSWORD_AUTH_SENT,
},
{
.flags = (COMPARE_SESSION_STATE |
COMPARE_ROLE |
COMPARE_AUTH_STATE |
COMPARE_DH_STATE),
.role = ROLE_CLIENT,
.session = SSH_SESSION_STATE_AUTHENTICATING,
.dh = DH_STATE_FINISHED,
.auth = SSH_AUTH_STATE_GSSAPI_MIC_SENT,
},
{
.flags = (COMPARE_SESSION_STATE |
COMPARE_ROLE |
COMPARE_AUTH_STATE |
COMPARE_DH_STATE),
.role = ROLE_CLIENT,
.session = SSH_SESSION_STATE_AUTHENTICATING,
.dh = DH_STATE_FINISHED,
.auth = SSH_AUTH_STATE_KBDINT_SENT,
},
{
.flags = (COMPARE_SESSION_STATE |
COMPARE_ROLE |
COMPARE_AUTH_STATE |
COMPARE_DH_STATE |
COMPARE_CURRENT_METHOD),
.role = ROLE_CLIENT,
.session = SSH_SESSION_STATE_AUTHENTICATING,
.dh = DH_STATE_FINISHED,
.auth = SSH_AUTH_STATE_AUTH_NONE_SENT,
}
};
int accepted_count = 5;
/* Unused */
(void) state;
rc = check_message_in_all_states(accepted, accepted_count,
SSH2_MSG_USERAUTH_SUCCESS);
assert_int_equal(rc, 0);
}
static void torture_packet_filter_check_channel_open(void **state)
{
int rc;
/* The only condition to accept a CHANNEL_OPEN is to be authenticated */
global_state accepted[] = {
{
.flags = COMPARE_SESSION_STATE,
.session = SSH_SESSION_STATE_AUTHENTICATED,
}
};
int accepted_count = 1;
/* Unused */
(void) state;
rc = check_message_in_all_states(accepted, accepted_count,
SSH2_MSG_CHANNEL_OPEN);
assert_int_equal(rc, 0);
}
int torture_run_tests(void)
{
int rc;
struct CMUnitTest tests[] = {
cmocka_unit_test(torture_packet_filter_check_auth_success),
cmocka_unit_test(torture_packet_filter_check_channel_open),
cmocka_unit_test(torture_packet_filter_check_unfiltered),
};
ssh_init();
torture_filter_tests(tests);
rc = cmocka_run_group_tests(tests, NULL, NULL);
ssh_finalize();
return rc;
}

View File

@@ -82,7 +82,7 @@ static void torture_pki_dsa_import_pubkey_file(void **state)
assert_return_code(rc, errno);
assert_non_null(pubkey);
ssh_key_free(pubkey);
SSH_KEY_FREE(pubkey);
}
static void torture_pki_dsa_import_pubkey_from_openssh_privkey(void **state)
@@ -97,7 +97,7 @@ static void torture_pki_dsa_import_pubkey_from_openssh_privkey(void **state)
assert_return_code(rc, errno);
assert_non_null(pubkey);
ssh_key_free(pubkey);
SSH_KEY_FREE(pubkey);
}
static void torture_pki_dsa_import_privkey_base64(void **state)
@@ -115,7 +115,7 @@ static void torture_pki_dsa_import_privkey_base64(void **state)
&key);
assert_true(rc == 0);
ssh_key_free(key);
SSH_KEY_FREE(key);
}
#ifdef HAVE_LIBCRYPTO
@@ -154,8 +154,8 @@ static void torture_pki_dsa_write_privkey(void **state)
rc = ssh_key_cmp(origkey, privkey, SSH_KEY_CMP_PRIVATE);
assert_true(rc == 0);
ssh_key_free(origkey);
ssh_key_free(privkey);
SSH_KEY_FREE(origkey);
SSH_KEY_FREE(privkey);
/* Test with passphrase */
rc = ssh_pki_import_privkey_file(LIBSSH_DSA_TESTKEY_PASSPHRASE,
@@ -192,8 +192,8 @@ static void torture_pki_dsa_write_privkey(void **state)
rc = ssh_key_cmp(origkey, privkey, SSH_KEY_CMP_PRIVATE);
assert_true(rc == 0);
ssh_key_free(origkey);
ssh_key_free(privkey);
SSH_KEY_FREE(origkey);
SSH_KEY_FREE(privkey);
}
#endif
@@ -215,8 +215,7 @@ static void torture_pki_dsa_import_privkey_base64_passphrase(void **state)
rc = ssh_key_is_private(key);
assert_true(rc == 1);
ssh_key_free(key);
key = NULL;
SSH_KEY_FREE(key);
/* test if it returns -1 if passphrase is wrong */
rc = ssh_pki_import_privkey_base64(torture_get_testkey(SSH_KEYTYPE_DSS, 0, 1),
@@ -247,8 +246,7 @@ static void torture_pki_dsa_import_privkey_base64_passphrase(void **state)
rc = ssh_key_is_private(key);
assert_true(rc == 1);
ssh_key_free(key);
key = NULL;
SSH_KEY_FREE(key);
/* test if it returns -1 if passphrase is wrong */
rc = ssh_pki_import_privkey_base64(torture_get_testkey(SSH_KEYTYPE_DSS, 0, 1),
@@ -259,7 +257,7 @@ static void torture_pki_dsa_import_privkey_base64_passphrase(void **state)
assert_true(rc == -1);
/* This free in unnecessary, but the static analyser does not know */
ssh_key_free(key);
SSH_KEY_FREE(key);
#ifndef HAVE_LIBCRYPTO
/* test if it returns -1 if passphrase is NULL */
@@ -272,7 +270,7 @@ static void torture_pki_dsa_import_privkey_base64_passphrase(void **state)
assert_true(rc == -1);
/* This free in unnecessary, but the static analyser does not know */
ssh_key_free(key);
SSH_KEY_FREE(key);
#endif /* HAVE_LIBCRYPTO */
}
@@ -299,8 +297,7 @@ torture_pki_dsa_import_openssh_privkey_base64_passphrase(void **state)
rc = ssh_key_is_private(key);
assert_true(rc == 1);
ssh_key_free(key);
key = NULL;
SSH_KEY_FREE(key);
/* test if it returns -1 if passphrase is wrong */
rc = ssh_pki_import_privkey_base64(keystring,
@@ -328,8 +325,7 @@ torture_pki_dsa_import_openssh_privkey_base64_passphrase(void **state)
rc = ssh_key_is_private(key);
assert_true(rc == 1);
ssh_key_free(key);
key = NULL;
SSH_KEY_FREE(key);
/* test if it returns -1 if passphrase is wrong */
rc = ssh_pki_import_privkey_base64(keystring,
@@ -339,6 +335,9 @@ torture_pki_dsa_import_openssh_privkey_base64_passphrase(void **state)
&key);
assert_true(rc == -1);
/* This free is unnecessary, but the static analyser does not know */
SSH_KEY_FREE(key);
/* test if it returns -1 if passphrase is NULL */
rc = ssh_pki_import_privkey_base64(keystring,
NULL,
@@ -346,6 +345,9 @@ torture_pki_dsa_import_openssh_privkey_base64_passphrase(void **state)
NULL,
&key);
assert_true(rc == -1);
/* This free is unnecessary, but the static analyser does not know */
SSH_KEY_FREE(key);
}
@@ -371,8 +373,8 @@ static void torture_pki_dsa_publickey_from_privatekey(void **state)
rc = ssh_pki_export_privkey_to_pubkey(key, &pubkey);
assert_true(rc == SSH_OK);
ssh_key_free(key);
ssh_key_free(pubkey);
SSH_KEY_FREE(key);
SSH_KEY_FREE(pubkey);
}
static void torture_pki_dsa_import_cert_file(void **state)
@@ -392,7 +394,7 @@ static void torture_pki_dsa_import_cert_file(void **state)
rc = ssh_key_is_public(cert);
assert_true(rc == 1);
ssh_key_free(cert);
SSH_KEY_FREE(cert);
}
static void torture_pki_dsa_publickey_base64(void **state)
@@ -443,7 +445,7 @@ static void torture_pki_dsa_publickey_base64(void **state)
free(b64_key);
free(key_buf);
ssh_key_free(key);
SSH_KEY_FREE(key);
}
static void torture_pki_dsa_generate_pubkey_from_privkey(void **state)
@@ -482,8 +484,8 @@ static void torture_pki_dsa_generate_pubkey_from_privkey(void **state)
pubkey_generated,
len);
ssh_key_free(privkey);
ssh_key_free(pubkey);
SSH_KEY_FREE(privkey);
SSH_KEY_FREE(pubkey);
}
static void torture_pki_dsa_duplicate_key(void **state)
@@ -503,7 +505,7 @@ static void torture_pki_dsa_duplicate_key(void **state)
rc = ssh_pki_export_pubkey_base64(pubkey, &b64_key);
assert_true(rc == 0);
ssh_key_free(pubkey);
SSH_KEY_FREE(pubkey);
rc = ssh_pki_import_privkey_file(LIBSSH_DSA_TESTKEY,
NULL,
@@ -530,11 +532,11 @@ static void torture_pki_dsa_duplicate_key(void **state)
rc = ssh_key_cmp(privkey, privkey_dup, SSH_KEY_CMP_PRIVATE);
assert_true(rc == 0);
ssh_key_free(pubkey);
ssh_key_free(privkey);
ssh_key_free(privkey_dup);
ssh_string_free_char(b64_key);
ssh_string_free_char(b64_key_gen);
SSH_KEY_FREE(pubkey);
SSH_KEY_FREE(privkey);
SSH_KEY_FREE(privkey_dup);
SSH_STRING_FREE_CHAR(b64_key);
SSH_STRING_FREE_CHAR(b64_key_gen);
}
static void torture_pki_dsa_generate_key(void **state)
@@ -553,8 +555,7 @@ static void torture_pki_dsa_generate_key(void **state)
rc = pki_signature_verify(session,sign,key,DSA_HASH,20);
assert_true(rc == SSH_OK);
ssh_signature_free(sign);
ssh_key_free(key);
key=NULL;
SSH_KEY_FREE(key);
rc = ssh_pki_generate(SSH_KEYTYPE_DSS, 2048, &key);
assert_true(rc == SSH_OK);
@@ -564,8 +565,7 @@ static void torture_pki_dsa_generate_key(void **state)
rc = pki_signature_verify(session,sign,key,DSA_HASH,20);
assert_true(rc == SSH_OK);
ssh_signature_free(sign);
ssh_key_free(key);
key=NULL;
SSH_KEY_FREE(key);
rc = ssh_pki_generate(SSH_KEYTYPE_DSS, 3072, &key);
assert_true(rc == SSH_OK);
@@ -575,8 +575,7 @@ static void torture_pki_dsa_generate_key(void **state)
rc = pki_signature_verify(session,sign,key,DSA_HASH,20);
assert_true(rc == SSH_OK);
ssh_signature_free(sign);
ssh_key_free(key);
key=NULL;
SSH_KEY_FREE(key);
ssh_free(session);
}

View File

@@ -121,7 +121,7 @@ static void torture_pki_ecdsa_import_pubkey_file(void **state)
assert_return_code(rc, errno);
assert_non_null(pubkey);
ssh_key_free(pubkey);
SSH_KEY_FREE(pubkey);
}
static void torture_pki_ecdsa_import_pubkey_from_openssh_privkey(void **state)
@@ -136,7 +136,7 @@ static void torture_pki_ecdsa_import_pubkey_from_openssh_privkey(void **state)
assert_return_code(rc, errno);
assert_non_null(pubkey);
ssh_key_free(pubkey);
SSH_KEY_FREE(pubkey);
}
static void torture_pki_ecdsa_import_privkey_base64(void **state)
@@ -158,7 +158,7 @@ static void torture_pki_ecdsa_import_privkey_base64(void **state)
assert_true(rc == 1);
free(key_str);
ssh_key_free(key);
SSH_KEY_FREE(key);
}
static void torture_pki_ecdsa_publickey_from_privatekey(void **state)
@@ -181,8 +181,8 @@ static void torture_pki_ecdsa_publickey_from_privatekey(void **state)
assert_true(rc == SSH_OK);
free(key_str);
ssh_key_free(key);
ssh_key_free(pubkey);
SSH_KEY_FREE(key);
SSH_KEY_FREE(pubkey);
}
static void torture_pki_ecdsa_publickey_base64(void **state)
@@ -219,7 +219,7 @@ static void torture_pki_ecdsa_publickey_base64(void **state)
free(b64_key);
free(key_buf);
ssh_key_free(key);
SSH_KEY_FREE(key);
}
static void torture_pki_ecdsa_generate_pubkey_from_privkey(void **state)
@@ -261,8 +261,8 @@ static void torture_pki_ecdsa_generate_pubkey_from_privkey(void **state)
len = torture_pubkey_len(pubkey_original);
assert_int_equal(strncmp(pubkey_original, pubkey_generated, len), 0);
ssh_key_free(privkey);
ssh_key_free(pubkey);
SSH_KEY_FREE(privkey);
SSH_KEY_FREE(pubkey);
}
static void torture_pki_ecdsa_duplicate_key(void **state)
@@ -281,7 +281,7 @@ static void torture_pki_ecdsa_duplicate_key(void **state)
rc = ssh_pki_export_pubkey_base64(pubkey, &b64_key);
assert_true(rc == 0);
ssh_key_free(pubkey);
SSH_KEY_FREE(pubkey);
rc = ssh_pki_import_privkey_file(LIBSSH_ECDSA_TESTKEY,
NULL,
@@ -307,11 +307,11 @@ static void torture_pki_ecdsa_duplicate_key(void **state)
rc = ssh_key_cmp(privkey, privkey_dup, SSH_KEY_CMP_PRIVATE);
assert_true(rc == 0);
ssh_key_free(pubkey);
ssh_key_free(privkey);
ssh_key_free(privkey_dup);
ssh_string_free_char(b64_key);
ssh_string_free_char(b64_key_gen);
SSH_KEY_FREE(pubkey);
SSH_KEY_FREE(privkey);
SSH_KEY_FREE(privkey_dup);
SSH_STRING_FREE_CHAR(b64_key);
SSH_STRING_FREE_CHAR(b64_key_gen);
}
/* Test case for bug #147: Private ECDSA key duplication did not carry
@@ -342,9 +342,9 @@ static void torture_pki_ecdsa_duplicate_then_demote(void **state)
assert_true(rc == 0);
assert_int_equal(pubkey->ecdsa_nid, privkey->ecdsa_nid);
ssh_key_free(pubkey);
ssh_key_free(privkey);
ssh_key_free(privkey_dup);
SSH_KEY_FREE(pubkey);
SSH_KEY_FREE(privkey);
SSH_KEY_FREE(privkey_dup);
}
static void torture_pki_generate_key_ecdsa(void **state)
@@ -373,8 +373,7 @@ static void torture_pki_generate_key_ecdsa(void **state)
assert_true(strcmp(etype_char, "ecdsa-sha2-nistp256") == 0);
ssh_signature_free(sign);
ssh_key_free(key);
key=NULL;
SSH_KEY_FREE(key);
rc = ssh_pki_generate(SSH_KEYTYPE_ECDSA, 384, &key);
assert_true(rc == SSH_OK);
@@ -391,8 +390,7 @@ static void torture_pki_generate_key_ecdsa(void **state)
assert_true(strcmp(etype_char, "ecdsa-sha2-nistp384") == 0);
ssh_signature_free(sign);
ssh_key_free(key);
key=NULL;
SSH_KEY_FREE(key);
rc = ssh_pki_generate(SSH_KEYTYPE_ECDSA, 512, &key);
assert_true(rc == SSH_OK);
@@ -409,8 +407,7 @@ static void torture_pki_generate_key_ecdsa(void **state)
assert_true(strcmp(etype_char, "ecdsa-sha2-nistp521") == 0);
ssh_signature_free(sign);
ssh_key_free(key);
key=NULL;
SSH_KEY_FREE(key);
ssh_free(session);
}
@@ -451,8 +448,8 @@ static void torture_pki_ecdsa_write_privkey(void **state)
rc = ssh_key_cmp(origkey, privkey, SSH_KEY_CMP_PRIVATE);
assert_true(rc == 0);
ssh_key_free(origkey);
ssh_key_free(privkey);
SSH_KEY_FREE(origkey);
SSH_KEY_FREE(privkey);
/* Test with passphrase */
rc = ssh_pki_import_privkey_file(LIBSSH_ECDSA_TESTKEY_PASSPHRASE,
@@ -489,8 +486,8 @@ static void torture_pki_ecdsa_write_privkey(void **state)
rc = ssh_key_cmp(origkey, privkey, SSH_KEY_CMP_PRIVATE);
assert_true(rc == 0);
ssh_key_free(origkey);
ssh_key_free(privkey);
SSH_KEY_FREE(origkey);
SSH_KEY_FREE(privkey);
}
#endif /* HAVE_LIBCRYPTO */
@@ -508,7 +505,7 @@ static void torture_pki_ecdsa_name(void **state, const char *expected_name)
etype_char =ssh_pki_key_ecdsa_name(key);
assert_true(strcmp(etype_char, expected_name) == 0);
ssh_key_free(key);
SSH_KEY_FREE(key);
}
static void torture_pki_ecdsa_name256(void **state)

View File

@@ -62,7 +62,7 @@ static void torture_pki_ed25519_import_pubkey_file(void **state)
assert_return_code(rc, errno);
assert_non_null(pubkey);
ssh_key_free(pubkey);
SSH_KEY_FREE(pubkey);
}
static void torture_pki_ed25519_import_pubkey_from_openssh_privkey(void **state)
@@ -77,7 +77,7 @@ static void torture_pki_ed25519_import_pubkey_from_openssh_privkey(void **state)
assert_return_code(rc, errno);
assert_non_null(pubkey);
ssh_key_free(pubkey);
SSH_KEY_FREE(pubkey);
}
static void torture_pki_ed25519_import_privkey_base64(void **state)
@@ -106,7 +106,7 @@ static void torture_pki_ed25519_import_privkey_base64(void **state)
assert_true(rc == 1);
free(key_str);
ssh_key_free(key);
SSH_KEY_FREE(key);
}
@@ -141,7 +141,7 @@ static void torture_pki_ed25519_import_export_privkey_base64(void **state)
NULL,
&b64_key);
assert_return_code(rc, errno);
ssh_key_free(key);
SSH_KEY_FREE(key);
rc = ssh_pki_import_privkey_base64(b64_key,
passphrase,
@@ -157,7 +157,7 @@ static void torture_pki_ed25519_import_export_privkey_base64(void **state)
assert_true(rc == 1);
SSH_STRING_FREE_CHAR(b64_key);
ssh_key_free(key);
SSH_KEY_FREE(key);
}
static void torture_pki_ed25519_publickey_from_privatekey(void **state)
@@ -184,8 +184,8 @@ static void torture_pki_ed25519_publickey_from_privatekey(void **state)
rc = ssh_pki_export_privkey_to_pubkey(key, &pubkey);
assert_true(rc == SSH_OK);
ssh_key_free(key);
ssh_key_free(pubkey);
SSH_KEY_FREE(key);
SSH_KEY_FREE(pubkey);
}
static void torture_pki_ed25519_publickey_base64(void **state)
@@ -222,7 +222,7 @@ static void torture_pki_ed25519_publickey_base64(void **state)
free(b64_key);
free(key_buf);
ssh_key_free(key);
SSH_KEY_FREE(key);
}
static void torture_pki_ed25519_generate_pubkey_from_privkey(void **state)
@@ -261,8 +261,8 @@ static void torture_pki_ed25519_generate_pubkey_from_privkey(void **state)
pubkey_generated,
len);
ssh_key_free(privkey);
ssh_key_free(pubkey);
SSH_KEY_FREE(privkey);
SSH_KEY_FREE(pubkey);
}
static void torture_pki_ed25519_generate_key(void **state)
@@ -293,8 +293,7 @@ static void torture_pki_ed25519_generate_key(void **state)
assert_true(rc == SSH_ERROR);
ssh_signature_free(sign);
ssh_key_free(key);
key=NULL;
SSH_KEY_FREE(key);
ssh_free(session);
}
@@ -336,7 +335,7 @@ static void torture_pki_ed25519_write_privkey(void **state)
assert_true(rc == 0);
unlink(LIBSSH_ED25519_TESTKEY);
ssh_key_free(privkey);
SSH_KEY_FREE(privkey);
/* do the same with passphrase */
rc = ssh_pki_export_privkey_file(origkey,
torture_get_testkey_passphrase(),
@@ -365,8 +364,8 @@ static void torture_pki_ed25519_write_privkey(void **state)
assert_true(rc == 0);
unlink(LIBSSH_ED25519_TESTKEY);
ssh_key_free(origkey);
ssh_key_free(privkey);
SSH_KEY_FREE(origkey);
SSH_KEY_FREE(privkey);
/* Test with passphrase */
rc = ssh_pki_import_privkey_file(LIBSSH_ED25519_TESTKEY_PASSPHRASE,
@@ -404,8 +403,8 @@ static void torture_pki_ed25519_write_privkey(void **state)
rc = ssh_key_cmp(origkey, privkey, SSH_KEY_CMP_PRIVATE);
assert_true(rc == 0);
ssh_key_free(origkey);
ssh_key_free(privkey);
SSH_KEY_FREE(origkey);
SSH_KEY_FREE(privkey);
}
static void torture_pki_ed25519_sign(void **state)
@@ -441,8 +440,8 @@ static void torture_pki_ed25519_sign(void **state)
assert_memory_equal(ssh_string_data(blob), ref_signature, sizeof(ref_signature));
/* ssh_print_hexa("signature", ssh_string_data(blob), ssh_string_len(blob)); */
ssh_signature_free(sig);
ssh_key_free(privkey);
ssh_string_free(blob);
SSH_KEY_FREE(privkey);
SSH_STRING_FREE(blob);
}
@@ -473,8 +472,8 @@ static void torture_pki_ed25519_verify(void **state){
ssh_signature_free(sig);
/* alter signature and expect false result */
ssh_key_free(pubkey);
ssh_string_free(blob);
SSH_KEY_FREE(pubkey);
SSH_STRING_FREE(blob);
free(pkey_ptr);
}
@@ -509,8 +508,8 @@ static void torture_pki_ed25519_verify_bad(void **state){
ssh_signature_free(sig);
}
ssh_key_free(pubkey);
ssh_string_free(blob);
SSH_KEY_FREE(pubkey);
SSH_STRING_FREE(blob);
free(pkey_ptr);
}
@@ -535,8 +534,7 @@ static void torture_pki_ed25519_import_privkey_base64_passphrase(void **state)
rc = ssh_key_is_private(key);
assert_true(rc == 1);
ssh_key_free(key);
key = NULL;
SSH_KEY_FREE(key);
/* test if it returns -1 if passphrase is wrong */
rc = ssh_pki_import_privkey_base64(testkey,
@@ -545,7 +543,7 @@ static void torture_pki_ed25519_import_privkey_base64_passphrase(void **state)
NULL,
&key);
assert_true(rc == -1);
ssh_key_free(key);
SSH_KEY_FREE(key);
}
static void torture_pki_ed25519_privkey_dup(void **state)
@@ -572,8 +570,8 @@ static void torture_pki_ed25519_privkey_dup(void **state)
dup = ssh_key_dup(key);
assert_non_null(dup);
ssh_key_free(key);
ssh_key_free(dup);
SSH_KEY_FREE(key);
SSH_KEY_FREE(dup);
}
static void torture_pki_ed25519_pubkey_dup(void **state)
@@ -609,8 +607,8 @@ static void torture_pki_ed25519_pubkey_dup(void **state)
assert_true(rc == 1);
SAFE_FREE(pub_str);
ssh_key_free(pubkey);
ssh_key_free(dup);
SSH_KEY_FREE(pubkey);
SSH_KEY_FREE(dup);
}
int torture_run_tests(void) {

View File

@@ -84,7 +84,7 @@ static void torture_pki_rsa_import_pubkey_file(void **state)
assert_return_code(rc, errno);
assert_non_null(pubkey);
ssh_key_free(pubkey);
SSH_KEY_FREE(pubkey);
}
static void torture_pki_rsa_import_pubkey_from_openssh_privkey(void **state)
@@ -99,7 +99,7 @@ static void torture_pki_rsa_import_pubkey_from_openssh_privkey(void **state)
assert_return_code(rc, errno);
assert_non_null(pubkey);
ssh_key_free(pubkey);
SSH_KEY_FREE(pubkey);
}
static void torture_pki_rsa_import_privkey_base64_NULL_key(void **state)
@@ -131,7 +131,7 @@ static void torture_pki_rsa_import_privkey_base64_NULL_str(void **state)
rc = ssh_pki_import_privkey_base64(NULL, passphrase, NULL, NULL, &key);
assert_true(rc == -1);
ssh_key_free(key);
SSH_KEY_FREE(key);
}
static void torture_pki_rsa_import_privkey_base64(void **state)
@@ -160,7 +160,7 @@ static void torture_pki_rsa_import_privkey_base64(void **state)
assert_true(rc == 1);
free(key_str);
ssh_key_free(key);
SSH_KEY_FREE(key);
}
static void torture_pki_rsa_publickey_from_privatekey(void **state)
@@ -185,8 +185,8 @@ static void torture_pki_rsa_publickey_from_privatekey(void **state)
rc = ssh_pki_export_privkey_to_pubkey(key, &pubkey);
assert_true(rc == SSH_OK);
ssh_key_free(key);
ssh_key_free(pubkey);
SSH_KEY_FREE(key);
SSH_KEY_FREE(pubkey);
}
static void torture_pki_rsa_copy_cert_to_privkey(void **state)
@@ -239,9 +239,9 @@ static void torture_pki_rsa_copy_cert_to_privkey(void **state)
rc = ssh_pki_copy_cert_to_privkey(cert, privkey);
assert_true(rc == SSH_ERROR);
ssh_key_free(cert);
ssh_key_free(privkey);
ssh_key_free(pubkey);
SSH_KEY_FREE(cert);
SSH_KEY_FREE(privkey);
SSH_KEY_FREE(pubkey);
}
static void torture_pki_rsa_import_cert_file(void **state) {
@@ -260,7 +260,7 @@ static void torture_pki_rsa_import_cert_file(void **state) {
rc = ssh_key_is_public(cert);
assert_true(rc == 1);
ssh_key_free(cert);
SSH_KEY_FREE(cert);
}
static void torture_pki_rsa_publickey_base64(void **state)
@@ -297,7 +297,7 @@ static void torture_pki_rsa_publickey_base64(void **state)
free(b64_key);
free(key_buf);
ssh_key_free(key);
SSH_KEY_FREE(key);
}
static void torture_pki_rsa_generate_pubkey_from_privkey(void **state) {
@@ -335,8 +335,8 @@ static void torture_pki_rsa_generate_pubkey_from_privkey(void **state) {
pubkey_generated,
len);
ssh_key_free(privkey);
ssh_key_free(pubkey);
SSH_KEY_FREE(privkey);
SSH_KEY_FREE(pubkey);
}
static void torture_pki_rsa_duplicate_key(void **state)
@@ -356,7 +356,7 @@ static void torture_pki_rsa_duplicate_key(void **state)
rc = ssh_pki_export_pubkey_base64(pubkey, &b64_key);
assert_true(rc == 0);
ssh_key_free(pubkey);
SSH_KEY_FREE(pubkey);
rc = ssh_pki_import_privkey_file(LIBSSH_RSA_TESTKEY,
NULL,
@@ -382,11 +382,11 @@ static void torture_pki_rsa_duplicate_key(void **state)
rc = ssh_key_cmp(privkey, privkey_dup, SSH_KEY_CMP_PRIVATE);
assert_true(rc == 0);
ssh_key_free(pubkey);
ssh_key_free(privkey);
ssh_key_free(privkey_dup);
ssh_string_free_char(b64_key);
ssh_string_free_char(b64_key_gen);
SSH_KEY_FREE(pubkey);
SSH_KEY_FREE(privkey);
SSH_KEY_FREE(privkey_dup);
SSH_STRING_FREE_CHAR(b64_key);
SSH_STRING_FREE_CHAR(b64_key_gen);
}
static void torture_pki_rsa_generate_key(void **state)
@@ -405,7 +405,7 @@ static void torture_pki_rsa_generate_key(void **state)
rc = pki_signature_verify(session,sign,key,RSA_HASH,20);
assert_true(rc == SSH_OK);
ssh_signature_free(sign);
ssh_key_free(key);
SSH_KEY_FREE(key);
key=NULL;
rc = ssh_pki_generate(SSH_KEYTYPE_RSA, 2048, &key);
@@ -416,7 +416,7 @@ static void torture_pki_rsa_generate_key(void **state)
rc = pki_signature_verify(session,sign,key,RSA_HASH,20);
assert_true(rc == SSH_OK);
ssh_signature_free(sign);
ssh_key_free(key);
SSH_KEY_FREE(key);
key=NULL;
rc = ssh_pki_generate(SSH_KEYTYPE_RSA, 4096, &key);
@@ -427,7 +427,7 @@ static void torture_pki_rsa_generate_key(void **state)
rc = pki_signature_verify(session,sign,key,RSA_HASH,20);
assert_true(rc == SSH_OK);
ssh_signature_free(sign);
ssh_key_free(key);
SSH_KEY_FREE(key);
key=NULL;
ssh_free(session);
@@ -477,7 +477,7 @@ static void torture_pki_rsa_sha2(void **state)
ssh_signature_free(sign);
/* Cleanup */
ssh_key_free(key);
SSH_KEY_FREE(key);
ssh_free(session);
}
@@ -518,8 +518,8 @@ static void torture_pki_rsa_write_privkey(void **state)
rc = ssh_key_cmp(origkey, privkey, SSH_KEY_CMP_PRIVATE);
assert_true(rc == 0);
ssh_key_free(origkey);
ssh_key_free(privkey);
SSH_KEY_FREE(origkey);
SSH_KEY_FREE(privkey);
/* Test with passphrase */
rc = ssh_pki_import_privkey_file(LIBSSH_RSA_TESTKEY_PASSPHRASE,
@@ -557,8 +557,8 @@ static void torture_pki_rsa_write_privkey(void **state)
rc = ssh_key_cmp(origkey, privkey, SSH_KEY_CMP_PRIVATE);
assert_true(rc == 0);
ssh_key_free(origkey);
ssh_key_free(privkey);
SSH_KEY_FREE(origkey);
SSH_KEY_FREE(privkey);
}
#endif /* HAVE_LIBCRYPTO */
@@ -581,8 +581,7 @@ static void torture_pki_rsa_import_privkey_base64_passphrase(void **state)
rc = ssh_key_is_private(key);
assert_true(rc == 1);
ssh_key_free(key);
key = NULL;
SSH_KEY_FREE(key);
/* test if it returns -1 if passphrase is wrong */
rc = ssh_pki_import_privkey_base64(torture_get_testkey(SSH_KEYTYPE_RSA, 0, 1),
@@ -591,8 +590,7 @@ static void torture_pki_rsa_import_privkey_base64_passphrase(void **state)
NULL,
&key);
assert_true(rc == -1);
ssh_key_free(key);
key = NULL;
SSH_KEY_FREE(key);
#ifndef HAVE_LIBCRYPTO
/* test if it returns -1 if passphrase is NULL */
@@ -603,8 +601,7 @@ static void torture_pki_rsa_import_privkey_base64_passphrase(void **state)
NULL,
&key);
assert_true(rc == -1);
ssh_key_free(key);
key = NULL;
SSH_KEY_FREE(key);
#endif
}
@@ -631,8 +628,7 @@ torture_pki_rsa_import_openssh_privkey_base64_passphrase(void **state)
rc = ssh_key_is_private(key);
assert_true(rc == 1);
ssh_key_free(key);
key = NULL;
SSH_KEY_FREE(key);
/* test if it returns -1 if passphrase is wrong */
rc = ssh_pki_import_privkey_base64(keystring,
@@ -641,8 +637,7 @@ torture_pki_rsa_import_openssh_privkey_base64_passphrase(void **state)
NULL,
&key);
assert_true(rc == -1);
ssh_key_free(key);
key = NULL;
SSH_KEY_FREE(key);
/* test if it returns -1 if passphrase is NULL */
/* libcrypto asks for a passphrase, so skip this test */
@@ -652,8 +647,7 @@ torture_pki_rsa_import_openssh_privkey_base64_passphrase(void **state)
NULL,
&key);
assert_true(rc == -1);
ssh_key_free(key);
key = NULL;
SSH_KEY_FREE(key);
}
int torture_run_tests(void) {

View File

@@ -87,7 +87,7 @@ static void *thread_growing_buffer(void *threadid)
}
/* Teardown */
ssh_buffer_free(buffer);
SSH_BUFFER_FREE(buffer);
pthread_exit(NULL);
}
@@ -134,14 +134,14 @@ static void *thread_growing_buffer_shifting(void *threadid)
if (ssh_buffer_get_len(buffer) * 4 < buffer->allocated) {
assert_true(ssh_buffer_get_len(buffer) * 4 >= buffer->allocated);
/* Teardown */
ssh_buffer_free(buffer);
SSH_BUFFER_FREE(buffer);
pthread_exit(NULL);
}
}
}
/* Teardown */
ssh_buffer_free(buffer);
SSH_BUFFER_FREE(buffer);
pthread_exit(NULL);
}
@@ -198,7 +198,7 @@ static void *thread_buffer_prepend(void *threadid)
assert_memory_equal(ssh_buffer_get(buffer), "12345bcdef", 10);
/* Teardown */
ssh_buffer_free(buffer);
SSH_BUFFER_FREE(buffer);
pthread_exit(NULL);
}
@@ -247,9 +247,9 @@ static void *thread_ssh_buffer_get_ssh_string(void *threadid)
for (l = 0; l < k; ++l) {
ssh_string str = ssh_buffer_get_ssh_string(buffer);
assert_null(str);
ssh_string_free(str);
SSH_STRING_FREE(str);
}
ssh_buffer_free(buffer);
SSH_BUFFER_FREE(buffer);
}
}
}
@@ -316,10 +316,10 @@ static void *thread_ssh_buffer_add_format(void *threadid)
assert_int_equal(len, sizeof(verif) - 1);
assert_memory_equal(ssh_buffer_get(buffer), verif, sizeof(verif) -1);
ssh_string_free(s);
SSH_STRING_FREE(s);
/* Teardown */
ssh_buffer_free(buffer);
SSH_BUFFER_FREE(buffer);
pthread_exit(NULL);
}
@@ -397,7 +397,7 @@ static void *thread_ssh_buffer_get_format(void *threadid) {
SAFE_FREE(s2);
/* Teardown */
ssh_buffer_free(buffer);
SSH_BUFFER_FREE(buffer);
pthread_exit(NULL);
}
@@ -458,7 +458,7 @@ static void *thread_ssh_buffer_get_format_error(void *threadid)
assert_true(s2 == NULL);
/* Teardown */
ssh_buffer_free(buffer);
SSH_BUFFER_FREE(buffer);
pthread_exit(NULL);
}
@@ -514,7 +514,7 @@ static void *thread_buffer_pack_badformat(void *threadid)
* it could crash the process */
/* Teardown */
ssh_buffer_free(buffer);
SSH_BUFFER_FREE(buffer);
pthread_exit(NULL);
}

View File

@@ -143,7 +143,7 @@ static void *thread_pki_rsa_import_pubkey_file(void *threadid)
assert_return_code(rc, errno);
assert_non_null(pubkey);
ssh_key_free(pubkey);
SSH_KEY_FREE(pubkey);
pthread_exit(NULL);
}
@@ -201,7 +201,7 @@ static void *thread_pki_rsa_import_privkey_base64_NULL_str(void *threadid)
rc = ssh_pki_import_privkey_base64(NULL, passphrase, NULL, NULL, &key);
assert_true(rc == -1);
ssh_key_free(key);
SSH_KEY_FREE(key);
pthread_exit(NULL);
}
@@ -242,7 +242,7 @@ static void *thread_pki_rsa_import_privkey_base64(void *threadid)
assert_true(ok);
free(key_str);
ssh_key_free(key);
SSH_KEY_FREE(key);
pthread_exit(NULL);
}
@@ -283,8 +283,8 @@ static void *thread_pki_rsa_publickey_from_privatekey(void *threadid)
assert_true(rc == SSH_OK);
assert_non_null(pubkey);
ssh_key_free(key);
ssh_key_free(pubkey);
SSH_KEY_FREE(key);
SSH_KEY_FREE(pubkey);
pthread_exit(NULL);
}
@@ -349,9 +349,9 @@ static void *thread_pki_rsa_copy_cert_to_privkey(void *threadid)
rc = ssh_pki_copy_cert_to_privkey(cert, privkey);
assert_true(rc == SSH_ERROR);
ssh_key_free(cert);
ssh_key_free(privkey);
ssh_key_free(pubkey);
SSH_KEY_FREE(cert);
SSH_KEY_FREE(privkey);
SSH_KEY_FREE(pubkey);
pthread_exit(NULL);
}
@@ -383,7 +383,7 @@ static void *thread_pki_rsa_import_cert_file(void *threadid)
rc = ssh_key_is_public(cert);
assert_true(rc == 1);
ssh_key_free(cert);
SSH_KEY_FREE(cert);
pthread_exit(NULL);
}
@@ -432,7 +432,7 @@ static void *thread_pki_rsa_publickey_base64(void *threadid)
free(b64_key);
free(key_buf);
ssh_key_free(key);
SSH_KEY_FREE(key);
pthread_exit(NULL);
}
@@ -464,7 +464,7 @@ static void *thread_pki_rsa_duplicate_key(void *threadid)
rc = ssh_pki_export_pubkey_base64(pubkey, &b64_key);
assert_true(rc == 0);
ssh_key_free(pubkey);
SSH_KEY_FREE(pubkey);
rc = ssh_pki_import_privkey_file(LIBSSH_RSA_TESTKEY,
NULL,
@@ -489,11 +489,11 @@ static void *thread_pki_rsa_duplicate_key(void *threadid)
cmp = ssh_key_cmp(privkey, privkey_dup, SSH_KEY_CMP_PRIVATE);
assert_true(cmp == 0);
ssh_key_free(pubkey);
ssh_key_free(privkey);
ssh_key_free(privkey_dup);
ssh_string_free_char(b64_key);
ssh_string_free_char(b64_key_gen);
SSH_KEY_FREE(pubkey);
SSH_KEY_FREE(privkey);
SSH_KEY_FREE(privkey_dup);
SSH_STRING_FREE_CHAR(b64_key);
SSH_STRING_FREE_CHAR(b64_key_gen);
pthread_exit(NULL);
}
@@ -531,8 +531,7 @@ static void *thread_pki_rsa_generate_key(void *threadid)
assert_ssh_return_code(session, rc);
ssh_signature_free(sign);
ssh_key_free(key);
key = NULL;
SSH_KEY_FREE(key);
rc = ssh_pki_generate(SSH_KEYTYPE_RSA, 2048, &key);
assert_ssh_return_code(session, rc);
@@ -545,8 +544,7 @@ static void *thread_pki_rsa_generate_key(void *threadid)
assert_ssh_return_code(session, rc);
ssh_signature_free(sign);
ssh_key_free(key);
key = NULL;
SSH_KEY_FREE(key);
rc = ssh_pki_generate(SSH_KEYTYPE_RSA, 4096, &key);
@@ -560,7 +558,7 @@ static void *thread_pki_rsa_generate_key(void *threadid)
assert_true(rc == SSH_OK);
ssh_signature_free(sign);
ssh_key_free(key);
SSH_KEY_FREE(key);
key = NULL;
ssh_free(session);
@@ -596,8 +594,7 @@ static void *thread_pki_rsa_import_privkey_base64_passphrase(void *threadid)
rc = ssh_key_is_private(key);
assert_true(rc == 1);
ssh_key_free(key);
key = NULL;
SSH_KEY_FREE(key);
/* test if it returns -1 if passphrase is wrong */
rc = ssh_pki_import_privkey_base64(torture_get_testkey(SSH_KEYTYPE_RSA, 0, 1),
@@ -606,8 +603,7 @@ static void *thread_pki_rsa_import_privkey_base64_passphrase(void *threadid)
NULL,
&key);
assert_true(rc == -1);
ssh_key_free(key);
key = NULL;
SSH_KEY_FREE(key);
#ifndef HAVE_LIBCRYPTO
/* test if it returns -1 if passphrase is NULL */
@@ -618,8 +614,7 @@ static void *thread_pki_rsa_import_privkey_base64_passphrase(void *threadid)
NULL,
&key);
assert_true(rc == -1);
ssh_key_free(key);
key = NULL;
SSH_KEY_FREE(key);
#endif
pthread_exit(NULL);
}