aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/libssh/libssh.h4
-rw-r--r--include/libssh/priv.h27
-rw-r--r--include/libssh/server.h24
-rw-r--r--libssh/error.c23
-rw-r--r--libssh/options.c1
-rw-r--r--libssh/server.c99
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 */
+*/
+