aboutsummaryrefslogtreecommitdiff
path: root/libssh/server.c
diff options
context:
space:
mode:
Diffstat (limited to 'libssh/server.c')
-rw-r--r--libssh/server.c128
1 files changed, 128 insertions, 0 deletions
diff --git a/libssh/server.c b/libssh/server.c
new file mode 100644
index 00000000..8bfe209d
--- /dev/null
+++ b/libssh/server.c
@@ -0,0 +1,128 @@
+/* server.c */
+
+/* No. It doesn't work yet. It's just hard to have 2 separated trees, one for releases
+ * and one for development */
+/*
+Copyright 2004 Aris Adamantiadis
+
+This file is part of the SSH Library
+
+The SSH Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or (at your
+option) any later version.
+
+The SSH Library is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the SSH Library; see the file COPYING. If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+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>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <errno.h>
+#include <string.h>
+#include "libssh/libssh.h"
+#include "libssh/server.h"
+
+int bind_socket() {
+ struct sockaddr_in myaddr;
+ int opt = 1;
+ int s = socket(PF_INET, SOCK_STREAM, 0);
+ memset(&myaddr, 0, sizeof(myaddr));
+ myaddr.sin_family = AF_INET;
+ myaddr.sin_port = htons(2222);
+ 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;
+ }
+ /* 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;
+}
+
+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;
+}
+
+
+SSH_SESSION *getserver(SSH_OPTIONS * options) {
+ int socket;
+ int fd;
+ SSH_SESSION *session;
+ socket = bind_socket();
+ if (socket < 0)
+ return NULL;
+ if (listen_socket(socket) < 0)
+ return NULL;
+ fd = accept_socket(socket);
+ close(socket);
+ if (fd < 0) {
+ return NULL;
+ }
+ session = malloc(sizeof(SSH_SESSION));
+ memset(session, 0, sizeof(SSH_SESSION));
+ session->fd = fd;
+ session->options = options;
+ ssh_send_banner(session);
+ return session;
+}
+
+extern char *supported_methods[];
+int server_set_kex(SSH_SESSION * session) {
+ KEX *server = &session->server_kex;
+ SSH_OPTIONS *options = session->options;
+ int i;
+ char *wanted;
+ if (!options) {
+ ssh_set_error(session, SSH_FATAL,
+ "Options structure is null(client's bug)");
+ return -1;
+ }
+ memset(server,0,sizeof(KEX));
+ /* 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
+ ssh_get_random(server->cookie, 16);
+ server->methods = malloc(10 * sizeof(char **));
+ for (i = 0; i < 10; i++) {
+ if (!(wanted = options->wanted_methods[i]))
+ wanted = supported_methods[i];
+ server->methods[i] = wanted;
+ printf("server->methods[%d]=%s\n",i,wanted);
+ if (!server->methods[i]) {
+ ssh_set_error(session, SSH_FATAL,
+ "kex error : did not find algo");
+ return -1;
+ }
+ return 0;
+}
+
+#endif /* HAVE_SERVER */