Example #1
0
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);
}
Example #2
0
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();
}
Example #3
0
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;
}
Example #5
0
File: main.c Project: Jman012/toxic
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);
}
Example #6
0
File: gamin.c Project: GNOME/gamin
int
main(void)
{
    int loop;

    /* setenv("GAM_CLIENT_ID", "test-id", 0); */
    for (loop = 0; loop < 1; loop++)
        do_connection();

    return (0);
}
Example #7
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;
	}
}
Example #8
0
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);
}
Example #9
0
File: main.c Project: B-Rich/smart
/* 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);
}
Example #10
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;
}
Example #11
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);
}