mirror of
https://git.libssh.org/projects/libssh.git
synced 2025-08-05 20:55:46 +03:00
big changes :
Some documentation, and a new logging system. some work must be done to get rid of the infamous ssh_say() git-svn-id: svn+ssh://svn.berlios.de/svnroot/repos/libssh/trunk@166 7dcaeef0-15fb-0310-b436-a5af3365683c
This commit is contained in:
2
Doxyfile
2
Doxyfile
@@ -31,7 +31,7 @@ PROJECT_NAME = libssh
|
|||||||
# This could be handy for archiving the generated documentation or
|
# This could be handy for archiving the generated documentation or
|
||||||
# if some version control system is used.
|
# if some version control system is used.
|
||||||
|
|
||||||
PROJECT_NUMBER = 0.2
|
PROJECT_NUMBER = 0.2-svn
|
||||||
|
|
||||||
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
|
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
|
||||||
# base path where the generated documentation will be put.
|
# base path where the generated documentation will be put.
|
||||||
|
@@ -33,6 +33,7 @@ typedef unsigned long long uint64_t;
|
|||||||
#endif
|
#endif
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
#include <sys/select.h> /* for fd_set * */
|
#include <sys/select.h> /* for fd_set * */
|
||||||
|
#include <netdb.h>
|
||||||
#endif
|
#endif
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
@@ -123,11 +124,15 @@ void ssh_say(int priority,char *format,...);
|
|||||||
void ssh_set_verbosity(int num);
|
void ssh_set_verbosity(int num);
|
||||||
|
|
||||||
/* There is a verbosity level */
|
/* There is a verbosity level */
|
||||||
/* 3 : packet level */
|
|
||||||
/* 2 : protocol level */
|
#define SSH_LOG_NOLOG 0 // no log
|
||||||
/* 1 : functions level */
|
#define SSH_LOG_RARE 1 // rare conditions
|
||||||
/* 0 : important messages only */
|
#define SSH_LOG_ENTRY 2 // user-accessible entrypoints
|
||||||
/* -1 : no messages */
|
#define SSH_LOG_PACKET 3 // packet id and size
|
||||||
|
#define SSH_LOG_FUNCTIONS 4 // every function in and return
|
||||||
|
|
||||||
|
/* log.c */
|
||||||
|
void ssh_log(SSH_SESSION *session, int prioriry, char *format, ...);
|
||||||
|
|
||||||
/* session.c */
|
/* session.c */
|
||||||
SSH_SESSION *ssh_new();
|
SSH_SESSION *ssh_new();
|
||||||
@@ -240,6 +245,9 @@ void ssh_options_allow_ssh1(SSH_OPTIONS *opt, int allow);
|
|||||||
void ssh_options_allow_ssh2(SSH_OPTIONS *opt, int allow);
|
void ssh_options_allow_ssh2(SSH_OPTIONS *opt, int allow);
|
||||||
void ssh_options_set_dsa_server_key(SSH_OPTIONS *opt, char *dsakey);
|
void ssh_options_set_dsa_server_key(SSH_OPTIONS *opt, char *dsakey);
|
||||||
void ssh_options_set_rsa_server_key(SSH_OPTIONS *opt, char *rsakey);
|
void ssh_options_set_rsa_server_key(SSH_OPTIONS *opt, char *rsakey);
|
||||||
|
void ssh_options_set_log_function(SSH_OPTIONS *opt,
|
||||||
|
void (*callback)(const char *message, SSH_SESSION *session, int verbosity ));
|
||||||
|
void ssh_options_set_log_verbosity(SSH_OPTIONS *opt, int verbosity);
|
||||||
|
|
||||||
|
|
||||||
/* buffer.c */
|
/* buffer.c */
|
||||||
|
@@ -237,6 +237,8 @@ struct ssh_options_struct {
|
|||||||
int ssh1allowed;
|
int ssh1allowed;
|
||||||
char *dsakey;
|
char *dsakey;
|
||||||
char *rsakey; /* host key for server implementation */
|
char *rsakey; /* host key for server implementation */
|
||||||
|
int log_verbosity;
|
||||||
|
void (*log_function)(const char *message, SSH_SESSION *session, int verbosity); //log callback
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct ssh_crypto_struct {
|
typedef struct ssh_crypto_struct {
|
||||||
@@ -355,6 +357,8 @@ struct ssh_session {
|
|||||||
int auth_methods;
|
int auth_methods;
|
||||||
int hostkeys; /* contains type of host key wanted by client, in server impl */
|
int hostkeys; /* contains type of host key wanted by client, in server impl */
|
||||||
struct ssh_message *ssh_message; /* ssh message */
|
struct ssh_message *ssh_message; /* ssh message */
|
||||||
|
int log_verbosity; /*cached copy of the option structure */
|
||||||
|
int log_indent; /* indentation level in enter_function logs */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ssh_kbdint {
|
struct ssh_kbdint {
|
||||||
@@ -612,6 +616,27 @@ int channel_write1(CHANNEL *channel, void *data, int len);
|
|||||||
|
|
||||||
int ssh_handle_packets(SSH_SESSION *session);
|
int ssh_handle_packets(SSH_SESSION *session);
|
||||||
|
|
||||||
|
/* log.c */
|
||||||
|
|
||||||
|
#define _enter_function(sess) \
|
||||||
|
do {\
|
||||||
|
if((sess)->log_verbosity >= SSH_LOG_FUNCTIONS){ \
|
||||||
|
ssh_log((sess),SSH_LOG_FUNCTIONS,"entering function %s line %d in " __FILE__ , __FUNCTION__,__LINE__);\
|
||||||
|
(sess)->log_indent++; \
|
||||||
|
} \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
#define _leave_function(sess) \
|
||||||
|
do { \
|
||||||
|
if((sess)->log_verbosity >= SSH_LOG_FUNCTIONS){ \
|
||||||
|
(sess)->log_indent--; \
|
||||||
|
ssh_log((sess),SSH_LOG_FUNCTIONS,"leaving function %s line %d in " __FILE__ , __FUNCTION__,__LINE__);\
|
||||||
|
}\
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
#define enter_function() _enter_function(session)
|
||||||
|
#define leave_function() _leave_function(session)
|
||||||
|
|
||||||
#ifdef HAVE_LIBGCRYPT
|
#ifdef HAVE_LIBGCRYPT
|
||||||
/* gcrypt_missing.c */
|
/* gcrypt_missing.c */
|
||||||
int my_gcry_dec2bn(bignum *bn, const char *data);
|
int my_gcry_dec2bn(bignum *bn, const char *data);
|
||||||
|
@@ -7,7 +7,7 @@ libssh_la_SOURCES = auth1.c auth.c base64.c buffer.c \
|
|||||||
keys.c messages.c misc.c options.c \
|
keys.c messages.c misc.c options.c \
|
||||||
packet.c server.c session.c sftp.c \
|
packet.c server.c session.c sftp.c \
|
||||||
sftpserver.c string.c wrapper.c \
|
sftpserver.c string.c wrapper.c \
|
||||||
socket.c
|
socket.c log.c
|
||||||
|
|
||||||
libssh_la_CPPFLAGS = -I$(top_srcdir)/include
|
libssh_la_CPPFLAGS = -I$(top_srcdir)/include
|
||||||
|
|
||||||
|
171
libssh/auth.c
171
libssh/auth.c
@@ -32,16 +32,16 @@ MA 02111-1307, USA. */
|
|||||||
* @{ */
|
* @{ */
|
||||||
|
|
||||||
static int ask_userauth(SSH_SESSION *session){
|
static int ask_userauth(SSH_SESSION *session){
|
||||||
|
int ret=0;
|
||||||
|
enter_function();
|
||||||
if(session->auth_service_asked)
|
if(session->auth_service_asked)
|
||||||
return 0;
|
ret = 0;
|
||||||
else {
|
else if(ssh_service_request(session,"ssh-userauth"))
|
||||||
if(ssh_service_request(session,"ssh-userauth"))
|
ret = -1;
|
||||||
return -1;
|
else
|
||||||
else
|
session->auth_service_asked++;
|
||||||
session->auth_service_asked++;
|
leave_function();
|
||||||
}
|
return ret;
|
||||||
return 0;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void burn(char *ptr){
|
static void burn(char *ptr){
|
||||||
@@ -55,6 +55,7 @@ static int wait_auth_status(SSH_SESSION *session,int kbdint){
|
|||||||
STRING *can_continue;
|
STRING *can_continue;
|
||||||
u8 partial=0;
|
u8 partial=0;
|
||||||
char *c_cont;
|
char *c_cont;
|
||||||
|
enter_function();
|
||||||
while(cont){
|
while(cont){
|
||||||
if(packet_read(session))
|
if(packet_read(session))
|
||||||
break;
|
break;
|
||||||
@@ -66,6 +67,7 @@ static int wait_auth_status(SSH_SESSION *session,int kbdint){
|
|||||||
if(!can_continue || buffer_get_u8(session->in_buffer,&partial)!=1 ){
|
if(!can_continue || buffer_get_u8(session->in_buffer,&partial)!=1 ){
|
||||||
ssh_set_error(session,SSH_FATAL,
|
ssh_set_error(session,SSH_FATAL,
|
||||||
"invalid SSH_MSG_USERAUTH_FAILURE message");
|
"invalid SSH_MSG_USERAUTH_FAILURE message");
|
||||||
|
leave_function();
|
||||||
return SSH_AUTH_ERROR;
|
return SSH_AUTH_ERROR;
|
||||||
}
|
}
|
||||||
c_cont=string_to_char(can_continue);
|
c_cont=string_to_char(can_continue);
|
||||||
@@ -114,6 +116,7 @@ static int wait_auth_status(SSH_SESSION *session,int kbdint){
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
leave_function();
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,19 +136,27 @@ int ssh_userauth_none(SSH_SESSION *session,char *username){
|
|||||||
STRING *user;
|
STRING *user;
|
||||||
STRING *service;
|
STRING *service;
|
||||||
STRING *method;
|
STRING *method;
|
||||||
|
int ret;
|
||||||
|
enter_function();
|
||||||
#ifdef HAVE_SSH1
|
#ifdef HAVE_SSH1
|
||||||
if(session->version==1)
|
if(session->version==1){
|
||||||
return ssh_userauth1_none(session,username);
|
ret = ssh_userauth1_none(session,username);
|
||||||
|
leave_function();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
if(!username)
|
if(!username)
|
||||||
if(!(username=session->options->username)){
|
if(!(username=session->options->username)){
|
||||||
if(ssh_options_default_username(session->options))
|
if(ssh_options_default_username(session->options)){
|
||||||
return SSH_AUTH_ERROR;
|
leave_function();
|
||||||
else
|
return SSH_AUTH_ERROR;
|
||||||
|
} else
|
||||||
username=session->options->username;
|
username=session->options->username;
|
||||||
}
|
}
|
||||||
if(ask_userauth(session))
|
if(ask_userauth(session)){
|
||||||
return SSH_AUTH_ERROR;
|
leave_function();
|
||||||
|
return SSH_AUTH_ERROR;
|
||||||
|
}
|
||||||
user=string_from_char(username);
|
user=string_from_char(username);
|
||||||
method=string_from_char("none");
|
method=string_from_char("none");
|
||||||
service=string_from_char("ssh-connection");
|
service=string_from_char("ssh-connection");
|
||||||
@@ -158,7 +169,9 @@ int ssh_userauth_none(SSH_SESSION *session,char *username){
|
|||||||
free(method);
|
free(method);
|
||||||
free(user);
|
free(user);
|
||||||
packet_send(session);
|
packet_send(session);
|
||||||
return wait_auth_status(session,0);
|
ret = wait_auth_status(session,0);
|
||||||
|
leave_function();
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \brief Try to authenticate through public key
|
/** \brief Try to authenticate through public key
|
||||||
@@ -182,19 +195,26 @@ int ssh_userauth_offer_pubkey(SSH_SESSION *session, char *username,int type, STR
|
|||||||
STRING *method;
|
STRING *method;
|
||||||
STRING *algo;
|
STRING *algo;
|
||||||
int err=SSH_AUTH_ERROR;
|
int err=SSH_AUTH_ERROR;
|
||||||
|
enter_function();
|
||||||
#ifdef HAVE_SSH1
|
#ifdef HAVE_SSH1
|
||||||
if(session->version==1)
|
if(session->version==1){
|
||||||
return ssh_userauth1_offer_pubkey(session,username,type,publickey);
|
err= ssh_userauth1_offer_pubkey(session,username,type,publickey);
|
||||||
|
leave_function();
|
||||||
|
return err;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
if(!username)
|
if(!username)
|
||||||
if(!(username=session->options->username)){
|
if(!(username=session->options->username)){
|
||||||
if(ssh_options_default_username(session->options))
|
if(ssh_options_default_username(session->options)){
|
||||||
return SSH_AUTH_ERROR;
|
leave_function();
|
||||||
else
|
return SSH_AUTH_ERROR;
|
||||||
|
} else
|
||||||
username=session->options->username;
|
username=session->options->username;
|
||||||
}
|
}
|
||||||
if(ask_userauth(session))
|
if(ask_userauth(session)){
|
||||||
return SSH_AUTH_ERROR;
|
leave_function();
|
||||||
|
return SSH_AUTH_ERROR;
|
||||||
|
}
|
||||||
user=string_from_char(username);
|
user=string_from_char(username);
|
||||||
service=string_from_char("ssh-connection");
|
service=string_from_char("ssh-connection");
|
||||||
method=string_from_char("publickey");
|
method=string_from_char("publickey");
|
||||||
@@ -214,6 +234,7 @@ int ssh_userauth_offer_pubkey(SSH_SESSION *session, char *username,int type, STR
|
|||||||
free(method);
|
free(method);
|
||||||
free(service);
|
free(service);
|
||||||
free(algo);
|
free(algo);
|
||||||
|
leave_function();
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -241,17 +262,21 @@ int ssh_userauth_pubkey(SSH_SESSION *session, char *username, STRING *publickey,
|
|||||||
STRING *algo;
|
STRING *algo;
|
||||||
STRING *sign;
|
STRING *sign;
|
||||||
int err=SSH_AUTH_ERROR;
|
int err=SSH_AUTH_ERROR;
|
||||||
|
enter_function();
|
||||||
// if(session->version==1)
|
// if(session->version==1)
|
||||||
// return ssh_userauth1_pubkey(session,username,publickey,privatekey);
|
// return ssh_userauth1_pubkey(session,username,publickey,privatekey);
|
||||||
if(!username)
|
if(!username)
|
||||||
if(!(username=session->options->username)){
|
if(!(username=session->options->username)){
|
||||||
if(ssh_options_default_username(session->options))
|
if(ssh_options_default_username(session->options)){
|
||||||
return err;
|
leave_function();
|
||||||
else
|
return err;
|
||||||
|
} else
|
||||||
username=session->options->username;
|
username=session->options->username;
|
||||||
}
|
}
|
||||||
if(ask_userauth(session))
|
if(ask_userauth(session)){
|
||||||
return err;
|
leave_function();
|
||||||
|
return err;
|
||||||
|
}
|
||||||
user=string_from_char(username);
|
user=string_from_char(username);
|
||||||
service=string_from_char("ssh-connection");
|
service=string_from_char("ssh-connection");
|
||||||
method=string_from_char("publickey");
|
method=string_from_char("publickey");
|
||||||
@@ -278,6 +303,7 @@ int ssh_userauth_pubkey(SSH_SESSION *session, char *username, STRING *publickey,
|
|||||||
free(service);
|
free(service);
|
||||||
free(method);
|
free(method);
|
||||||
free(algo);
|
free(algo);
|
||||||
|
leave_function();
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -300,19 +326,27 @@ int ssh_userauth_password(SSH_SESSION *session,char *username,char *password){
|
|||||||
STRING *method;
|
STRING *method;
|
||||||
STRING *password_s;
|
STRING *password_s;
|
||||||
int err;
|
int err;
|
||||||
|
enter_function();
|
||||||
#ifdef HAVE_SSH1
|
#ifdef HAVE_SSH1
|
||||||
if(session->version==1)
|
if(session->version==1){
|
||||||
return ssh_userauth1_password(session,username,password);
|
err = ssh_userauth1_password(session,username,password);
|
||||||
|
leave_function();
|
||||||
|
return err;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
if(!username)
|
if(!username)
|
||||||
if(!(username=session->options->username)){
|
if(!(username=session->options->username)){
|
||||||
if(ssh_options_default_username(session->options))
|
if(ssh_options_default_username(session->options)){
|
||||||
return SSH_AUTH_ERROR;
|
err = SSH_AUTH_ERROR;
|
||||||
else
|
leave_function();
|
||||||
|
return err;
|
||||||
|
} else
|
||||||
username=session->options->username;
|
username=session->options->username;
|
||||||
}
|
}
|
||||||
if(ask_userauth(session))
|
if(ask_userauth(session)){
|
||||||
return SSH_AUTH_ERROR;
|
leave_function();
|
||||||
|
return SSH_AUTH_ERROR;
|
||||||
|
}
|
||||||
user=string_from_char(username);
|
user=string_from_char(username);
|
||||||
service=string_from_char("ssh-connection");
|
service=string_from_char("ssh-connection");
|
||||||
method=string_from_char("password");
|
method=string_from_char("password");
|
||||||
@@ -332,6 +366,7 @@ int ssh_userauth_password(SSH_SESSION *session,char *username,char *password){
|
|||||||
free(password_s);
|
free(password_s);
|
||||||
packet_send(session);
|
packet_send(session);
|
||||||
err=wait_auth_status(session,0);
|
err=wait_auth_status(session,0);
|
||||||
|
leave_function();
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -362,9 +397,11 @@ int ssh_userauth_autopubkey(SSH_SESSION *session){
|
|||||||
char *privkeyfile=NULL;
|
char *privkeyfile=NULL;
|
||||||
PRIVATE_KEY *privkey;
|
PRIVATE_KEY *privkey;
|
||||||
char *id=NULL;
|
char *id=NULL;
|
||||||
|
enter_function();
|
||||||
// always testing none
|
// always testing none
|
||||||
err=ssh_userauth_none(session,NULL);
|
err=ssh_userauth_none(session,NULL);
|
||||||
if(err==SSH_AUTH_ERROR || err==SSH_AUTH_SUCCESS){
|
if(err==SSH_AUTH_ERROR || err==SSH_AUTH_SUCCESS){
|
||||||
|
leave_function();
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
if(session->options->identity){
|
if(session->options->identity){
|
||||||
@@ -386,6 +423,7 @@ int ssh_userauth_autopubkey(SSH_SESSION *session){
|
|||||||
}
|
}
|
||||||
free(pubkey);
|
free(pubkey);
|
||||||
free(privkeyfile);
|
free(privkeyfile);
|
||||||
|
leave_function();
|
||||||
return err;
|
return err;
|
||||||
} else
|
} else
|
||||||
if(err != SSH_AUTH_SUCCESS){
|
if(err != SSH_AUTH_SUCCESS){
|
||||||
@@ -416,6 +454,7 @@ int ssh_userauth_autopubkey(SSH_SESSION *session){
|
|||||||
free(pubkey);
|
free(pubkey);
|
||||||
free(privkeyfile);
|
free(privkeyfile);
|
||||||
private_key_free(privkey);
|
private_key_free(privkey);
|
||||||
|
leave_function();
|
||||||
return err;
|
return err;
|
||||||
} else
|
} else
|
||||||
if(err != SSH_AUTH_SUCCESS){
|
if(err != SSH_AUTH_SUCCESS){
|
||||||
@@ -437,6 +476,7 @@ int ssh_userauth_autopubkey(SSH_SESSION *session){
|
|||||||
keys_path[0]=NULL;
|
keys_path[0]=NULL;
|
||||||
free(id);
|
free(id);
|
||||||
}
|
}
|
||||||
|
leave_function();
|
||||||
return SSH_AUTH_SUCCESS;
|
return SSH_AUTH_SUCCESS;
|
||||||
}
|
}
|
||||||
/* at this point, pubkey is NULL and so is privkeyfile */
|
/* at this point, pubkey is NULL and so is privkeyfile */
|
||||||
@@ -447,7 +487,7 @@ int ssh_userauth_autopubkey(SSH_SESSION *session){
|
|||||||
keys_path[0]=NULL;
|
keys_path[0]=NULL;
|
||||||
free(id);
|
free(id);
|
||||||
}
|
}
|
||||||
|
leave_function();
|
||||||
return SSH_AUTH_DENIED;
|
return SSH_AUTH_DENIED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -525,6 +565,8 @@ static int kbdauth_init(SSH_SESSION *session,
|
|||||||
STRING *submethods_s=(submethods ? string_from_char(submethods): string_from_char(""));
|
STRING *submethods_s=(submethods ? string_from_char(submethods): string_from_char(""));
|
||||||
STRING *service=string_from_char("ssh-connection");
|
STRING *service=string_from_char("ssh-connection");
|
||||||
STRING *method=string_from_char("keyboard-interactive");
|
STRING *method=string_from_char("keyboard-interactive");
|
||||||
|
int err;
|
||||||
|
enter_function();
|
||||||
packet_clear_out(session);
|
packet_clear_out(session);
|
||||||
buffer_add_u8(session->out_buffer,SSH2_MSG_USERAUTH_REQUEST);
|
buffer_add_u8(session->out_buffer,SSH2_MSG_USERAUTH_REQUEST);
|
||||||
buffer_add_ssh_string(session->out_buffer,user_s);
|
buffer_add_ssh_string(session->out_buffer,user_s);
|
||||||
@@ -536,9 +578,13 @@ static int kbdauth_init(SSH_SESSION *session,
|
|||||||
free(service);
|
free(service);
|
||||||
free(method);
|
free(method);
|
||||||
free(submethods_s);
|
free(submethods_s);
|
||||||
if(packet_send(session))
|
if(packet_send(session)){
|
||||||
return SSH_AUTH_ERROR;
|
leave_function();
|
||||||
return wait_auth_status(session,1);
|
return SSH_AUTH_ERROR;
|
||||||
|
}
|
||||||
|
err=wait_auth_status(session,1);
|
||||||
|
leave_function();
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int kbdauth_info_get(SSH_SESSION *session){
|
static int kbdauth_info_get(SSH_SESSION *session){
|
||||||
@@ -547,6 +593,7 @@ static int kbdauth_info_get(SSH_SESSION *session){
|
|||||||
STRING *tmp;
|
STRING *tmp;
|
||||||
u32 nprompts;
|
u32 nprompts;
|
||||||
int i;
|
int i;
|
||||||
|
enter_function();
|
||||||
name=buffer_get_ssh_string(session->in_buffer);
|
name=buffer_get_ssh_string(session->in_buffer);
|
||||||
instruction=buffer_get_ssh_string(session->in_buffer);
|
instruction=buffer_get_ssh_string(session->in_buffer);
|
||||||
tmp=buffer_get_ssh_string(session->in_buffer);
|
tmp=buffer_get_ssh_string(session->in_buffer);
|
||||||
@@ -558,6 +605,7 @@ static int kbdauth_info_get(SSH_SESSION *session){
|
|||||||
free(instruction);
|
free(instruction);
|
||||||
// tmp must be empty if we got here
|
// tmp must be empty if we got here
|
||||||
ssh_set_error(session,SSH_FATAL,"Invalid USERAUTH_INFO_REQUEST msg");
|
ssh_set_error(session,SSH_FATAL,"Invalid USERAUTH_INFO_REQUEST msg");
|
||||||
|
leave_function();
|
||||||
return SSH_AUTH_ERROR;
|
return SSH_AUTH_ERROR;
|
||||||
}
|
}
|
||||||
if(tmp)
|
if(tmp)
|
||||||
@@ -573,6 +621,7 @@ static int kbdauth_info_get(SSH_SESSION *session){
|
|||||||
nprompts=ntohl(nprompts);
|
nprompts=ntohl(nprompts);
|
||||||
if(nprompts>KBDINT_MAX_PROMPT){
|
if(nprompts>KBDINT_MAX_PROMPT){
|
||||||
ssh_set_error(session,SSH_FATAL,"Too much prompt asked from server: %lu(0x%.8lx)",nprompts,nprompts);
|
ssh_set_error(session,SSH_FATAL,"Too much prompt asked from server: %lu(0x%.8lx)",nprompts,nprompts);
|
||||||
|
leave_function();
|
||||||
return SSH_AUTH_ERROR;
|
return SSH_AUTH_ERROR;
|
||||||
}
|
}
|
||||||
session->kbdint->nprompts=nprompts;
|
session->kbdint->nprompts=nprompts;
|
||||||
@@ -585,11 +634,13 @@ static int kbdauth_info_get(SSH_SESSION *session){
|
|||||||
buffer_get_u8(session->in_buffer,&session->kbdint->echo[i]);
|
buffer_get_u8(session->in_buffer,&session->kbdint->echo[i]);
|
||||||
if(!tmp){
|
if(!tmp){
|
||||||
ssh_set_error(session,SSH_FATAL,"Short INFO_REQUEST packet");
|
ssh_set_error(session,SSH_FATAL,"Short INFO_REQUEST packet");
|
||||||
|
leave_function();
|
||||||
return SSH_AUTH_ERROR;
|
return SSH_AUTH_ERROR;
|
||||||
}
|
}
|
||||||
session->kbdint->prompts[i]=string_to_char(tmp);
|
session->kbdint->prompts[i]=string_to_char(tmp);
|
||||||
free(tmp);
|
free(tmp);
|
||||||
}
|
}
|
||||||
|
leave_function();
|
||||||
return SSH_AUTH_INFO; /* we are not auth. but we parsed the packet */
|
return SSH_AUTH_INFO; /* we are not auth. but we parsed the packet */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -597,6 +648,8 @@ static int kbdauth_info_get(SSH_SESSION *session){
|
|||||||
static int kbdauth_send(SSH_SESSION *session) {
|
static int kbdauth_send(SSH_SESSION *session) {
|
||||||
STRING *answer;
|
STRING *answer;
|
||||||
int i;
|
int i;
|
||||||
|
int err;
|
||||||
|
enter_function();
|
||||||
packet_clear_out(session);
|
packet_clear_out(session);
|
||||||
buffer_add_u8(session->out_buffer,SSH2_MSG_USERAUTH_INFO_RESPONSE);
|
buffer_add_u8(session->out_buffer,SSH2_MSG_USERAUTH_INFO_RESPONSE);
|
||||||
buffer_add_u32(session->out_buffer,htonl(session->kbdint->nprompts));
|
buffer_add_u32(session->out_buffer,htonl(session->kbdint->nprompts));
|
||||||
@@ -609,9 +662,13 @@ static int kbdauth_send(SSH_SESSION *session) {
|
|||||||
string_burn(answer);
|
string_burn(answer);
|
||||||
free(answer);
|
free(answer);
|
||||||
}
|
}
|
||||||
if(packet_send(session))
|
if(packet_send(session)){
|
||||||
return SSH_AUTH_ERROR;
|
leave_function();
|
||||||
return wait_auth_status(session,1);
|
return SSH_AUTH_ERROR;
|
||||||
|
}
|
||||||
|
err = wait_auth_status(session,1);
|
||||||
|
leave_function();
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \brief Try to authenticate through the "keyboard-interactive" method
|
/** \brief Try to authenticate through the "keyboard-interactive" method
|
||||||
@@ -637,25 +694,32 @@ int ssh_userauth_kbdint(SSH_SESSION *session,char *user,char *submethods){
|
|||||||
int err;
|
int err;
|
||||||
if(session->version==1)
|
if(session->version==1)
|
||||||
return SSH_AUTH_DENIED; // no keyb-interactive for ssh1
|
return SSH_AUTH_DENIED; // no keyb-interactive for ssh1
|
||||||
|
enter_function();
|
||||||
if( !session->kbdint){
|
if( !session->kbdint){
|
||||||
/* first time we call. we must ask for a challenge */
|
/* first time we call. we must ask for a challenge */
|
||||||
if(!user)
|
if(!user)
|
||||||
if(!(user=session->options->username)){
|
if(!(user=session->options->username)){
|
||||||
if(ssh_options_default_username(session->options))
|
if(ssh_options_default_username(session->options)){
|
||||||
return SSH_AUTH_ERROR;
|
leave_function();
|
||||||
else
|
return SSH_AUTH_ERROR;
|
||||||
|
} else
|
||||||
user=session->options->username;
|
user=session->options->username;
|
||||||
}
|
}
|
||||||
if(ask_userauth(session))
|
if(ask_userauth(session)){
|
||||||
return SSH_AUTH_ERROR;
|
leave_function();
|
||||||
|
return SSH_AUTH_ERROR;
|
||||||
|
}
|
||||||
err=kbdauth_init(session,user,submethods);
|
err=kbdauth_init(session,user,submethods);
|
||||||
if(err!=SSH_AUTH_INFO)
|
if(err!=SSH_AUTH_INFO){
|
||||||
return err; /* error or first try success */
|
leave_function();
|
||||||
|
return err; /* error or first try success */
|
||||||
|
}
|
||||||
err=kbdauth_info_get(session);
|
err=kbdauth_info_get(session);
|
||||||
if(err==SSH_AUTH_ERROR){
|
if(err==SSH_AUTH_ERROR){
|
||||||
kbdint_free(session->kbdint);
|
kbdint_free(session->kbdint);
|
||||||
session->kbdint=NULL;
|
session->kbdint=NULL;
|
||||||
}
|
}
|
||||||
|
leave_function();
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
/* if we are at this point, it's because session->kbdint exists */
|
/* if we are at this point, it's because session->kbdint exists */
|
||||||
@@ -665,13 +729,16 @@ int ssh_userauth_kbdint(SSH_SESSION *session,char *user,char *submethods){
|
|||||||
err=kbdauth_send(session);
|
err=kbdauth_send(session);
|
||||||
kbdint_free(session->kbdint);
|
kbdint_free(session->kbdint);
|
||||||
session->kbdint=NULL;
|
session->kbdint=NULL;
|
||||||
if(err!=SSH_AUTH_INFO)
|
if(err!=SSH_AUTH_INFO){
|
||||||
return err;
|
leave_function();
|
||||||
|
return err;
|
||||||
|
}
|
||||||
err=kbdauth_info_get(session);
|
err=kbdauth_info_get(session);
|
||||||
if(err==SSH_AUTH_ERROR){
|
if(err==SSH_AUTH_ERROR){
|
||||||
kbdint_free(session->kbdint);
|
kbdint_free(session->kbdint);
|
||||||
session->kbdint=NULL;
|
session->kbdint=NULL;
|
||||||
}
|
}
|
||||||
|
leave_function();
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -71,6 +71,7 @@ static int channel_open(CHANNEL *channel,char *type_c,int window,
|
|||||||
STRING *type=string_from_char(type_c);
|
STRING *type=string_from_char(type_c);
|
||||||
u32 foo;
|
u32 foo;
|
||||||
int err;
|
int err;
|
||||||
|
enter_function();
|
||||||
packet_clear_out(session);
|
packet_clear_out(session);
|
||||||
buffer_add_u8(session->out_buffer,SSH2_MSG_CHANNEL_OPEN);
|
buffer_add_u8(session->out_buffer,SSH2_MSG_CHANNEL_OPEN);
|
||||||
channel->local_channel=ssh_channel_new_id(session);
|
channel->local_channel=ssh_channel_new_id(session);
|
||||||
@@ -94,6 +95,7 @@ static int channel_open(CHANNEL *channel,char *type_c,int window,
|
|||||||
if(channel->local_channel!=ntohl(foo)){
|
if(channel->local_channel!=ntohl(foo)){
|
||||||
ssh_set_error(session,SSH_FATAL,"server answered with sender chan num %d instead of given %d",
|
ssh_set_error(session,SSH_FATAL,"server answered with sender chan num %d instead of given %d",
|
||||||
ntohl(foo),channel->local_channel);
|
ntohl(foo),channel->local_channel);
|
||||||
|
leave_function();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
buffer_get_u32(session->in_buffer,&foo);
|
buffer_get_u32(session->in_buffer,&foo);
|
||||||
@@ -107,6 +109,7 @@ static int channel_open(CHANNEL *channel,char *type_c,int window,
|
|||||||
ssh_say(3,"Remote window : %ld, maxpacket : %ld\n",
|
ssh_say(3,"Remote window : %ld, maxpacket : %ld\n",
|
||||||
channel->remote_window, channel->remote_maxpacket);
|
channel->remote_window, channel->remote_maxpacket);
|
||||||
channel->open=1;
|
channel->open=1;
|
||||||
|
leave_function();
|
||||||
return 0;
|
return 0;
|
||||||
case SSH2_MSG_CHANNEL_OPEN_FAILURE:
|
case SSH2_MSG_CHANNEL_OPEN_FAILURE:
|
||||||
{
|
{
|
||||||
@@ -121,12 +124,15 @@ static int channel_open(CHANNEL *channel,char *type_c,int window,
|
|||||||
channel->local_channel,ntohl(code),error);
|
channel->local_channel,ntohl(code),error);
|
||||||
free(error);
|
free(error);
|
||||||
free(error_s);
|
free(error_s);
|
||||||
|
leave_function();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
ssh_set_error(session,SSH_FATAL,"Received unknown packet %d\n",session->in_packet.type);
|
ssh_set_error(session,SSH_FATAL,"Received unknown packet %d\n",session->in_packet.type);
|
||||||
|
leave_function();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
leave_function();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,6 +151,7 @@ CHANNEL *ssh_channel_from_local(SSH_SESSION *session,u32 num){
|
|||||||
|
|
||||||
static void grow_window(SSH_SESSION *session, CHANNEL *channel){
|
static void grow_window(SSH_SESSION *session, CHANNEL *channel){
|
||||||
u32 new_window=WINDOWBASE;
|
u32 new_window=WINDOWBASE;
|
||||||
|
enter_function();
|
||||||
packet_clear_out(session);
|
packet_clear_out(session);
|
||||||
buffer_add_u8(session->out_buffer,SSH2_MSG_CHANNEL_WINDOW_ADJUST);
|
buffer_add_u8(session->out_buffer,SSH2_MSG_CHANNEL_WINDOW_ADJUST);
|
||||||
buffer_add_u32(session->out_buffer,htonl(channel->remote_channel));
|
buffer_add_u32(session->out_buffer,htonl(channel->remote_channel));
|
||||||
@@ -154,6 +161,7 @@ static void grow_window(SSH_SESSION *session, CHANNEL *channel){
|
|||||||
channel->local_channel,channel->remote_channel,
|
channel->local_channel,channel->remote_channel,
|
||||||
channel->local_window + new_window);
|
channel->local_window + new_window);
|
||||||
channel->local_window+=new_window;
|
channel->local_window+=new_window;
|
||||||
|
leave_function();
|
||||||
}
|
}
|
||||||
|
|
||||||
static CHANNEL *channel_from_msg(SSH_SESSION *session){
|
static CHANNEL *channel_from_msg(SSH_SESSION *session){
|
||||||
@@ -173,27 +181,32 @@ static void channel_rcv_change_window(SSH_SESSION *session){
|
|||||||
u32 bytes;
|
u32 bytes;
|
||||||
CHANNEL *channel;
|
CHANNEL *channel;
|
||||||
int err;
|
int err;
|
||||||
|
enter_function();
|
||||||
channel=channel_from_msg(session);
|
channel=channel_from_msg(session);
|
||||||
if(!channel)
|
if(!channel)
|
||||||
ssh_say(0,"%s\n",ssh_get_error(session));
|
ssh_say(0,"%s\n",ssh_get_error(session));
|
||||||
err = buffer_get_u32(session->in_buffer,&bytes);
|
err = buffer_get_u32(session->in_buffer,&bytes);
|
||||||
if(!channel || err!= sizeof(u32)){
|
if(!channel || err!= sizeof(u32)){
|
||||||
ssh_say(1,"Error getting a window adjust message : invalid packet\n");
|
ssh_say(1,"Error getting a window adjust message : invalid packet\n");
|
||||||
|
leave_function();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
bytes=ntohl(bytes);
|
bytes=ntohl(bytes);
|
||||||
ssh_say(3,"Adding %d bytes to channel (%d:%d) (from %d bytes)\n",bytes,
|
ssh_say(3,"Adding %d bytes to channel (%d:%d) (from %d bytes)\n",bytes,
|
||||||
channel->local_channel,channel->remote_channel,channel->remote_window);
|
channel->local_channel,channel->remote_channel,channel->remote_window);
|
||||||
channel->remote_window+=bytes;
|
channel->remote_window+=bytes;
|
||||||
|
leave_function();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* is_stderr is set to 1 if the data are extended, ie stderr */
|
/* is_stderr is set to 1 if the data are extended, ie stderr */
|
||||||
static void channel_rcv_data(SSH_SESSION *session,int is_stderr){
|
static void channel_rcv_data(SSH_SESSION *session,int is_stderr){
|
||||||
STRING *str;
|
STRING *str;
|
||||||
CHANNEL *channel;
|
CHANNEL *channel;
|
||||||
|
enter_function();
|
||||||
channel=channel_from_msg(session);
|
channel=channel_from_msg(session);
|
||||||
if(!channel){
|
if(!channel){
|
||||||
ssh_say(0,"%s",ssh_get_error(session));
|
ssh_say(0,"%s",ssh_get_error(session));
|
||||||
|
leave_function();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(is_stderr){
|
if(is_stderr){
|
||||||
@@ -205,6 +218,7 @@ static void channel_rcv_data(SSH_SESSION *session,int is_stderr){
|
|||||||
|
|
||||||
if(!str){
|
if(!str){
|
||||||
ssh_say(0,"Invalid data packet !\n");
|
ssh_say(0,"Invalid data packet !\n");
|
||||||
|
leave_function();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ssh_say(3,"adding %d bytes data in %d\n",string_len(str),is_stderr);
|
ssh_say(3,"adding %d bytes data in %d\n",string_len(str),is_stderr);
|
||||||
@@ -219,26 +233,32 @@ static void channel_rcv_data(SSH_SESSION *session,int is_stderr){
|
|||||||
if(channel->local_window < WINDOWLIMIT)
|
if(channel->local_window < WINDOWLIMIT)
|
||||||
grow_window(session,channel); /* i wonder if this is the correct place to do that */
|
grow_window(session,channel); /* i wonder if this is the correct place to do that */
|
||||||
free(str);
|
free(str);
|
||||||
|
leave_function();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void channel_rcv_eof(SSH_SESSION *session){
|
static void channel_rcv_eof(SSH_SESSION *session){
|
||||||
CHANNEL *channel;
|
CHANNEL *channel;
|
||||||
|
enter_function();
|
||||||
channel=channel_from_msg(session);
|
channel=channel_from_msg(session);
|
||||||
if(!channel){
|
if(!channel){
|
||||||
ssh_say(0,"%s\n",ssh_get_error(session));
|
ssh_say(0,"%s\n",ssh_get_error(session));
|
||||||
|
leave_function();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ssh_say(2,"Received eof on channel (%d:%d)\n",channel->local_channel,
|
ssh_say(2,"Received eof on channel (%d:%d)\n",channel->local_channel,
|
||||||
channel->remote_channel);
|
channel->remote_channel);
|
||||||
// channel->remote_window=0;
|
// channel->remote_window=0;
|
||||||
channel->remote_eof=1;
|
channel->remote_eof=1;
|
||||||
|
leave_function();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void channel_rcv_close(SSH_SESSION *session){
|
static void channel_rcv_close(SSH_SESSION *session){
|
||||||
CHANNEL *channel;
|
CHANNEL *channel;
|
||||||
|
enter_function();
|
||||||
channel=channel_from_msg(session);
|
channel=channel_from_msg(session);
|
||||||
if(!channel){
|
if(!channel){
|
||||||
ssh_say(0,"%s\n",ssh_get_error(session));
|
ssh_say(0,"%s\n",ssh_get_error(session));
|
||||||
|
leave_function();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ssh_say(2,"Received close on channel (%d:%d)\n",channel->local_channel,
|
ssh_say(2,"Received close on channel (%d:%d)\n",channel->local_channel,
|
||||||
@@ -253,6 +273,7 @@ static void channel_rcv_close(SSH_SESSION *session){
|
|||||||
channel->remote_eof=1;
|
channel->remote_eof=1;
|
||||||
/* the remote eof doesn't break things if there was still data into read
|
/* the remote eof doesn't break things if there was still data into read
|
||||||
* buffer because the eof is ignored until the buffer is empty. */
|
* buffer because the eof is ignored until the buffer is empty. */
|
||||||
|
leave_function();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void channel_rcv_request(SSH_SESSION *session){
|
static void channel_rcv_request(SSH_SESSION *session){
|
||||||
@@ -260,13 +281,16 @@ static void channel_rcv_request(SSH_SESSION *session){
|
|||||||
char *request;
|
char *request;
|
||||||
u32 status;
|
u32 status;
|
||||||
CHANNEL *channel=channel_from_msg(session);
|
CHANNEL *channel=channel_from_msg(session);
|
||||||
|
enter_function();
|
||||||
if(!channel){
|
if(!channel){
|
||||||
ssh_say(1,"%s\n",ssh_get_error(session));
|
ssh_say(1,"%s\n",ssh_get_error(session));
|
||||||
|
leave_function();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
request_s=buffer_get_ssh_string(session->in_buffer);
|
request_s=buffer_get_ssh_string(session->in_buffer);
|
||||||
if(!request_s){
|
if(!request_s){
|
||||||
ssh_say(0,"Invalid MSG_CHANNEL_REQUEST\n");
|
ssh_say(0,"Invalid MSG_CHANNEL_REQUEST\n");
|
||||||
|
leave_function();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
buffer_get_u8(session->in_buffer,(u8 *)&status);
|
buffer_get_u8(session->in_buffer,(u8 *)&status);
|
||||||
@@ -274,9 +298,10 @@ static void channel_rcv_request(SSH_SESSION *session){
|
|||||||
if(!strcmp(request,"exit-status")){
|
if(!strcmp(request,"exit-status")){
|
||||||
buffer_get_u32(session->in_buffer,&status);
|
buffer_get_u32(session->in_buffer,&status);
|
||||||
status=ntohl(status);
|
status=ntohl(status);
|
||||||
/* XXX do something with status, we might need it */
|
/* TODO do something with status, we might need it */
|
||||||
free(request_s);
|
free(request_s);
|
||||||
free(request);
|
free(request);
|
||||||
|
leave_function();
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
if(!strcmp(request,"exit-signal")){
|
if(!strcmp(request,"exit-signal")){
|
||||||
@@ -289,6 +314,7 @@ static void channel_rcv_request(SSH_SESSION *session){
|
|||||||
ssh_say(0,"Invalid MSG_CHANNEL_REQUEST\n");
|
ssh_say(0,"Invalid MSG_CHANNEL_REQUEST\n");
|
||||||
free(request_s);
|
free(request_s);
|
||||||
free(request);
|
free(request);
|
||||||
|
leave_function();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
signal=string_to_char(signal_s);
|
signal=string_to_char(signal_s);
|
||||||
@@ -300,15 +326,18 @@ static void channel_rcv_request(SSH_SESSION *session){
|
|||||||
free(signal);
|
free(signal);
|
||||||
free(request_s);
|
free(request_s);
|
||||||
free(request);
|
free(request);
|
||||||
|
leave_function();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ssh_say(0,"Unknown request %s\n",request);
|
ssh_say(0,"Unknown request %s\n",request);
|
||||||
free(request_s);
|
free(request_s);
|
||||||
free(request);
|
free(request);
|
||||||
|
leave_function();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* channel_handle is called by wait_packet, ie, when there is channel informations to handle . */
|
/* channel_handle is called by wait_packet, ie, when there is channel informations to handle . */
|
||||||
void channel_handle(SSH_SESSION *session, int type){
|
void channel_handle(SSH_SESSION *session, int type){
|
||||||
|
enter_function();
|
||||||
ssh_say(3,"Channel_handle(%d)\n",type);
|
ssh_say(3,"Channel_handle(%d)\n",type);
|
||||||
switch(type){
|
switch(type){
|
||||||
case SSH2_MSG_CHANNEL_WINDOW_ADJUST:
|
case SSH2_MSG_CHANNEL_WINDOW_ADJUST:
|
||||||
@@ -332,6 +361,7 @@ void channel_handle(SSH_SESSION *session, int type){
|
|||||||
default:
|
default:
|
||||||
ssh_say(0,"Unexpected message %d\n",type);
|
ssh_say(0,"Unexpected message %d\n",type);
|
||||||
}
|
}
|
||||||
|
leave_function();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* when data has been received from the ssh server, it can be applied to the known
|
/* when data has been received from the ssh server, it can be applied to the known
|
||||||
@@ -386,7 +416,9 @@ int channel_open_session(CHANNEL *channel){
|
|||||||
int channel_open_forward(CHANNEL *channel,char *remotehost, int remoteport, char *sourcehost, int localport){
|
int channel_open_forward(CHANNEL *channel,char *remotehost, int remoteport, char *sourcehost, int localport){
|
||||||
BUFFER *payload=buffer_new();
|
BUFFER *payload=buffer_new();
|
||||||
STRING *str=string_from_char(remotehost);
|
STRING *str=string_from_char(remotehost);
|
||||||
|
SSH_SESSION *session=channel->session;
|
||||||
int ret;
|
int ret;
|
||||||
|
enter_function();
|
||||||
buffer_add_ssh_string(payload,str);
|
buffer_add_ssh_string(payload,str);
|
||||||
free(str);
|
free(str);
|
||||||
str=string_from_char(sourcehost);
|
str=string_from_char(sourcehost);
|
||||||
@@ -396,6 +428,7 @@ int channel_open_forward(CHANNEL *channel,char *remotehost, int remoteport, char
|
|||||||
buffer_add_u32(payload,htonl(localport));
|
buffer_add_u32(payload,htonl(localport));
|
||||||
ret=channel_open(channel,"direct-tcpip",64000,32000,payload);
|
ret=channel_open(channel,"direct-tcpip",64000,32000,payload);
|
||||||
buffer_free(payload);
|
buffer_free(payload);
|
||||||
|
leave_function();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -405,6 +438,7 @@ int channel_open_forward(CHANNEL *channel,char *remotehost, int remoteport, char
|
|||||||
*/
|
*/
|
||||||
void channel_free(CHANNEL *channel){
|
void channel_free(CHANNEL *channel){
|
||||||
SSH_SESSION *session=channel->session;
|
SSH_SESSION *session=channel->session;
|
||||||
|
enter_function();
|
||||||
if(session->alive && channel->open)
|
if(session->alive && channel->open)
|
||||||
channel_close(channel);
|
channel_close(channel);
|
||||||
/* handle the "my channel is first on session list" case */
|
/* handle the "my channel is first on session list" case */
|
||||||
@@ -424,6 +458,7 @@ void channel_free(CHANNEL *channel){
|
|||||||
/* debug trick to catch use after frees */
|
/* debug trick to catch use after frees */
|
||||||
memset(channel,'X',sizeof(CHANNEL));
|
memset(channel,'X',sizeof(CHANNEL));
|
||||||
free(channel);
|
free(channel);
|
||||||
|
leave_function();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** it doesn't close the channel. You may still read from it but not write.
|
/** it doesn't close the channel. You may still read from it but not write.
|
||||||
@@ -437,6 +472,7 @@ void channel_free(CHANNEL *channel){
|
|||||||
int channel_send_eof(CHANNEL *channel){
|
int channel_send_eof(CHANNEL *channel){
|
||||||
SSH_SESSION *session=channel->session;
|
SSH_SESSION *session=channel->session;
|
||||||
int ret;
|
int ret;
|
||||||
|
enter_function();
|
||||||
packet_clear_out(session);
|
packet_clear_out(session);
|
||||||
buffer_add_u8(session->out_buffer,SSH2_MSG_CHANNEL_EOF);
|
buffer_add_u8(session->out_buffer,SSH2_MSG_CHANNEL_EOF);
|
||||||
buffer_add_u32(session->out_buffer,htonl(channel->remote_channel));
|
buffer_add_u32(session->out_buffer,htonl(channel->remote_channel));
|
||||||
@@ -444,6 +480,7 @@ int channel_send_eof(CHANNEL *channel){
|
|||||||
ssh_say(1,"Sent a EOF on client channel (%d:%d)\n",channel->local_channel,
|
ssh_say(1,"Sent a EOF on client channel (%d:%d)\n",channel->local_channel,
|
||||||
channel->remote_channel);
|
channel->remote_channel);
|
||||||
channel->local_eof=1;
|
channel->local_eof=1;
|
||||||
|
leave_function();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -459,10 +496,13 @@ int channel_send_eof(CHANNEL *channel){
|
|||||||
int channel_close(CHANNEL *channel){
|
int channel_close(CHANNEL *channel){
|
||||||
SSH_SESSION *session=channel->session;
|
SSH_SESSION *session=channel->session;
|
||||||
int ret=0;
|
int ret=0;
|
||||||
|
enter_function();
|
||||||
if(!channel->local_eof)
|
if(!channel->local_eof)
|
||||||
ret=channel_send_eof(channel);
|
ret=channel_send_eof(channel);
|
||||||
if(ret)
|
if(ret){
|
||||||
return ret;
|
leave_function();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
packet_clear_out(session);
|
packet_clear_out(session);
|
||||||
buffer_add_u8(session->out_buffer,SSH2_MSG_CHANNEL_CLOSE);
|
buffer_add_u8(session->out_buffer,SSH2_MSG_CHANNEL_CLOSE);
|
||||||
buffer_add_u32(session->out_buffer,htonl(channel->remote_channel));
|
buffer_add_u32(session->out_buffer,htonl(channel->remote_channel));
|
||||||
@@ -471,6 +511,7 @@ int channel_close(CHANNEL *channel){
|
|||||||
channel->remote_channel);
|
channel->remote_channel);
|
||||||
if(!ret)
|
if(!ret)
|
||||||
channel->open =0;
|
channel->open =0;
|
||||||
|
leave_function();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -486,18 +527,23 @@ int channel_write(CHANNEL *channel ,void *data,int len){
|
|||||||
SSH_SESSION *session=channel->session;
|
SSH_SESSION *session=channel->session;
|
||||||
int effectivelen;
|
int effectivelen;
|
||||||
int origlen=len;
|
int origlen=len;
|
||||||
|
enter_function();
|
||||||
if(channel->local_eof){
|
if(channel->local_eof){
|
||||||
ssh_set_error(session,SSH_REQUEST_DENIED,"Can't write to channel %d:%d"
|
ssh_set_error(session,SSH_REQUEST_DENIED,"Can't write to channel %d:%d"
|
||||||
" after EOF was sent",channel->local_channel,channel->remote_channel);
|
" after EOF was sent",channel->local_channel,channel->remote_channel);
|
||||||
|
leave_function();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if(!channel->open || channel->delayed_close){
|
if(!channel->open || channel->delayed_close){
|
||||||
ssh_set_error(session,SSH_REQUEST_DENIED,"Remote channel is closed");
|
ssh_set_error(session,SSH_REQUEST_DENIED,"Remote channel is closed");
|
||||||
|
leave_function();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
#ifdef HAVE_SSH1
|
#ifdef HAVE_SSH1
|
||||||
if(channel->version==1)
|
if(channel->version==1){
|
||||||
return channel_write1(channel,data,len);
|
err = channel_write1(channel,data,len);
|
||||||
|
leave_function();
|
||||||
|
return err;
|
||||||
#endif
|
#endif
|
||||||
while(len >0){
|
while(len >0){
|
||||||
if(channel->remote_window<len){
|
if(channel->remote_window<len){
|
||||||
@@ -523,6 +569,7 @@ int channel_write(CHANNEL *channel ,void *data,int len){
|
|||||||
len -= effectivelen;
|
len -= effectivelen;
|
||||||
data+=effectivelen;
|
data+=effectivelen;
|
||||||
}
|
}
|
||||||
|
leave_function();
|
||||||
return origlen;
|
return origlen;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -571,6 +618,7 @@ static int channel_request(CHANNEL *channel,char *request, BUFFER *buffer,int re
|
|||||||
STRING *request_s=string_from_char(request);
|
STRING *request_s=string_from_char(request);
|
||||||
SSH_SESSION *session=channel->session;
|
SSH_SESSION *session=channel->session;
|
||||||
int err;
|
int err;
|
||||||
|
enter_function();
|
||||||
packet_clear_out(session);
|
packet_clear_out(session);
|
||||||
buffer_add_u8(session->out_buffer,SSH2_MSG_CHANNEL_REQUEST);
|
buffer_add_u8(session->out_buffer,SSH2_MSG_CHANNEL_REQUEST);
|
||||||
buffer_add_u32(session->out_buffer,htonl(channel->remote_channel));
|
buffer_add_u32(session->out_buffer,htonl(channel->remote_channel));
|
||||||
@@ -581,8 +629,10 @@ static int channel_request(CHANNEL *channel,char *request, BUFFER *buffer,int re
|
|||||||
packet_send(session);
|
packet_send(session);
|
||||||
ssh_say(3,"Sent a SSH_MSG_CHANNEL_REQUEST %s\n",request);
|
ssh_say(3,"Sent a SSH_MSG_CHANNEL_REQUEST %s\n",request);
|
||||||
free(request_s);
|
free(request_s);
|
||||||
if(!reply)
|
if(!reply){
|
||||||
return 0;
|
leave_function();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
err=packet_wait(session,SSH2_MSG_CHANNEL_SUCCESS,1);
|
err=packet_wait(session,SSH2_MSG_CHANNEL_SUCCESS,1);
|
||||||
if(err)
|
if(err)
|
||||||
if(session->in_packet.type==SSH2_MSG_CHANNEL_FAILURE){
|
if(session->in_packet.type==SSH2_MSG_CHANNEL_FAILURE){
|
||||||
@@ -593,6 +643,7 @@ static int channel_request(CHANNEL *channel,char *request, BUFFER *buffer,int re
|
|||||||
ssh_say(3,"Received an unexpected %d message\n",session->in_packet.type);
|
ssh_say(3,"Received an unexpected %d message\n",session->in_packet.type);
|
||||||
else
|
else
|
||||||
ssh_say(3,"Received a SUCCESS\n");
|
ssh_say(3,"Received a SUCCESS\n");
|
||||||
|
leave_function();
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -607,10 +658,15 @@ static int channel_request(CHANNEL *channel,char *request, BUFFER *buffer,int re
|
|||||||
int channel_request_pty_size(CHANNEL *channel, char *terminal, int col, int row){
|
int channel_request_pty_size(CHANNEL *channel, char *terminal, int col, int row){
|
||||||
STRING *term;
|
STRING *term;
|
||||||
BUFFER *buffer;
|
BUFFER *buffer;
|
||||||
|
SSH_SESSION *session=channel->session;
|
||||||
int err;
|
int err;
|
||||||
|
enter_function();
|
||||||
#ifdef HAVE_SSH1
|
#ifdef HAVE_SSH1
|
||||||
if(channel->version==1)
|
if(channel->version==1){
|
||||||
return channel_request_pty_size1(channel,terminal, col, row);
|
err = channel_request_pty_size1(channel,terminal, col, row);
|
||||||
|
leave_function();
|
||||||
|
return err;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
term=string_from_char(terminal);
|
term=string_from_char(terminal);
|
||||||
buffer=buffer_new();
|
buffer=buffer_new();
|
||||||
@@ -625,6 +681,7 @@ int channel_request_pty_size(CHANNEL *channel, char *terminal, int col, int row)
|
|||||||
free(term);
|
free(term);
|
||||||
err=channel_request(channel,"pty-req",buffer,1);
|
err=channel_request(channel,"pty-req",buffer,1);
|
||||||
buffer_free(buffer);
|
buffer_free(buffer);
|
||||||
|
leave_function();
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -649,9 +706,14 @@ int channel_request_pty(CHANNEL *channel){
|
|||||||
int channel_change_pty_size(CHANNEL *channel,int cols,int rows){
|
int channel_change_pty_size(CHANNEL *channel,int cols,int rows){
|
||||||
BUFFER *buffer;
|
BUFFER *buffer;
|
||||||
int err;
|
int err;
|
||||||
|
SSH_SESSION *session=channel->session;
|
||||||
|
enter_function();
|
||||||
#ifdef HAVE_SSH1
|
#ifdef HAVE_SSH1
|
||||||
if(channel->version==1)
|
if(channel->version==1){
|
||||||
return channel_change_pty_size1(channel,cols,rows);
|
err = channel_change_pty_size1(channel,cols,rows);
|
||||||
|
leave_function();
|
||||||
|
return err;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
buffer=buffer_new();
|
buffer=buffer_new();
|
||||||
//buffer_add_u8(buffer,0);
|
//buffer_add_u8(buffer,0);
|
||||||
@@ -661,6 +723,7 @@ int channel_change_pty_size(CHANNEL *channel,int cols,int rows){
|
|||||||
buffer_add_u32(buffer,0);
|
buffer_add_u32(buffer,0);
|
||||||
err=channel_request(channel,"window-change",buffer,0);
|
err=channel_request(channel,"window-change",buffer,0);
|
||||||
buffer_free(buffer);
|
buffer_free(buffer);
|
||||||
|
leave_function();
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -764,9 +827,11 @@ int channel_request_exec(CHANNEL *channel, char *cmd){
|
|||||||
*/
|
*/
|
||||||
int channel_read(CHANNEL *channel, BUFFER *buffer,int bytes,int is_stderr){
|
int channel_read(CHANNEL *channel, BUFFER *buffer,int bytes,int is_stderr){
|
||||||
BUFFER *stdbuf=NULL;
|
BUFFER *stdbuf=NULL;
|
||||||
|
SSH_SESSION *session=channel->session;
|
||||||
int len;
|
int len;
|
||||||
buffer_reinit(buffer);
|
buffer_reinit(buffer);
|
||||||
int maxread=bytes;
|
int maxread=bytes;
|
||||||
|
enter_function();
|
||||||
if(bytes==0)
|
if(bytes==0)
|
||||||
maxread=MAX_PACKET_LEN;
|
maxread=MAX_PACKET_LEN;
|
||||||
/* maybe i should always set a buffer to avoid races between channel_default_bufferize and channel_read */
|
/* maybe i should always set a buffer to avoid races between channel_default_bufferize and channel_read */
|
||||||
@@ -777,15 +842,19 @@ int channel_read(CHANNEL *channel, BUFFER *buffer,int bytes,int is_stderr){
|
|||||||
|
|
||||||
/* block reading if asked bytes=0 */
|
/* block reading if asked bytes=0 */
|
||||||
while((buffer_get_rest_len(stdbuf)==0) || (buffer_get_rest_len(stdbuf) < bytes)){
|
while((buffer_get_rest_len(stdbuf)==0) || (buffer_get_rest_len(stdbuf) < bytes)){
|
||||||
if(channel->remote_eof && buffer_get_rest_len(stdbuf)==0)
|
if(channel->remote_eof && buffer_get_rest_len(stdbuf)==0){
|
||||||
return 0;
|
leave_function();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
if(channel->remote_eof)
|
if(channel->remote_eof)
|
||||||
break; /* return the resting bytes in buffer */
|
break; /* return the resting bytes in buffer */
|
||||||
if(buffer_get_rest_len(stdbuf)>=maxread) // stop reading when buffer is full enough
|
if(buffer_get_rest_len(stdbuf)>=maxread) // stop reading when buffer is full enough
|
||||||
break;
|
break;
|
||||||
if(packet_read(channel->session)||packet_translate(channel->session))
|
if(packet_read(session)||packet_translate(session)){
|
||||||
return -1;
|
leave_function();
|
||||||
packet_parse(channel->session);
|
return -1;
|
||||||
|
}
|
||||||
|
packet_parse(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(bytes==0){
|
if(bytes==0){
|
||||||
@@ -798,6 +867,7 @@ int channel_read(CHANNEL *channel, BUFFER *buffer,int bytes,int is_stderr){
|
|||||||
buffer_add_data(buffer,buffer_get_rest(stdbuf),len);
|
buffer_add_data(buffer,buffer_get_rest(stdbuf),len);
|
||||||
buffer_pass_bytes(stdbuf,len);
|
buffer_pass_bytes(stdbuf,len);
|
||||||
}
|
}
|
||||||
|
leave_function();
|
||||||
return buffer_get_len(buffer);
|
return buffer_get_len(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -812,7 +882,9 @@ int channel_read(CHANNEL *channel, BUFFER *buffer,int bytes,int is_stderr){
|
|||||||
*/
|
*/
|
||||||
int channel_poll(CHANNEL *channel, int is_stderr){
|
int channel_poll(CHANNEL *channel, int is_stderr){
|
||||||
BUFFER *buffer;
|
BUFFER *buffer;
|
||||||
|
SSH_SESSION *session=channel->session;
|
||||||
int r=0;
|
int r=0;
|
||||||
|
enter_function();
|
||||||
if(is_stderr)
|
if(is_stderr)
|
||||||
buffer=channel->stderr_buffer;
|
buffer=channel->stderr_buffer;
|
||||||
else
|
else
|
||||||
@@ -823,8 +895,11 @@ int channel_poll(CHANNEL *channel, int is_stderr){
|
|||||||
if(r<=0)
|
if(r<=0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(channel->remote_eof)
|
if(channel->remote_eof){
|
||||||
return 1;
|
leave_function();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
leave_function();
|
||||||
return buffer_get_rest_len(buffer);
|
return buffer_get_rest_len(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -845,11 +920,14 @@ int channel_poll(CHANNEL *channel, int is_stderr){
|
|||||||
* \see channel_is_eof()
|
* \see channel_is_eof()
|
||||||
*/
|
*/
|
||||||
int channel_read_nonblocking(CHANNEL *channel, char *dest, int len, int is_stderr){
|
int channel_read_nonblocking(CHANNEL *channel, char *dest, int len, int is_stderr){
|
||||||
|
SSH_SESSION *session=channel->session;
|
||||||
|
enter_function();
|
||||||
int to_read=channel_poll(channel,is_stderr);
|
int to_read=channel_poll(channel,is_stderr);
|
||||||
int lu;
|
int lu;
|
||||||
BUFFER *buffer=buffer_new();
|
BUFFER *buffer=buffer_new();
|
||||||
if(to_read<=0){
|
if(to_read<=0){
|
||||||
buffer_free(buffer);
|
buffer_free(buffer);
|
||||||
|
leave_function();
|
||||||
return to_read; /* may be an error code */
|
return to_read; /* may be an error code */
|
||||||
}
|
}
|
||||||
if(to_read>len)
|
if(to_read>len)
|
||||||
@@ -857,6 +935,7 @@ int channel_read_nonblocking(CHANNEL *channel, char *dest, int len, int is_stder
|
|||||||
lu=channel_read(channel,buffer,to_read,is_stderr);
|
lu=channel_read(channel,buffer,to_read,is_stderr);
|
||||||
memcpy(dest,buffer_get(buffer),lu>=0?lu:0);
|
memcpy(dest,buffer_get(buffer),lu>=0?lu:0);
|
||||||
buffer_free(buffer);
|
buffer_free(buffer);
|
||||||
|
leave_function();
|
||||||
return lu;
|
return lu;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -34,20 +34,26 @@ MA 02111-1307, USA. */
|
|||||||
char *ssh_get_banner(SSH_SESSION *session){
|
char *ssh_get_banner(SSH_SESSION *session){
|
||||||
char buffer[128];
|
char buffer[128];
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
char *ret;
|
||||||
|
enter_function();
|
||||||
while (i < 127) {
|
while (i < 127) {
|
||||||
if(!ssh_socket_is_open(session->socket) || ssh_socket_read(session->socket, &buffer[i], 1)<=0){
|
if(!ssh_socket_is_open(session->socket) || ssh_socket_read(session->socket, &buffer[i], 1)<=0){
|
||||||
ssh_set_error(session,SSH_FATAL,"Remote host closed connection");
|
ssh_set_error(session,SSH_FATAL,"Remote host closed connection");
|
||||||
|
leave_function();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (buffer[i] == '\r')
|
if (buffer[i] == '\r')
|
||||||
buffer[i] = 0;
|
buffer[i] = 0;
|
||||||
if (buffer[i] == '\n') {
|
if (buffer[i] == '\n') {
|
||||||
buffer[i] = 0;
|
buffer[i] = 0;
|
||||||
return strdup(buffer);
|
ret= strdup(buffer);
|
||||||
|
leave_function();
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
ssh_set_error(session,SSH_FATAL,"Too large banner");
|
ssh_set_error(session,SSH_FATAL,"Too large banner");
|
||||||
|
leave_function();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,6 +95,7 @@ int ssh_analyze_banner(SSH_SESSION *session, int *ssh1, int *ssh2){
|
|||||||
int ssh_send_banner(SSH_SESSION *session,int server){
|
int ssh_send_banner(SSH_SESSION *session,int server){
|
||||||
char *banner;
|
char *banner;
|
||||||
char buffer[128];
|
char buffer[128];
|
||||||
|
enter_function();
|
||||||
banner=session->version==1?CLIENTBANNER1:CLIENTBANNER2;
|
banner=session->version==1?CLIENTBANNER1:CLIENTBANNER2;
|
||||||
if(session->options->banner)
|
if(session->options->banner)
|
||||||
banner=session->options->banner;
|
banner=session->options->banner;
|
||||||
@@ -98,6 +105,7 @@ int ssh_send_banner(SSH_SESSION *session,int server){
|
|||||||
session->clientbanner=strdup(banner);
|
session->clientbanner=strdup(banner);
|
||||||
snprintf(buffer,128,"%s\r\n",banner);
|
snprintf(buffer,128,"%s\r\n",banner);
|
||||||
ssh_socket_write(session->socket,buffer,strlen(buffer));
|
ssh_socket_write(session->socket,buffer,strlen(buffer));
|
||||||
|
leave_function();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,6 +118,7 @@ int ssh_send_banner(SSH_SESSION *session,int server){
|
|||||||
static int dh_handshake(SSH_SESSION *session){
|
static int dh_handshake(SSH_SESSION *session){
|
||||||
STRING *e,*f,*pubkey,*signature;
|
STRING *e,*f,*pubkey,*signature;
|
||||||
int ret;
|
int ret;
|
||||||
|
enter_function();
|
||||||
switch(session->dh_handshake_state){
|
switch(session->dh_handshake_state){
|
||||||
case DH_STATE_INIT:
|
case DH_STATE_INIT:
|
||||||
packet_clear_out(session);
|
packet_clear_out(session);
|
||||||
@@ -121,32 +130,41 @@ static int dh_handshake(SSH_SESSION *session){
|
|||||||
ret=packet_send(session);
|
ret=packet_send(session);
|
||||||
free(e);
|
free(e);
|
||||||
session->dh_handshake_state=DH_STATE_INIT_TO_SEND;
|
session->dh_handshake_state=DH_STATE_INIT_TO_SEND;
|
||||||
if(ret==SSH_ERROR)
|
if(ret==SSH_ERROR){
|
||||||
|
leave_function();
|
||||||
return ret;
|
return ret;
|
||||||
|
}
|
||||||
case DH_STATE_INIT_TO_SEND:
|
case DH_STATE_INIT_TO_SEND:
|
||||||
ret=packet_flush(session,0);
|
ret=packet_flush(session,0);
|
||||||
if(ret!=SSH_OK)
|
if(ret!=SSH_OK){
|
||||||
return ret; // SSH_ERROR or SSH_AGAIN
|
leave_function();
|
||||||
|
return ret; // SSH_ERROR or SSH_AGAIN
|
||||||
|
}
|
||||||
session->dh_handshake_state=DH_STATE_INIT_SENT;
|
session->dh_handshake_state=DH_STATE_INIT_SENT;
|
||||||
case DH_STATE_INIT_SENT:
|
case DH_STATE_INIT_SENT:
|
||||||
ret=packet_wait(session,SSH2_MSG_KEXDH_REPLY,1);
|
ret=packet_wait(session,SSH2_MSG_KEXDH_REPLY,1);
|
||||||
if(ret != SSH_OK)
|
if(ret != SSH_OK){
|
||||||
return ret;
|
leave_function();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
pubkey=buffer_get_ssh_string(session->in_buffer);
|
pubkey=buffer_get_ssh_string(session->in_buffer);
|
||||||
if(!pubkey){
|
if(!pubkey){
|
||||||
ssh_set_error(session,SSH_FATAL,"No public key in packet");
|
ssh_set_error(session,SSH_FATAL,"No public key in packet");
|
||||||
|
leave_function();
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
dh_import_pubkey(session,pubkey);
|
dh_import_pubkey(session,pubkey);
|
||||||
f=buffer_get_ssh_string(session->in_buffer);
|
f=buffer_get_ssh_string(session->in_buffer);
|
||||||
if(!f){
|
if(!f){
|
||||||
ssh_set_error(session,SSH_FATAL,"No F number in packet");
|
ssh_set_error(session,SSH_FATAL,"No F number in packet");
|
||||||
|
leave_function();
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
dh_import_f(session,f);
|
dh_import_f(session,f);
|
||||||
free(f);
|
free(f);
|
||||||
if(!(signature=buffer_get_ssh_string(session->in_buffer))){
|
if(!(signature=buffer_get_ssh_string(session->in_buffer))){
|
||||||
ssh_set_error(session,SSH_FATAL,"No signature in packet");
|
ssh_set_error(session,SSH_FATAL,"No signature in packet");
|
||||||
|
leave_function();
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
session->dh_server_signature=signature;
|
session->dh_server_signature=signature;
|
||||||
@@ -158,26 +176,33 @@ static int dh_handshake(SSH_SESSION *session){
|
|||||||
session->dh_handshake_state=DH_STATE_NEWKEYS_TO_SEND;
|
session->dh_handshake_state=DH_STATE_NEWKEYS_TO_SEND;
|
||||||
case DH_STATE_NEWKEYS_TO_SEND:
|
case DH_STATE_NEWKEYS_TO_SEND:
|
||||||
ret=packet_flush(session,0);
|
ret=packet_flush(session,0);
|
||||||
if(ret != SSH_OK)
|
if(ret != SSH_OK){
|
||||||
return ret;
|
leave_function();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
ssh_say(2,"SSH_MSG_NEWKEYS sent\n");
|
ssh_say(2,"SSH_MSG_NEWKEYS sent\n");
|
||||||
session->dh_handshake_state=DH_STATE_NEWKEYS_SENT;
|
session->dh_handshake_state=DH_STATE_NEWKEYS_SENT;
|
||||||
case DH_STATE_NEWKEYS_SENT:
|
case DH_STATE_NEWKEYS_SENT:
|
||||||
ret=packet_wait(session,SSH2_MSG_NEWKEYS,1);
|
ret=packet_wait(session,SSH2_MSG_NEWKEYS,1);
|
||||||
if(ret != SSH_OK)
|
if(ret != SSH_OK){
|
||||||
return ret;
|
leave_function();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
ssh_say(2,"Got SSH_MSG_NEWKEYS\n");
|
ssh_say(2,"Got SSH_MSG_NEWKEYS\n");
|
||||||
make_sessionid(session);
|
make_sessionid(session);
|
||||||
/* set the cryptographic functions for the next crypto */
|
/* set the cryptographic functions for the next crypto */
|
||||||
/* (it is needed for generate_session_keys for key lenghts) */
|
/* (it is needed for generate_session_keys for key lenghts) */
|
||||||
if(crypt_set_algorithms(session))
|
if(crypt_set_algorithms(session)){
|
||||||
return SSH_ERROR;
|
leave_function();
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
generate_session_keys(session);
|
generate_session_keys(session);
|
||||||
/* verify the host's signature. XXX do it sooner */
|
/* verify the host's signature. XXX do it sooner */
|
||||||
signature=session->dh_server_signature;
|
signature=session->dh_server_signature;
|
||||||
session->dh_server_signature=NULL;
|
session->dh_server_signature=NULL;
|
||||||
if(signature_verify(session,signature)){
|
if(signature_verify(session,signature)){
|
||||||
free(signature);
|
free(signature);
|
||||||
|
leave_function();
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
free(signature); /* forget it for now ... */
|
free(signature); /* forget it for now ... */
|
||||||
@@ -188,17 +213,21 @@ static int dh_handshake(SSH_SESSION *session){
|
|||||||
session->current_crypto=session->next_crypto;
|
session->current_crypto=session->next_crypto;
|
||||||
session->next_crypto=crypto_new();
|
session->next_crypto=crypto_new();
|
||||||
session->dh_handshake_state=DH_STATE_FINISHED;
|
session->dh_handshake_state=DH_STATE_FINISHED;
|
||||||
|
leave_function();
|
||||||
return SSH_OK;
|
return SSH_OK;
|
||||||
default:
|
default:
|
||||||
ssh_set_error(session,SSH_FATAL,"Invalid state in dh_handshake():%d",session->dh_handshake_state);
|
ssh_set_error(session,SSH_FATAL,"Invalid state in dh_handshake():%d",session->dh_handshake_state);
|
||||||
|
leave_function();
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
/* not reached */
|
/* not reached */
|
||||||
|
leave_function();
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ssh_service_request(SSH_SESSION *session,char *service){
|
int ssh_service_request(SSH_SESSION *session,char *service){
|
||||||
STRING *service_s;
|
STRING *service_s;
|
||||||
|
enter_function();
|
||||||
packet_clear_out(session);
|
packet_clear_out(session);
|
||||||
buffer_add_u8(session->out_buffer,SSH2_MSG_SERVICE_REQUEST);
|
buffer_add_u8(session->out_buffer,SSH2_MSG_SERVICE_REQUEST);
|
||||||
service_s=string_from_char(service);
|
service_s=string_from_char(service);
|
||||||
@@ -208,9 +237,11 @@ int ssh_service_request(SSH_SESSION *session,char *service){
|
|||||||
ssh_say(3,"Sent SSH_MSG_SERVICE_REQUEST (service %s)\n",service);
|
ssh_say(3,"Sent SSH_MSG_SERVICE_REQUEST (service %s)\n",service);
|
||||||
if(packet_wait(session,SSH2_MSG_SERVICE_ACCEPT,1)){
|
if(packet_wait(session,SSH2_MSG_SERVICE_ACCEPT,1)){
|
||||||
ssh_set_error(session,SSH_FATAL,"did not receive SERVICE_ACCEPT");
|
ssh_set_error(session,SSH_FATAL,"did not receive SERVICE_ACCEPT");
|
||||||
|
leave_function();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
ssh_say(3,"Received SSH_MSG_SERVICE_ACCEPT (service %s)\n",service);
|
ssh_say(3,"Received SSH_MSG_SERVICE_ACCEPT (service %s)\n",service);
|
||||||
|
leave_function();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -231,12 +262,14 @@ int ssh_connect(SSH_SESSION *session){
|
|||||||
ssh_set_error(session,SSH_FATAL,"Must set options before connect");
|
ssh_set_error(session,SSH_FATAL,"Must set options before connect");
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
|
enter_function();
|
||||||
session->alive=0;
|
session->alive=0;
|
||||||
session->client=1;
|
session->client=1;
|
||||||
ssh_crypto_init();
|
ssh_crypto_init();
|
||||||
ssh_socket_init();
|
ssh_socket_init();
|
||||||
if(options->fd==-1 && !options->host){
|
if(options->fd==-1 && !options->host){
|
||||||
ssh_set_error(session,SSH_FATAL,"Hostname required");
|
ssh_set_error(session,SSH_FATAL,"Hostname required");
|
||||||
|
leave_function();
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
if(options->fd != -1)
|
if(options->fd != -1)
|
||||||
@@ -244,14 +277,17 @@ int ssh_connect(SSH_SESSION *session){
|
|||||||
else
|
else
|
||||||
fd=ssh_connect_host(session,options->host,options->bindaddr,options->port,
|
fd=ssh_connect_host(session,options->host,options->bindaddr,options->port,
|
||||||
options->timeout,options->timeout_usec);
|
options->timeout,options->timeout_usec);
|
||||||
if(fd<0)
|
if(fd<0){
|
||||||
return -1;
|
leave_function();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
set_status(options,0.2);
|
set_status(options,0.2);
|
||||||
ssh_socket_set_fd(session->socket,fd);
|
ssh_socket_set_fd(session->socket,fd);
|
||||||
session->alive=1;
|
session->alive=1;
|
||||||
if(!(session->serverbanner=ssh_get_banner(session))){
|
if(!(session->serverbanner=ssh_get_banner(session))){
|
||||||
ssh_socket_close(session->socket);
|
ssh_socket_close(session->socket);
|
||||||
session->alive=0;
|
session->alive=0;
|
||||||
|
leave_function();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
set_status(options,0.4);
|
set_status(options,0.4);
|
||||||
@@ -260,6 +296,7 @@ int ssh_connect(SSH_SESSION *session){
|
|||||||
if(ssh_analyze_banner(session,&ssh1,&ssh2)){
|
if(ssh_analyze_banner(session,&ssh1,&ssh2)){
|
||||||
ssh_socket_close(session->socket);
|
ssh_socket_close(session->socket);
|
||||||
session->alive=0;
|
session->alive=0;
|
||||||
|
leave_function();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
/* here we decide which version of the protocol to use */
|
/* here we decide which version of the protocol to use */
|
||||||
@@ -273,6 +310,7 @@ int ssh_connect(SSH_SESSION *session){
|
|||||||
session->serverbanner);
|
session->serverbanner);
|
||||||
ssh_socket_close(session->socket);
|
ssh_socket_close(session->socket);
|
||||||
session->alive=0;
|
session->alive=0;
|
||||||
|
leave_function();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
ssh_send_banner(session,0);
|
ssh_send_banner(session,0);
|
||||||
@@ -282,6 +320,7 @@ int ssh_connect(SSH_SESSION *session){
|
|||||||
if(ssh_get_kex(session,0)){
|
if(ssh_get_kex(session,0)){
|
||||||
ssh_socket_close(session->socket);
|
ssh_socket_close(session->socket);
|
||||||
session->alive=0;
|
session->alive=0;
|
||||||
|
leave_function();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
set_status(options,0.6);
|
set_status(options,0.6);
|
||||||
@@ -289,6 +328,7 @@ int ssh_connect(SSH_SESSION *session){
|
|||||||
if(set_kex(session)){
|
if(set_kex(session)){
|
||||||
ssh_socket_close(session->socket);
|
ssh_socket_close(session->socket);
|
||||||
session->alive=0;
|
session->alive=0;
|
||||||
|
leave_function();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
ssh_send_kex(session,0);
|
ssh_send_kex(session,0);
|
||||||
@@ -296,6 +336,7 @@ int ssh_connect(SSH_SESSION *session){
|
|||||||
if(dh_handshake(session)){
|
if(dh_handshake(session)){
|
||||||
ssh_socket_close(session->socket);
|
ssh_socket_close(session->socket);
|
||||||
session->alive=0;
|
session->alive=0;
|
||||||
|
leave_function();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
set_status(options,1.0);
|
set_status(options,1.0);
|
||||||
@@ -305,12 +346,14 @@ int ssh_connect(SSH_SESSION *session){
|
|||||||
if(ssh_get_kex1(session)){
|
if(ssh_get_kex1(session)){
|
||||||
ssh_socket_close(session->socket);
|
ssh_socket_close(session->socket);
|
||||||
session->alive=0;
|
session->alive=0;
|
||||||
|
leave_function();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
set_status(options,0.6);
|
set_status(options,0.6);
|
||||||
session->connected=1;
|
session->connected=1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
leave_function();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -331,6 +374,7 @@ char *ssh_get_issue_banner(SSH_SESSION *session){
|
|||||||
*/
|
*/
|
||||||
void ssh_disconnect(SSH_SESSION *session){
|
void ssh_disconnect(SSH_SESSION *session){
|
||||||
STRING *str;
|
STRING *str;
|
||||||
|
enter_function();
|
||||||
if(ssh_socket_is_open(session->socket)) {
|
if(ssh_socket_is_open(session->socket)) {
|
||||||
packet_clear_out(session);
|
packet_clear_out(session);
|
||||||
buffer_add_u8(session->out_buffer,SSH2_MSG_DISCONNECT);
|
buffer_add_u8(session->out_buffer,SSH2_MSG_DISCONNECT);
|
||||||
@@ -342,6 +386,7 @@ void ssh_disconnect(SSH_SESSION *session){
|
|||||||
ssh_socket_close(session->socket);
|
ssh_socket_close(session->socket);
|
||||||
}
|
}
|
||||||
session->alive=0;
|
session->alive=0;
|
||||||
|
leave_function();
|
||||||
ssh_cleanup(session);
|
ssh_cleanup(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -98,6 +98,7 @@ int ssh_connect_ai_timeout(SSH_SESSION *session, const char *host, int port, str
|
|||||||
fd_set set;
|
fd_set set;
|
||||||
int ret=0;
|
int ret=0;
|
||||||
unsigned int len=sizeof(ret);
|
unsigned int len=sizeof(ret);
|
||||||
|
enter_function();
|
||||||
to.tv_sec=timeout;
|
to.tv_sec=timeout;
|
||||||
to.tv_usec=usec;
|
to.tv_usec=usec;
|
||||||
sock_set_nonblocking(s);
|
sock_set_nonblocking(s);
|
||||||
@@ -110,11 +111,13 @@ int ssh_connect_ai_timeout(SSH_SESSION *session, const char *host, int port, str
|
|||||||
/* timeout */
|
/* timeout */
|
||||||
ssh_set_error(session,SSH_FATAL,"Timeout while connecting to %s:%d",host,port);
|
ssh_set_error(session,SSH_FATAL,"Timeout while connecting to %s:%d",host,port);
|
||||||
close(s);
|
close(s);
|
||||||
|
leave_function();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if(ret<0){
|
if(ret<0){
|
||||||
ssh_set_error(session,SSH_FATAL,"Select error : %s",strerror(errno));
|
ssh_set_error(session,SSH_FATAL,"Select error : %s",strerror(errno));
|
||||||
close(s);
|
close(s);
|
||||||
|
leave_function();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
ret = 0;
|
ret = 0;
|
||||||
@@ -123,11 +126,13 @@ int ssh_connect_ai_timeout(SSH_SESSION *session, const char *host, int port, str
|
|||||||
if (ret!=0){
|
if (ret!=0){
|
||||||
ssh_set_error(session,SSH_FATAL,"Connecting : %s",strerror(ret));
|
ssh_set_error(session,SSH_FATAL,"Connecting : %s",strerror(ret));
|
||||||
close(s);
|
close(s);
|
||||||
|
leave_function();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
/* s is connected ? */
|
/* s is connected ? */
|
||||||
ssh_say(3,"socket connected with timeout\n");
|
ssh_say(3,"socket connected with timeout\n");
|
||||||
sock_set_blocking(s);
|
sock_set_blocking(s);
|
||||||
|
leave_function();
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -140,10 +145,11 @@ socket_t ssh_connect_host(SSH_SESSION *session, const char *host, const char
|
|||||||
socket_t s=-1;
|
socket_t s=-1;
|
||||||
int my_errno;
|
int my_errno;
|
||||||
struct addrinfo *ai, *ai2;
|
struct addrinfo *ai, *ai2;
|
||||||
|
enter_function();
|
||||||
my_errno=getai(host, port, &ai);
|
my_errno=getai(host, port, &ai);
|
||||||
if (my_errno){
|
if (my_errno){
|
||||||
ssh_set_error(session,SSH_FATAL,"Failed to resolve hostname %s (%s)",host,gai_strerror(my_errno));
|
ssh_set_error(session,SSH_FATAL,"Failed to resolve hostname %s (%s)",host,gai_strerror(my_errno));
|
||||||
|
leave_function();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,6 +168,7 @@ socket_t ssh_connect_host(SSH_SESSION *session, const char *host, const char
|
|||||||
my_errno=getai(host,0,&bind_ai);
|
my_errno=getai(host,0,&bind_ai);
|
||||||
if (my_errno){
|
if (my_errno){
|
||||||
ssh_set_error(session,SSH_FATAL,"Failed to resolve bind address %s (%s)",bind_addr,gai_strerror(my_errno));
|
ssh_set_error(session,SSH_FATAL,"Failed to resolve bind address %s (%s)",bind_addr,gai_strerror(my_errno));
|
||||||
|
leave_function();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -182,12 +189,15 @@ socket_t ssh_connect_host(SSH_SESSION *session, const char *host, const char
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(timeout||usec){
|
if(timeout||usec){
|
||||||
return ssh_connect_ai_timeout(session,host,port,ai2,timeout,usec,s);
|
socket_t ret=ssh_connect_ai_timeout(session,host,port,ai2,timeout,usec,s);
|
||||||
|
leave_function();
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
if(connect(s,ai2->ai_addr,ai2->ai_addrlen)<0){
|
if(connect(s,ai2->ai_addr,ai2->ai_addrlen)<0){
|
||||||
ssh_set_error(session,SSH_FATAL,"connect: %s",strerror(errno));
|
ssh_set_error(session,SSH_FATAL,"connect: %s",strerror(errno));
|
||||||
close(s);
|
close(s);
|
||||||
s=-1;
|
s=-1;
|
||||||
|
leave_function();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else{ /*we are connected*/
|
else{ /*we are connected*/
|
||||||
@@ -195,6 +205,7 @@ socket_t ssh_connect_host(SSH_SESSION *session, const char *host, const char
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
freeaddrinfo(ai);
|
freeaddrinfo(ai);
|
||||||
|
leave_function();
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -214,7 +225,7 @@ int ssh_fd_poll(SSH_SESSION *session, int *write, int *except){
|
|||||||
fd_set wdes; // writing set
|
fd_set wdes; // writing set
|
||||||
fd_set edes; // exception set
|
fd_set edes; // exception set
|
||||||
int fdmax=-1;
|
int fdmax=-1;
|
||||||
|
enter_function();
|
||||||
FD_ZERO(&rdes);
|
FD_ZERO(&rdes);
|
||||||
FD_ZERO(&wdes);
|
FD_ZERO(&wdes);
|
||||||
FD_ZERO(&edes);
|
FD_ZERO(&edes);
|
||||||
@@ -223,6 +234,7 @@ int ssh_fd_poll(SSH_SESSION *session, int *write, int *except){
|
|||||||
*except=1;
|
*except=1;
|
||||||
*write=0;
|
*write=0;
|
||||||
session->alive=0;
|
session->alive=0;
|
||||||
|
leave_function();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if(!session->data_to_read)
|
if(!session->data_to_read)
|
||||||
@@ -238,6 +250,7 @@ int ssh_fd_poll(SSH_SESSION *session, int *write, int *except){
|
|||||||
/* Make the call, and listen for errors */
|
/* Make the call, and listen for errors */
|
||||||
if (select(fdmax, &rdes,&wdes,&edes, &sometime) < 0) {
|
if (select(fdmax, &rdes,&wdes,&edes, &sometime) < 0) {
|
||||||
ssh_set_error(session,SSH_FATAL, "select: %s", strerror(errno));
|
ssh_set_error(session,SSH_FATAL, "select: %s", strerror(errno));
|
||||||
|
leave_function();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if(!session->data_to_read)
|
if(!session->data_to_read)
|
||||||
@@ -246,6 +259,7 @@ int ssh_fd_poll(SSH_SESSION *session, int *write, int *except){
|
|||||||
session->data_to_write=ssh_socket_fd_isset(session->socket,&wdes);
|
session->data_to_write=ssh_socket_fd_isset(session->socket,&wdes);
|
||||||
*except=ssh_socket_fd_isset(session->socket,&edes);
|
*except=ssh_socket_fd_isset(session->socket,&edes);
|
||||||
*write=session->data_to_write;
|
*write=session->data_to_write;
|
||||||
|
leave_function();
|
||||||
return session->data_to_read;
|
return session->data_to_read;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
18
libssh/dh.c
18
libssh/dh.c
@@ -1,7 +1,7 @@
|
|||||||
/* dh.c */
|
/* dh.c */
|
||||||
/* this file contains usefull stuff for Diffie helman algorithm against SSH 2 */
|
/* this file contains usefull stuff for Diffie helman algorithm against SSH 2 */
|
||||||
/*
|
/*
|
||||||
Copyright 2003 Aris Adamantiadis
|
Copyright 2003-2008 Aris Adamantiadis
|
||||||
|
|
||||||
This file is part of the SSH Library
|
This file is part of the SSH Library
|
||||||
|
|
||||||
@@ -310,6 +310,7 @@ void make_sessionid(SSH_SESSION *session){
|
|||||||
BUFFER *server_hash, *client_hash;
|
BUFFER *server_hash, *client_hash;
|
||||||
BUFFER *buf=buffer_new();
|
BUFFER *buf=buffer_new();
|
||||||
u32 len;
|
u32 len;
|
||||||
|
enter_function();
|
||||||
ctx=sha1_init();
|
ctx=sha1_init();
|
||||||
|
|
||||||
str=string_from_char(session->clientbanner);
|
str=string_from_char(session->clientbanner);
|
||||||
@@ -379,6 +380,7 @@ void make_sessionid(SSH_SESSION *session){
|
|||||||
printf("Session hash : ");
|
printf("Session hash : ");
|
||||||
ssh_print_hexa("session id",session->next_crypto->session_id,SHA_DIGEST_LEN);
|
ssh_print_hexa("session id",session->next_crypto->session_id,SHA_DIGEST_LEN);
|
||||||
#endif
|
#endif
|
||||||
|
leave_function();
|
||||||
}
|
}
|
||||||
|
|
||||||
void hashbufout_add_cookie(SSH_SESSION *session){
|
void hashbufout_add_cookie(SSH_SESSION *session){
|
||||||
@@ -409,6 +411,7 @@ static void generate_one_key(STRING *k,unsigned char session_id[SHA_DIGEST_LEN],
|
|||||||
void generate_session_keys(SSH_SESSION *session){
|
void generate_session_keys(SSH_SESSION *session){
|
||||||
STRING *k_string;
|
STRING *k_string;
|
||||||
SHACTX ctx;
|
SHACTX ctx;
|
||||||
|
enter_function();
|
||||||
k_string=make_bignum_string(session->next_crypto->k);
|
k_string=make_bignum_string(session->next_crypto->k);
|
||||||
|
|
||||||
/* IV */
|
/* IV */
|
||||||
@@ -460,6 +463,7 @@ void generate_session_keys(SSH_SESSION *session){
|
|||||||
ssh_print_hexa("Decryption MAC",session->next_crypto->decryptMAC,20);
|
ssh_print_hexa("Decryption MAC",session->next_crypto->decryptMAC,20);
|
||||||
#endif
|
#endif
|
||||||
free(k_string);
|
free(k_string);
|
||||||
|
leave_function();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \addtogroup ssh_session
|
/** \addtogroup ssh_session
|
||||||
@@ -587,18 +591,24 @@ int signature_verify(SSH_SESSION *session,STRING *signature){
|
|||||||
PUBLIC_KEY *pubkey;
|
PUBLIC_KEY *pubkey;
|
||||||
SIGNATURE *sign;
|
SIGNATURE *sign;
|
||||||
int err;
|
int err;
|
||||||
|
enter_function();
|
||||||
if(session->options->dont_verify_hostkey){
|
if(session->options->dont_verify_hostkey){
|
||||||
ssh_say(1,"Host key wasn't verified\n");
|
ssh_say(1,"Host key wasn't verified\n");
|
||||||
|
leave_function();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
pubkey=publickey_from_string(session,session->next_crypto->server_pubkey);
|
pubkey=publickey_from_string(session,session->next_crypto->server_pubkey);
|
||||||
if(!pubkey)
|
if(!pubkey){
|
||||||
return -1;
|
leave_function();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if(session->options->wanted_methods[SSH_HOSTKEYS]){
|
if(session->options->wanted_methods[SSH_HOSTKEYS]){
|
||||||
if(match(session->options->wanted_methods[SSH_HOSTKEYS],pubkey->type_c)){
|
if(match(session->options->wanted_methods[SSH_HOSTKEYS],pubkey->type_c)){
|
||||||
ssh_set_error(session,SSH_FATAL,"Public key from server (%s) doesn't match user preference (%s)",
|
ssh_set_error(session,SSH_FATAL,"Public key from server (%s) doesn't match user preference (%s)",
|
||||||
pubkey->type_c,session->options->wanted_methods[SSH_HOSTKEYS]);
|
pubkey->type_c,session->options->wanted_methods[SSH_HOSTKEYS]);
|
||||||
publickey_free(pubkey);
|
publickey_free(pubkey);
|
||||||
|
leave_function();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -606,6 +616,7 @@ int signature_verify(SSH_SESSION *session,STRING *signature){
|
|||||||
if(!sign){
|
if(!sign){
|
||||||
ssh_set_error(session,SSH_FATAL,"Invalid signature blob");
|
ssh_set_error(session,SSH_FATAL,"Invalid signature blob");
|
||||||
publickey_free(pubkey);
|
publickey_free(pubkey);
|
||||||
|
leave_function();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
ssh_say(1,"Going to verify a %s type signature\n",pubkey->type_c);
|
ssh_say(1,"Going to verify a %s type signature\n",pubkey->type_c);
|
||||||
@@ -613,6 +624,7 @@ int signature_verify(SSH_SESSION *session,STRING *signature){
|
|||||||
signature_free(sign);
|
signature_free(sign);
|
||||||
session->next_crypto->server_pubkey_type=pubkey->type_c;
|
session->next_crypto->server_pubkey_type=pubkey->type_c;
|
||||||
publickey_free(pubkey);
|
publickey_free(pubkey);
|
||||||
|
leave_function();
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
28
libssh/kex.c
28
libssh/kex.c
@@ -165,10 +165,14 @@ int ssh_get_kex(SSH_SESSION *session,int server_kex ){
|
|||||||
STRING *str;
|
STRING *str;
|
||||||
char *strings[10];
|
char *strings[10];
|
||||||
int i;
|
int i;
|
||||||
if(packet_wait(session,SSH2_MSG_KEXINIT,1))
|
enter_function();
|
||||||
return -1;
|
if(packet_wait(session,SSH2_MSG_KEXINIT,1)){
|
||||||
|
leave_function();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
if(buffer_get_data(session->in_buffer,session->server_kex.cookie,16)!=16){
|
if(buffer_get_data(session->in_buffer,session->server_kex.cookie,16)!=16){
|
||||||
ssh_set_error(session,SSH_FATAL,"get_kex(): no cookie in packet");
|
ssh_set_error(session,SSH_FATAL,"get_kex(): no cookie in packet");
|
||||||
|
leave_function();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
hashbufin_add_cookie(session,session->server_kex.cookie);
|
hashbufin_add_cookie(session,session->server_kex.cookie);
|
||||||
@@ -194,6 +198,7 @@ int ssh_get_kex(SSH_SESSION *session,int server_kex ){
|
|||||||
for(i=0;i<10;++i)
|
for(i=0;i<10;++i)
|
||||||
session->server_kex.methods[i]=strings[i];
|
session->server_kex.methods[i]=strings[i];
|
||||||
}
|
}
|
||||||
|
leave_function();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -217,6 +222,7 @@ int set_kex(SSH_SESSION *session){
|
|||||||
SSH_OPTIONS *options=session->options;
|
SSH_OPTIONS *options=session->options;
|
||||||
int i;
|
int i;
|
||||||
char *wanted;
|
char *wanted;
|
||||||
|
enter_function();
|
||||||
/* the client might ask for a specific cookie to be sent. useful for server debugging */
|
/* the client might ask for a specific cookie to be sent. useful for server debugging */
|
||||||
if(options->wanted_cookie)
|
if(options->wanted_cookie)
|
||||||
memcpy(client->cookie,options->wanted_cookie,16);
|
memcpy(client->cookie,options->wanted_cookie,16);
|
||||||
@@ -231,12 +237,14 @@ int set_kex(SSH_SESSION *session){
|
|||||||
if(!client->methods[i] && i < SSH_LANG_C_S){
|
if(!client->methods[i] && i < SSH_LANG_C_S){
|
||||||
ssh_set_error(session,SSH_FATAL,"kex error : did not find one of algos %s in list %s for %s",
|
ssh_set_error(session,SSH_FATAL,"kex error : did not find one of algos %s in list %s for %s",
|
||||||
wanted,server->methods[i],ssh_kex_nums[i]);
|
wanted,server->methods[i],ssh_kex_nums[i]);
|
||||||
|
leave_function();
|
||||||
return -1;
|
return -1;
|
||||||
} else {
|
} else {
|
||||||
if(i>=SSH_LANG_C_S && !client->methods[i])
|
if(i>=SSH_LANG_C_S && !client->methods[i])
|
||||||
client->methods[i]=strdup(""); // we can safely do that for languages
|
client->methods[i]=strdup(""); // we can safely do that for languages
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
leave_function();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -245,6 +253,7 @@ void ssh_send_kex(SSH_SESSION *session, int server_kex){
|
|||||||
STRING *str;
|
STRING *str;
|
||||||
int i=0;
|
int i=0;
|
||||||
KEX *kex=(server_kex ? &session->server_kex : &session->client_kex);
|
KEX *kex=(server_kex ? &session->server_kex : &session->client_kex);
|
||||||
|
enter_function();
|
||||||
packet_clear_out(session);
|
packet_clear_out(session);
|
||||||
buffer_add_u8(session->out_buffer,SSH2_MSG_KEXINIT);
|
buffer_add_u8(session->out_buffer,SSH2_MSG_KEXINIT);
|
||||||
buffer_add_data(session->out_buffer,kex->cookie,16);
|
buffer_add_data(session->out_buffer,kex->cookie,16);
|
||||||
@@ -260,6 +269,7 @@ void ssh_send_kex(SSH_SESSION *session, int server_kex){
|
|||||||
buffer_add_u8(session->out_buffer,0);
|
buffer_add_u8(session->out_buffer,0);
|
||||||
buffer_add_u32(session->out_buffer,0);
|
buffer_add_u32(session->out_buffer,0);
|
||||||
packet_send(session);
|
packet_send(session);
|
||||||
|
leave_function();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* returns 1 if at least one of the name algos is in the default algorithms table */
|
/* returns 1 if at least one of the name algos is in the default algorithms table */
|
||||||
@@ -401,13 +411,16 @@ int ssh_get_kex1(SSH_SESSION *session){
|
|||||||
PUBLIC_KEY *svr,*host;
|
PUBLIC_KEY *svr,*host;
|
||||||
int ko;
|
int ko;
|
||||||
u16 bits;
|
u16 bits;
|
||||||
|
enter_function();
|
||||||
ssh_say(3,"Waiting for a SSH_SMSG_PUBLIC_KEY\n");
|
ssh_say(3,"Waiting for a SSH_SMSG_PUBLIC_KEY\n");
|
||||||
if(packet_wait(session,SSH_SMSG_PUBLIC_KEY,1)){
|
if(packet_wait(session,SSH_SMSG_PUBLIC_KEY,1)){
|
||||||
|
leave_function();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
ssh_say(3,"Got a SSH_SMSG_PUBLIC_KEY\n");
|
ssh_say(3,"Got a SSH_SMSG_PUBLIC_KEY\n");
|
||||||
if(buffer_get_data(session->in_buffer,session->server_kex.cookie,8)!=8){
|
if(buffer_get_data(session->in_buffer,session->server_kex.cookie,8)!=8){
|
||||||
ssh_set_error(session,SSH_FATAL,"Can't get cookie in buffer");
|
ssh_set_error(session,SSH_FATAL,"Can't get cookie in buffer");
|
||||||
|
leave_function();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
buffer_get_u32(session->in_buffer,&server_bits);
|
buffer_get_u32(session->in_buffer,&server_bits);
|
||||||
@@ -430,6 +443,7 @@ int ssh_get_kex1(SSH_SESSION *session){
|
|||||||
free(server_mod);
|
free(server_mod);
|
||||||
if(server_exp)
|
if(server_exp)
|
||||||
free(server_exp);
|
free(server_exp);
|
||||||
|
leave_function();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
server_bits=ntohl(server_bits);
|
server_bits=ntohl(server_bits);
|
||||||
@@ -457,6 +471,7 @@ int ssh_get_kex1(SSH_SESSION *session){
|
|||||||
/* hardcode 3des */
|
/* hardcode 3des */
|
||||||
if(!(supported_ciphers_mask & (1<<SSH_CIPHER_3DES))){
|
if(!(supported_ciphers_mask & (1<<SSH_CIPHER_3DES))){
|
||||||
ssh_set_error(session,SSH_FATAL,"Remote server doesn't accept 3des");
|
ssh_set_error(session,SSH_FATAL,"Remote server doesn't accept 3des");
|
||||||
|
leave_function();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
packet_clear_out(session);
|
packet_clear_out(session);
|
||||||
@@ -477,18 +492,21 @@ int ssh_get_kex1(SSH_SESSION *session){
|
|||||||
|
|
||||||
packet_send(session);
|
packet_send(session);
|
||||||
/* we can set encryption */
|
/* we can set encryption */
|
||||||
if(crypt_set_algorithms(session))
|
if(crypt_set_algorithms(session)){
|
||||||
return -1;
|
leave_function();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
session->current_crypto=session->next_crypto;
|
session->current_crypto=session->next_crypto;
|
||||||
session->next_crypto=NULL;
|
session->next_crypto=NULL;
|
||||||
if(packet_wait(session,SSH_SMSG_SUCCESS,1)){
|
if(packet_wait(session,SSH_SMSG_SUCCESS,1)){
|
||||||
char buffer[1024];
|
char buffer[1024];
|
||||||
snprintf(buffer,sizeof(buffer),"Key exchange failed : %s",ssh_get_error(session));
|
snprintf(buffer,sizeof(buffer),"Key exchange failed : %s",ssh_get_error(session));
|
||||||
ssh_set_error(session,SSH_FATAL,"%s",buffer);
|
ssh_set_error(session,SSH_FATAL,"%s",buffer);
|
||||||
|
leave_function();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
ssh_say(1,"received SSH_SMSG_SUCCESS\n");
|
ssh_say(1,"received SSH_SMSG_SUCCESS\n");
|
||||||
|
leave_function();
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -850,6 +850,7 @@ static char **ssh_parse_knownhost(char *filename, char *hostname, char *type){
|
|||||||
* \see ssh_options_set_wanted_algo()
|
* \see ssh_options_set_wanted_algo()
|
||||||
* \see ssh_get_pubkey_hash()
|
* \see ssh_get_pubkey_hash()
|
||||||
* \bug there is no current way to remove or modify an entry into the known host table
|
* \bug there is no current way to remove or modify an entry into the known host table
|
||||||
|
* \todo TODO this is a real mess. Clean this up someday
|
||||||
*/
|
*/
|
||||||
int ssh_is_server_known(SSH_SESSION *session){
|
int ssh_is_server_known(SSH_SESSION *session){
|
||||||
char *pubkey_64;
|
char *pubkey_64;
|
||||||
|
61
libssh/log.c
Normal file
61
libssh/log.c
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2008 Aris Adamantiadis
|
||||||
|
*
|
||||||
|
* This file is part of the SSH Library
|
||||||
|
*
|
||||||
|
* 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. */
|
||||||
|
|
||||||
|
|
||||||
|
/** \defgroup ssh_log SSH logging
|
||||||
|
* \brief Logging functions for debugging and problem resolving
|
||||||
|
*/
|
||||||
|
/** \addtogroup ssh_log
|
||||||
|
* @{ */
|
||||||
|
#include "libssh/priv.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <string.h>
|
||||||
|
/** \brief logs an event
|
||||||
|
* \param session the SSH session
|
||||||
|
* \param verbosity verbosity of the event
|
||||||
|
* \param format format string of the log entry
|
||||||
|
*/
|
||||||
|
void ssh_log(SSH_SESSION *session, int verbosity, char *format, ...){
|
||||||
|
char buffer[1024];
|
||||||
|
char buf2[256];
|
||||||
|
int min;
|
||||||
|
va_list va;
|
||||||
|
if(verbosity <= session->log_verbosity){
|
||||||
|
va_start(va,format);
|
||||||
|
vsnprintf(buffer,sizeof(buffer),format,va);
|
||||||
|
va_end(va);
|
||||||
|
if(session->options->log_function)
|
||||||
|
session->options->log_function(buffer,session,verbosity);
|
||||||
|
else if(verbosity==SSH_LOG_FUNCTIONS){
|
||||||
|
if(session->log_indent > 255)
|
||||||
|
min=255;
|
||||||
|
else
|
||||||
|
min=session->log_indent;
|
||||||
|
memset(buf2,' ',min);
|
||||||
|
buf2[min]=0;
|
||||||
|
fprintf(stderr,"[func] %s%s\n",buf2,buffer);
|
||||||
|
} else {
|
||||||
|
fprintf(stderr,"[%d] %s\n",verbosity,buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @} */
|
@@ -48,9 +48,11 @@ static SSH_MESSAGE *message_new(SSH_SESSION *session){
|
|||||||
static int handle_service_request(SSH_SESSION *session){
|
static int handle_service_request(SSH_SESSION *session){
|
||||||
STRING *service;
|
STRING *service;
|
||||||
char *service_c;
|
char *service_c;
|
||||||
|
enter_function();
|
||||||
service=buffer_get_ssh_string(session->in_buffer);
|
service=buffer_get_ssh_string(session->in_buffer);
|
||||||
if(!service){
|
if(!service){
|
||||||
ssh_set_error(session,SSH_FATAL,"Invalid SSH_MSG_SERVICE_REQUEST packet");
|
ssh_set_error(session,SSH_FATAL,"Invalid SSH_MSG_SERVICE_REQUEST packet");
|
||||||
|
leave_function();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
service_c=string_to_char(service);
|
service_c=string_to_char(service);
|
||||||
@@ -61,6 +63,7 @@ static int handle_service_request(SSH_SESSION *session){
|
|||||||
buffer_add_ssh_string(session->out_buffer,service);
|
buffer_add_ssh_string(session->out_buffer,service);
|
||||||
packet_send(session);
|
packet_send(session);
|
||||||
free(service);
|
free(service);
|
||||||
|
leave_function();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,6 +79,7 @@ static SSH_MESSAGE *handle_userauth_request(SSH_SESSION *session){
|
|||||||
STRING *method=buffer_get_ssh_string(session->in_buffer);
|
STRING *method=buffer_get_ssh_string(session->in_buffer);
|
||||||
SSH_MESSAGE *msg;
|
SSH_MESSAGE *msg;
|
||||||
char *service_c,*method_c;
|
char *service_c,*method_c;
|
||||||
|
enter_function();
|
||||||
msg=message_new(session);
|
msg=message_new(session);
|
||||||
msg->type=SSH_AUTH_REQUEST;
|
msg->type=SSH_AUTH_REQUEST;
|
||||||
msg->auth_request.username=string_to_char(user);
|
msg->auth_request.username=string_to_char(user);
|
||||||
@@ -88,6 +92,7 @@ static SSH_MESSAGE *handle_userauth_request(SSH_SESSION *session){
|
|||||||
if(!strcmp(method_c,"none")){
|
if(!strcmp(method_c,"none")){
|
||||||
msg->auth_request.method=SSH_AUTH_NONE;
|
msg->auth_request.method=SSH_AUTH_NONE;
|
||||||
free(method_c);
|
free(method_c);
|
||||||
|
leave_function();
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
if(!strcmp(method_c,"password")){
|
if(!strcmp(method_c,"password")){
|
||||||
@@ -99,10 +104,12 @@ static SSH_MESSAGE *handle_userauth_request(SSH_SESSION *session){
|
|||||||
pass=buffer_get_ssh_string(session->in_buffer);
|
pass=buffer_get_ssh_string(session->in_buffer);
|
||||||
msg->auth_request.password=string_to_char(pass);
|
msg->auth_request.password=string_to_char(pass);
|
||||||
free(pass);
|
free(pass);
|
||||||
|
leave_function();
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
msg->auth_request.method=SSH_AUTH_UNKNOWN;
|
msg->auth_request.method=SSH_AUTH_UNKNOWN;
|
||||||
free(method_c);
|
free(method_c);
|
||||||
|
leave_function();
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,18 +128,21 @@ void ssh_message_auth_set_methods(SSH_MESSAGE *msg,int methods){
|
|||||||
static int ssh_message_auth_reply_default(SSH_MESSAGE *msg,int partial){
|
static int ssh_message_auth_reply_default(SSH_MESSAGE *msg,int partial){
|
||||||
char methods_c[128]="";
|
char methods_c[128]="";
|
||||||
STRING *methods;
|
STRING *methods;
|
||||||
packet_clear_out(msg->session);
|
SSH_SESSION *session=msg->session;
|
||||||
buffer_add_u8(msg->session->out_buffer,SSH2_MSG_USERAUTH_FAILURE);
|
int ret;
|
||||||
if(msg->session->auth_methods==0){
|
enter_function();
|
||||||
msg->session->auth_methods=SSH_AUTH_PUBLICKEY|SSH_AUTH_PASSWORD;
|
packet_clear_out(session);
|
||||||
|
buffer_add_u8(session->out_buffer,SSH2_MSG_USERAUTH_FAILURE);
|
||||||
|
if(session->auth_methods==0){
|
||||||
|
session->auth_methods=SSH_AUTH_PUBLICKEY|SSH_AUTH_PASSWORD;
|
||||||
}
|
}
|
||||||
if(msg->session->auth_methods & SSH_AUTH_PUBLICKEY)
|
if(session->auth_methods & SSH_AUTH_PUBLICKEY)
|
||||||
strcat(methods_c,"publickey,");
|
strcat(methods_c,"publickey,");
|
||||||
if(msg->session->auth_methods & SSH_AUTH_KEYBINT)
|
if(session->auth_methods & SSH_AUTH_KEYBINT)
|
||||||
strcat(methods_c,"keyboard-interactive,");
|
strcat(methods_c,"keyboard-interactive,");
|
||||||
if(msg->session->auth_methods & SSH_AUTH_PASSWORD)
|
if(session->auth_methods & SSH_AUTH_PASSWORD)
|
||||||
strcat(methods_c,"password,");
|
strcat(methods_c,"password,");
|
||||||
if(msg->session->auth_methods & SSH_AUTH_HOSTBASED)
|
if(session->auth_methods & SSH_AUTH_HOSTBASED)
|
||||||
strcat(methods_c,"hostbased,");
|
strcat(methods_c,"hostbased,");
|
||||||
methods_c[strlen(methods_c)-1]=0; // strip the comma. We are sure there is at
|
methods_c[strlen(methods_c)-1]=0; // strip the comma. We are sure there is at
|
||||||
// least one word into the list
|
// least one word into the list
|
||||||
@@ -141,10 +151,12 @@ static int ssh_message_auth_reply_default(SSH_MESSAGE *msg,int partial){
|
|||||||
buffer_add_ssh_string(msg->session->out_buffer,methods);
|
buffer_add_ssh_string(msg->session->out_buffer,methods);
|
||||||
free(methods);
|
free(methods);
|
||||||
if(partial)
|
if(partial)
|
||||||
buffer_add_u8(msg->session->out_buffer,1);
|
buffer_add_u8(session->out_buffer,1);
|
||||||
else
|
else
|
||||||
buffer_add_u8(msg->session->out_buffer,0); // no partial success
|
buffer_add_u8(session->out_buffer,0); // no partial success
|
||||||
return packet_send(msg->session);
|
ret = packet_send(msg->session);
|
||||||
|
leave_function();
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ssh_message_auth_reply_success(SSH_MESSAGE *msg,int partial){
|
int ssh_message_auth_reply_success(SSH_MESSAGE *msg,int partial){
|
||||||
@@ -156,6 +168,7 @@ int ssh_message_auth_reply_success(SSH_MESSAGE *msg,int partial){
|
|||||||
}
|
}
|
||||||
|
|
||||||
static SSH_MESSAGE *handle_channel_request_open(SSH_SESSION *session){
|
static SSH_MESSAGE *handle_channel_request_open(SSH_SESSION *session){
|
||||||
|
enter_function();
|
||||||
SSH_MESSAGE *msg=message_new(session);
|
SSH_MESSAGE *msg=message_new(session);
|
||||||
STRING *type;
|
STRING *type;
|
||||||
char *type_c;
|
char *type_c;
|
||||||
@@ -173,32 +186,38 @@ static SSH_MESSAGE *handle_channel_request_open(SSH_SESSION *session){
|
|||||||
msg->channel_request_open.packet_size=ntohl(packet);
|
msg->channel_request_open.packet_size=ntohl(packet);
|
||||||
if(!strcmp(type_c,"session")){
|
if(!strcmp(type_c,"session")){
|
||||||
msg->channel_request_open.type=SSH_CHANNEL_SESSION;
|
msg->channel_request_open.type=SSH_CHANNEL_SESSION;
|
||||||
|
leave_function();
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
msg->channel_request_open.type=SSH_CHANNEL_UNKNOWN;
|
msg->channel_request_open.type=SSH_CHANNEL_UNKNOWN;
|
||||||
|
leave_function();
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
CHANNEL *ssh_message_channel_request_open_reply_accept(SSH_MESSAGE *msg){
|
CHANNEL *ssh_message_channel_request_open_reply_accept(SSH_MESSAGE *msg){
|
||||||
CHANNEL *chan=channel_new(msg->session);
|
SSH_SESSION *session=msg->session;
|
||||||
chan->local_channel=ssh_channel_new_id(msg->session);
|
enter_function();
|
||||||
|
CHANNEL *chan=channel_new(session);
|
||||||
|
chan->local_channel=ssh_channel_new_id(session);
|
||||||
chan->local_maxpacket=35000;
|
chan->local_maxpacket=35000;
|
||||||
chan->local_window=32000;
|
chan->local_window=32000;
|
||||||
chan->remote_channel=msg->channel_request_open.sender;
|
chan->remote_channel=msg->channel_request_open.sender;
|
||||||
chan->remote_maxpacket=msg->channel_request_open.packet_size;
|
chan->remote_maxpacket=msg->channel_request_open.packet_size;
|
||||||
chan->remote_window=msg->channel_request_open.window;
|
chan->remote_window=msg->channel_request_open.window;
|
||||||
chan->open=1;
|
chan->open=1;
|
||||||
packet_clear_out(msg->session);
|
packet_clear_out(session);
|
||||||
buffer_add_u8(msg->session->out_buffer,SSH2_MSG_CHANNEL_OPEN_CONFIRMATION);
|
buffer_add_u8(session->out_buffer,SSH2_MSG_CHANNEL_OPEN_CONFIRMATION);
|
||||||
buffer_add_u32(msg->session->out_buffer,htonl(chan->remote_channel));
|
buffer_add_u32(session->out_buffer,htonl(chan->remote_channel));
|
||||||
buffer_add_u32(msg->session->out_buffer,htonl(chan->local_channel));
|
buffer_add_u32(session->out_buffer,htonl(chan->local_channel));
|
||||||
buffer_add_u32(msg->session->out_buffer,htonl(chan->local_window));
|
buffer_add_u32(session->out_buffer,htonl(chan->local_window));
|
||||||
buffer_add_u32(msg->session->out_buffer,htonl(chan->local_maxpacket));
|
buffer_add_u32(session->out_buffer,htonl(chan->local_maxpacket));
|
||||||
ssh_say(2,"Accepting a channel request_open for chan %d\n",chan->remote_channel);
|
ssh_say(2,"Accepting a channel request_open for chan %d\n",chan->remote_channel);
|
||||||
if(packet_send(msg->session)){
|
if(packet_send(session)){
|
||||||
channel_free(chan);
|
channel_free(chan);
|
||||||
|
leave_function();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
leave_function();
|
||||||
return chan;
|
return chan;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -219,6 +238,7 @@ static SSH_MESSAGE *handle_channel_request(SSH_SESSION *session){
|
|||||||
char *type_c;
|
char *type_c;
|
||||||
u8 want_reply;
|
u8 want_reply;
|
||||||
SSH_MESSAGE *msg=message_new(session);
|
SSH_MESSAGE *msg=message_new(session);
|
||||||
|
enter_function();
|
||||||
buffer_get_u32(session->in_buffer,&channel);
|
buffer_get_u32(session->in_buffer,&channel);
|
||||||
channel=ntohl(channel);
|
channel=ntohl(channel);
|
||||||
type=buffer_get_ssh_string(session->in_buffer);
|
type=buffer_get_ssh_string(session->in_buffer);
|
||||||
@@ -247,6 +267,7 @@ static SSH_MESSAGE *handle_channel_request(SSH_SESSION *session){
|
|||||||
msg->channel_request.pxwidth=ntohl(msg->channel_request.pxwidth);
|
msg->channel_request.pxwidth=ntohl(msg->channel_request.pxwidth);
|
||||||
msg->channel_request.pxheight=ntohl(msg->channel_request.pxheight);
|
msg->channel_request.pxheight=ntohl(msg->channel_request.pxheight);
|
||||||
msg->channel_request.modes=buffer_get_ssh_string(session->in_buffer);
|
msg->channel_request.modes=buffer_get_ssh_string(session->in_buffer);
|
||||||
|
leave_function();
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
if(!strcmp(type_c,"subsystem")){
|
if(!strcmp(type_c,"subsystem")){
|
||||||
@@ -257,10 +278,12 @@ static SSH_MESSAGE *handle_channel_request(SSH_SESSION *session){
|
|||||||
free(subsys);
|
free(subsys);
|
||||||
msg->channel_request.type=SSH_CHANNEL_REQUEST_SUBSYSTEM;
|
msg->channel_request.type=SSH_CHANNEL_REQUEST_SUBSYSTEM;
|
||||||
msg->channel_request.subsystem=subsys_c;
|
msg->channel_request.subsystem=subsys_c;
|
||||||
|
leave_function();
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
if(!strcmp(type_c,"shell")){
|
if(!strcmp(type_c,"shell")){
|
||||||
msg->channel_request.type=SSH_CHANNEL_REQUEST_SHELL;
|
msg->channel_request.type=SSH_CHANNEL_REQUEST_SHELL;
|
||||||
|
leave_function();
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
if(!strcmp(type_c,"exec")){
|
if(!strcmp(type_c,"exec")){
|
||||||
@@ -268,10 +291,12 @@ static SSH_MESSAGE *handle_channel_request(SSH_SESSION *session){
|
|||||||
msg->channel_request.type=SSH_CHANNEL_REQUEST_EXEC;
|
msg->channel_request.type=SSH_CHANNEL_REQUEST_EXEC;
|
||||||
msg->channel_request.command=string_to_char(cmd);
|
msg->channel_request.command=string_to_char(cmd);
|
||||||
free(cmd);
|
free(cmd);
|
||||||
|
leave_function();
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
msg->channel_request.type=SSH_CHANNEL_UNKNOWN;
|
msg->channel_request.type=SSH_CHANNEL_UNKNOWN;
|
||||||
|
leave_function();
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -310,34 +335,43 @@ static int ssh_message_channel_request_reply_default(SSH_MESSAGE *msg){
|
|||||||
}
|
}
|
||||||
|
|
||||||
SSH_MESSAGE *ssh_message_get(SSH_SESSION *session){
|
SSH_MESSAGE *ssh_message_get(SSH_SESSION *session){
|
||||||
|
SSH_MESSAGE *ret;
|
||||||
|
enter_function();
|
||||||
while(1){
|
while(1){
|
||||||
if(packet_read(session))
|
if(packet_read(session) || packet_translate(session)){
|
||||||
return NULL;
|
leave_function();
|
||||||
if(packet_translate(session))
|
return NULL;
|
||||||
return NULL;
|
}
|
||||||
switch(session->in_packet.type){
|
switch(session->in_packet.type){
|
||||||
case SSH2_MSG_SERVICE_REQUEST:
|
case SSH2_MSG_SERVICE_REQUEST:
|
||||||
if(handle_service_request(session))
|
if(handle_service_request(session)){
|
||||||
return NULL;
|
leave_function();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case SSH2_MSG_IGNORE:
|
case SSH2_MSG_IGNORE:
|
||||||
case SSH2_MSG_DEBUG:
|
case SSH2_MSG_DEBUG:
|
||||||
break;
|
break;
|
||||||
case SSH2_MSG_USERAUTH_REQUEST:
|
case SSH2_MSG_USERAUTH_REQUEST:
|
||||||
return handle_userauth_request(session);
|
ret = handle_userauth_request(session);
|
||||||
break;
|
leave_function();
|
||||||
|
return ret;
|
||||||
case SSH2_MSG_CHANNEL_OPEN:
|
case SSH2_MSG_CHANNEL_OPEN:
|
||||||
return handle_channel_request_open(session);
|
ret = handle_channel_request_open(session);
|
||||||
break;
|
leave_function();
|
||||||
|
return ret;
|
||||||
case SSH2_MSG_CHANNEL_REQUEST:
|
case SSH2_MSG_CHANNEL_REQUEST:
|
||||||
return handle_channel_request(session);
|
ret = handle_channel_request(session);
|
||||||
break;
|
leave_function();
|
||||||
|
return ret;
|
||||||
default:
|
default:
|
||||||
handle_unimplemented(session);
|
handle_unimplemented(session);
|
||||||
ssh_set_error(session,SSH_FATAL,"Unhandled message %d\n",session->in_packet.type);
|
ssh_set_error(session,SSH_FATAL,"Unhandled message %d\n",session->in_packet.type);
|
||||||
|
leave_function();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
leave_function();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -108,6 +108,8 @@ SSH_OPTIONS *ssh_options_copy(SSH_OPTIONS *opt){
|
|||||||
ret->timeout_usec=opt->timeout_usec;
|
ret->timeout_usec=opt->timeout_usec;
|
||||||
ret->ssh2allowed=opt->ssh2allowed;
|
ret->ssh2allowed=opt->ssh2allowed;
|
||||||
ret->ssh1allowed=opt->ssh1allowed;
|
ret->ssh1allowed=opt->ssh1allowed;
|
||||||
|
ret->log_function=opt->log_function;
|
||||||
|
ret->log_verbosity=opt->log_verbosity;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -406,6 +408,29 @@ void ssh_options_allow_ssh2(SSH_OPTIONS *opt, int allow){
|
|||||||
opt->ssh2allowed=0;
|
opt->ssh2allowed=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Default is a write on stderr
|
||||||
|
* \brief Change the writer callback for logging
|
||||||
|
* \param opt options structure
|
||||||
|
* \param callback a callback function for the printing
|
||||||
|
* \warning the message string may contain format string characters.
|
||||||
|
*/
|
||||||
|
void ssh_options_set_log_function(SSH_OPTIONS *opt,
|
||||||
|
void (*callback)(const char *message, SSH_SESSION *session, int priority )){
|
||||||
|
opt->log_function=callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \brief set this session's logging priority
|
||||||
|
* \param opt options structure
|
||||||
|
* \param verbosity verbosity of the messages. Every log smaller or equal to verbosity will be shown\n
|
||||||
|
* SSH_LOG_NOLOG No logging \n
|
||||||
|
* SSH_LOG_RARE Rare conditions or warnings\n
|
||||||
|
* SSH_LOG_ENTRY Api-accessible entrypoints\n
|
||||||
|
* SSH_LOG_PACKET Packet id and size\n
|
||||||
|
* SSH_LOG_FUNCTIONS function entering and leaving\n
|
||||||
|
*/
|
||||||
|
void ssh_options_set_log_verbosity(SSH_OPTIONS *opt, int verbosity){
|
||||||
|
opt->log_verbosity=verbosity;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* This is a helper for your application to generate the appropriate
|
* This is a helper for your application to generate the appropriate
|
||||||
* options from the command line arguments.\n
|
* options from the command line arguments.\n
|
||||||
@@ -502,7 +527,7 @@ int ssh_options_getopt(SSH_OPTIONS *options, int *argcptr, char **argv){
|
|||||||
ssh_set_error(options,SSH_FATAL,"either RSA or DSS must be chosen");
|
ssh_set_error(options,SSH_FATAL,"either RSA or DSS must be chosen");
|
||||||
cont=0;
|
cont=0;
|
||||||
}
|
}
|
||||||
ssh_set_verbosity(debuglevel);
|
ssh_options_set_log_verbosity(options,debuglevel);
|
||||||
optind=saveoptind;
|
optind=saveoptind;
|
||||||
if(!cont){
|
if(!cont){
|
||||||
free(save);
|
free(save);
|
||||||
|
109
libssh/packet.c
109
libssh/packet.c
@@ -33,13 +33,12 @@ MA 02111-1307, USA. */
|
|||||||
/* XXX include selected mac size */
|
/* XXX include selected mac size */
|
||||||
static int macsize=SHA_DIGEST_LEN;
|
static int macsize=SHA_DIGEST_LEN;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* in nonblocking mode, socket_read will read as much as it can, and return */
|
/* 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. */
|
/* 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. */
|
/* in blocking mode, it will read at least len bytes and will block until it's ok. */
|
||||||
|
|
||||||
static int socket_read(SSH_SESSION *session,int len){
|
static int socket_read(SSH_SESSION *session,int len){
|
||||||
|
enter_function();
|
||||||
int except, can_write;
|
int except, can_write;
|
||||||
int to_read;
|
int to_read;
|
||||||
int r;
|
int r;
|
||||||
@@ -48,8 +47,10 @@ static int socket_read(SSH_SESSION *session,int len){
|
|||||||
if(!session->in_socket_buffer)
|
if(!session->in_socket_buffer)
|
||||||
session->in_socket_buffer=buffer_new();
|
session->in_socket_buffer=buffer_new();
|
||||||
to_read=len - buffer_get_rest_len(session->in_socket_buffer);
|
to_read=len - buffer_get_rest_len(session->in_socket_buffer);
|
||||||
if(to_read <= 0)
|
if(to_read <= 0){
|
||||||
|
leave_function();
|
||||||
return SSH_OK;
|
return SSH_OK;
|
||||||
|
}
|
||||||
if(session->blocking){
|
if(session->blocking){
|
||||||
buf=malloc(to_read);
|
buf=malloc(to_read);
|
||||||
r=ssh_socket_completeread(session->socket,buf,to_read);
|
r=ssh_socket_completeread(session->socket,buf,to_read);
|
||||||
@@ -60,18 +61,22 @@ static int socket_read(SSH_SESSION *session,int len){
|
|||||||
ssh_socket_close(session->socket);
|
ssh_socket_close(session->socket);
|
||||||
session->alive=0;
|
session->alive=0;
|
||||||
session->data_except=1;
|
session->data_except=1;
|
||||||
|
leave_function();
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer_add_data(session->in_socket_buffer,buf,to_read);
|
buffer_add_data(session->in_socket_buffer,buf,to_read);
|
||||||
free(buf);
|
free(buf);
|
||||||
|
leave_function();
|
||||||
return SSH_OK;
|
return SSH_OK;
|
||||||
}
|
}
|
||||||
/* nonblocking read */
|
/* nonblocking read */
|
||||||
do {
|
do {
|
||||||
ssh_fd_poll(session,&can_write,&except); /* internally sets data_to_read */
|
ssh_fd_poll(session,&can_write,&except); /* internally sets data_to_read */
|
||||||
if(!session->data_to_read)
|
if(!session->data_to_read){
|
||||||
return SSH_AGAIN;
|
leave_function();
|
||||||
|
return SSH_AGAIN;
|
||||||
|
}
|
||||||
session->data_to_read=0;
|
session->data_to_read=0;
|
||||||
/* read as much as we can */
|
/* read as much as we can */
|
||||||
if(ssh_socket_is_open(session->socket))
|
if(ssh_socket_is_open(session->socket))
|
||||||
@@ -84,10 +89,12 @@ static int socket_read(SSH_SESSION *session,int len){
|
|||||||
ssh_socket_close(session->socket);
|
ssh_socket_close(session->socket);
|
||||||
session->data_except=1;
|
session->data_except=1;
|
||||||
session->alive=0;
|
session->alive=0;
|
||||||
|
leave_function();
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
buffer_add_data(session->in_socket_buffer,buffer,r);
|
buffer_add_data(session->in_socket_buffer,buffer,r);
|
||||||
} while(buffer_get_rest_len(session->in_socket_buffer)<len);
|
} while(buffer_get_rest_len(session->in_socket_buffer)<len);
|
||||||
|
leave_function();
|
||||||
return SSH_OK;
|
return SSH_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,8 +111,11 @@ static int packet_read2(SSH_SESSION *session){
|
|||||||
u8 padding;
|
u8 padding;
|
||||||
unsigned int blocksize=(session->current_crypto?session->current_crypto->in_cipher->blocksize:8);
|
unsigned int blocksize=(session->current_crypto?session->current_crypto->in_cipher->blocksize:8);
|
||||||
int current_macsize=session->current_crypto?macsize:0;
|
int current_macsize=session->current_crypto?macsize:0;
|
||||||
if(!session->alive || session->data_except)
|
enter_function();
|
||||||
|
if(!session->alive || session->data_except){
|
||||||
|
leave_function();
|
||||||
return SSH_ERROR; // the error message was already set into this session
|
return SSH_ERROR; // the error message was already set into this session
|
||||||
|
}
|
||||||
switch(session->packet_state){
|
switch(session->packet_state){
|
||||||
case PACKET_STATE_INIT:
|
case PACKET_STATE_INIT:
|
||||||
memset(&session->in_packet,0,sizeof(PACKET));
|
memset(&session->in_packet,0,sizeof(PACKET));
|
||||||
@@ -114,8 +124,10 @@ static int packet_read2(SSH_SESSION *session){
|
|||||||
else
|
else
|
||||||
session->in_buffer=buffer_new();
|
session->in_buffer=buffer_new();
|
||||||
ret=socket_read(session,blocksize);
|
ret=socket_read(session,blocksize);
|
||||||
if(ret != SSH_OK)
|
if(ret != SSH_OK){
|
||||||
return ret; // can be SSH_ERROR or SSH_AGAIN
|
leave_function();
|
||||||
|
return ret; // can be SSH_ERROR or SSH_AGAIN
|
||||||
|
}
|
||||||
// be_read=completeread(session->fd,buffer,blocksize);
|
// be_read=completeread(session->fd,buffer,blocksize);
|
||||||
memcpy(buffer,buffer_get_rest(session->in_socket_buffer),blocksize);
|
memcpy(buffer,buffer_get_rest(session->in_socket_buffer),blocksize);
|
||||||
buffer_pass_bytes(session->in_socket_buffer,blocksize); // mark them as read
|
buffer_pass_bytes(session->in_socket_buffer,blocksize); // mark them as read
|
||||||
@@ -123,12 +135,14 @@ static int packet_read2(SSH_SESSION *session){
|
|||||||
buffer_add_data(session->in_buffer,buffer,blocksize);
|
buffer_add_data(session->in_buffer,buffer,blocksize);
|
||||||
if(len> MAX_PACKET_LEN){
|
if(len> MAX_PACKET_LEN){
|
||||||
ssh_set_error(session,SSH_FATAL,"read_packet(): Packet len too high(%uld %.8lx)",len,len);
|
ssh_set_error(session,SSH_FATAL,"read_packet(): Packet len too high(%uld %.8lx)",len,len);
|
||||||
|
leave_function();
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
to_be_read=len-blocksize+sizeof(u32);
|
to_be_read=len-blocksize+sizeof(u32);
|
||||||
if(to_be_read<0){
|
if(to_be_read<0){
|
||||||
/* remote sshd sends invalid sizes?*/
|
/* remote sshd sends invalid sizes?*/
|
||||||
ssh_set_error(session,SSH_FATAL,"given numbers of bytes left to be read <0 (%d)!",to_be_read);
|
ssh_set_error(session,SSH_FATAL,"given numbers of bytes left to be read <0 (%d)!",to_be_read);
|
||||||
|
leave_function();
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
/* saves the status of the current operations */
|
/* saves the status of the current operations */
|
||||||
@@ -140,8 +154,10 @@ static int packet_read2(SSH_SESSION *session){
|
|||||||
/* if to_be_read is zero, the whole packet was blocksize bytes. */
|
/* if to_be_read is zero, the whole packet was blocksize bytes. */
|
||||||
if(to_be_read != 0){
|
if(to_be_read != 0){
|
||||||
ret=socket_read(session,to_be_read);
|
ret=socket_read(session,to_be_read);
|
||||||
if(ret!=SSH_OK)
|
if(ret!=SSH_OK){
|
||||||
return ret;
|
leave_function();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
packet=malloc(to_be_read);
|
packet=malloc(to_be_read);
|
||||||
memcpy(packet,buffer_get_rest(session->in_socket_buffer),to_be_read-current_macsize);
|
memcpy(packet,buffer_get_rest(session->in_socket_buffer),to_be_read-current_macsize);
|
||||||
buffer_pass_bytes(session->in_socket_buffer,to_be_read-current_macsize);
|
buffer_pass_bytes(session->in_socket_buffer,to_be_read-current_macsize);
|
||||||
@@ -157,6 +173,7 @@ static int packet_read2(SSH_SESSION *session){
|
|||||||
buffer_pass_bytes(session->in_socket_buffer,macsize);
|
buffer_pass_bytes(session->in_socket_buffer,macsize);
|
||||||
if(packet_hmac_verify(session,session->in_buffer,mac)){
|
if(packet_hmac_verify(session,session->in_buffer,mac)){
|
||||||
ssh_set_error(session,SSH_FATAL,"HMAC error");
|
ssh_set_error(session,SSH_FATAL,"HMAC error");
|
||||||
|
leave_function();
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -164,6 +181,7 @@ static int packet_read2(SSH_SESSION *session){
|
|||||||
/*pass the size which has been processed before*/
|
/*pass the size which has been processed before*/
|
||||||
if(!buffer_get_u8(session->in_buffer,&padding)){
|
if(!buffer_get_u8(session->in_buffer,&padding)){
|
||||||
ssh_set_error(session,SSH_FATAL,"Packet too short to read padding");
|
ssh_set_error(session,SSH_FATAL,"Packet too short to read padding");
|
||||||
|
leave_function();
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
ssh_say(3,"%hhd bytes padding, %d bytes left in buffer\n",
|
ssh_say(3,"%hhd bytes padding, %d bytes left in buffer\n",
|
||||||
@@ -175,6 +193,7 @@ static int packet_read2(SSH_SESSION *session){
|
|||||||
ssh_print_hexa("incrimined packet",
|
ssh_print_hexa("incrimined packet",
|
||||||
buffer_get(session->in_buffer),buffer_get_len(session->in_buffer));
|
buffer_get(session->in_buffer),buffer_get_len(session->in_buffer));
|
||||||
#endif
|
#endif
|
||||||
|
leave_function();
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
buffer_pass_bytes_end(session->in_buffer,padding);
|
buffer_pass_bytes_end(session->in_buffer,padding);
|
||||||
@@ -187,9 +206,11 @@ static int packet_read2(SSH_SESSION *session){
|
|||||||
#endif
|
#endif
|
||||||
session->recv_seq++;
|
session->recv_seq++;
|
||||||
session->packet_state=PACKET_STATE_INIT;
|
session->packet_state=PACKET_STATE_INIT;
|
||||||
|
leave_function();
|
||||||
return SSH_OK;
|
return SSH_OK;
|
||||||
}
|
}
|
||||||
ssh_set_error(session,SSH_FATAL,"Invalid state into packet_read2() : %d",session->packet_state);
|
ssh_set_error(session,SSH_FATAL,"Invalid state into packet_read2() : %d",session->packet_state);
|
||||||
|
leave_function();
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -306,16 +327,21 @@ int packet_read(SSH_SESSION *session){
|
|||||||
}
|
}
|
||||||
|
|
||||||
int packet_translate(SSH_SESSION *session){
|
int packet_translate(SSH_SESSION *session){
|
||||||
|
enter_function();
|
||||||
memset(&session->in_packet,0,sizeof(PACKET));
|
memset(&session->in_packet,0,sizeof(PACKET));
|
||||||
if(!session->in_buffer)
|
if(!session->in_buffer){
|
||||||
return -1;
|
leave_function();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
ssh_say(3,"Final size %d\n",buffer_get_rest_len(session->in_buffer));
|
ssh_say(3,"Final size %d\n",buffer_get_rest_len(session->in_buffer));
|
||||||
if(!buffer_get_u8(session->in_buffer,&session->in_packet.type)){
|
if(!buffer_get_u8(session->in_buffer,&session->in_packet.type)){
|
||||||
ssh_set_error(session,SSH_FATAL,"Packet too short to read type");
|
ssh_set_error(session,SSH_FATAL,"Packet too short to read type");
|
||||||
|
leave_function();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
ssh_say(3,"type %hhd\n",session->in_packet.type);
|
ssh_say(3,"type %hhd\n",session->in_packet.type);
|
||||||
session->in_packet.valid=1;
|
session->in_packet.valid=1;
|
||||||
|
leave_function();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -339,11 +365,13 @@ static int atomic_write(struct socket *s, void *buffer, int len){
|
|||||||
static int packet_nonblocking_flush(SSH_SESSION *session){
|
static int packet_nonblocking_flush(SSH_SESSION *session){
|
||||||
int except, can_write;
|
int except, can_write;
|
||||||
int w;
|
int w;
|
||||||
|
enter_function();
|
||||||
ssh_fd_poll(session,&can_write,&except); /* internally sets data_to_write */
|
ssh_fd_poll(session,&can_write,&except); /* internally sets data_to_write */
|
||||||
if(!ssh_socket_is_open(session->socket)){
|
if(!ssh_socket_is_open(session->socket)){
|
||||||
session->alive=0;
|
session->alive=0;
|
||||||
// FIXME use ssh_socket_get_errno
|
// FIXME use ssh_socket_get_errno
|
||||||
ssh_set_error(session,SSH_FATAL,"Writing packet : error on socket (or connection closed): %s",strerror(errno));
|
ssh_set_error(session,SSH_FATAL,"Writing packet : error on socket (or connection closed): %s",strerror(errno));
|
||||||
|
leave_function();
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
while(session->data_to_write && buffer_get_rest_len(session->out_socket_buffer)>0){
|
while(session->data_to_write && buffer_get_rest_len(session->out_socket_buffer)>0){
|
||||||
@@ -361,27 +389,37 @@ static int packet_nonblocking_flush(SSH_SESSION *session){
|
|||||||
// FIXME use ssh_socket_get_errno()
|
// FIXME use ssh_socket_get_errno()
|
||||||
ssh_set_error(session,SSH_FATAL,"Writing packet : error on socket (or connection closed): %s",
|
ssh_set_error(session,SSH_FATAL,"Writing packet : error on socket (or connection closed): %s",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
|
leave_function();
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
buffer_pass_bytes(session->out_socket_buffer,w);
|
buffer_pass_bytes(session->out_socket_buffer,w);
|
||||||
/* refresh the socket status */
|
/* refresh the socket status */
|
||||||
ssh_fd_poll(session,&can_write,&except);
|
ssh_fd_poll(session,&can_write,&except);
|
||||||
}
|
}
|
||||||
if(buffer_get_rest_len(session->out_socket_buffer)>0)
|
if(buffer_get_rest_len(session->out_socket_buffer)>0){
|
||||||
return SSH_AGAIN; /* there is data pending */
|
leave_function();
|
||||||
|
return SSH_AGAIN; /* there is data pending */
|
||||||
|
}
|
||||||
|
leave_function();
|
||||||
return SSH_OK; // all data written
|
return SSH_OK; // all data written
|
||||||
}
|
}
|
||||||
|
|
||||||
/* blocking packet flush */
|
/* blocking packet flush */
|
||||||
static int packet_blocking_flush(SSH_SESSION *session){
|
static int packet_blocking_flush(SSH_SESSION *session){
|
||||||
|
enter_function();
|
||||||
if(!ssh_socket_is_open(session->socket)) {
|
if(!ssh_socket_is_open(session->socket)) {
|
||||||
session->alive=0;
|
session->alive=0;
|
||||||
|
leave_function();
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
if(session->data_except)
|
if(session->data_except){
|
||||||
return SSH_ERROR;
|
leave_function();
|
||||||
if(buffer_get_rest(session->out_socket_buffer)==0)
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
if(buffer_get_rest(session->out_socket_buffer)==0){
|
||||||
|
leave_function();
|
||||||
return SSH_OK;
|
return SSH_OK;
|
||||||
|
}
|
||||||
if(atomic_write(session->socket,buffer_get_rest(session->out_socket_buffer),
|
if(atomic_write(session->socket,buffer_get_rest(session->out_socket_buffer),
|
||||||
buffer_get_rest_len(session->out_socket_buffer))){
|
buffer_get_rest_len(session->out_socket_buffer))){
|
||||||
session->data_to_write=0;
|
session->data_to_write=0;
|
||||||
@@ -391,10 +429,12 @@ static int packet_blocking_flush(SSH_SESSION *session){
|
|||||||
// FIXME use the proper errno
|
// FIXME use the proper errno
|
||||||
ssh_set_error(session,SSH_FATAL,"Writing packet : error on socket (or connection closed): %s",
|
ssh_set_error(session,SSH_FATAL,"Writing packet : error on socket (or connection closed): %s",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
|
leave_function();
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
session->data_to_write=0;
|
session->data_to_write=0;
|
||||||
buffer_reinit(session->out_socket_buffer);
|
buffer_reinit(session->out_socket_buffer);
|
||||||
|
leave_function();
|
||||||
return SSH_OK; // no data pending
|
return SSH_OK; // no data pending
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -410,15 +450,19 @@ int packet_flush(SSH_SESSION *session, int enforce_blocking){
|
|||||||
|
|
||||||
/* this function places the outgoing packet buffer into an outgoing socket buffer */
|
/* this function places the outgoing packet buffer into an outgoing socket buffer */
|
||||||
static int socket_write(SSH_SESSION *session){
|
static int socket_write(SSH_SESSION *session){
|
||||||
|
int ret;
|
||||||
|
enter_function();
|
||||||
if(!session->out_socket_buffer){
|
if(!session->out_socket_buffer){
|
||||||
session->out_socket_buffer=buffer_new();
|
session->out_socket_buffer=buffer_new();
|
||||||
}
|
}
|
||||||
buffer_add_data(session->out_socket_buffer,
|
buffer_add_data(session->out_socket_buffer,
|
||||||
buffer_get(session->out_buffer),buffer_get_len(session->out_buffer));
|
buffer_get(session->out_buffer),buffer_get_len(session->out_buffer));
|
||||||
if(!session->blocking){
|
if(!session->blocking)
|
||||||
return packet_nonblocking_flush(session);
|
ret = packet_nonblocking_flush(session);
|
||||||
} else
|
else
|
||||||
return packet_blocking_flush(session);
|
ret = packet_blocking_flush(session);
|
||||||
|
leave_function();
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int packet_send2(SSH_SESSION *session){
|
static int packet_send2(SSH_SESSION *session){
|
||||||
@@ -429,6 +473,7 @@ static int packet_send2(SSH_SESSION *session){
|
|||||||
unsigned char *hmac;
|
unsigned char *hmac;
|
||||||
int ret=0;
|
int ret=0;
|
||||||
unsigned int blocksize=(session->current_crypto?session->current_crypto->out_cipher->blocksize:8);
|
unsigned int blocksize=(session->current_crypto?session->current_crypto->out_cipher->blocksize:8);
|
||||||
|
enter_function();
|
||||||
ssh_say(3,"Writing on the wire a packet having %ld bytes before",currentlen);
|
ssh_say(3,"Writing on the wire a packet having %ld bytes before",currentlen);
|
||||||
#ifdef HAVE_LIBZ
|
#ifdef HAVE_LIBZ
|
||||||
if(session->current_crypto && session->current_crypto->do_compress_out){
|
if(session->current_crypto && session->current_crypto->do_compress_out){
|
||||||
@@ -455,6 +500,7 @@ static int packet_send2(SSH_SESSION *session){
|
|||||||
ret=socket_write(session);
|
ret=socket_write(session);
|
||||||
session->send_seq++;
|
session->send_seq++;
|
||||||
buffer_reinit(session->out_buffer);
|
buffer_reinit(session->out_buffer);
|
||||||
|
leave_function();
|
||||||
return ret; /* SSH_OK, AGAIN or ERROR */
|
return ret; /* SSH_OK, AGAIN or ERROR */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -611,16 +657,22 @@ static int packet_wait1(SSH_SESSION *session,int type,int blocking){
|
|||||||
#endif /* HAVE_SSH1 */
|
#endif /* HAVE_SSH1 */
|
||||||
static int packet_wait2(SSH_SESSION *session,int type,int blocking){
|
static int packet_wait2(SSH_SESSION *session,int type,int blocking){
|
||||||
int ret;
|
int ret;
|
||||||
|
enter_function();
|
||||||
while(1){
|
while(1){
|
||||||
ret=packet_read2(session);
|
ret=packet_read2(session);
|
||||||
if(ret != SSH_OK)
|
if(ret != SSH_OK){
|
||||||
return ret;
|
leave_function();
|
||||||
if(packet_translate(session))
|
return ret;
|
||||||
|
}
|
||||||
|
if(packet_translate(session)){
|
||||||
|
leave_function();
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
switch(session->in_packet.type){
|
switch(session->in_packet.type){
|
||||||
case SSH2_MSG_DISCONNECT:
|
case SSH2_MSG_DISCONNECT:
|
||||||
packet_parse(session);
|
packet_parse(session);
|
||||||
ssh_say(2,"received disconnect packet\n");
|
ssh_say(2,"received disconnect packet\n");
|
||||||
|
leave_function();
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
case SSH2_MSG_CHANNEL_WINDOW_ADJUST:
|
case SSH2_MSG_CHANNEL_WINDOW_ADJUST:
|
||||||
case SSH2_MSG_CHANNEL_DATA:
|
case SSH2_MSG_CHANNEL_DATA:
|
||||||
@@ -635,13 +687,18 @@ static int packet_wait2(SSH_SESSION *session,int type,int blocking){
|
|||||||
default:
|
default:
|
||||||
if(type && (type != session->in_packet.type)){
|
if(type && (type != session->in_packet.type)){
|
||||||
ssh_set_error(session,SSH_FATAL,"waitpacket(): Received a %d type packet, was waiting for a %d\n",session->in_packet.type,type);
|
ssh_set_error(session,SSH_FATAL,"waitpacket(): Received a %d type packet, was waiting for a %d\n",session->in_packet.type,type);
|
||||||
|
leave_function();
|
||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
|
leave_function();
|
||||||
return SSH_OK;
|
return SSH_OK;
|
||||||
}
|
}
|
||||||
if(blocking==0)
|
if(blocking==0){
|
||||||
return SSH_OK; //shouldn't it return SSH_AGAIN here ?
|
leave_function();
|
||||||
|
return SSH_OK; //shouldn't it return SSH_AGAIN here ?
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
leave_function();
|
||||||
return SSH_OK;
|
return SSH_OK;
|
||||||
}
|
}
|
||||||
int packet_wait(SSH_SESSION *session, int type, int block){
|
int packet_wait(SSH_SESSION *session, int type, int block){
|
||||||
|
@@ -44,10 +44,12 @@ SSH_SESSION *ssh_new() {
|
|||||||
session->socket=ssh_socket_new();
|
session->socket=ssh_socket_new();
|
||||||
session->alive=0;
|
session->alive=0;
|
||||||
session->blocking=1;
|
session->blocking=1;
|
||||||
|
session->log_indent=0;
|
||||||
return session;
|
return session;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ssh_cleanup(SSH_SESSION *session){
|
void ssh_cleanup(SSH_SESSION *session){
|
||||||
|
enter_function();
|
||||||
int i;
|
int i;
|
||||||
if(session->serverbanner)
|
if(session->serverbanner)
|
||||||
free(session->serverbanner);
|
free(session->serverbanner);
|
||||||
@@ -95,15 +97,19 @@ void ssh_cleanup(SSH_SESSION *session){
|
|||||||
memset(session,'X',sizeof(SSH_SESSION)); /* burn connection, it could hangs
|
memset(session,'X',sizeof(SSH_SESSION)); /* burn connection, it could hangs
|
||||||
sensitive datas */
|
sensitive datas */
|
||||||
free(session);
|
free(session);
|
||||||
|
//leave_function();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \brief disconnect impolitely from remote host
|
/** \brief disconnect impolitely from remote host
|
||||||
* \param session current ssh session
|
* \param session current ssh session
|
||||||
*/
|
*/
|
||||||
void ssh_silent_disconnect(SSH_SESSION *session){
|
void ssh_silent_disconnect(SSH_SESSION *session){
|
||||||
|
enter_function();
|
||||||
|
ssh_log(session,SSH_LOG_ENTRY,"ssh_silent_disconnect()");
|
||||||
ssh_socket_close(session->socket);
|
ssh_socket_close(session->socket);
|
||||||
session->alive=0;
|
session->alive=0;
|
||||||
ssh_disconnect(session);
|
ssh_disconnect(session);
|
||||||
|
//leave_function();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \brief set the options for the current session
|
/** \brief set the options for the current session
|
||||||
@@ -114,6 +120,7 @@ void ssh_silent_disconnect(SSH_SESSION *session){
|
|||||||
*/
|
*/
|
||||||
void ssh_set_options(SSH_SESSION *session, SSH_OPTIONS *options){
|
void ssh_set_options(SSH_SESSION *session, SSH_OPTIONS *options){
|
||||||
session->options=options;
|
session->options=options;
|
||||||
|
session->log_verbosity=options->log_verbosity;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \brief set the session in blocking/nonblocking mode
|
/** \brief set the session in blocking/nonblocking mode
|
||||||
@@ -163,16 +170,22 @@ void ssh_set_fd_except(SSH_SESSION *session){
|
|||||||
/* looks if there is data to read on the socket and parse it. */
|
/* looks if there is data to read on the socket and parse it. */
|
||||||
int ssh_handle_packets(SSH_SESSION *session){
|
int ssh_handle_packets(SSH_SESSION *session){
|
||||||
int w,err,r,i=0;
|
int w,err,r,i=0;
|
||||||
|
enter_function();
|
||||||
do {
|
do {
|
||||||
r=ssh_fd_poll(session,&w,&err);
|
r=ssh_fd_poll(session,&w,&err);
|
||||||
if(r<=0)
|
if(r<=0){
|
||||||
|
leave_function();
|
||||||
return r; // error or no data available
|
return r; // error or no data available
|
||||||
|
}
|
||||||
/* if an exception happened, it will be trapped by packet_read() */
|
/* if an exception happened, it will be trapped by packet_read() */
|
||||||
if(packet_read(session)||packet_translate(session))
|
if(packet_read(session)||packet_translate(session)){
|
||||||
return -1;
|
leave_function();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
packet_parse(session);
|
packet_parse(session);
|
||||||
++i;
|
++i;
|
||||||
} while(r>0 && i<5);
|
} while(r>0 && i<5);
|
||||||
|
leave_function();
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -42,6 +42,8 @@ MA 02111-1307, USA. */
|
|||||||
/* can fetch it, while continuing to read for other messages (it is inspecified in which order messages may */
|
/* can fetch it, while continuing to read for other messages (it is inspecified in which order messages may */
|
||||||
/* be sent back to the client */
|
/* be sent back to the client */
|
||||||
|
|
||||||
|
#define sftp_enter_function() _enter_function(sftp->channel->session)
|
||||||
|
#define sftp_leave_function() _leave_function(sftp->channel->session)
|
||||||
|
|
||||||
/* functions */
|
/* functions */
|
||||||
void sftp_enqueue(SFTP_SESSION *session, SFTP_MESSAGE *msg);
|
void sftp_enqueue(SFTP_SESSION *session, SFTP_MESSAGE *msg);
|
||||||
@@ -49,18 +51,22 @@ static void sftp_message_free(SFTP_MESSAGE *msg);
|
|||||||
|
|
||||||
SFTP_SESSION *sftp_new(SSH_SESSION *session){
|
SFTP_SESSION *sftp_new(SSH_SESSION *session){
|
||||||
SFTP_SESSION *sftp=malloc(sizeof(SFTP_SESSION));
|
SFTP_SESSION *sftp=malloc(sizeof(SFTP_SESSION));
|
||||||
|
enter_function();
|
||||||
memset(sftp,0,sizeof(SFTP_SESSION));
|
memset(sftp,0,sizeof(SFTP_SESSION));
|
||||||
sftp->session=session;
|
sftp->session=session;
|
||||||
sftp->channel=channel_new(session);
|
sftp->channel=channel_new(session);
|
||||||
if(channel_open_session(sftp->channel)){
|
if(channel_open_session(sftp->channel)){
|
||||||
channel_free(sftp->channel);
|
channel_free(sftp->channel);
|
||||||
free(sftp);
|
free(sftp);
|
||||||
|
leave_function();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if(channel_request_sftp(sftp->channel)){
|
if(channel_request_sftp(sftp->channel)){
|
||||||
sftp_free(sftp);
|
sftp_free(sftp);
|
||||||
|
leave_function();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
leave_function();
|
||||||
return sftp;
|
return sftp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,11 +144,13 @@ int sftp_packet_write(SFTP_SESSION *sftp,u8 type, BUFFER *payload){
|
|||||||
SFTP_PACKET *sftp_packet_read(SFTP_SESSION *sftp){
|
SFTP_PACKET *sftp_packet_read(SFTP_SESSION *sftp){
|
||||||
SFTP_PACKET *packet=malloc(sizeof(SFTP_PACKET));
|
SFTP_PACKET *packet=malloc(sizeof(SFTP_PACKET));
|
||||||
u32 size;
|
u32 size;
|
||||||
|
sftp_enter_function();
|
||||||
packet->sftp=sftp;
|
packet->sftp=sftp;
|
||||||
packet->payload=buffer_new();
|
packet->payload=buffer_new();
|
||||||
if(channel_read(sftp->channel,packet->payload,4,0)<=0){
|
if(channel_read(sftp->channel,packet->payload,4,0)<=0){
|
||||||
buffer_free(packet->payload);
|
buffer_free(packet->payload);
|
||||||
free(packet);
|
free(packet);
|
||||||
|
sftp_leave_function();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
buffer_get_u32(packet->payload,&size);
|
buffer_get_u32(packet->payload,&size);
|
||||||
@@ -150,6 +158,7 @@ SFTP_PACKET *sftp_packet_read(SFTP_SESSION *sftp){
|
|||||||
if(channel_read(sftp->channel,packet->payload,1,0)<=0){
|
if(channel_read(sftp->channel,packet->payload,1,0)<=0){
|
||||||
buffer_free(packet->payload);
|
buffer_free(packet->payload);
|
||||||
free(packet);
|
free(packet);
|
||||||
|
sftp_leave_function();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
buffer_get_u8(packet->payload,&packet->type);
|
buffer_get_u8(packet->payload,&packet->type);
|
||||||
@@ -157,8 +166,10 @@ SFTP_PACKET *sftp_packet_read(SFTP_SESSION *sftp){
|
|||||||
if(channel_read(sftp->channel,packet->payload,size-1,0)<=0){
|
if(channel_read(sftp->channel,packet->payload,size-1,0)<=0){
|
||||||
buffer_free(packet->payload);
|
buffer_free(packet->payload);
|
||||||
free(packet);
|
free(packet);
|
||||||
|
sftp_leave_function();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
sftp_leave_function();
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -196,17 +207,23 @@ SFTP_MESSAGE *sftp_get_message(SFTP_PACKET *packet){
|
|||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sftp_read_and_dispatch(SFTP_SESSION *session){
|
int sftp_read_and_dispatch(SFTP_SESSION *sftp){
|
||||||
SFTP_PACKET *packet;
|
SFTP_PACKET *packet;
|
||||||
SFTP_MESSAGE *message=NULL;
|
SFTP_MESSAGE *message=NULL;
|
||||||
packet=sftp_packet_read(session);
|
sftp_enter_function();
|
||||||
if(!packet)
|
packet=sftp_packet_read(sftp);
|
||||||
return -1; /* something nasty happened reading the packet */
|
if(!packet){
|
||||||
|
sftp_leave_function();
|
||||||
|
return -1; /* something nasty happened reading the packet */
|
||||||
|
}
|
||||||
message=sftp_get_message(packet);
|
message=sftp_get_message(packet);
|
||||||
sftp_packet_free(packet);
|
sftp_packet_free(packet);
|
||||||
if(!message)
|
if(!message){
|
||||||
return -1;
|
sftp_leave_function();
|
||||||
sftp_enqueue(session,message);
|
return -1;
|
||||||
|
}
|
||||||
|
sftp_enqueue(sftp,message);
|
||||||
|
sftp_leave_function();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -222,15 +239,19 @@ int sftp_init(SFTP_SESSION *sftp){
|
|||||||
STRING *ext_name_s=NULL, *ext_data_s=NULL;
|
STRING *ext_name_s=NULL, *ext_data_s=NULL;
|
||||||
char *ext_name,*ext_data;
|
char *ext_name,*ext_data;
|
||||||
u32 version=htonl(LIBSFTP_VERSION);
|
u32 version=htonl(LIBSFTP_VERSION);
|
||||||
|
sftp_enter_function();
|
||||||
buffer_add_u32(buffer,version);
|
buffer_add_u32(buffer,version);
|
||||||
sftp_packet_write(sftp,SSH_FXP_INIT,buffer);
|
sftp_packet_write(sftp,SSH_FXP_INIT,buffer);
|
||||||
buffer_free(buffer);
|
buffer_free(buffer);
|
||||||
packet=sftp_packet_read(sftp);
|
packet=sftp_packet_read(sftp);
|
||||||
if(!packet)
|
if(!packet){
|
||||||
return -1;
|
sftp_leave_function();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
if(packet->type != SSH_FXP_VERSION){
|
if(packet->type != SSH_FXP_VERSION){
|
||||||
ssh_set_error(sftp->session,SSH_FATAL,"Received a %d messages instead of SSH_FXP_VERSION",packet->type);
|
ssh_set_error(sftp->session,SSH_FATAL,"Received a %d messages instead of SSH_FXP_VERSION",packet->type);
|
||||||
sftp_packet_free(packet);
|
sftp_packet_free(packet);
|
||||||
|
sftp_leave_function();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
buffer_get_u32(packet->payload,&version);
|
buffer_get_u32(packet->payload,&version);
|
||||||
@@ -250,6 +271,7 @@ int sftp_init(SFTP_SESSION *sftp){
|
|||||||
free(ext_data_s);
|
free(ext_data_s);
|
||||||
sftp_packet_free(packet);
|
sftp_packet_free(packet);
|
||||||
sftp->version=sftp->server_version=version;
|
sftp->version=sftp->server_version=version;
|
||||||
|
sftp_leave_function();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user