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 #ifdef WITH_SERVER 29 30 #include <fcntl.h> 31 #include <unistd.h> 32 #include <stdio.h> 33 #include <sys/types.h> 34 #include <sys/socket.h> 35 #include <netdb.h> 36 #include <errno.h> 37 #include <string.h> 38 #include "libssh/libssh.h" 39 #include "libssh/server.h" 40 41 int bind_socket() { 42 struct sockaddr_in myaddr; 43 int opt = 1; 44 int s = socket(PF_INET, SOCK_STREAM, 0); 45 memset(&myaddr, 0, sizeof(myaddr)); 46 myaddr.sin_family = AF_INET; 47 myaddr.sin_port = htons(2222); 48 setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); 49 if (bind(s, (struct sockaddr *) &myaddr, sizeof(myaddr)) < 0) { 50 ssh_set_error(NULL, SSH_FATAL, "%s", strerror(errno)); 51 return -1; 52 } 53 /* ok, bound */ 54 return s; 55 } 56 57 int listen_socket(int socket) { 58 int i = listen(socket, 1); 59 if (i < 0) 60 ssh_set_error(NULL, SSH_FATAL, "listening on %d : %s", 61 strerror(errno)); 62 return i; 63 } 64 65 int accept_socket(int socket) { 66 int i = accept(socket, NULL, NULL); 67 if (i < 0) 68 ssh_set_error(NULL, SSH_FATAL, "accepting client on socket %d : %s", 69 strerror(errno)); 70 return i; 71 } 72 73 74 SSH_SESSION *getserver(SSH_OPTIONS * options) { 75 int socket; 76 int fd; 77 SSH_SESSION *session; 78 socket = bind_socket(); 79 if (socket < 0) 80 return NULL; 81 if (listen_socket(socket) < 0) 82 return NULL; 83 fd = accept_socket(socket); 84 close(socket); 85 if (fd < 0) { 86 return NULL; 87 } 88 session = malloc(sizeof(SSH_SESSION)); 89 memset(session, 0, sizeof(SSH_SESSION)); 90 session->fd = fd; 91 session->options = options; 92 ssh_send_banner(session); 93 return session; 94 } 95 96 extern char *supported_methods[]; 97 int server_set_kex(SSH_SESSION * session) { 98 KEX *server = &session->server_kex; 99 SSH_OPTIONS *options = session->options; 100 int i; 101 char *wanted; 102 if (!options) { 103 ssh_set_error((session->connected ? session : NULL), SSH_FATAL, 104 "Options structure is null(client's bug)"); 105 return -1; 106 } 107 memset(server,0,sizeof(KEX)); 108 /* the program might ask for a specific cookie to be sent. useful for server 109 debugging */ 110 if (options->wanted_cookie) 111 memcpy(server->cookie, options->wanted_cookie, 16); 112 else 113 ssh_get_random(server->cookie, 16); 114 server->methods = malloc(10 * sizeof(char **)); 115 for (i = 0; i < 10; i++) { 116 if (!(wanted = options->wanted_methods[i])) 117 wanted = supported_methods[i]; 118 server->methods[i] = wanted; 119 printf("server->methods[%d]=%s\n",i,wanted); 120 if (!server->methods[i]) { 121 ssh_set_error((session->connected ? session : NULL), SSH_FATAL, 122 "kex error : did not find algo"); 123 return -1; 124 } 125 return 0; 126 } 127 128 #endif /* HAVE_SERVER */ |