int main(void) { char host[256]; /* * Bouncer: get hold of a machine. */ buflen = 0; if (do_connection ("mono.org", 99)) strcpy (host, "electron.mono.org"); else { char *p = buffer, *q = buffer; buffer[buflen] = '\0'; while (*p && *p != ' ' && *p != '\n' && *p != '\r') p++; if (*p == ' ') { q = ++p; while (*p && *p != '\n' && *p != '\r') p++; } *p = '\0'; strcpy (host, q); } buflen = -1; debugfd = open("logfile", O_WRONLY | O_CREAT | O_TRUNC, 0666); return do_connection(host, -1); }
static void do_listen(char *port) { struct addrinfo hints; struct addrinfo *result, *rp; int sfd, s, cfd; struct sockaddr_storage peer_addr; socklen_t peer_addr_len; int pid; if (!debug) signal_setup(SIGCHLD, clean_up); memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; s = getaddrinfo(NULL, port, &hints, &result); if (s != 0) pdie("getaddrinfo: error opening %s", port); for (rp = result; rp != NULL; rp = rp->ai_next) { sfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); if (sfd < 0) continue; if (bind(sfd, rp->ai_addr, rp->ai_addrlen) == 0) break; close(sfd); } if (rp == NULL) pdie("Could not bind"); freeaddrinfo(result); if (listen(sfd, backlog) < 0) pdie("listen"); peer_addr_len = sizeof(peer_addr); do { cfd = accept(sfd, (struct sockaddr *)&peer_addr, &peer_addr_len); printf("connected!\n"); if (cfd < 0 && errno == EINTR) continue; if (cfd < 0) pdie("connecting"); pid = do_connection(cfd, &peer_addr, peer_addr_len); if (pid > 0) add_process(pid); } while (!done); kill_clients(); }
static void do_toxic(Tox *m, ToxWindow *prompt) { pthread_mutex_lock(&Winthread.lock); do_connection(m, prompt); do_file_senders(m); tox_do(m); /* main tox-core loop */ pthread_mutex_unlock(&Winthread.lock); }
static gboolean glib_main (gpointer data) { xmlDoc *doc = NULL; xmlNode *root_element = NULL; struct connection conn; static struct start_network_data start_network_data; if (!(start_network_data.client = nm_client_new())) { network_status (NULL, "Unable to connect to NetworkManager"); g_main_loop_quit (loop); return FALSE; } g_timeout_add_seconds (2, do_timeout, &start_network_data); start_network_data.should_quit = TRUE; /*parse the file and get the DOM */ if( NULL == (doc = xmlReadFile(NETWORK_CONFIG, NULL, 0))) { network_status (start_network_data.client, "error: Could not parse " NETWORK_CONFIG "\n"); g_main_loop_quit (loop); return FALSE; } /*Get the root element node */ root_element = xmlDocGetRootElement(doc); if (root_element->type == XML_ELEMENT_NODE && !strcmp((char *)root_element->name, "configuration")) { gchar *err = read_connection(&conn, root_element); if (err) { gchar err2[1024]; g_snprintf(err2, sizeof(err2), "Unable to parse configuration data: %s", err); network_status (start_network_data.client, err2); g_main_loop_quit (loop); return FALSE; } } else { network_status (start_network_data.client, "error: Invalid " NETWORK_CONFIG " file: No <configuration/> root node\n"); g_main_loop_quit (loop); return FALSE; } xmlFreeDoc(doc); xmlCleanupParser(); /* Generate the UUID from the connection information */ generate_uuid(&conn, start_network_data.uuid, sizeof(start_network_data.uuid)); /* Hand control over to do_connection. Execution will continue in callbacks. */ do_connection(&start_network_data); return FALSE; }
static void do_toxic(Tox *m, ToxWindow *prompt) { do_connection(m, prompt); draw_active_window(m); do_file_senders(m); /* main tox-core loop */ tox_do(m); }
int main(void) { int loop; /* setenv("GAM_CLIENT_ID", "test-id", 0); */ for (loop = 0; loop < 1; loop++) do_connection(); return (0); }
TCPConnection::TCPConnection( Service & service, asio::io_service & io_service, const std::string & address, const std::string & port ) : Connection( io_service, service ), socket_address_( address ), socket_port_( port ), socket_( io_service ) { try { do_connection(); } catch( TCPConnectionException & e ) { throw; } }
int check_validteam(t_serv *serveur, t_client *client, int cs) { int i; int len; i = 0; len = strlen(client[cs].request[0]); if (client[cs].request[0][len - 1] != '\n') return (0); if (client[cs].request[0][len - 2] == '\r') client[cs].request[0][len - 2] = '\0'; else client[cs].request[0][len - 1] = '\0'; while (i < serveur->nb_team) { if (!strcmp(client[cs].request[0], serveur->team[i].name)) return (do_connection(serveur, client, cs, i)); i++; } if (!strcmp(client[cs].request[0], "GRAPHIC")) return (connect_graphic(serveur, client, cs)); xsend(cs, KO, strlen(KO), 0); return (-1); }
/* Open LDAP and Notifier connection. * @return 0 on success, 1 on error. */ static int do_connection(univention_ldap_parameters_t *lp) { LDAPMessage *res; int rc; struct timeval timeout = { .tv_sec = 10, .tv_usec = 0, }; if (univention_ldap_open(lp) != LDAP_SUCCESS) goto fail; if (notifier_client_new(NULL, lp->host, 1) != 0) goto fail; /* check if we are connected to an OpenLDAP */ rc = ldap_search_ext_s(lp->ld, lp->base, LDAP_SCOPE_BASE, "objectClass=univentionBase", NULL, 0, NULL, NULL, &timeout, 0, &res); ldap_msgfree(res); switch (rc) { case LDAP_SUCCESS: return 0; case LDAP_NO_SUCH_OBJECT: univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "Failed to find \"(objectClass=univentionBase)\" on LDAP server %s:%d", lp->host, lp->port); break; default: univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "Failed to search for \"(objectClass=univentionBase)\" on LDAP server %s:%d with message %s", lp->host, lp->port, ldap_err2string(rc)); break; } fail: notifier_client_destroy(NULL); if (lp->ld) ldap_unbind_ext(lp->ld, NULL, NULL); lp->ld = NULL; return 1; } int main(int argc, char* argv[]) { univention_ldap_parameters_t *lp; univention_ldap_parameters_t *lp_local; char *server_role; #ifdef WITH_KRB5 univention_krb5_parameters_t *kp = NULL; bool do_kinit = false; #else void *kp = NULL ; #endif int debugging = 0; bool from_scratch = false; bool foreground = false; bool initialize_only = false; bool write_transaction_file = false; int rv; NotifierID id = -1; #ifndef WITH_DB42 NotifierID old_id = -1; #else CacheMasterEntry master_entry; #endif struct stat stbuf; char *f = NULL; univention_debug_init("stderr", 1, 1); if ((lp = univention_ldap_new()) == NULL) exit(1); lp->authmethod = LDAP_AUTH_SASL; if ((lp_local = univention_ldap_new()) == NULL) exit(1); #if WITH_KRB5 if ((kp=univention_krb5_new()) == NULL) exit(1); #endif /* parse arguments */ for (;;) { int c; c = getopt(argc, argv, "d:FH:h:p:b:D:w:y:xZY:U:R:Km:Bc:giol:"); if (c < 0) break; switch (c) { case 'd': debugging=atoi(optarg); break; case 'F': foreground = true; break; case 'H': lp->uri=strdup(optarg); break; case 'h': lp->host=strdup(optarg); break; case 'p': lp->port=atoi(optarg); break; case 'b': lp->base=strdup(optarg); break; case 'm': if ((module_dirs = realloc(module_dirs, (module_dir_count+2)*sizeof(char*))) == NULL) { return 1; } module_dirs[module_dir_count] = strdup(optarg); module_dirs[module_dir_count+1] = NULL; module_dir_count++; break; case 'c': cache_dir=strdup(optarg); break; case 'l': ldap_dir = strdup(optarg); if (asprintf(&transaction_file, "%s/listener/listener", ldap_dir) < 0) abort(); break; case 'D': lp->binddn=strdup(optarg); break; case 'w': lp->bindpw=strdup(optarg); #ifdef WITH_KRB5 kp->password=strdup(optarg); #endif /* remove password from process list */ memset(optarg, 'X', strlen(optarg)); break; case 'Z': lp->start_tls++; break; case 'x': lp->authmethod = LDAP_AUTH_SIMPLE; break; case 'y': lp->bindpw=read_pwd_from_file(optarg); #ifdef WITH_KRB5 kp->password=strdup(lp->bindpw); #endif break; case 'Y': lp->sasl_mech=strdup(optarg); break; case 'U': asprintf(&lp->sasl_authzid, "u:%s", optarg); /* kp->username=strdup(optarg); */ case 'R': lp->sasl_realm=strdup(optarg); #ifdef WITH_KRB5 kp->realm=strdup(optarg); #endif break; #ifdef WITH_KRB5 case 'K': do_kinit = true; break; #endif case 'g': from_scratch = true; break; case 'i': initialize_only = true; from_scratch = true; foreground = true; break; case 'o': write_transaction_file = true; break; case 'B': backup_notifier = 1; break; default: usage(); exit(1); } } if (asprintf(&f, "%s/bad_cache", cache_dir) < 0) abort(); if (stat(f, &stbuf) == 0) { exit(3); } free(f); univention_debug_set_level(UV_DEBUG_LISTENER, debugging); univention_debug_set_level(UV_DEBUG_LDAP, debugging); univention_debug_set_level(UV_DEBUG_KERBEROS, debugging); snprintf(pidfile, PATH_MAX, "%s/pid", cache_dir); signals_init(); if (!foreground && daemonize() != 0) exit(EXIT_FAILURE); drop_privileges(); if (from_scratch) purge_cache(cache_dir); prepare_cache(cache_dir); /* choose server to connect to */ if (lp->host == NULL && lp->uri == NULL) { select_server(lp); univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_INFO, "no server given, choosing one by myself (%s)", lp->host); } #ifdef WITH_KRB5 if (!do_kinit) kp = NULL; if (kp != NULL && univention_krb5_init(kp) != 0) { univention_debug(UV_DEBUG_KERBEROS, UV_DEBUG_ERROR, "kinit failed"); exit(1); } #endif while (do_connection(lp) != 0) { univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_WARN, "can not connect to ldap server %s:%d", lp->host, lp->port); if (suspend_connect()) { if (initialize_only) { univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "can not connect to any ldap server, exit"); exit(1); } univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_WARN, "can not connect to any ldap server, retrying in 30 seconds"); sleep(30); } select_server(lp); univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_WARN, "chosen server: %s:%d", lp->host, lp->port); } univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_INFO, "connection okay to host %s:%d", lp->host, lp->port); /* connect to local LDAP server */ server_role = univention_config_get_string("server/role"); if ( server_role != NULL ) { if (!strcmp(server_role, "domaincontroller_backup") || !strcmp(server_role, "domaincontroller_slave")) { // if not master lp_local->host = strdup("localhost"); // or fqdn e.g. from univention_config_get_string("ldap/server/name"); lp_local->base = strdup(lp->base); lp_local->binddn = strdup(lp->binddn); lp_local->bindpw = strdup(lp->bindpw); } free(server_role); } /* XXX: we shouldn't block all signals for so long */ signals_block(); cache_init(); handlers_init(); /* pass data to handlers */ if (lp->base != NULL) handlers_set_data_all("basedn", lp->base); if (lp->binddn != NULL) handlers_set_data_all("binddn", lp->binddn); if (lp->bindpw != NULL) handlers_set_data_all("bindpw", lp->bindpw); if (lp->host != NULL) handlers_set_data_all("ldapserver", lp->host); convert_cookie(); if (notifier_get_id_s(NULL, &id) != 0) { univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "failed to receive current ID"); return 1; } if (initialize_only) { INIT_ONLY=1; } /* update schema */ if ((rv=change_update_schema(lp)) != LDAP_SUCCESS) return rv; /* do initial import of entries */ if ((rv=change_new_modules(lp)) != LDAP_SUCCESS) { univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "change_new_modules: %s", ldap_err2string(rv)); return rv; } signals_unblock(); /* if no ID is set, assume the database has just been initialized */ #ifdef WITH_DB42 if ((rv=cache_get_master_entry(&master_entry)) == DB_NOTFOUND) { master_entry.id = id; if ((rv=cache_update_master_entry(&master_entry, NULL)) != 0) exit(1); } else if (rv != 0) exit(1); #else cache_get_int("notifier_id", &old_id, -1); if ((long)old_id == -1) { cache_set_int("notifier_id", id); } #endif if (!initialize_only) { rv = notifier_listen(lp, kp, write_transaction_file, lp_local); } if (rv != 0) univention_debug(UV_DEBUG_LISTENER, UV_DEBUG_ERROR, "listener: %d", rv); univention_ldap_close(lp); univention_ldap_close(lp_local); exit_handler(0); }
int main(int argc, char *argv[]) { struct sockaddr_in sin; mysocket_t bindsd; int len, opt, errflg = 0; char localname[256]; /* Parse the command line */ while ((opt = getopt(argc, argv, "")) != EOF) { switch (opt) { case '?': ++errflg; break; } } if (errflg || optind != argc) { fprintf(stderr, usage, argv[0]); exit(EXIT_FAILURE); } /* open connection on any available port */ if ((bindsd = mysocket()) < 0) { perror("mysocket"); exit(EXIT_FAILURE); } memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_addr.s_addr = htonl(INADDR_ANY); sin.sin_port = htons(0); len = sizeof(struct sockaddr_in); if (mybind(bindsd, (struct sockaddr *) &sin, len) < 0) { perror("mybind"); exit(EXIT_FAILURE); } if (mylisten(bindsd, 5) < 0) { perror("mylisten"); exit(EXIT_FAILURE); } if (local_name(bindsd, localname) < 0) { perror("local_name"); exit(EXIT_FAILURE); } fprintf(stderr, "Server's address is %s\n", localname); fflush(stderr); for (;;) { mysocket_t sd; /* just keep accepting connections forever */ if ((sd = myaccept(bindsd, (struct sockaddr *) &sin, &len)) < 0) { perror("myaccept"); exit(EXIT_FAILURE); } assert(sin.sin_family == AF_INET); fprintf(stderr, "connected to %s at port %u\n", inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); do_connection(sd); } /* end for(;;) */ if (myclose(bindsd) < 0) perror("myclose (bindsd)"); return 0; }
int main(int ac, char **av) { extern char *optarg; extern int optind; int opt, sock_in, sock_out, newsock, i, pid = 0, on = 1; socklen_t aux; int remote_major, remote_minor; int perm_denied = 0; int ret; fd_set fdset; #ifdef HAVE_IPV6_SMTH struct sockaddr_in6 sin; #else struct sockaddr_in sin; #endif char buf[100]; /* Must not be larger than remote_version. */ char remote_version[100]; /* Must be at least as big as buf. */ char addr[STRLEN]; char *comment; char *ssh_remote_version_string = NULL; FILE *f; #if defined(SO_LINGER) && defined(ENABLE_SO_LINGER) struct linger linger; #endif /* SO_LINGER */ int done; chdir(BBSHOME); /* Save argv[0]. */ saved_argv = av; if (strchr(av[0], '/')) av0 = strrchr(av[0], '/') + 1; else av0 = av[0]; /* Prevent core dumps to avoid revealing sensitive information. */ signals_prevent_core(); /* Set SIGPIPE to be ignored. */ signal(SIGPIPE, SIG_IGN); /* Initialize configuration options to their default values. */ initialize_server_options(&options); addr[0]=0; /* Parse command-line arguments. */ while ((opt = getopt(ac, av, "f:a:p:b:k:h:g:diqV:")) != EOF) { switch (opt) { case 'f': config_file_name = optarg; break; case 'd': debug_flag = 1; break; case 'i': inetd_flag = 1; break; case 'q': options.quiet_mode = 1; break; case 'b': options.server_key_bits = atoi(optarg); break; case 'a': if(optarg[0]) snprintf(addr,STRLEN,"%s",optarg); break; case 'p': if(isdigit(optarg[0])) options.port=atoi(optarg); break; case 'g': options.login_grace_time = atoi(optarg); break; case 'k': options.key_regeneration_time = atoi(optarg); break; case 'h': options.host_key_file = optarg; break; case 'V': ssh_remote_version_string = optarg; break; case '?': default: #ifdef F_SECURE_COMMERCIAL #endif /* F_SECURE_COMMERCIAL */ fprintf(stderr, "sshd version %s [%s]\n", SSH_VERSION, HOSTTYPE); fprintf(stderr, "Usage: %s [options]\n", av0); fprintf(stderr, "Options:\n"); fprintf(stderr, " -f file Configuration file (default %s/sshd_config)\n", ETCDIR); fprintf(stderr, " -d Debugging mode\n"); fprintf(stderr, " -i Started from inetd\n"); fprintf(stderr, " -q Quiet (no logging)\n"); fprintf(stderr, " -a addr Bind to the specified address (default: all)\n"); fprintf(stderr, " -p port Listen on the specified port (default: 22)\n"); fprintf(stderr, " -k seconds Regenerate server key every this many seconds (default: 3600)\n"); fprintf(stderr, " -g seconds Grace period for authentication (default: 300)\n"); fprintf(stderr, " -b bits Size of server RSA key (default: 768 bits)\n"); fprintf(stderr, " -h file File from which to read host key (default: %s)\n", HOST_KEY_FILE); fprintf(stderr, " -V str Remote version string already read from the socket\n"); exit(1); } } /* Read server configuration options from the configuration file. */ read_server_config(&options, config_file_name); /* Fill in default values for those options not explicitly set. */ fill_default_server_options(&options); /* Check certain values for sanity. */ if (options.server_key_bits < 512 || options.server_key_bits > 32768) { fprintf(stderr, "fatal: Bad server key size.\n"); exit(1); } if (options.port < 1 || options.port > 65535) { fprintf(stderr, "fatal: Bad port number.\n"); exit(1); } if (options.umask != -1) { umask(options.umask); } /* Check that there are no remaining arguments. */ if (optind < ac) { fprintf(stderr, "fatal: Extra argument %.100s.\n", av[optind]); exit(1); } /* Initialize the log (it is reinitialized below in case we forked). */ log_init(av0, debug_flag && !inetd_flag, debug_flag || options.fascist_logging, options.quiet_mode, options.log_facility); debug("sshd version %.100s [%.100s]", SSH_VERSION, HOSTTYPE); /* Load the host key. It must have empty passphrase. */ done = load_private_key(geteuid(), options.host_key_file, "", &sensitive_data.host_key, &comment); if (!done) { if (debug_flag) { fprintf(stderr, "Could not load host key: %.200s\n", options.host_key_file); fprintf(stderr, "fatal: Please check that you have sufficient permissions and the file exists.\n"); } else { log_init(av0, !inetd_flag, 1, 0, options.log_facility); error("fatal: Could not load host key: %.200s. Check path and permissions.", options.host_key_file); } exit(1); } xfree(comment); /* If not in debugging mode, and not started from inetd, disconnect from the controlling terminal, and fork. The original process exits. */ if (!debug_flag && !inetd_flag) #ifdef HAVE_DAEMON if (daemon(0, 0) < 0) error("daemon: %.100s", strerror(errno)); chdir(BBSHOME); #else /* HAVE_DAEMON */ { #ifdef TIOCNOTTY int fd; #endif /* TIOCNOTTY */ /* Fork, and have the parent exit. The child becomes the server. */ if (fork()) exit(0); /* Redirect stdin, stdout, and stderr to /dev/null. */ freopen("/dev/null", "r", stdin); freopen("/dev/null", "w", stdout); freopen("/dev/null", "w", stderr); /* Disconnect from the controlling tty. */ #ifdef TIOCNOTTY fd = open("/dev/tty", O_RDWR | O_NOCTTY); if (fd >= 0) { (void) ioctl(fd, TIOCNOTTY, NULL); close(fd); } #endif /* TIOCNOTTY */ #ifdef HAVE_SETSID #ifdef ultrix setpgrp(0, 0); #else /* ultrix */ if (setsid() < 0) error("setsid: %.100s", strerror(errno)); #endif #endif /* HAVE_SETSID */ } #endif /* HAVE_DAEMON */ /* Reinitialize the log (because of the fork above). */ log_init(av0, debug_flag && !inetd_flag, debug_flag || options.fascist_logging, options.quiet_mode, options.log_facility); /* Check that server and host key lengths differ sufficiently. This is necessary to make double encryption work with rsaref. Oh, I hate software patents. */ if (options.server_key_bits > sensitive_data.host_key.bits - SSH_KEY_BITS_RESERVED && options.server_key_bits < sensitive_data.host_key.bits + SSH_KEY_BITS_RESERVED) { options.server_key_bits = sensitive_data.host_key.bits + SSH_KEY_BITS_RESERVED; debug("Forcing server key to %d bits to make it differ from host key.", options.server_key_bits); } /* Initialize memory allocation so that any freed MP_INT data will be zeroed. */ rsa_set_mp_memory_allocation(); /* Do not display messages to stdout in RSA code. */ rsa_set_verbose(debug_flag); /* Initialize the random number generator. */ debug("Initializing random number generator; seed file %.200s", options.random_seed_file); random_initialize(&sensitive_data.random_state, geteuid(), options.random_seed_file); /* Chdir to the root directory so that the current disk can be unmounted if desired. */ idle_timeout = options.idle_timeout; /* Start listening for a socket, unless started from inetd. */ if (inetd_flag) { int s1, s2; s1 = dup(0); /* Make sure descriptors 0, 1, and 2 are in use. */ s2 = dup(s1); sock_in = dup(0); sock_out = dup(1); /* We intentionally do not close the descriptors 0, 1, and 2 as our code for setting the descriptors won\'t work if ttyfd happens to be one of those. */ debug("inetd sockets after dupping: %d, %d", sock_in, sock_out); /* Generate an rsa key. */ log_msg("Generating %d bit RSA key.", options.server_key_bits); rsa_generate_key(&sensitive_data.private_key, &public_key, &sensitive_data.random_state, options.server_key_bits); random_save(&sensitive_data.random_state, geteuid(), options.random_seed_file); log_msg("RSA key generation complete."); } else { /* Create socket for listening. */ #ifdef HAVE_IPV6_SMTH listen_sock = socket(AF_INET6, SOCK_STREAM, 0); #else listen_sock = socket(AF_INET, SOCK_STREAM, 0); #endif if (listen_sock < 0) fatal("socket: %.100s", strerror(errno)); /* Set socket options. We try to make the port reusable and have it close as fast as possible without waiting in unnecessary wait states on close. */ setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, (void *) &on, sizeof(on)); #if defined(SO_LINGER) && defined(ENABLE_SO_LINGER) linger.l_onoff = 1; linger.l_linger = 15; setsockopt(listen_sock, SOL_SOCKET, SO_LINGER, (void *) &linger, sizeof(linger)); #endif /* SO_LINGER */ /* Initialize the socket address. */ memset(&sin, 0, sizeof(sin)); #ifdef HAVE_IPV6_SMTH sin.sin6_family = AF_INET6; if ( inet_pton(AF_INET6, addr, &(sin.sin6_addr)) <= 0 ) sin.sin6_addr = in6addr_any; sin.sin6_port = htons(options.port); #else sin.sin_family = AF_INET; if ( inet_pton(AF_INET, addr, &(sin.sin_addr)) <= 0 ) sin.sin_addr.s_addr = htonl(INADDR_ANY); sin.sin_port = htons(options.port); #endif /* Bind the socket to the desired port. */ if (bind(listen_sock, (struct sockaddr *) &sin, sizeof(sin)) < 0) { error("bind: %.100s", strerror(errno)); shutdown(listen_sock, 2); close(listen_sock); fatal("Bind to port %d failed: %.200s.", options.port, strerror(errno)); } /* COMMAN : setuid to bbs */ if(setgid(BBSGID)==-1) exit(8); if(setuid(BBSUID)==-1) exit(8); #if 0 /* etnlegend, 2006.10.31 ... */ if (!debug_flag) { /* Record our pid in /etc/sshd_pid to make it easier to kill the correct sshd. We don\'t want to do this before the bind above because the bind will fail if there already is a daemon, and this will overwrite any old pid in the file. */ f = fopen(options.pid_file, "w"); if (f) { fprintf(f, "%u\n", (unsigned int) getpid()); fclose(f); } } #endif /* Start listening on the port. */ log_msg("Server listening on port %d.", options.port); if (listen(listen_sock, 5) < 0) fatal("listen: %.100s", strerror(errno)); /* Generate an rsa key. */ log_msg("Generating %d bit RSA key.", options.server_key_bits); rsa_generate_key(&sensitive_data.private_key, &public_key, &sensitive_data.random_state, options.server_key_bits); random_save(&sensitive_data.random_state, geteuid(), options.random_seed_file); log_msg("RSA key generation complete."); /* Schedule server key regeneration alarm. */ signal(SIGALRM, key_regeneration_alarm); alarm(options.key_regeneration_time); /* Arrange to restart on SIGHUP. The handler needs listen_sock. */ signal(SIGHUP, sighup_handler); signal(SIGTERM, sigterm_handler); signal(SIGQUIT, sigterm_handler); /* AIX sends SIGDANGER when memory runs low. The default action is to terminate the process. This sometimes makes it difficult to log in and fix the problem. */ #ifdef SIGDANGER signal(SIGDANGER, sigdanger_handler); #endif /* SIGDANGER */ /* Arrange SIGCHLD to be caught. */ signal(SIGCHLD, main_sigchld_handler); if(!debug_flag){ if(!addr[0]) sprintf(buf,"var/sshbbsd.%d.pid",options.port); else sprintf(buf,"var/sshbbsd.%d_%s.pid",options.port,addr); if((f=fopen(buf,"w"))){ fprintf(f,"%d\n",(int)getpid()); fclose(f); } } /* Stay listening for connections until the system crashes or the daemon is killed with a signal. */ for (;;) { if (received_sighup) sighup_restart(); /* Wait in select until there is a connection. */ FD_ZERO(&fdset); FD_SET(listen_sock, &fdset); ret = select(listen_sock + 1, &fdset, NULL, NULL, NULL); if (ret < 0 || !FD_ISSET(listen_sock, &fdset)) { if (errno == EINTR) continue; error("select: %.100s", strerror(errno)); continue; } aux = sizeof(sin); newsock = accept(listen_sock, (struct sockaddr *) &sin, &aux); if (newsock < 0) { if (errno == EINTR) continue; error("accept: %.100s", strerror(errno)); continue; } /* Got connection. Fork a child to handle it, unless we are in debugging mode. */ if (debug_flag) { /* In debugging mode. Close the listening socket, and start processing the connection without forking. */ debug("Server will not fork when running in debugging mode."); close(listen_sock); sock_in = newsock; sock_out = newsock; pid = getpid(); #ifdef LIBWRAP { struct request_info req; signal(SIGCHLD, SIG_DFL); request_init(&req, RQ_DAEMON, av0, RQ_FILE, newsock, NULL); fromhost(&req); if (!hosts_access(&req)) refuse(&req); syslog(allow_severity, "connect from %s", eval_client(&req)); } #endif /* LIBWRAP */ break; } else { #ifdef CHECK_IP_LINK #ifdef HAVE_IPV6_SMTH if (check_IP_lists(sin.sin6_addr)==0) #else if (check_IP_lists(sin.sin_addr.s_addr)==0) #endif #endif /* Normal production daemon. Fork, and have the child process the connection. The parent continues listening. */ if ((pid = fork()) == 0) { /* Child. Close the listening socket, and start using the accepted socket. Reinitialize logging (since our pid has changed). We break out of the loop to handle the connection. */ close(listen_sock); sock_in = newsock; sock_out = newsock; #ifdef LIBWRAP { struct request_info req; signal(SIGCHLD, SIG_DFL); request_init(&req, RQ_DAEMON, av0, RQ_FILE, newsock, NULL); fromhost(&req); if (!hosts_access(&req)) refuse(&req); syslog(allow_severity, "connect from %s", eval_client(&req)); } #endif /* LIBWRAP */ log_init(av0, debug_flag && !inetd_flag, options.fascist_logging || debug_flag, options.quiet_mode, options.log_facility); break; } } /* Parent. Stay in the loop. */ if (pid < 0) error("fork: %.100s", strerror(errno)); else debug("Forked child %d.", pid); /* Mark that the key has been used (it was "given" to the child). */ key_used = 1; random_acquire_light_environmental_noise(&sensitive_data.random_state); /* Close the new socket (the child is now taking care of it). */ close(newsock); } } /* This is the child processing a new connection. */ /* Disable the key regeneration alarm. We will not regenerate the key since we are no longer in a position to give it to anyone. We will not restart on SIGHUP since it no longer makes sense. */ alarm(0); signal(SIGALRM, SIG_DFL); signal(SIGHUP, SIG_DFL); signal(SIGTERM, SIG_DFL); signal(SIGQUIT, SIG_DFL); signal(SIGCHLD, SIG_DFL); /* Set socket options for the connection. We want the socket to close as fast as possible without waiting for anything. If the connection is not a socket, these will do nothing. */ /* setsockopt(sock_in, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(on)); */ #if defined(SO_LINGER) && defined(ENABLE_SO_LINGER) linger.l_onoff = 1; linger.l_linger = 15; setsockopt(sock_in, SOL_SOCKET, SO_LINGER, (void *) &linger, sizeof(linger)); #endif /* SO_LINGER */ /* Register our connection. This turns encryption off because we do not have a key. */ packet_set_connection(sock_in, sock_out, &sensitive_data.random_state); /* Log the connection. */ log_msg("Connection from %.100s port %d", get_remote_ipaddr(), get_remote_port()); /* Check whether logins are denied from this host. */ { const char *hostname = get_canonical_hostname(); const char *ipaddr = get_remote_ipaddr(); int i; if (options.num_deny_hosts > 0) { for (i = 0; i < options.num_deny_hosts; i++) if (match_host(hostname, ipaddr, options.deny_hosts[i])) perm_denied = 1; } if ((!perm_denied) && options.num_allow_hosts > 0) { for (i = 0; i < options.num_allow_hosts; i++) if (match_host(hostname, ipaddr, options.allow_hosts[i])) break; if (i >= options.num_allow_hosts) perm_denied = 1; } if (perm_denied && options.silent_deny) { close(sock_in); close(sock_out); exit(0); } } /* We don't want to listen forever unless the other side successfully authenticates itself. So we set up an alarm which is cleared after successful authentication. A limit of zero indicates no limit. Note that we don't set the alarm in debugging mode; it is just annoying to have the server exit just when you are about to discover the bug. */ signal(SIGALRM, grace_alarm_handler); if (!debug_flag) alarm(options.login_grace_time); if (ssh_remote_version_string == NULL) { /* Send our protocol version identification. */ snprintf(buf, sizeof(buf), "SSH-%d.%d-%.50s", PROTOCOL_MAJOR, PROTOCOL_MINOR, SSH_VERSION); strcat(buf, "\n"); if (write(sock_out, buf, strlen(buf)) != strlen(buf)) fatal_severity(SYSLOG_SEVERITY_INFO, "Could not write ident string."); } if (ssh_remote_version_string == NULL) { /* Read other side\'s version identification. */ for (i = 0; i < sizeof(buf) - 1; i++) { if (read(sock_in, &buf[i], 1) != 1) fatal_severity(SYSLOG_SEVERITY_INFO, "Did not receive ident string."); if (buf[i] == '\r') { buf[i] = '\n'; buf[i + 1] = 0; break; } if (buf[i] == '\n') { /* buf[i] == '\n' */ buf[i + 1] = 0; break; } } buf[sizeof(buf) - 1] = 0; } else { strncpy(buf, ssh_remote_version_string, sizeof(buf) - 1); buf[sizeof(buf) - 1] = 0; } /* Check that the versions match. In future this might accept several versions and set appropriate flags to handle them. */ if (sscanf(buf, "SSH-%d.%d-%[^\n]\n", &remote_major, &remote_minor, remote_version) != 3) { const char *s = "Protocol mismatch.\n"; (void) write(sock_out, s, strlen(s)); close(sock_in); close(sock_out); fatal_severity(SYSLOG_SEVERITY_INFO, "Bad protocol version identification: %.100s", buf); } debug("Client protocol version %d.%d; client software version %.100s", remote_major, remote_minor, remote_version); switch (check_emulation(remote_major, remote_minor, NULL, NULL)) { case EMULATE_MAJOR_VERSION_MISMATCH: { const char *s = "Protocol major versions differ.\n"; (void) write(sock_out, s, strlen(s)); close(sock_in); close(sock_out); fatal_severity(SYSLOG_SEVERITY_INFO, "Protocol major versions differ: %d vs. %d", PROTOCOL_MAJOR, remote_major); } break; case EMULATE_VERSION_TOO_OLD: packet_disconnect("Your ssh version is too old and is no " "longer supported. Please install a newer version."); break; case EMULATE_VERSION_NEWER: packet_disconnect("This server does not support your " "new ssh version."); break; case EMULATE_VERSION_OK: break; default: fatal("Unexpected return value from check_emulation."); } if (perm_denied) { const char *hostname = get_canonical_hostname(); log_msg("Connection from %.200s not allowed.\n", hostname); packet_disconnect("Sorry, you are not allowed to connect."); /*NOTREACHED*/} packet_set_nonblocking(); /* Handle the connection. We pass as argument whether the connection came from a privileged port. */ do_connection(get_remote_port() < 1024); /* The connection has been terminated. */ log_msg("Closing connection to %.100s", get_remote_ipaddr()); packet_close(); exit(0); }