1
0
mirror of https://git.libssh.org/projects/libssh.git synced 2025-12-02 01:17:52 +03:00

Trying to adapt client.c to use callbacks

This commit is contained in:
Aris Adamantiadis
2009-12-03 23:55:46 +01:00
parent 4924ac8099
commit 2f6fbbd706
2 changed files with 84 additions and 47 deletions

View File

@@ -27,6 +27,17 @@
typedef struct ssh_kbdint_struct* ssh_kbdint; typedef struct ssh_kbdint_struct* ssh_kbdint;
/* These are the different states a SSH session can be into its life */
enum ssh_session_state_e {
SSH_SESSION_STATE_NONE,
SSH_SESSION_STATE_CONNECTING,
SSH_SESSION_STATE_SOCKET_CONNECTED,
SSH_SESSION_STATE_BANNER_RECEIVED,
SSH_SESSION_STATE_INITIAL_KEX,
SSH_SESSION_STATE_AUTHENTICATED,
SSH_SESSION_STATE_ERROR
};
struct ssh_session_struct { struct ssh_session_struct {
struct error_struct error; struct error_struct error;
struct socket *socket; struct socket *socket;
@@ -63,6 +74,7 @@ struct ssh_session_struct {
/* the states are used by the nonblocking stuff to remember */ /* the states are used by the nonblocking stuff to remember */
/* where it was before being interrupted */ /* where it was before being interrupted */
enum ssh_session_state_e session_state;
int packet_state; int packet_state;
int dh_handshake_state; int dh_handshake_state;
ssh_string dh_server_signature; //information used by dh_handshake. ssh_string dh_server_signature; //information used by dh_handshake.

View File

@@ -44,52 +44,71 @@
/** /**
* @internal * @internal
* * @brief Callback to be called when the socket is connected or had a
* @brief Get a banner from a socket. * connection error. Changes the state of the session and updates the error
* * message.
* The caller has to free memroy. * @param code one of SSH_SOCKET_CONNECTED_OK or SSH_SOCKET_CONNECTED_ERROR
* * @param user is a pointer to session
* @param session The session to get the banner from.
*
* @return A newly allocated string with the banner or NULL on error.
*/ */
char *ssh_get_banner(ssh_session session) { static void socket_callback_connected(int code, int errno, void *user){
char buffer[128] = {0}; ssh_session session=(ssh_session)user;
enter_function();
ssh_log(session,SSH_LOG_RARE,"Socket connection callback: %d (%d)",code, errno);
if(code == SSH_SOCKET_CONNECTED_OK)
session->session_state=SSH_SESSION_STATE_SOCKET_CONNECTED;
else {
session->session_state=SSH_SESSION_STATE_ERROR;
ssh_set_error(session,SSH_FATAL,"Connection failed: %s",strerror(errno));
}
leave_function();
}
/**
* @internal
*
* @brief Gets the banner from socket and saves it in session.
* Updates the session state
*
* @param data pointer to the begining of header
* @param len size of the banner
* @param user is a pointer to session
* @returns Number of bytes processed, or zero if the banner is not complete.
*/
static int callback_receive_banner(const void *data, size_t len, void *user) {
char *buffer = (char *)data;
ssh_session session=(ssh_session) user;
char *str = NULL; char *str = NULL;
int i; size_t i;
int ret=0;
enter_function(); enter_function();
for(i=0;i<len;++i){
for (i = 0; i < 127; i++) {
if (ssh_socket_read(session->socket, &buffer[i], 1) != SSH_OK) {
ssh_set_error(session, SSH_FATAL, "Remote host closed connection");
leave_function();
return NULL;
}
#ifdef WITH_PCAP #ifdef WITH_PCAP
if(session->pcap_ctx && buffer[i] == '\n'){ if(session->pcap_ctx && buffer[i] == '\n'){
ssh_pcap_context_write(session->pcap_ctx,SSH_PCAP_DIR_IN,buffer,i+1,i+1); ssh_pcap_context_write(session->pcap_ctx,SSH_PCAP_DIR_IN,buffer,i+1,i+1);
} }
#endif #endif
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'; str=strdup(buffer);
str = strdup(buffer); /* number of bytes read */
if (str == NULL) { ret=i+1;
leave_function(); session->remotebanner=str;
return NULL; session->session_state=SSH_SESSION_STATE_BANNER_RECEIVED;
} leave_function();
leave_function(); return ret;
return str; }
} if(i>127){
/* Too big banner */
session->session_state=SSH_SESSION_STATE_ERROR;
ssh_set_error(session,SSH_FATAL,"Receiving banner: too large banner");
leave_function();
return 0;
}
} }
ssh_set_error(session, SSH_FATAL, "Too large banner");
leave_function(); leave_function();
return NULL; return ret;
} }
/** /**
@@ -484,7 +503,7 @@ int ssh_service_request(ssh_session session, const char *service) {
int ssh_connect(ssh_session session) { int ssh_connect(ssh_session session) {
int ssh1 = 0; int ssh1 = 0;
int ssh2 = 0; int ssh2 = 0;
int fd = -1; int ret;
if (session == NULL) { if (session == NULL) {
ssh_set_error(session, SSH_FATAL, "Invalid session pointer"); ssh_set_error(session, SSH_FATAL, "Invalid session pointer");
@@ -505,20 +524,26 @@ int ssh_connect(ssh_session session) {
leave_function(); leave_function();
return SSH_ERROR; return SSH_ERROR;
} }
session->session_state=SSH_SESSION_STATE_CONNECTING;
ssh_socket_set_callbacks(session->socket,&session->socket_callbacks);
session->socket_callbacks.connected=socket_callback_connected;
session->socket_callbacks.data=callback_receive_banner;
session->socket_callbacks.user=session;
if (session->fd != -1) { if (session->fd != -1) {
fd = session->fd; ssh_socket_set_fd(session->socket, session->fd);
ret=SSH_OK;
} else { } else {
fd = ssh_connect_host(session, session->host, session->bindaddr, ret=ssh_socket_connect(session->socket, session->host, session->port,
session->port, session->timeout, session->timeout_usec); session->bindaddr);
//, session->timeout * 1000 + session->timeout_usec);
} }
if (fd < 0) { if (ret != SSH_OK) {
leave_function(); leave_function();
return SSH_ERROR; return SSH_ERROR;
} }
set_status(session, 0.2); set_status(session, 0.2);
ssh_socket_set_fd(session->socket, fd);
session->alive = 1; session->alive = 1;
session->serverbanner = ssh_get_banner(session); session->serverbanner = ssh_get_banner(session);
if (session->serverbanner == NULL) { if (session->serverbanner == NULL) {
@@ -697,7 +722,7 @@ error:
} }
const char *ssh_copyright(void) { const char *ssh_copyright(void) {
return SSH_STRINGIFY(LIBSSH_VERSION) " (c) 2003-2008 Aris Adamantiadis " return SSH_STRINGIFY(LIBSSH_VERSION) " (c) 2003-2010 Aris Adamantiadis "
"(aris@0xbadc0de.be) Distributed under the LGPL, please refer to COPYING" "(aris@0xbadc0de.be) Distributed under the LGPL, please refer to COPYING"
"file for informations about your rights"; "file for informations about your rights";
} }