mirror of
https://git.libssh.org/projects/libssh.git
synced 2026-02-11 18:50:28 +09:00
Add more error checks to ssh_connect().
git-svn-id: svn+ssh://svn.berlios.de/svnroot/repos/libssh/trunk@487 7dcaeef0-15fb-0310-b436-a5af3365683c
This commit is contained in:
215
libssh/client.c
215
libssh/client.c
@@ -406,113 +406,152 @@ int ssh_service_request(SSH_SESSION *session, const char *service) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** \addtogroup ssh_session
|
/** \addtogroup ssh_session
|
||||||
* * @{ */
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
/** \brief connect to the ssh server
|
/** \brief connect to the ssh server
|
||||||
* \param session ssh session
|
* \param session ssh session
|
||||||
* \return 0 on success, SSH_ERROR on error
|
* \return SSH_OK on success, SSH_ERROR on error
|
||||||
* \see ssh_new()
|
* \see ssh_new()
|
||||||
* \see ssh_disconnect()
|
* \see ssh_disconnect()
|
||||||
*/
|
*/
|
||||||
int ssh_connect(SSH_SESSION *session){
|
int ssh_connect(SSH_SESSION *session) {
|
||||||
int fd;
|
SSH_OPTIONS *options = session->options;
|
||||||
int ssh1, ssh2;
|
int ssh1 = 0;
|
||||||
SSH_OPTIONS *options=session->options;
|
int ssh2 = 0;
|
||||||
if(!session->options){
|
int fd = -1;
|
||||||
ssh_set_error(session,SSH_FATAL,"Must set options before connect");
|
|
||||||
return SSH_ERROR;
|
if (session == NULL) {
|
||||||
|
ssh_set_error(session, SSH_FATAL, "Invalid session pointer");
|
||||||
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (session->options == NULL) {
|
||||||
|
ssh_set_error(session, SSH_FATAL, "No options set");
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
options = session->options;
|
||||||
|
|
||||||
enter_function();
|
enter_function();
|
||||||
session->alive=0;
|
|
||||||
session->client=1;
|
session->alive = 0;
|
||||||
|
session->client = 1;
|
||||||
|
|
||||||
ssh_crypto_init();
|
ssh_crypto_init();
|
||||||
ssh_socket_init();
|
ssh_socket_init();
|
||||||
if(options->fd==-1 && !options->host){
|
|
||||||
ssh_set_error(session,SSH_FATAL,"Hostname required");
|
if (options->fd == -1 && options->host == NULL) {
|
||||||
leave_function();
|
ssh_set_error(session, SSH_FATAL, "Hostname required");
|
||||||
return SSH_ERROR;
|
leave_function();
|
||||||
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
if(options->fd != -1)
|
if (options->fd != -1) {
|
||||||
fd=options->fd;
|
fd = options->fd;
|
||||||
else
|
} else {
|
||||||
fd=ssh_connect_host(session,options->host,options->bindaddr,options->port,
|
fd = ssh_connect_host(session, options->host, options->bindaddr,
|
||||||
options->timeout,options->timeout_usec);
|
options->port, options->timeout, options->timeout_usec);
|
||||||
if(fd<0){
|
|
||||||
leave_function();
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
set_status(options,0.2);
|
if (fd < 0) {
|
||||||
ssh_socket_set_fd(session->socket,fd);
|
leave_function();
|
||||||
session->alive=1;
|
return SSH_ERROR;
|
||||||
if(!(session->serverbanner=ssh_get_banner(session))){
|
|
||||||
ssh_socket_close(session->socket);
|
|
||||||
session->alive=0;
|
|
||||||
leave_function();
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
set_status(options,0.4);
|
set_status(options, 0.2);
|
||||||
ssh_log(session, SSH_LOG_RARE, "banner: %s\n", session->serverbanner);
|
|
||||||
/* here we analyse the different protocols the server allows */
|
ssh_socket_set_fd(session->socket, fd);
|
||||||
if(ssh_analyze_banner(session,&ssh1,&ssh2)){
|
|
||||||
ssh_socket_close(session->socket);
|
session->alive = 1;
|
||||||
session->alive=0;
|
session->serverbanner = ssh_get_banner(session);
|
||||||
leave_function();
|
if (session->serverbanner == NULL) {
|
||||||
return -1;
|
ssh_socket_close(session->socket);
|
||||||
|
session->alive = 0;
|
||||||
|
leave_function();
|
||||||
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
/* here we decide which version of the protocol to use */
|
set_status(options, 0.4);
|
||||||
if(ssh2 && options->ssh2allowed)
|
|
||||||
session->version=2;
|
ssh_log(session, SSH_LOG_RARE,
|
||||||
else if(ssh1 && options->ssh1allowed)
|
"SSH server banner: %s", session->serverbanner);
|
||||||
session->version=1;
|
|
||||||
else {
|
/* Here we analyse the different protocols the server allows. */
|
||||||
ssh_set_error(session,SSH_FATAL,
|
if (ssh_analyze_banner(session, &ssh1, &ssh2) < 0) {
|
||||||
"no version of SSH protocol usable (banner: %s)",
|
ssh_socket_close(session->socket);
|
||||||
|
session->alive = 0;
|
||||||
|
leave_function();
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Here we decide which version of the protocol to use. */
|
||||||
|
if (ssh2 && options->ssh2allowed) {
|
||||||
|
session->version = 2;
|
||||||
|
} else if(ssh1 && options->ssh1allowed) {
|
||||||
|
session->version = 1;
|
||||||
|
} else {
|
||||||
|
ssh_set_error(session, SSH_FATAL,
|
||||||
|
"No version of SSH protocol usable (banner: %s)",
|
||||||
session->serverbanner);
|
session->serverbanner);
|
||||||
|
ssh_socket_close(session->socket);
|
||||||
|
session->alive = 0;
|
||||||
|
leave_function();
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ssh_send_banner(session, 0) < 0) {
|
||||||
|
ssh_set_error(session, SSH_FATAL, "Sending the banner failed");
|
||||||
|
ssh_socket_close(session->socket);
|
||||||
|
session->alive = 0;
|
||||||
|
leave_function();
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
set_status(options, 0.5);
|
||||||
|
|
||||||
|
switch (session->version) {
|
||||||
|
case 2:
|
||||||
|
if (ssh_get_kex(session,0) < 0) {
|
||||||
ssh_socket_close(session->socket);
|
ssh_socket_close(session->socket);
|
||||||
session->alive=0;
|
session->alive = 0;
|
||||||
leave_function();
|
leave_function();
|
||||||
return -1;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
ssh_send_banner(session,0);
|
set_status(options,0.6);
|
||||||
set_status(options,0.5);
|
|
||||||
switch(session->version){
|
ssh_list_kex(session, &session->server_kex);
|
||||||
case 2:
|
if (set_kex(session) < 0) {
|
||||||
if(ssh_get_kex(session,0) < 0) {
|
ssh_socket_close(session->socket);
|
||||||
ssh_socket_close(session->socket);
|
session->alive = 0;
|
||||||
session->alive=0;
|
leave_function();
|
||||||
leave_function();
|
return SSH_ERROR;
|
||||||
return -1;
|
}
|
||||||
}
|
if (ssh_send_kex(session, 0) < 0) {
|
||||||
set_status(options,0.6);
|
ssh_socket_close(session->socket);
|
||||||
ssh_list_kex(session, &session->server_kex);
|
session->alive = 0;
|
||||||
if(set_kex(session)){
|
leave_function();
|
||||||
ssh_socket_close(session->socket);
|
return SSH_ERROR;
|
||||||
session->alive=0;
|
}
|
||||||
leave_function();
|
set_status(options,0.8);
|
||||||
return -1;
|
|
||||||
}
|
if (dh_handshake(session) < 0) {
|
||||||
ssh_send_kex(session,0);
|
ssh_socket_close(session->socket);
|
||||||
set_status(options,0.8);
|
session->alive = 0;
|
||||||
if(dh_handshake(session)){
|
leave_function();
|
||||||
ssh_socket_close(session->socket);
|
return SSH_ERROR;
|
||||||
session->alive=0;
|
}
|
||||||
leave_function();
|
set_status(options,1.0);
|
||||||
return -1;
|
|
||||||
}
|
session->connected = 1;
|
||||||
set_status(options,1.0);
|
break;
|
||||||
session->connected=1;
|
|
||||||
break;
|
|
||||||
case 1:
|
case 1:
|
||||||
if(ssh_get_kex1(session)){
|
if (ssh_get_kex1(session) < 0) {
|
||||||
ssh_socket_close(session->socket);
|
ssh_socket_close(session->socket);
|
||||||
session->alive=0;
|
session->alive = 0;
|
||||||
leave_function();
|
leave_function();
|
||||||
return -1;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
set_status(options,0.6);
|
set_status(options,0.6);
|
||||||
session->connected=1;
|
|
||||||
break;
|
session->connected = 1;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
leave_function();
|
leave_function();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user