1 /* server.c */ 2 3 /* No. It doesn't work yet. It's just hard to have 2 separated trees, one for releases 4 * and one for development */ 5 /* 6 Copyright 2004 Aris Adamantiadis 7 8 This file is part of the SSH Library 9 10 The SSH Library is free software; you can redistribute it and/or modify 11 it under the terms of the GNU Lesser General Public License as published by 12 the Free Software Foundation; either version 2.1 of the License, or (at your 13 option) any later version. 14 15 The SSH Library is distributed in the hope that it will be useful, but 16 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 17 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 18 License for more details. 19 20 You should have received a copy of the GNU Lesser General Public License 21 along with the SSH Library; see the file COPYING. If not, write to 22 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, 23 MA 02111-1307, USA. */ 24 25 /* from times to times, you need to serve your friends */ 26 /* and, perhaps, ssh connections. */ 27 28 #include "libssh/priv.h" 29 30 #ifdef WITH_SERVER 31 32 #include <fcntl.h> 33 #include <unistd.h> 34 #include <stdio.h> 35 #include <sys/types.h> 36 #ifdef HAVE_SYS_SOCKET_H 37 #include <sys/socket.h> 38 #endif 39 #ifdef HAVE_NETDB_H 40 #include <netdb.h> 41 #endif 42 #include <errno.h> 43 #include <string.h> 44 #include "libssh/libssh.h" 45 #include "libssh/server.h" 46 47 int bind_socket() { 48 struct sockaddr_in myaddr; 49 int opt = 1; 50 int s; 51 52 ssh_net_init(); 53 54 s = socket(PF_INET, SOCK_STREAM, 0); 55 memset(&myaddr, 0, sizeof(myaddr)); 56 myaddr.sin_family = AF_INET; 57 myaddr.sin_port = htons(2222); 58 setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); 59 if (bind(s, (struct sockaddr *) &myaddr, sizeof(myaddr)) < 0) { 60 ssh_set_error(NULL, SSH_FATAL, "%s", strerror(errno)); 61 return -1; 62 } 63 /* ok, bound */ 64 return s; 65 } 66 67 int listen_socket(int socket) { 68 int i = listen(socket, 1); 69 if (i < 0) 70 ssh_set_error(NULL, SSH_FATAL, "listening on %d : %s", 71 strerror(errno)); 72 return i; 73 } 74 75 int accept_socket(int socket) { 76 int i = accept(socket, NULL, NULL); 77 if (i < 0) 78 ssh_set_error(NULL, SSH_FATAL, "accepting client on socket %d : %s", 79 strerror(errno)); 80 return i; 81 } 82 83 84 SSH_SESSION *getserver(SSH_OPTIONS * options) { 85 int socket; 86 int fd; 87 SSH_SESSION *session; 88 socket = bind_socket(); 89 if (socket < 0) 90 return NULL; 91 if (listen_socket(socket) < 0) 92 return NULL; 93 fd = accept_socket(socket); 94 close(socket); 95 if (fd < 0) { 96 return NULL; 97 } 98 session = malloc(sizeof(SSH_SESSION)); 99 memset(session, 0, sizeof(SSH_SESSION)); 100 session->fd = fd; 101 session->options = options; 102 ssh_send_banner(session); 103 return session; 104 } 105 106 extern char *supported_methods[]; 107 int server_set_kex(SSH_SESSION * session) { 108 KEX *server = &session->server_kex; 109 SSH_OPTIONS *options = session->options; 110 int i; 111 char *wanted; 112 if (!options) { 113 ssh_set_error((session->connected ? session : NULL), SSH_FATAL, 114 "Options structure is null(client's bug)"); 115 return -1; 116 } 117 memset(server,0,sizeof(KEX)); 118 /* the program might ask for a specific cookie to be sent. useful for server 119 debugging */ 120 if (options->wanted_cookie) 121 memcpy(server->cookie, options->wanted_cookie, 16); 122 else 123 ssh_get_random(server->cookie, 16); 124 server->methods = malloc(10 * sizeof(char **)); 125 for (i = 0; i < 10; i++) { 126 if (!(wanted = options->wanted_methods[i])) 127 wanted = supported_methods[i]; 128 server->methods[i] = wanted; 129 printf("server->methods[%d]=%s\n",i,wanted); 130 if (!server->methods[i]) { 131 ssh_set_error((session->connected ? session : NULL), SSH_FATAL, 132 "kex error : did not find algo"); 133 return -1; 134 } 135 } 136 return 0; 137 138 } 139 140 #endif /* HAVE_SERVER */ |