aboutsummaryrefslogtreecommitdiff
path: root/libssh/client.c
diff options
context:
space:
mode:
Diffstat (limited to 'libssh/client.c')
-rw-r--r--libssh/client.c73
1 files changed, 59 insertions, 14 deletions
diff --git a/libssh/client.c b/libssh/client.c
index d8dffcc6..f06a7363 100644
--- a/libssh/client.c
+++ b/libssh/client.c
@@ -34,20 +34,26 @@ MA 02111-1307, USA. */
char *ssh_get_banner(SSH_SESSION *session){
char buffer[128];
int i = 0;
+ char *ret;
+ enter_function();
while (i < 127) {
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");
+ leave_function();
return NULL;
}
if (buffer[i] == '\r')
buffer[i] = 0;
if (buffer[i] == '\n') {
buffer[i] = 0;
- return strdup(buffer);
+ ret= strdup(buffer);
+ leave_function();
+ return ret;
}
i++;
}
ssh_set_error(session,SSH_FATAL,"Too large banner");
+ leave_function();
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){
char *banner;
char buffer[128];
+ enter_function();
banner=session->version==1?CLIENTBANNER1:CLIENTBANNER2;
if(session->options->banner)
banner=session->options->banner;
@@ -98,6 +105,7 @@ int ssh_send_banner(SSH_SESSION *session,int server){
session->clientbanner=strdup(banner);
snprintf(buffer,128,"%s\r\n",banner);
ssh_socket_write(session->socket,buffer,strlen(buffer));
+ leave_function();
return 0;
}
@@ -110,6 +118,7 @@ int ssh_send_banner(SSH_SESSION *session,int server){
static int dh_handshake(SSH_SESSION *session){
STRING *e,*f,*pubkey,*signature;
int ret;
+ enter_function();
switch(session->dh_handshake_state){
case DH_STATE_INIT:
packet_clear_out(session);
@@ -121,32 +130,41 @@ static int dh_handshake(SSH_SESSION *session){
ret=packet_send(session);
free(e);
session->dh_handshake_state=DH_STATE_INIT_TO_SEND;
- if(ret==SSH_ERROR)
+ if(ret==SSH_ERROR){
+ leave_function();
return ret;
+ }
case DH_STATE_INIT_TO_SEND:
ret=packet_flush(session,0);
- if(ret!=SSH_OK)
- return ret; // SSH_ERROR or SSH_AGAIN
+ if(ret!=SSH_OK){
+ leave_function();
+ return ret; // SSH_ERROR or SSH_AGAIN
+ }
session->dh_handshake_state=DH_STATE_INIT_SENT;
case DH_STATE_INIT_SENT:
ret=packet_wait(session,SSH2_MSG_KEXDH_REPLY,1);
- if(ret != SSH_OK)
- return ret;
+ if(ret != SSH_OK){
+ leave_function();
+ return ret;
+ }
pubkey=buffer_get_ssh_string(session->in_buffer);
if(!pubkey){
ssh_set_error(session,SSH_FATAL,"No public key in packet");
+ leave_function();
return SSH_ERROR;
}
dh_import_pubkey(session,pubkey);
f=buffer_get_ssh_string(session->in_buffer);
if(!f){
ssh_set_error(session,SSH_FATAL,"No F number in packet");
+ leave_function();
return SSH_ERROR;
}
dh_import_f(session,f);
free(f);
if(!(signature=buffer_get_ssh_string(session->in_buffer))){
ssh_set_error(session,SSH_FATAL,"No signature in packet");
+ leave_function();
return SSH_ERROR;
}
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;
case DH_STATE_NEWKEYS_TO_SEND:
ret=packet_flush(session,0);
- if(ret != SSH_OK)
- return ret;
+ if(ret != SSH_OK){
+ leave_function();
+ return ret;
+ }
ssh_say(2,"SSH_MSG_NEWKEYS sent\n");
session->dh_handshake_state=DH_STATE_NEWKEYS_SENT;
case DH_STATE_NEWKEYS_SENT:
ret=packet_wait(session,SSH2_MSG_NEWKEYS,1);
- if(ret != SSH_OK)
- return ret;
+ if(ret != SSH_OK){
+ leave_function();
+ return ret;
+ }
ssh_say(2,"Got SSH_MSG_NEWKEYS\n");
make_sessionid(session);
/* set the cryptographic functions for the next crypto */
/* (it is needed for generate_session_keys for key lenghts) */
- if(crypt_set_algorithms(session))
- return SSH_ERROR;
+ if(crypt_set_algorithms(session)){
+ leave_function();
+ return SSH_ERROR;
+ }
generate_session_keys(session);
/* verify the host's signature. XXX do it sooner */
signature=session->dh_server_signature;
session->dh_server_signature=NULL;
if(signature_verify(session,signature)){
free(signature);
+ leave_function();
return SSH_ERROR;
}
free(signature); /* forget it for now ... */
@@ -188,17 +213,21 @@ static int dh_handshake(SSH_SESSION *session){
session->current_crypto=session->next_crypto;
session->next_crypto=crypto_new();
session->dh_handshake_state=DH_STATE_FINISHED;
+ leave_function();
return SSH_OK;
default:
ssh_set_error(session,SSH_FATAL,"Invalid state in dh_handshake():%d",session->dh_handshake_state);
+ leave_function();
return SSH_ERROR;
}
/* not reached */
+ leave_function();
return SSH_ERROR;
}
int ssh_service_request(SSH_SESSION *session,char *service){
STRING *service_s;
+ enter_function();
packet_clear_out(session);
buffer_add_u8(session->out_buffer,SSH2_MSG_SERVICE_REQUEST);
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);
if(packet_wait(session,SSH2_MSG_SERVICE_ACCEPT,1)){
ssh_set_error(session,SSH_FATAL,"did not receive SERVICE_ACCEPT");
+ leave_function();
return -1;
}
ssh_say(3,"Received SSH_MSG_SERVICE_ACCEPT (service %s)\n",service);
+ leave_function();
return 0;
}
@@ -231,12 +262,14 @@ int ssh_connect(SSH_SESSION *session){
ssh_set_error(session,SSH_FATAL,"Must set options before connect");
return SSH_ERROR;
}
+ enter_function();
session->alive=0;
session->client=1;
ssh_crypto_init();
ssh_socket_init();
if(options->fd==-1 && !options->host){
ssh_set_error(session,SSH_FATAL,"Hostname required");
+ leave_function();
return SSH_ERROR;
}
if(options->fd != -1)
@@ -244,14 +277,17 @@ int ssh_connect(SSH_SESSION *session){
else
fd=ssh_connect_host(session,options->host,options->bindaddr,options->port,
options->timeout,options->timeout_usec);
- if(fd<0)
- return -1;
+ if(fd<0){
+ leave_function();
+ return -1;
+ }
set_status(options,0.2);
ssh_socket_set_fd(session->socket,fd);
session->alive=1;
if(!(session->serverbanner=ssh_get_banner(session))){
ssh_socket_close(session->socket);
session->alive=0;
+ leave_function();
return -1;
}
set_status(options,0.4);
@@ -260,6 +296,7 @@ int ssh_connect(SSH_SESSION *session){
if(ssh_analyze_banner(session,&ssh1,&ssh2)){
ssh_socket_close(session->socket);
session->alive=0;
+ leave_function();
return -1;
}
/* here we decide which version of the protocol to use */
@@ -273,6 +310,7 @@ int ssh_connect(SSH_SESSION *session){
session->serverbanner);
ssh_socket_close(session->socket);
session->alive=0;
+ leave_function();
return -1;
}
ssh_send_banner(session,0);
@@ -282,6 +320,7 @@ int ssh_connect(SSH_SESSION *session){
if(ssh_get_kex(session,0)){
ssh_socket_close(session->socket);
session->alive=0;
+ leave_function();
return -1;
}
set_status(options,0.6);
@@ -289,6 +328,7 @@ int ssh_connect(SSH_SESSION *session){
if(set_kex(session)){
ssh_socket_close(session->socket);
session->alive=0;
+ leave_function();
return -1;
}
ssh_send_kex(session,0);
@@ -296,6 +336,7 @@ int ssh_connect(SSH_SESSION *session){
if(dh_handshake(session)){
ssh_socket_close(session->socket);
session->alive=0;
+ leave_function();
return -1;
}
set_status(options,1.0);
@@ -305,12 +346,14 @@ int ssh_connect(SSH_SESSION *session){
if(ssh_get_kex1(session)){
ssh_socket_close(session->socket);
session->alive=0;
+ leave_function();
return -1;
}
set_status(options,0.6);
session->connected=1;
break;
}
+ leave_function();
return 0;
}
@@ -331,6 +374,7 @@ char *ssh_get_issue_banner(SSH_SESSION *session){
*/
void ssh_disconnect(SSH_SESSION *session){
STRING *str;
+ enter_function();
if(ssh_socket_is_open(session->socket)) {
packet_clear_out(session);
buffer_add_u8(session->out_buffer,SSH2_MSG_DISCONNECT);
@@ -342,6 +386,7 @@ void ssh_disconnect(SSH_SESSION *session){
ssh_socket_close(session->socket);
}
session->alive=0;
+ leave_function();
ssh_cleanup(session);
}