mirror of
https://git.libssh.org/projects/libssh.git
synced 2026-02-05 04:40:31 +09:00
Compare commits
37 Commits
libssh-0.8
...
libssh-0.8
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
789df0b7d0 | ||
|
|
66a222a73c | ||
|
|
09a7638575 | ||
|
|
203818608a | ||
|
|
f8c452cbef | ||
|
|
adeaa69cc5 | ||
|
|
72bce5ece7 | ||
|
|
7819621fc2 | ||
|
|
fcfba0d8aa | ||
|
|
b166ac4749 | ||
|
|
160a416ef6 | ||
|
|
59071bc4c5 | ||
|
|
2ae63251d3 | ||
|
|
eefae820b5 | ||
|
|
0792fb37b0 | ||
|
|
e23c28a82b | ||
|
|
7291b50420 | ||
|
|
c1d61617fb | ||
|
|
488fb47c32 | ||
|
|
721132696c | ||
|
|
ee034e0484 | ||
|
|
d56c8fdfc6 | ||
|
|
4269b62153 | ||
|
|
c6c63030c5 | ||
|
|
afa5dbb8b1 | ||
|
|
bd7e8295e2 | ||
|
|
933d9c6b07 | ||
|
|
0f0eb05e03 | ||
|
|
171a950a80 | ||
|
|
b1b1da0f97 | ||
|
|
7453038d74 | ||
|
|
29ef92a95e | ||
|
|
6650685758 | ||
|
|
bdca6b7efa | ||
|
|
97b2a61d74 | ||
|
|
781ce47dea | ||
|
|
277ee932d6 |
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -1 +1 @@
|
||||
4.7.0
|
||||
4.7.1
|
||||
415
src/ABI/libssh-4.7.1.symbols
Normal file
415
src/ABI/libssh-4.7.1.symbols
Normal 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
|
||||
56
src/auth.c
56
src/auth.c
@@ -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) {
|
||||
|
||||
@@ -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){
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
127
src/connector.c
127
src/connector.c
@@ -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;
|
||||
}
|
||||
|
||||
2
src/external/chacha.c
vendored
2
src/external/chacha.c
vendored
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
809
src/packet.c
809
src/packet.c
@@ -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 */
|
||||
|
||||
21
src/sftp.c
21
src/sftp.c
@@ -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){
|
||||
|
||||
@@ -232,8 +232,6 @@ sftp_client_message sftp_get_client_message(sftp_session sftp) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sftp_packet_free(packet);
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
|
||||
327
src/socket.c
327
src/socket.c
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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})
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 */
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
|
||||
502
tests/unittests/torture_packet_filter.c
Normal file
502
tests/unittests/torture_packet_filter.c
Normal 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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user