diff options
-rw-r--r-- | include/libssh/libssh.h | 4 | ||||
-rw-r--r-- | include/libssh/priv.h | 27 | ||||
-rw-r--r-- | include/libssh/server.h | 24 | ||||
-rw-r--r-- | libssh/error.c | 23 | ||||
-rw-r--r-- | libssh/options.c | 1 | ||||
-rw-r--r-- | libssh/server.c | 99 |
6 files changed, 130 insertions, 48 deletions
diff --git a/include/libssh/libssh.h b/include/libssh/libssh.h index 9e3495b8..0fc40178 100644 --- a/include/libssh/libssh.h +++ b/include/libssh/libssh.h @@ -91,8 +91,8 @@ typedef u_int8_t u8; #define SSH_EINTR 3 -char *ssh_get_error(SSH_SESSION *session); -int ssh_get_error_code(SSH_SESSION *session); +char *ssh_get_error(void *error); +int ssh_get_error_code(void *error); void ssh_say(int priority,char *format,...); void ssh_set_verbosity(int num); diff --git a/include/libssh/priv.h b/include/libssh/priv.h index 5899fb6a..4c5b9d30 100644 --- a/include/libssh/priv.h +++ b/include/libssh/priv.h @@ -223,12 +223,23 @@ struct channel_struct { int blocking; }; + +struct error_struct { +/* error handling */ + int error_code; + char error_buffer[ERROR_BUFFERLEN]; +}; + + struct ssh_session { + struct error_struct error; int fd; SSH_OPTIONS *options; char *serverbanner; char *clientbanner; int protoversion; + int server; + int client; u32 send_seq; u32 recv_seq; /* status flags */ @@ -272,9 +283,6 @@ struct ssh_session { int exec_channel_opened; /* version 1 only. more info in channels1.c */ -/* error handling */ - int error_code; - char error_buffer[ERROR_BUFFERLEN]; /* keyb interactive data */ struct ssh_kbdint *kbdint; int version; /* 1 or 2 */ @@ -294,7 +302,7 @@ void ssh_cleanup(SSH_SESSION *session); /* errors.c */ -void ssh_set_error(SSH_SESSION *session,int code,char *descr,...); +void ssh_set_error(void *error,int code,char *descr,...); /* in dh.c */ /* DH key generation */ @@ -360,12 +368,15 @@ void channel_handle(SSH_SESSION *session, int type); CHANNEL *channel_new(SSH_SESSION *session); void channel_default_bufferize(CHANNEL *channel, void *data, int len, int is_stderr); + + /* options.c */ -void options_free(SSH_OPTIONS *opt); + +void ssh_options_free(SSH_OPTIONS *opt); /* this function must be called when no specific username has been asked. it has to guess it */ -int options_default_username(SSH_OPTIONS *opt); -int options_default_ssh_dir(SSH_OPTIONS *opt); -int options_default_known_hosts_file(SSH_OPTIONS *opt); +int ssh_options_default_username(SSH_OPTIONS *opt); +int ssh_options_default_ssh_dir(SSH_OPTIONS *opt); +int ssh_options_default_known_hosts_file(SSH_OPTIONS *opt); /* buffer.c */ void buffer_add_ssh_string(BUFFER *buffer,STRING *string); diff --git a/include/libssh/server.h b/include/libssh/server.h index 90c280ee..8e68f137 100644 --- a/include/libssh/server.h +++ b/include/libssh/server.h @@ -20,12 +20,28 @@ MA 02111-1307, USA. */ #ifndef SERVER_H #define SERVER_H -/* the client banner doesn't say hey! look i'm a client ! */ + #include "libssh/libssh.h" +#include "libssh/priv.h" #define SERVERBANNER CLIENTBANNER -int bind_socket(); -int listen_socket(int s); -int accept_socket(int s); +struct ssh_bind_struct { + struct error_struct error; + int bindfd; + SSH_OPTIONS *options; + int blocking; + int toaccept; +}; + +typedef struct ssh_bind_struct SSH_BIND; + +SSH_BIND *ssh_bind_new(); +void ssh_bind_set_options(SSH_BIND *ssh_bind, SSH_OPTIONS *options); +int ssh_bind_listen(SSH_BIND *ssh_bind); +void ssh_bind_set_blocking(SSH_BIND *ssh_bind,int blocking); +int ssh_bind_get_fd(SSH_BIND *ssh_bind); +int ssh_bind_set_toaccept(SSH_BIND *ssh_bind); +SSH_SESSION *ssh_bind_accept(SSH_BIND *ssh_bind); + #endif diff --git a/libssh/error.c b/libssh/error.c index f3db7948..78a7ea12 100644 --- a/libssh/error.c +++ b/libssh/error.c @@ -27,20 +27,23 @@ MA 02111-1307, USA. */ static int verbosity; /* ssh_set_error registers an error with a description. the error code is the class of error, and description is obvious.*/ -void ssh_set_error(SSH_SESSION *session,int code,char *descr,...){ - va_list va; - va_start(va,descr); - vsnprintf(session->error_buffer,ERROR_BUFFERLEN,descr,va); - va_end(va); - session->error_code=code; +void ssh_set_error(void *error,int code,char *descr,...){ + struct error_struct *err= error; + va_list va; + va_start(va,descr); + vsnprintf(err->error_buffer,ERROR_BUFFERLEN,descr,va); + va_end(va); + err->error_code=code; } -char *ssh_get_error(SSH_SESSION *session){ - return session->error_buffer; +char *ssh_get_error(void *error){ + struct error_struct *err=error; + return err->error_buffer; } -int ssh_get_error_code(SSH_SESSION *session){ - return session->error_code; +int ssh_get_error_code(void *error){ + struct error_struct *err=error; + return err->error_code; } void ssh_say(int priority, char *format,...){ diff --git a/libssh/options.c b/libssh/options.c index 17d9d3df..1de36256 100644 --- a/libssh/options.c +++ b/libssh/options.c @@ -35,6 +35,7 @@ SSH_OPTIONS *ssh_options_new(){ option->fd=-1; option->ssh2allowed=1; option->ssh1allowed=0; + option->bindport=22; return option; } diff --git a/libssh/server.c b/libssh/server.c index 8bfe209d..134ffbee 100644 --- a/libssh/server.c +++ b/libssh/server.c @@ -25,8 +25,6 @@ MA 02111-1307, USA. */ /* from times to times, you need to serve your friends */ /* and, perhaps, ssh connections. */ -#ifdef WITH_SERVER - #include <fcntl.h> #include <unistd.h> #include <stdio.h> @@ -37,40 +35,92 @@ MA 02111-1307, USA. */ #include <string.h> #include "libssh/libssh.h" #include "libssh/server.h" - -int bind_socket() { +static int bind_socket(char *hostname, int port) { struct sockaddr_in myaddr; int opt = 1; int s = socket(PF_INET, SOCK_STREAM, 0); + struct hostent *hp=NULL; +#ifdef HAVE_GETHOSTBYADDR + hp=gethostbyaddr(hostname,4,AF_INET); +#endif +#ifdef HAVE_GETHOSTBYNAME + if(!hp) + hp=gethostbyname(hostname); +#endif + if(!hp){ + close(s); + return -1; + } + memset(&myaddr, 0, sizeof(myaddr)); - myaddr.sin_family = AF_INET; - myaddr.sin_port = htons(2222); + memcpy(&myaddr.sin_addr,hp->h_addr,hp->h_length); + myaddr.sin_family=hp->h_addrtype; + myaddr.sin_port = htons(port); setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); if (bind(s, (struct sockaddr *) &myaddr, sizeof(myaddr)) < 0) { - ssh_set_error(NULL, SSH_FATAL, "%s", strerror(errno)); - return -1; + close(s); + return -1; } - /* ok, bound */ return s; } -int listen_socket(int socket) { - int i = listen(socket, 1); - if (i < 0) - ssh_set_error(NULL, SSH_FATAL, "listening on %d : %s", - strerror(errno)); - return i; +SSH_BIND *ssh_bind_new(){ + SSH_BIND *ptr=malloc(sizeof(SSH_BIND)); + memset(ptr,0,sizeof(*ptr)); + ptr->bindfd=-1; + return ptr; +} + +void ssh_bind_set_options(SSH_BIND *ssh_bind, SSH_OPTIONS *options){ + ssh_bind->options=options; +} + +int ssh_bind_listen(SSH_BIND *ssh_bind){ + char *host; + int fd; + if(!ssh_bind->options) + return -1; + host=ssh_bind->options->bindaddr; + if(!host) + host="0.0.0.0"; + fd=bind_socket(host,ssh_bind->options->bindport); + if(fd<0) + return -1; + ssh_bind->bindfd=fd; + if(listen(fd,10)<0){ + close(fd); + return -1; + } + return 0; +} + +void ssh_bind_set_blocking(SSH_BIND *ssh_bind, int blocking){ + ssh_bind->blocking=blocking?1:0; } -int accept_socket(int socket) { - int i = accept(socket, NULL, NULL); - if (i < 0) - ssh_set_error(NULL, SSH_FATAL, "accepting client on socket %d : %s", - strerror(errno)); - return i; +int ssh_bind_get_fd(SSH_BIND *ssh_bind){ + return ssh_bind->bindfd; } +void ssh_bind_fd_toaccept(SSH_BIND *ssh_bind){ + ssh_bind->toaccept=1; +} +SSH_SESSION *ssh_bind_accept(SSH_BIND *ssh_bind){ + SSH_SESSION *session; + if(ssh_bind->bindfd<0) + return NULL; + int fd=accept(ssh_bind->bindfd,NULL,NULL); + if(fd<0) + return NULL; + session=ssh_new(ssh_options_copy(ssh_bind->options)); + session->server=1; + session->fd=fd; + return session; +} + +/* + SSH_SESSION *getserver(SSH_OPTIONS * options) { int socket; int fd; @@ -105,8 +155,8 @@ int server_set_kex(SSH_SESSION * session) { return -1; } memset(server,0,sizeof(KEX)); - /* the program might ask for a specific cookie to be sent. useful for server - debugging */ + // the program might ask for a specific cookie to be sent. useful for server + // debugging if (options->wanted_cookie) memcpy(server->cookie, options->wanted_cookie, 16); else @@ -125,4 +175,5 @@ int server_set_kex(SSH_SESSION * session) { return 0; } -#endif /* HAVE_SERVER */ +*/ + |