예제 #1
0
static int check(char *name, int fd) {
    struct request_info request;

    request_init(&request, RQ_DAEMON, name, RQ_FILE, fd, 0);
    fromhost(&request);
    return hosts_access(&request);
}
예제 #2
0
bool socket_tcpwrap(int fd, const char *name) {
#ifdef HAVE_LIBWRAP
        struct request_info req;
        union {
                struct sockaddr sa;
                struct sockaddr_in in;
                struct sockaddr_in6 in6;
                struct sockaddr_un un;
                struct sockaddr_storage storage;
        } sa_union;
        socklen_t l = sizeof(sa_union);

        if (getsockname(fd, &sa_union.sa, &l) < 0)
                return true;

        if (sa_union.sa.sa_family != AF_INET &&
            sa_union.sa.sa_family != AF_INET6)
                return true;

        request_init(&req,
                     RQ_DAEMON, name,
                     RQ_FILE, fd,
                     NULL);

        fromhost(&req);

        if (!hosts_access(&req)) {
                log_warning("Connection refused by tcpwrap.");
                return false;
        }

        log_debug("Connection accepted by tcpwrap.");
#endif
        return true;
}
예제 #3
0
static gboolean
afsocket_sd_process_connection(AFSocketSourceDriver *self, GSockAddr *client_addr, GSockAddr *local_addr, gint fd)
{
  gchar buf[MAX_SOCKADDR_STRING], buf2[MAX_SOCKADDR_STRING];
#if SYSLOG_NG_ENABLE_TCP_WRAPPER
  if (client_addr && (client_addr->sa.sa_family == AF_INET
#if SYSLOG_NG_ENABLE_IPV6
                   || client_addr->sa.sa_family == AF_INET6
#endif
     ))
    {
      struct request_info req;

      request_init(&req, RQ_DAEMON, "syslog-ng", RQ_FILE, fd, 0);
      fromhost(&req);
      if (hosts_access(&req) == 0)
        {

          msg_error("Syslog connection rejected by tcpd",
                    evt_tag_str("client", g_sockaddr_format(client_addr, buf, sizeof(buf), GSA_FULL)),
                    evt_tag_str("local", g_sockaddr_format(local_addr, buf2, sizeof(buf2), GSA_FULL)),
                    NULL);
          return FALSE;
        }
    }

#endif

  if (self->num_connections >= self->max_connections)
    {
      msg_error("Number of allowed concurrent connections reached, rejecting connection",
                evt_tag_str("client", g_sockaddr_format(client_addr, buf, sizeof(buf), GSA_FULL)),
                evt_tag_str("local", g_sockaddr_format(local_addr, buf2, sizeof(buf2), GSA_FULL)),
                evt_tag_int("max", self->max_connections),
                NULL);
      return FALSE;
    }
  else
    {
      AFSocketSourceConnection *conn;

      conn = afsocket_sc_new(client_addr, fd, self->super.super.super.cfg);
      afsocket_sc_set_owner(conn, self);
      if (log_pipe_init(&conn->super))
        {
          afsocket_sd_add_connection(self, conn);
          self->num_connections++;
          log_pipe_append(&conn->super, &self->super.super.super);
        }
      else
        {
          log_pipe_unref(&conn->super);
          return FALSE;
        }
    }
  return TRUE;
}
예제 #4
0
파일: utils.c 프로젝트: BwRy/tgcd
int	peer_ok(char *prog, int sd)
{
	struct request_info request;

	request_init(&request, RQ_DAEMON, prog, RQ_FILE, sd, 0);
	fromhost(&request);
	if (!hosts_access(&request)) 
		return 0;
	else
		return 1;
}
예제 #5
0
static void callback(pa_mainloop_api *mainloop, pa_io_event *e, int fd, pa_io_event_flags_t f, void *userdata) {
    pa_socket_server *s = userdata;
    pa_iochannel *io;
    int nfd;

    pa_assert(s);
    pa_assert(PA_REFCNT_VALUE(s) >= 1);
    pa_assert(s->mainloop == mainloop);
    pa_assert(s->io_event == e);
    pa_assert(e);
    pa_assert(fd >= 0);
    pa_assert(fd == s->fd);

    pa_socket_server_ref(s);

    if ((nfd = pa_accept_cloexec(fd, NULL, NULL)) < 0) {
        pa_log("accept(): %s", pa_cstrerror(errno));
        goto finish;
    }

    if (!s->on_connection) {
        pa_close(nfd);
        goto finish;
    }

#ifdef HAVE_LIBWRAP

    if (s->tcpwrap_service) {
        struct request_info req;

        request_init(&req, RQ_DAEMON, s->tcpwrap_service, RQ_FILE, nfd, NULL);
        fromhost(&req);
        if (!hosts_access(&req)) {
            pa_log_warn("TCP connection refused by tcpwrap.");
            pa_close(nfd);
            goto finish;
        }

        pa_log_info("TCP connection accepted by tcpwrap.");
    }
#endif

    /* There should be a check for socket type here */
    if (s->type == SOCKET_SERVER_IPV4)
        pa_make_tcp_socket_low_delay(fd);
    else
        pa_make_socket_low_delay(fd);

    pa_assert_se(io = pa_iochannel_new(s->mainloop, nfd, nfd));
    s->on_connection(s, io, s->userdata);

finish:
    pa_socket_server_unref(s);
}
예제 #6
0
static void
httpd_listen_in_event(int fd, const struct sockaddr *address,
		      size_t address_length, G_GNUC_UNUSED int uid, void *ctx)
{
	struct httpd_output *httpd = ctx;

	/* the listener socket has become readable - a client has
	   connected */

#ifdef HAVE_LIBWRAP
	if (address->sa_family != AF_UNIX) {
		char *hostaddr = sockaddr_to_string(address, address_length, NULL);
		const char *progname = g_get_prgname();

		struct request_info req;
		request_init(&req, RQ_FILE, fd, RQ_DAEMON, progname, 0);

		fromhost(&req);

		if (!hosts_access(&req)) {
			/* tcp wrappers says no */
			g_warning("libwrap refused connection (libwrap=%s) from %s",
			      progname, hostaddr);
			g_free(hostaddr);
			close_socket(fd);
			g_mutex_unlock(httpd->mutex);
			return;
		}

		g_free(hostaddr);
	}
#else
	(void)address;
	(void)address_length;
#endif	/* HAVE_WRAP */

	g_mutex_lock(httpd->mutex);

	if (fd >= 0) {
		/* can we allow additional client */
		if (httpd->open &&
		    (httpd->clients_max == 0 ||
		     httpd->clients_cnt < httpd->clients_max))
			httpd_client_add(httpd, fd);
		else
			close_socket(fd);
	} else if (fd < 0 && errno != EINTR) {
		g_warning("accept() failed: %s", g_strerror(errno));
	}

	g_mutex_unlock(httpd->mutex);
}
예제 #7
0
static int tcpd_auth(int connfd)
{
	struct request_info request;
	int rc;

	request_init(&request, RQ_DAEMON, PROGNAME, RQ_FILE, connfd, 0);
	fromhost(&request);
	rc = hosts_access(&request);
	if (rc == 0)
		return -1;

	return 0;
}
예제 #8
0
void aha1542a_device::device_add_mconfig(machine_config &config)
{
	i8085a_cpu_device &localcpu(I8085A(config, m_localcpu, 10'000'000));
	localcpu.set_addrmap(AS_PROGRAM, &aha1542a_device::i8085_map);

	generic_latch_8_device &fromhost(GENERIC_LATCH_8(config, "fromhost"));
	fromhost.data_pending_callback().set_inputline(m_localcpu, I8085_RST55_LINE);

	GENERIC_LATCH_8(config, "tohost");

	scsi_add(config);

	DP8473(config, m_fdc, 24_MHz_XTAL);
}
예제 #9
0
static int auth_libwrap(CLI *c) {
#ifdef USE_LIBWRAP
    struct request_info request;
    int fd[2];
    int result=0; /* deny by default */

    if(pipe(fd)<0) {
        ioerror("pipe");
        return -1;
    }
    if(alloc_fd(fd[0]) || alloc_fd(fd[1]))
        return -1;
    switch(fork()) {
    case -1:    /* error */
        close(fd[0]);
        close(fd[1]);
        ioerror("fork");
        return -1;
    case  0:    /* child */
        close(fd[0]); /* read side */
        request_init(&request,
            RQ_DAEMON, c->opt->servname, RQ_FILE, c->local_rfd.fd, 0);
        fromhost(&request);
        result=hosts_access(&request);
        write_blocking(c, fd[1], (u8 *)&result, sizeof(result));
            /* ignore the returned error */
        close(fd[1]); /* write side */
        _exit(0);
    default:    /* parent */
        close(fd[1]); /* write side */
        read_blocking(c, fd[0], (u8 *)&result, sizeof(result));
            /* ignore the returned error */
        close(fd[0]); /* read side */
        /* no need to wait() for zombies here:
         *  - in UCONTEXT/PTHREAD mode they're removed using the signal pipe
         *  - in FORK mode they're removed with the client process */
    }

    if(!result) {
        s_log(LOG_WARNING, "Connection from %s REFUSED by libwrap",
            c->accepting_address);
        s_log(LOG_DEBUG, "See hosts_access(5) manual for details");
        return -1; /* FAILED */
    }
    s_log(LOG_DEBUG, "Connection from %s permitted by libwrap",
        c->accepting_address);
#endif
    return 0; /* OK */
}
예제 #10
0
static int tcpd_auth(int csock)
{
	int ret;
	struct request_info request;

	request_init(&request, RQ_DAEMON, "usbipd", RQ_FILE, csock, 0);

	fromhost(&request);

	ret = hosts_access(&request);
	if (!ret)
		return -1;

	return 0;
}
예제 #11
0
파일: tcpwrap.c 프로젝트: Raffprta/core
static void tcpwrap_client_handle(struct tcpwrap_client *client, int check_fd,
				  const char *daemon_name)
{
	struct request_info request;

	request_init(&request, RQ_DAEMON, daemon_name,
		     RQ_FILE, check_fd, 0);
	fromhost(&request);

	if (!hosts_access(&request))
		(void)write_full(client->fd, "0\n", 2);
	else
		(void)write_full(client->fd, "1\n", 2);
	exit(0);
}
예제 #12
0
static int tcpd_auth(server_generic_client_t *cdata, int clnt_sock)
{
        int ret;
        struct request_info request;

        request_init(&request, RQ_DAEMON, "prelude-manager", RQ_FILE, clnt_sock, 0);

        fromhost(&request);

        ret = hosts_access(&request);
        if ( ! ret ) {
                server_generic_log_client(cdata, PRELUDE_LOG_WARN, "tcp wrapper refused connection.\n");
                return -1;
        }

        return 0;
}
예제 #13
0
/*
 * send_stats:
 *	Accept a connection to the statistics port, and emit
 *	the stats.
 */
static void
send_stats(void)
{
	FILE	*fp;
	int	s;
	struct sockaddr_in	sockstruct;
	socklen_t	socklen;
	struct request_info ri;
	int	flags;

	/* Accept a connection to the statistics socket: */
	socklen = sizeof sockstruct;
	s = accept(Status, (struct sockaddr *) &sockstruct, &socklen);
	if (s < 0) {
		if (errno == EINTR)
			return;
		logx(LOG_ERR, "accept");
		return;
	}

	/* Check for access permissions: */
	request_init(&ri, RQ_DAEMON, "huntd", RQ_FILE, s, 0);
	fromhost(&ri);
	if (hosts_access(&ri) == 0) {
		logx(LOG_INFO, "rejected connection from %s", eval_client(&ri));
		close(s);
		return;
	}

	/* Don't allow the writes to block: */
	flags = fcntl(s, F_GETFL, 0);
	flags |= O_NDELAY;
	(void) fcntl(s, F_SETFL, flags);

	fp = fdopen(s, "w");
	if (fp == NULL) {
		logit(LOG_ERR, "fdopen");
		(void) close(s);
		return;
	}

	print_stats(fp);

	(void) fclose(fp);
}
예제 #14
0
static int auth_libwrap(CLI *c) {
#ifdef USE_LIBWRAP
    struct request_info request;
    int result;

    enter_critical_section(CRIT_NTOA); /* libwrap is not mt-safe */
    request_init(&request,
        RQ_DAEMON, c->opt->servname, RQ_FILE, c->local_rfd.fd, 0);
    fromhost(&request);
    result=hosts_access(&request);
    leave_critical_section(CRIT_NTOA);

    if (!result) {
        log(LOG_WARNING, "Connection from %s:%d REFUSED by libwrap",
            c->accepting_address, ntohs(c->addr.sin_port));
        log(LOG_DEBUG, "See hosts_access(5) for details");
        return -1; /* FAILED */
    }
#endif
    return 0; /* OK */
}
예제 #15
0
파일: util.c 프로젝트: vstakhov/mpd
int
TcpAcceptConnection(int sock, struct sockaddr_storage *addr, int block)
{
	int new_sock;
	socklen_t size = sizeof(struct sockaddr_storage);

/* Accept incoming connection */

	memset(addr, 0, sizeof(*addr));
	if ((new_sock = accept(sock, (struct sockaddr *)addr, &size)) < 0) {
		Perror("%s: accept", __FUNCTION__);
		return (-1);
	}
#ifdef USE_WRAP
	if (Enabled(&gGlobalConf.options, GLOBAL_CONF_TCPWRAPPER)) {
		struct request_info req;

		request_init(&req, RQ_DAEMON, "mpd", RQ_FILE, new_sock, NULL);
		fromhost(&req);
		if (!hosts_access(&req)) {
			Log(LG_ERR, ("refused connection (tcp-wrapper) from %s",
			    eval_client(&req)));
			close(new_sock);
			return (-1);
		}
	}
#endif

	if (!block) {
		(void)fcntl(new_sock, F_SETFD, 1);
		if (fcntl(new_sock, F_SETFL, O_NONBLOCK) < 0) {
			Perror("%s: fcntl", __FUNCTION__);
			return (-1);
		}
	}
/* Done */

	return (new_sock);
}
예제 #16
0
void
answer_first()
{
	struct sockaddr		sockstruct;
	int			newsock;
	socklen_t		socklen;
	int			flags;
	struct request_info	ri;
	struct spawn *sp;

	/* Answer the call to hunt: */
	socklen = sizeof sockstruct;
	newsock = accept(Socket, (struct sockaddr *) &sockstruct, &socklen);
	if (newsock < 0) {
		logit(LOG_ERR, "accept");
		return;
	}

	/* Check for access permissions: */
	request_init(&ri, RQ_DAEMON, "huntd", RQ_FILE, newsock, 0);
	fromhost(&ri);
	if (hosts_access(&ri) == 0) {
		logx(LOG_INFO, "rejected connection from %s", eval_client(&ri));
		close(newsock);
		return;
	}

	/* Remember this spawning connection: */
	sp = (struct spawn *)malloc(sizeof *sp);
	if (sp == NULL) {
		logit(LOG_ERR, "malloc");
		close(newsock);
		return;
	}
	memset(sp, '\0', sizeof *sp);

	/* Keep the calling machine's source addr for ident purposes: */
	memcpy(&sp->source, &sockstruct, sizeof sp->source);
	sp->sourcelen = socklen;

	/* Warn if we lose connection info: */
	if (socklen > sizeof Spawn->source) 
		logx(LOG_WARNING, 
		    "struct sockaddr is not big enough! (%d > %zu)",
		    socklen, sizeof Spawn->source);

	/*
	 * Turn off blocking I/O, so a slow or dead terminal won't stop
	 * the game.  All subsequent reads check how many bytes they read.
	 */
	flags = fcntl(newsock, F_GETFL, 0);
	flags |= O_NDELAY;
	(void) fcntl(newsock, F_SETFL, flags);

	/* Start listening to the spawning connection */
	sp->fd = newsock;
	FD_SET(sp->fd, &Fds_mask);
	if (sp->fd >= Num_fds)
		Num_fds = sp->fd + 1;

	sp->reading_msg = 0;
	sp->inlen = 0;

	/* Add to the spawning list */
	if ((sp->next = Spawn) != NULL)
		Spawn->prevnext = &sp->next;
	sp->prevnext = &Spawn;
	Spawn = sp;
}
예제 #17
0
void my_fromhost(struct request_info *req)
{
  fromhost(req);
}
예제 #18
0
int mqtt3_socket_accept(struct _mosquitto_db *db, int listensock)
{
	int i;
	int j;
	int new_sock = -1;
	struct mosquitto **tmp_contexts = NULL;
	struct mosquitto *new_context;
	int opt = 1;
#ifdef WITH_TLS
	BIO *bio;
	int rc;
#endif
#ifdef WITH_WRAP
	struct request_info wrap_req;
#endif

	new_sock = accept(listensock, NULL, 0);
	if(new_sock == INVALID_SOCKET) return -1;

#ifndef WIN32
	/* Set non-blocking */
	opt = fcntl(new_sock, F_GETFL, 0);
	if(opt == -1 || fcntl(new_sock, F_SETFL, opt | O_NONBLOCK) == -1){
		/* If either fcntl fails, don't want to allow this client to connect. */
		close(new_sock);
		return -1;
	}
#else
	if(ioctlsocket(new_sock, FIONBIO, &opt)){
		closesocket(new_sock);
		return INVALID_SOCKET;
	}
#endif

#ifdef WITH_WRAP
	/* Use tcpd / libwrap to determine whether a connection is allowed. */
	request_init(&wrap_req, RQ_FILE, new_sock, RQ_DAEMON, "mosquitto", 0);
	fromhost(&wrap_req);
	if(!hosts_access(&wrap_req)){
		/* Access is denied */
		_mosquitto_log_printf(NULL, MOSQ_LOG_NOTICE, "Client connection denied access by tcpd.");
		COMPAT_CLOSE(new_sock);
		return -1;
	}else{
#endif
		new_context = mqtt3_context_init(new_sock);
		if(!new_context){
			COMPAT_CLOSE(new_sock);
			return -1;
		}
		for(i=0; i<db->config->listener_count; i++){
			for(j=0; j<db->config->listeners[i].sock_count; j++){
				if(db->config->listeners[i].socks[j] == listensock){
					new_context->listener = &db->config->listeners[i];
					break;
				}
			}
		}
		if(!new_context->listener){
			COMPAT_CLOSE(new_sock);
			return -1;
		}

		if(new_context->listener->max_connections > 0 && new_context->listener->client_count >= new_context->listener->max_connections){
			COMPAT_CLOSE(new_sock);
			return -1;
		}
		_mosquitto_log_printf(NULL, MOSQ_LOG_NOTICE, "New connection from %s.", new_context->address);
		for(i=0; i<db->context_count; i++){
			if(db->contexts[i] == NULL){
				db->contexts[i] = new_context;
				break;
			}
		}
		if(i==db->context_count){
			tmp_contexts = _mosquitto_realloc(db->contexts, sizeof(struct mosquitto*)*(db->context_count+1));
			if(tmp_contexts){
				db->context_count++;
				db->contexts = tmp_contexts;
				db->contexts[db->context_count-1] = new_context;
			}else{
				mqtt3_context_cleanup(NULL, new_context, true);
			}
		}
		new_context->listener->client_count++;

#ifdef WITH_TLS
		/* TLS init */
		for(i=0; i<db->config->listener_count; i++){
			for(j=0; j<db->config->listeners[i].sock_count; j++){
				if(db->config->listeners[i].socks[j] == listensock){
					if(db->config->listeners[i].ssl_ctx){
						new_context->ssl = SSL_new(db->config->listeners[i].ssl_ctx);
						if(!new_context->ssl){
							COMPAT_CLOSE(new_sock);
							return -1;
						}
						SSL_set_ex_data(new_context->ssl, tls_ex_index_context, new_context);
						SSL_set_ex_data(new_context->ssl, tls_ex_index_listener, &db->config->listeners[i]);
						new_context->want_read = true;
						new_context->want_write = true;
						bio = BIO_new_socket(new_sock, BIO_NOCLOSE);
						SSL_set_bio(new_context->ssl, bio, bio);
						rc = SSL_accept(new_context->ssl);
						if(rc != 1){
							rc = SSL_get_error(new_context->ssl, rc);
							if(rc == SSL_ERROR_WANT_READ){
								new_context->want_read = true;
							}else if(rc == SSL_ERROR_WANT_WRITE){
								new_context->want_write = true;
							}
						}
					}
				}
			}
		}
#endif

#ifdef WITH_WRAP
	}
#endif
	return new_sock;
}
예제 #19
0
파일: tcpd.c 프로젝트: bingos/bitrig
int main(int argc, char *argv[])
{
    struct request_info request;
    char    path[MAXPATHNAMELEN];

    /* Attempt to prevent the creation of world-writable files. */

#ifdef DAEMON_UMASK
    umask(DAEMON_UMASK);
#endif

    /*
     * If argv[0] is an absolute path name, ignore REAL_DAEMON_DIR, and strip
     * argv[0] to its basename.
     */

    if (argv[0][0] == '/') {
	strlcpy(path, argv[0], sizeof path);
	argv[0] = strrchr(argv[0], '/') + 1;
    } else {
	snprintf(path, sizeof path, "%s/%s", REAL_DAEMON_DIR, argv[0]);
    }

    /*
     * Open a channel to the syslog daemon. Older versions of openlog()
     * require only two arguments.
     */

#ifdef LOG_MAIL
    (void) openlog(argv[0], LOG_PID, FACILITY);
#else
    (void) openlog(argv[0], LOG_PID);
#endif

    /*
     * Find out the endpoint addresses of this conversation. Host name
     * lookups and double checks will be done on demand.
     */

    request_init(&request, RQ_DAEMON, argv[0], RQ_FILE, STDIN_FILENO, 0);
    fromhost(&request);

    /*
     * Optionally look up and double check the remote host name. Sites
     * concerned with security may choose to refuse connections from hosts
     * that pretend to have someone elses host name.
     */

#ifdef PARANOID
    if (STR_EQ(eval_hostname(request.client), paranoid))
	refuse(&request);
#endif

    /*
     * The BSD rlogin and rsh daemons that came out after 4.3 BSD disallow
     * socket options at the IP level. They do so for a good reason.
     * Unfortunately, we cannot use this with SunOS 4.1.x because the
     * getsockopt() system call can panic the system.
     */

#ifdef KILL_IP_OPTIONS
    fix_options(&request);
#endif

    /*
     * Check whether this host can access the service in argv[0]. The
     * access-control code invokes optional shell commands as specified in
     * the access-control tables.
     */

#ifdef HOSTS_ACCESS
    if (!hosts_access(&request))
	refuse(&request);
#endif

    /* Report request and invoke the real daemon program. */

    syslog(allow_severity, "connect from %s", eval_client(&request));
    closelog();
    (void) execv(path, argv);
    syslog(LOG_ERR, "error: cannot execute %s: %m", path);
    clean_exit(&request);
    /* NOTREACHED */
}
예제 #20
0
/*
 * Handle a UDP packet sent to the well known port.
 */
static void
handle_wkport(int fd)
{
	struct sockaddr		fromaddr;
	socklen_t		fromlen;
	u_int16_t		query;
	u_int16_t		response;
	struct request_info	ri;

	request_init(&ri, RQ_DAEMON, "huntd", RQ_FILE, fd, 0);
	fromhost(&ri);
	fromlen = sizeof fromaddr;
	if (recvfrom(fd, &query, sizeof query, 0, &fromaddr, &fromlen) == -1)
	{
		logit(LOG_WARNING, "recvfrom");
		return;
	}

#ifdef DEBUG
	fprintf(stderr, "query %d (%s) from %s:%d\n", query,
		query == C_MESSAGE ? "C_MESSAGE" :
		query == C_SCORES ? "C_SCORES" :
		query == C_PLAYER ? "C_PLAYER" :
		query == C_MONITOR ? "C_MONITOR" : "?",
		inet_ntoa(((struct sockaddr_in *)&fromaddr)->sin_addr),
		ntohs(((struct sockaddr_in *)&fromaddr)->sin_port));
#endif

	/* Do we allow access? */
	if (hosts_access(&ri) == 0) {
		logx(LOG_INFO, "rejected connection from %s", eval_client(&ri));
		return;
	}

	query = ntohs(query);

	switch (query) {
	  case C_MESSAGE:
		if (Nplayer <= 0)
			/* Don't bother replying if nobody to talk to: */
			return;
		/* Return the number of people playing: */
		response = Nplayer;
		break;
	  case C_SCORES:
		/* Someone wants the statistics port: */
		response = stat_port;
		break;
	  case C_PLAYER:
	  case C_MONITOR:
		/* Someone wants to play or watch: */
		if (query == C_MONITOR && Nplayer <= 0)
			/* Don't bother replying if there's nothing to watch: */
			return;
		/* Otherwise, tell them how to get to the game: */
		response = sock_port;
		break;
	  default:
		logit(LOG_INFO, "unknown udp query %d", query);
		return;
	}

	response = ntohs(response);
	if (sendto(fd, &response, sizeof response, 0,
	    &fromaddr, sizeof fromaddr) == -1)
		logit(LOG_WARNING, "sendto");
}
예제 #21
0
파일: quendi.c 프로젝트: BlastTNG/flight
int quendi_dp_connect(void)
{
  int dsock;
  int i;
  char buffer[QUENDI_RESPONSE_LENGTH];
  struct sockaddr_in addr;
  socklen_t addrlen;
  struct request_info req;
  fd_set sock_set;
  struct timeval timeout;

  dsock = quendi_dp_open();
  if (dsock < 1) {
    quendi_respond(QUENYA_RESPONSE_OPEN_ERROR, NULL);
    return -1;
  }

  addrlen = sizeof(addr);
  getsockname(dsock, (struct sockaddr*)&addr, &addrlen);
  snprintf(buffer, QUENDI_RESPONSE_LENGTH - 1,
      "%i@%s:%i Listening on Port", 1, inet_ntoa(addr.sin_addr),
      ntohs(addr.sin_port));
  quendi_respond(QUENYA_RESPONSE_LISTENING, buffer);

  if (listen(dsock, 1)) {
    syslog(LOG_WARNING, "dp listen: %m");
    return 0;
  }

  FD_ZERO(&sock_set);
  FD_SET(dsock, &sock_set);

  timeout.tv_sec = 60;
  timeout.tv_usec = 0;

  i = select(dsock + 1, &sock_set, NULL, NULL, &timeout);
  if (i == -1)
    syslog(LOG_WARNING, "dp select: %m");
  else if (FD_ISSET(dsock, &sock_set)) {
    i = accept(dsock, (struct sockaddr*)&addr, &addrlen);
    if (i == -1)
      syslog(LOG_WARNING, "dp accept: %m");
  } else {
    close(dsock);
    return -2; /* timeout */
  }

  if (i == -1) {
    close(dsock);
    return -1; /* select or accept error */
  }

  /* tcp wrapper check */
  request_init(&req, RQ_DAEMON, quendi_server_data->server_name, RQ_FILE,
      quendi_server_data->csock, 0);
  fromhost(&req);

  if (!hosts_access(&req)) {
    close(dsock);
    return -3; /* host access error */
  }

  close(dsock);
  return i;
}
예제 #22
0
파일: sshchtcpfwd.c 프로젝트: AnthraX1/rk
void ssh_channel_ftcp_incoming_connection(SshIpError error, SshStream stream,
                                          void *context)
{
  SshRemoteTcpForward fwd = (SshRemoteTcpForward)context;
  char ip[20], port[20];
  SshBuffer buffer;

  SSH_DEBUG(5, ("connection to forwarded TCP/IP port"));
  
  /* We should only receive new connection notifications. */
  if (error != SSH_IP_NEW_CONNECTION)
    ssh_fatal("ssh_channel_ftcp_incoming_connection: error %d", (int)error);

  /* Get remote ip address and port. */
  if (!ssh_tcp_get_remote_address(stream, ip, sizeof(ip)))
    strcpy(ip, "UNKNOWN");
  if (!ssh_tcp_get_remote_port(stream, port, sizeof(port)))
    strcpy(port, "UNKNOWN");

  SSH_TRACE(0, ("Connection to forwarded port %s from %s:%s",
                fwd->port, ip, port));
  ssh_log_event(fwd->common->config->log_facility,
                SSH_LOG_INFORMATIONAL,
                "Connection to forwarded port %s from %s:%s",
                fwd->port, fwd->common->remote_host, port);

  /* XXXXXXXX */
#ifdef HAVE_LIBWRAP
  {
    struct request_info req;
    struct servent *serv;
    char fwdportname[32];
    void *old_handler;
    
    old_handler = signal(SIGCHLD, SIG_DFL);

    /* try to find port's name in /etc/services */
    serv = getservbyport(atoi(fwd->port), "tcp");
    if (serv == NULL)
      {
        /* not found (or faulty getservbyport) -
           use the number as a name */
        snprintf(fwdportname, sizeof(fwdportname), "sshdfwd-%s", fwd->port);
      }
    else
      {
        snprintf(fwdportname, sizeof(fwdportname), "sshdfwd-%.20s",
                 serv->s_name);
      }
    /* fill req struct with port name and fd number */
    request_init(&req, RQ_DAEMON, fwdportname,
                 RQ_FILE, ssh_stream_fd_get_readfd(stream), NULL);
    fromhost(&req);
    if (!hosts_access(&req))
      {
        ssh_conn_send_debug(fwd->common->conn, TRUE,
                            "Fwd connection from %.500s to local port " \
                            "%s refused by tcp_wrappers.",
                            eval_client(&req), fwdportname);
        ssh_stream_destroy(stream);
        signal(SIGCHLD, old_handler);
    
        return;
      }
    signal(SIGCHLD, old_handler);
        
    ssh_log_event(fwd->common->config->log_facility, SSH_LOG_INFORMATIONAL,
                  "Remote fwd connect from %.500s to local port %s",
                  eval_client(&req), fwdportname);
  }
#endif /* HAVE_LIBWRAP */

  /* Register that we have an open channel. */
  ssh_common_new_channel(fwd->common);
  
  /* Send a request to open a channel and connect it to the given port. */
  ssh_buffer_init(&buffer);
  ssh_encode_buffer(&buffer,
                    SSH_FORMAT_UINT32_STR,
                    fwd->address_to_bind, strlen(fwd->address_to_bind),
                    SSH_FORMAT_UINT32, (SshUInt32) atol(fwd->port),
                    SSH_FORMAT_UINT32_STR, ip, strlen(ip),
                    SSH_FORMAT_UINT32, (SshUInt32) atol(port),
                    SSH_FORMAT_END);
  ssh_conn_send_channel_open(fwd->common->conn, "forwarded-tcpip",
                             stream, TRUE, FALSE, SSH_TCPIP_WINDOW,
                             SSH_TCPIP_PACKET_SIZE,
                             ssh_buffer_ptr(&buffer), ssh_buffer_len(&buffer),
                             NULL,
                             ssh_channel_tcp_connection_destroy,
                             (void *)fwd->common, NULL, NULL);
  ssh_buffer_uninit(&buffer);
}  
예제 #23
0
int main(int argc, char *argv[])
{
  int new_fd;
  struct sockaddr_in server_addr, conn_addr;
  int sin_size;
  int c;
  char isdaemon = 0;

  /* check parameters */
  while (( c = getopt(argc, argv, "Dv")) != -1)
    switch(c) {
    case 'D':
      isdaemon = 1;
      break;
    case 'v':
      showversion();
      exit(0);
      break;
    case '?':
      return 1;
    default:
      abort();
    }

  if (isdaemon)
    run_as_daemon();

  /* initialize the error logging */
  error_init("nettrafd", isdaemon);

  /* initialize the nettraf library - used to fetch information from the system */
  if (!nettraf_init())
    error_exit("Cannot initialize nettraf library");

  if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
    error_sys_exit("socket");
  }

  memset(&server_addr, 0, sizeof(server_addr));
  server_addr.sin_family = AF_INET;
  server_addr.sin_port = htons(NETTRAFD_PORT);
  server_addr.sin_addr.s_addr = INADDR_ANY;

  if (bind(sockfd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1) {
    error_sys_exit("bind");
  }

  if (listen(sockfd, 10) == -1) {
    error_sys_exit("listen");
  }

  signal(SIGINT, (void *)&sighandler);

  while (1) {
    sin_size = sizeof(struct sockaddr_in);
    if ((new_fd = accept(sockfd, (struct sockaddr *)&conn_addr, &sin_size)) == -1) {
      error_sys_report("accept");
      continue;
    }
#ifdef DEBUG
    printf("server: got connection from %s\n", inet_ntoa(conn_addr.sin_addr));
#endif

#ifdef USE_LIBWRAP
    request_init(&request, RQ_DAEMON, "nettraf", RQ_FILE, 0, 0);
    fromhost(&request);
    if (! hosts_access(&request)) {
      char text[256];

      sprintf(text, "Connection from %s:%d REFUSED by LIBWRAP", inet_ntoa(conn_addr.sin_addr), ntohs(conn_addr.sin_port));
      error_report(text);
      close(new_fd);
    } else
#endif
    ntd_newconnection(new_fd, conn_addr);
  }

  /* should never reach this... */
  do_cleanup();
  exit(0);
}
예제 #24
0
파일: dsi_tcp.c 프로젝트: hajuuk/R7000
/* accept the socket and do a little sanity checking */
static int dsi_tcp_open(DSI *dsi)
{
    pid_t pid;
    SOCKLEN_T len;

    len = sizeof(dsi->client);
    dsi->socket = accept(dsi->serversock, (struct sockaddr *) &dsi->client, &len);

#ifdef TCPWRAP
    {
        struct request_info req;
        request_init(&req, RQ_DAEMON, dsi->program, RQ_FILE, dsi->socket, NULL);
        fromhost(&req);
        if (!hosts_access(&req)) {
            LOG(deny_severity, logtype_dsi, "refused connect from %s", eval_client(&req));
            close(dsi->socket);
            errno = ECONNREFUSED;
            dsi->socket = -1;
        }
    }
#endif /* TCPWRAP */

    if (dsi->socket < 0)
        return -1;

    getitimer(ITIMER_PROF, &itimer);
    if (0 == (pid = fork()) ) { /* child */
        static struct itimerval timer = {{0, 0}, {DSI_TCPTIMEOUT, 0}};
        struct sigaction newact, oldact;
        u_int8_t block[DSI_BLOCKSIZ];
        size_t stored;

        /* Immediateyl mark globally that we're a child now */
        parent_or_child = 1;

        /* reset signals */
        server_reset_signal();

#ifndef DEBUGGING
        /* install an alarm to deal with non-responsive connections */
        newact.sa_handler = timeout_handler;
        sigemptyset(&newact.sa_mask);
        newact.sa_flags = 0;
        sigemptyset(&oldact.sa_mask);
        oldact.sa_flags = 0;
        setitimer(ITIMER_PROF, &itimer, NULL);

        if ((sigaction(SIGALRM, &newact, &oldact) < 0) ||
            (setitimer(ITIMER_REAL, &timer, NULL) < 0)) {
            LOG(log_error, logtype_dsi, "dsi_tcp_open: %s", strerror(errno));
            exit(EXITERR_SYS);
        }
#endif

        /* read in commands. this is similar to dsi_receive except
         * for the fact that we do some sanity checking to prevent
         * delinquent connections from causing mischief. */

        /* read in the first two bytes */
        len = dsi_stream_read(dsi, block, 2);
        if (!len ) {
            /* connection already closed, don't log it (normal OSX 10.3 behaviour) */
            exit(EXITERR_CLNT);
        }
        if (len < 2 || (block[0] > DSIFL_MAX) || (block[1] > DSIFUNC_MAX)) {
            LOG(log_error, logtype_dsi, "dsi_tcp_open: invalid header");
            exit(EXITERR_CLNT);
        }

        /* read in the rest of the header */
        stored = 2;
        while (stored < DSI_BLOCKSIZ) {
            len = dsi_stream_read(dsi, block + stored, sizeof(block) - stored);
            if (len > 0)
                stored += len;
            else {
                LOG(log_error, logtype_dsi, "dsi_tcp_open: stream_read: %s", strerror(errno));
                exit(EXITERR_CLNT);
            }
        }

        dsi->header.dsi_flags = block[0];
        dsi->header.dsi_command = block[1];
        memcpy(&dsi->header.dsi_requestID, block + 2,
               sizeof(dsi->header.dsi_requestID));
        memcpy(&dsi->header.dsi_code, block + 4, sizeof(dsi->header.dsi_code));
        memcpy(&dsi->header.dsi_len, block + 8, sizeof(dsi->header.dsi_len));
        memcpy(&dsi->header.dsi_reserved, block + 12,
               sizeof(dsi->header.dsi_reserved));
        dsi->clientID = ntohs(dsi->header.dsi_requestID);

        /* make sure we don't over-write our buffers. */
        dsi->cmdlen = min(ntohl(dsi->header.dsi_len), DSI_CMDSIZ);

        stored = 0;
        while (stored < dsi->cmdlen) {
            len = dsi_stream_read(dsi, dsi->commands + stored, dsi->cmdlen - stored);
            if (len > 0)
                stored += len;
            else {
                LOG(log_error, logtype_dsi, "dsi_tcp_open: stream_read: %s", strerror(errno));
                exit(EXITERR_CLNT);
            }
        }

        /* stop timer and restore signal handler */
#ifndef DEBUGGING
        memset(&timer, 0, sizeof(timer));
        setitimer(ITIMER_REAL, &timer, NULL);
        sigaction(SIGALRM, &oldact, NULL);
#endif

        LOG(log_info, logtype_dsi, "AFP/TCP session from %s:%u",
            getip_string((struct sockaddr *)&dsi->client),
            getip_port((struct sockaddr *)&dsi->client));
    }

    /* send back our pid */
    return pid;
}
예제 #25
0
파일: trafficrcv.c 프로젝트: npad/npad
int
main(int argc, char *argv[])
{
    socklen_t       opt_len;
    struct sockaddr_in name,
                    newname;
    socklen_t       newnamelen;
    long            bufsize = 0;	/* use default */
    long            bufsizea = 0;	/* actual bufsize */
    long            bufsizea2 = 0;
    int             result;
    int             sock,
                    newsock;
    pid_t           pid;
    int             port = TPORT;
    int             errflg = 0;
    char            host[256];
    int             client = 0;
    int             maxbuf = 0;
    int             timeout = 0;
    int             daemon = 0;

    int             c;

    while ((c = getopt(argc, argv, "h?p:b:Bc:t:Dm:")) != -1) {
	switch (c) {
	case 'h':
	case '?':
	    errflg++;
	    break;
	case 'p':
	    port = atoi(optarg);
	    break;
	case 'b':
	    if (maxbuf != 0)
	        errflg++;
	    bufsize = atoi(optarg);
	    break;
	case 'B':
	    if (bufsize != 0)
	        errflg++;
	    maxbuf = 1;
	    break;
	case 'c':
	    strncpy(host, optarg, 255);
	    host[255] = '\0';
	    client = 1;
	    break;
	case 't':
	    timeout = atoi(optarg);
	    break;
	case 'D':
	    daemon = 1;
	    break;
	case 'm':
	    child_avail = atoi(optarg);
	    break;
	default:
	    errflg++;
	    break;
	}
    }

    // For backword compatibility; bufsize given as an arg
    if (optind == argc - 1)
	bufsize = atoi(argv[optind]);

    if (errflg) {
	usage(argv[0]);
	exit(2);
    }

    /*
     * Create a socket to test with
     */

    if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
	perror("Couldn't create a socket");
	exit(-1);
    }

    /*
     * Set the buffer size, if specified 
     */
    opt_len = sizeof(bufsize);

    if (bufsize) {
	if (setsockopt
	    (sock, SOL_SOCKET, SO_RCVBUF, (void *) &bufsize, opt_len)) {
	    perror("Couldn't set receive socket buffer size");
	    exit(-1);
	}
    } else if (maxbuf) {
	do {
	    bufsizea2 = bufsizea;
	    bufsize += BUF_STEPSIZE;
	    setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (void *)&bufsize, opt_len);
	    if (getsockopt(sock, SOL_SOCKET, SO_RCVBUF, (void *)&bufsizea, &opt_len)) {
		perror("getsockopt");
		exit(-1);
	    }
	} while (bufsizea > bufsizea2);
    }
    if (getsockopt
	(sock, SOL_SOCKET, SO_RCVBUF, (void *) &bufsizea, &opt_len)) {
	perror("Couldn't get receive socket buffer size");
	exit(-1);
    }
    printf("Getsockopt() reports %ld byte socket buffers\n", bufsizea);

    if (client) {
        /*
         * We're a client.  Do active connect.
         */
        
	struct hostent *hent;

	if ((hent = gethostbyname(host)) == NULL) {
	    fprintf(stderr, "gethostbyname error\n");
	    exit(-1);
	}
	memset(&name, 0, sizeof(name));
	name.sin_family = AF_INET;
	memcpy(&name.sin_addr, hent->h_addr_list[0], 4);
	name.sin_port = htons(port);

	if (connect(sock, (struct sockaddr *) &name, sizeof(name)) != 0) {
	    perror("connect");
	    exit(-1);
	}

	exit(read_until_close(sock, timeout));
    } else {
        /*
         * We're a server.  Listen, and loop indefinitely
         * accepting connections.
         */
	struct sigaction sa;

	memset(&sa, 0, sizeof(sa));
	sa.sa_handler = child_handler;
	if (sigaction(SIGCHLD, &sa, NULL)) {
	    fprintf(stderr, "sigaction for SIGCHLD failed\n");
	    exit(-1);
	}
	
	c = 1;
	if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&c, sizeof (c)) != 0) {
	    perror("setsockopt");
	    exit(-1);
	}
	
#ifdef HAVE_SIN_LEN
	name.sin_len = 16;
#endif
	name.sin_family = AF_INET;
	name.sin_addr.s_addr = 0;	/* allow connection on any
					 * interface */
	name.sin_port = htons(port);
	if (bind(sock, (struct sockaddr *) &name, sizeof(name)) == -1) {
	    perror("Bind failed");
	    exit(-1);
	}

	/*
	 * listen for new connections 
	 */
	do {
	    result = listen(sock, 5);
	} while ((result == -1) && (errno == EINTR));
	if (result == -1) {
	    perror("Listen failed");
	    exit(-1);
	}

	if (daemon) daemonize();
	/* Don't count on stdio from here on, use log() instead */
	log(LOG_INFO, "Listening on TCP port: %d\n", port);
	
	while (1) {
	    char *peerstr;
	    
	    newnamelen = sizeof(newname);
	    do {
		newsock = accept(sock, (struct sockaddr *) &newname,
				 &newnamelen);
	    } while ((newsock == -1) && (errno == EINTR));
	    if (newsock == -1) {
		log(LOG_ERR, "Accept failed: %s\n", strerror(errno));
		/* could be temporary, don't die */
		continue;
	    }
	    peerstr = inet_ntoa(newname.sin_addr);  // NOTE: Static buf

#ifdef LIBWRAP
	    {
		struct request_info req;

		request_init(&req, RQ_DAEMON, DAEMON, RQ_FILE, newsock, 0);
		fromhost(&req);

		if (!hosts_access(&req)) {
			log(LOG_INFO, "Connection refused from %s\n", peerstr);
			close(newsock);
			continue;
		}
	    }
#endif

	    if (!child_avail) {
		log(LOG_ERR, "Too many clients, refusing %s\n", peerstr);
		close(newsock);
		continue;
	    }

	    pid = fork();
	    if (!pid) {
		/*
		 * I am the child process 
		 */
		int ret;

		/* don't hold onto the listening socket */
		close(sock);

		log(LOG_INFO, "Connection from %s:%d\n", peerstr,
				ntohs(newname.sin_port));
		ret = read_until_close(newsock, timeout);
		log(LOG_INFO, "Connection %s\n",
				(alarmed) ? "timeout" : "closed");
		exit(ret);
	    } else if (pid < 0) {
		log(LOG_ERR, "Fork failed");
		/* could be temporary, don't die */
		close(newsock);
		continue;
	    }
	    /*
	     * Otherwise, I am the parent.
	     * Close the accepted socket, down our available count and loop
	     */
	    close(newsock);
	    child_down();
	}
    }

    return 0;
}
예제 #26
0
/* wait for incoming connection requests */
void wait_for_connections(void){
	struct sockaddr_in6 myname6;
	struct sockaddr_in6 src_sin;
	socklen_t socklen = sizeof(src_sin);
	struct sockaddr *remoteaddr = (struct sockaddr *)&src_sin;
	int rc;
	int sock, new_sd;
	pid_t pid;
	int flag=1;
	int max_fd = 0;
	int i = 0, j = 0;
	fd_set fdread;
	struct timeval timeout;
	int retval;
#ifdef HAVE_LIBWRAP
	struct request_info req;
#endif

	int rval;
	struct addrinfo addrinfo;
	struct addrinfo *res, *r;

	memset(&addrinfo, 0, sizeof(addrinfo));
	addrinfo.ai_family=AF_UNSPEC;
	addrinfo.ai_socktype=SOCK_STREAM;
	addrinfo.ai_protocol=IPPROTO_TCP;

	if(!server_address || !strlen(server_address)) {
		server_address = NULL;
		addrinfo.ai_flags=AI_PASSIVE;
		}
	if (rval = getaddrinfo(server_address, server_port, &addrinfo, &res) != 0) {
		syslog(LOG_ERR,"Invalid server_address (%d: %s)",errno,strerror(errno));
		exit(STATE_CRITICAL);
		}
	else {
		for (r=res; r; r = r->ai_next){
			if (r->ai_family != AF_INET && r->ai_family != AF_INET6)
				continue;
			if (num_listen_socks >= MAX_LISTEN_SOCKS){
				syslog(LOG_ERR,"Too many listen sockets. Enlarge MAX_LISTEN_SOCKS\n");
				exit(STATE_UNKNOWN);
				}
			sock = socket(r->ai_family, r->ai_socktype, r->ai_protocol);
			if (sock < 0)
				/* kernel may not support ipv6 */
				continue;
			/* socket should be non-blocking */
			fcntl(sock,F_SETFL,O_NONBLOCK);
			/* set the reuse address flag so we don't get errors when restarting */
			flag=1;
			if(setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(char *)&flag,sizeof(flag))<0){
				syslog(LOG_ERR,"Could not set reuse address option on socket!\n");
				exit(STATE_UNKNOWN);
				}
#ifdef IPV6_V6ONLY
			/* Only communicate in IPv6 over AF_INET6 sockets. */
			flag=1;
			if (r->ai_family == AF_INET6)
				if(setsockopt(sock,IPPROTO_IPV6,IPV6_V6ONLY,(char *)&flag,sizeof(flag))<0) {
					syslog(LOG_ERR,"Could not set IPV6_V6ONLY option on socket!\n");
					exit(STATE_UNKNOWN);
					}
#endif
			if(bind(sock, r->ai_addr, r->ai_addrlen) < 0) {
				syslog(LOG_ERR,"Network server bind failure (%d: %s)\n",errno,strerror(errno));
				(void) close(sock);
				exit(STATE_CRITICAL);
				}
			listen_socks[num_listen_socks] = sock;
			num_listen_socks++;
			if (listen(sock, 5) < 0){
				syslog(LOG_ERR,"Network server listen failure (%d: %s)\n",errno,strerror(errno));
	        		exit(STATE_CRITICAL);
				}
			if(sock > max_fd)
				max_fd = sock;
			}
		freeaddrinfo(res);
		if(num_listen_socks == 0) {
			exit(STATE_CRITICAL);
			}
		}


	/* log warning about command arguments */
#ifdef ENABLE_COMMAND_ARGUMENTS
	if(allow_arguments==TRUE)
		syslog(LOG_NOTICE,"Warning: Daemon is configured to accept command arguments from clients!");
#endif

	syslog(LOG_INFO,"Listening for connections on port %s\n",server_port);

	if(allowed_hosts)
		syslog(LOG_INFO,"Allowing connections from: %s\n",allowed_hosts);

	/* listen for connection requests - fork() if we get one */
	while(1){

		/* wait for a connection request */

		/* wait until there's something to do */
		FD_ZERO(&fdread);
		for(i=0; i < num_listen_socks; i++)
			FD_SET(listen_socks[i],&fdread);

		timeout.tv_sec=0;
		timeout.tv_usec=500000;
		retval=select(max_fd+1,&fdread,NULL,NULL,&timeout);
		/* bail out if necessary */
		if(sigrestart==TRUE || sigshutdown==TRUE)
			break;

		/* error */
		if(retval<0)
			continue;

		/* accept a new connection request */
		for (i = 0; i < num_listen_socks; i++){
			if (!FD_ISSET(listen_socks[i], &fdread))
				continue;
			new_sd=accept(listen_socks[i], remoteaddr, &socklen);

			/* some kind of error occurred... */
			if(new_sd<0){
				/* bail out if necessary */
				if(sigrestart==TRUE || sigshutdown==TRUE)
					break;

				/* retry */
				if(errno==EWOULDBLOCK || errno==EINTR)
					continue;

				/* socket is nonblocking and we don't have a connection yet */
				if(errno==EAGAIN)
					continue;

				/* fix for HP-UX 11.0 - just retry */
				if(errno==ENOBUFS)
					continue;

			        }		

			/* bail out if necessary */
			if(sigrestart==TRUE || sigshutdown==TRUE)
				break;

			/* child process should handle the connection */
	    		pid=fork();
	    		if(pid==0){

				/* fork again so we don't create zombies */
				pid=fork();
				if(pid==0){
					/* hey, there was an error... */
					if(new_sd<0){

						/* log error to syslog facility */
						syslog(LOG_ERR,"Network server accept failure (%d: %s)",errno,strerror(errno));

						/* close sockets prioer to exiting */
						for(j=0; j < num_listen_socks; j++)
							close(listen_socks[j]);
			
						return;
					        }

					/* handle siOAgnals */
					signal(SIGQUIT,child_sighandler);
					signal(SIGTERM,child_sighandler);
					signal(SIGHUP,child_sighandler);

					/* grandchild does not need to listen for connections, so close the sockets */
					for(j=0; j < num_listen_socks; j++)
						close(listen_socks[j]);

					/* log info to syslog facility */
					if(debug==TRUE)
						syslog(LOG_DEBUG,"Connection from %s port %d",get_ip_str(remoteaddr, buf, BUFLEN),get_port(remoteaddr));

                                	/* is this is a blessed machine? */
					if(allowed_hosts){
						if(!is_an_allowed_host(remoteaddr)){
							/* log error to syslog facility */
							syslog(LOG_ERR,"Host %s is not allowed to talk to us!",get_ip_str(remoteaddr, buf, BUFLEN));

							/* log info to syslog facility */
							if(debug==TRUE)
								syslog(LOG_DEBUG,"Connection from %s closed.",get_ip_str(remoteaddr, buf, BUFLEN));

							/* close socket prior to exiting */
							close(new_sd);

							exit(STATE_OK);
							}
						else{

							/* log info to syslog facility */
							if(debug==TRUE)
							syslog(LOG_DEBUG,"Host address is in allowed_hosts");
							}
						}

#ifdef HAVE_LIBWRAP

					/* Check whether or not connections are allowed from this host */
					request_init(&req,RQ_DAEMON,"nrpe",RQ_FILE,new_sd,0);
					fromhost(&req);

					if(!hosts_access(&req)){

						syslog(LOG_DEBUG,"Connection refused by TCP wrapper");

						/* refuse the connection */
						refuse(&req);
						close(new_sd);

						/* should not be reached */
						syslog(LOG_ERR,"libwrap refuse() returns!");
						exit(STATE_CRITICAL);
						}
#endif

					/* handle the client connection */
					handle_connection(new_sd);

					/* log info to syslog facility */
					if(debug==TRUE)
						syslog(LOG_DEBUG,"Connection from %s closed.",get_ip_str(remoteaddr, buf, BUFLEN));

					/* close socket prior to exiting */
					close(new_sd);

					exit(STATE_OK);
    			        	}

				/* first child returns immediately, grandchild is inherited by INIT process -> no zombies... */
				else
					exit(STATE_OK);
		        	}
		
			/* parent ... */
			else{
				/* parent doesn't need the new connection */
				close(new_sd);

				/* parent waits for first child to exit */
				waitpid(pid,NULL,0);
		        	}
  			}
		}
		/* close the sockets we're listening on */
		for(j=0; j < num_listen_socks; j++)
			close(listen_socks[j]);

		return;
	}
예제 #27
0
파일: sshchtcpfwd.c 프로젝트: AnthraX1/rk
void ssh_channel_dtcp_incoming_connection(SshStreamNotification op,
                                          SshStream stream, void *context)
{
  SshLocalTcpForward fwd = (SshLocalTcpForward)context;
  char ip[20], port[20];

  /* We should only receive new connection notifications. */
  if (op != SSH_IP_NEW_CONNECTION)
    ssh_fatal("ssh_channel_dtcp_incoming_connection: op %d", (int)op);

  /* Get remote ip address and port. */
  if (!ssh_tcp_get_remote_address(stream, ip, sizeof(ip)))
    strcpy(ip, "UNKNOWN");
  if (!ssh_tcp_get_remote_port(stream, port, sizeof(port)))
    strcpy(port, "UNKNOWN");

#ifdef HAVE_LIBWRAP
  {
    struct request_info req;
    struct servent *serv;
    char fwdportname[32];
    void *old_handler;
    
    old_handler = signal(SIGCHLD, SIG_DFL);
    
    /* try to find port's name in /etc/services */
    serv = getservbyport(atoi(fwd->port), "tcp");
    if (serv == NULL)
      {
        /* not found (or faulty getservbyport) -
           use the number as a name */
        snprintf(fwdportname, sizeof(fwdportname), "sshdfwd-%s", fwd->port);
      }
    else
      {
        snprintf(fwdportname, sizeof(fwdportname), "sshdfwd-%.20s",
                 serv->s_name);
      }
    /* fill req struct with port name and fd number */
    request_init(&req, RQ_DAEMON, fwdportname,
                 RQ_FILE, ssh_stream_fd_get_readfd(stream), NULL);
    fromhost(&req);
    if (!hosts_access(&req))
      {
        ssh_conn_send_debug(fwd->common->conn, TRUE,
                            "Fwd connection from %.500s to local port %s "
                            "refused by tcp_wrappers.",
                            eval_client(&req), fwdportname);
        ssh_log_event(fwd->common->config->log_facility, SSH_LOG_WARNING,
                      "Fwd connection from %.500s to local port %s "
                      "refused by tcp_wrappers.",
                      eval_client(&req), fwdportname);
        ssh_stream_destroy(stream);
        signal(SIGCHLD, old_handler);

        return;
      }
    signal(SIGCHLD, old_handler);

    ssh_log_event(fwd->common->config->log_facility, SSH_LOG_INFORMATIONAL,
                  "direct fwd connect from %.500s to local port %s",
                  eval_client(&req), fwdportname);
  }
#endif /* HAVE_LIBWRAP */

  /* Send a request to open a channel and connect it to the given port. */
  ssh_channel_dtcp_open_to_remote(fwd->common, stream,
                                  fwd->connect_to_host,
                                  fwd->connect_to_port,
                                  ip, port);
}
예제 #28
0
int pptp_manager(int argc, char **argv)
{
        int firstOpen = -1;
        int ctrl_pid;
        socklen_t addrsize;

        int hostSocket;
        fd_set connSet;

        int rc, sig_fd;

        rc = sigpipe_create();
        if (rc < 0) {
                syslog(LOG_ERR, "MGR: unable to setup sigchld pipe!");
                syslog_perror("sigpipe_create");
                exit(-1);
        }
        
        sigpipe_assign(SIGCHLD);
        sigpipe_assign(SIGTERM);
        sig_fd = sigpipe_fd();

        /* openlog() not required, done in pptpd.c */

        syslog(LOG_INFO, "MGR: Manager process started");

        if (!pptp_delegate) {
                syslog(LOG_INFO, "MGR: Maximum of %d connections available", 
                       pptp_connections);
        }

        /* Connect the host socket and activate it for listening */
        if (createHostSocket(&hostSocket) < 0) {
                syslog(LOG_ERR, "MGR: Couldn't create host socket");
                syslog_perror("createHostSocket");
                exit(-1);
        }

        while (1) {
                int max_fd;
                FD_ZERO(&connSet);
                if (pptp_delegate) {
                        FD_SET(hostSocket, &connSet);
                } else {
                        firstOpen = slot_find_empty();
                        if (firstOpen == -1) {
                                syslog(LOG_ERR, "MGR: No free connection slots or IPs - no more clients can connect!");
                        } else {
                                FD_SET(hostSocket, &connSet);
                        }
                }
                max_fd = hostSocket;

                FD_SET(sig_fd, &connSet);
                if (max_fd < sig_fd) max_fd = sig_fd;

                while (1) {
                        if (select(max_fd + 1, &connSet, NULL, NULL, NULL) != -1) break;
                        if (errno == EINTR) continue;
                        syslog(LOG_ERR, "MGR: Error with manager select()!");
                        syslog_perror("select");
                        exit(-1);
                }

                if (FD_ISSET(sig_fd, &connSet)) {       /* SIGCHLD */
                        int signum = sigpipe_read();
                        if (signum == SIGCHLD)
                                sigchld_responder(signum);
                        else if (signum == SIGTERM)
                        {
                                if (!keep_connections) sigterm_responder();
                                    return signum;
                        }
                }

                if (FD_ISSET(hostSocket, &connSet)) {   /* A call came! */
                        int clientSocket;
                        struct sockaddr_in client_addr;

                        /* Accept call and launch PPTPCTRL */
                        addrsize = sizeof(client_addr);
                        clientSocket = accept(hostSocket, (struct sockaddr *) &client_addr, &addrsize);

#ifdef HAVE_LIBWRAP
                        if (clientSocket != -1) {
                                struct request_info r;
                                request_init(&r, RQ_DAEMON, "pptpd", RQ_FILE, clientSocket, NULL);
                                fromhost(&r);
                                if (!hosts_access(&r)) {
                                        /* send a permission denied message? this is a tcp wrapper
                                         * type deny so probably best to just drop it immediately like
                                         * this, as tcp wrappers usually do.
                                         */
                                        close(clientSocket);
                                        /* this would never be file descriptor 0, so use it as a error
                                         * value
                                         */
                                        clientSocket = 0;
                                }
                        }
#endif
                        if (clientSocket == -1) {
                                /* accept failed, but life goes on... */
                                syslog(LOG_ERR, "MGR: accept() failed");
                                syslog_perror("accept");
                        } else if (clientSocket != 0) {
                                fd_set rfds;
                                struct timeval tv;
                                struct pptp_header ph;

                                /* TODO: this select below prevents
                                   other connections from being
                                   processed during the wait for the
                                   first data packet from the
                                   client. */

                                /*
                                 * DOS protection: get a peek at the first packet
                                 * and do some checks on it before we continue.
                                 * A 10 second timeout on the first packet seems reasonable
                                 * to me,  if anything looks sus,  throw it away.
                                 */

                                FD_ZERO(&rfds);
                                FD_SET(clientSocket, &rfds);
                                tv.tv_sec = pptp_stimeout;
                                tv.tv_usec = 0;
                                if (select(clientSocket + 1, &rfds, NULL, NULL, &tv) <= 0) {
                                        syslog(LOG_ERR, "MGR: dropped slow initial connection");
                                        close(clientSocket);
                                        continue;
                                }

                                if (recv(clientSocket, &ph, sizeof(ph), MSG_PEEK) !=
                                                sizeof(ph)) {
                                        syslog(LOG_ERR, "MGR: dropped small initial connection");
                                        close(clientSocket);
                                        continue;
                                }

                                ph.length = ntohs(ph.length);
                                ph.pptp_type = ntohs(ph.pptp_type);
                                ph.magic = ntohl(ph.magic);
                                ph.ctrl_type = ntohs(ph.ctrl_type);

                                if (ph.length <= 0 || ph.length > PPTP_MAX_CTRL_PCKT_SIZE) {
                                        syslog(LOG_WARNING, "MGR: initial packet length %d outside "
                                                        "(0 - %d)",  ph.length, PPTP_MAX_CTRL_PCKT_SIZE);
                                        goto dos_exit;
                                }

                                if (ph.magic != PPTP_MAGIC_COOKIE) {
                                        syslog(LOG_WARNING, "MGR: initial packet bad magic");
                                        goto dos_exit;
                                }

                                if (ph.pptp_type != PPTP_CTRL_MESSAGE) {
                                        syslog(LOG_WARNING, "MGR: initial packet has bad type");
                                        goto dos_exit;
                                }

                                if (ph.ctrl_type != START_CTRL_CONN_RQST) {
                                        syslog(LOG_WARNING, "MGR: initial packet has bad ctrl type "
                                                        "0x%x", ph.ctrl_type);
                dos_exit:
                                        close(clientSocket);
                                        continue;
                                }

#ifndef HAVE_FORK
                                switch (ctrl_pid = vfork()) {
#else
                                switch (ctrl_pid = fork()) {
#endif
                                case -1:        /* error */
                                        syslog(LOG_ERR, "MGR: fork() failed launching " PPTP_CTRL_BIN);
                                        close(clientSocket);
                                        break;

                                case 0: /* child */
                                        close(hostSocket);
                                        if (pptp_debug)
                                                syslog(LOG_DEBUG, "MGR: Launching " PPTP_CTRL_BIN " to handle client");
                                        connectCall(clientSocket, !pptp_delegate ? firstOpen : 0);
                                        _exit(1);
                                        /* NORETURN */
                                default:        /* parent */
                                        close(clientSocket);
                                        unique_call_id += MAX_CALLS_PER_TCP_LINK;
                                        if (!pptp_delegate)
                                                slot_set_pid(firstOpen, ctrl_pid);
                                        break;
                                }
                        }
                }               /* FD_ISSET(hostSocket, &connSet) */
        }                       /* while (1) */
}                               /* pptp_manager() */

/*
 * Author: Kevin Thayer
 * 
 * This creates a socket to listen on, sets the max # of pending connections and 
 * various other options.
 * 
 * Returns the fd of the host socket.
 * 
 * The function return values are:
 * 0 for sucessful
 * -1 for bad socket creation
 * -2 for bad socket options
 * -3 for bad bind
 * -4 for bad listen
 */
static int createHostSocket(int *hostSocket)
{
        int opt = 1;
        struct sockaddr_in address;
#ifdef HAVE_GETSERVBYNAME
        struct servent *serv;
#endif

        /* create the master socket and check it worked */
        if ((*hostSocket = vrf_socket(vrf, AF_INET, SOCK_STREAM, 0)) <= 0)
                return -1;

        /* set master socket to allow daemon to be restarted with connections active  */
        if (setsockopt(*hostSocket, SOL_SOCKET, SO_REUSEADDR,
                       (char *) &opt, sizeof(opt)) < 0)
                return -2;

        /* set up socket */
        memset(&address, 0, sizeof(address));
        address.sin_family = AF_INET;
        if(bindaddr)
                address.sin_addr.s_addr = inet_addr(bindaddr);
        else
                address.sin_addr.s_addr = INADDR_ANY;
#ifdef HAVE_GETSERVBYNAME
        if ((serv = getservbyname("pptp", "tcp")) != NULL) {
                address.sin_port = serv->s_port;
        } else
#endif
                address.sin_port = htons(PPTP_PORT);

        /* bind the socket to the pptp port */
        if (bind(*hostSocket, (struct sockaddr *) &address, sizeof(address)) < 0)
                return -3;

        /* minimal backlog to avoid DoS */
        if (listen(*hostSocket, 3) < 0)
                return -4;

        return 0;
}
예제 #29
0
파일: mod_wrap.c 프로젝트: OPSF/uClinux
MODRET wrap_handle_request(cmd_rec *cmd) {

  /* these variables are names expected to be set by the TCP wrapper code
   */
  struct request_info request;

  char *user = NULL;
  config_rec *conf = NULL, *access_conf = NULL, *syslog_conf = NULL;
  hosts_allow_table = NULL;
  hosts_deny_table = NULL;

  /* hide passwords */
  session.hide_password = TRUE;

  /* Sneaky...found in mod_auth.c's cmd_pass() function.  Need to find the
   * login UID in order to resolve the possibly-login-dependent filename.
   */
  user = (char *) get_param_ptr(cmd->server->conf, C_USER, FALSE);

  /* It's possible that a PASS command came before USER.  This is a PRE_CMD
   * handler, so it won't be protected from this case; we'll need to do
   * it manually.
   */
  if (!user)
    return DECLINED(cmd);

  /* Use mod_auth's _auth_resolve_user() [imported for use here] to get the
   * right configuration set, since the user may be logging in anonymously,
   * and the session struct hasn't yet been set for that yet (thus short-
   * circuiting the easiest way to get the right context...the macros.
   */
  conf = wrap_resolve_user(cmd->pool, &user);

  /* Search first for user-specific access files.  Multiple TCPUserAccessFiles
   * directives are allowed.
   */
  if ((access_conf = find_config(conf ? conf->subset : CURRENT_CONF, CONF_PARAM,
      "TCPUserAccessFiles", FALSE)) != NULL) {
    int matched = FALSE;
    array_header *user_array = NULL;

    while (access_conf) {

      user_array = make_array(cmd->tmp_pool, 0, sizeof(char *));
      *((char **) push_array(user_array)) = pstrdup(cmd->tmp_pool, user);

      /* Check the user expression -- don't forget the offset, to skip
       * the access file name strings in argv
       */
      if (wrap_eval_expression(((char **) access_conf->argv) + 2,
          user_array)) {
        pr_log_debug(DEBUG4, MOD_WRAP_VERSION
          ": matched TCPUserAccessFiles expression");
        matched = TRUE;
        break;
      }

      access_conf = find_config_next(access_conf, access_conf->next,
        CONF_PARAM, "TCPUserAccessFiles", FALSE);
    }

    if (!matched)
      access_conf = NULL;
  }

  /* Next, search for group-specific access files.  Multiple
   * TCPGroupAccessFiles directives are allowed.
   */ 
  if (!access_conf && (access_conf = find_config(conf ? conf->subset :
        CURRENT_CONF, CONF_PARAM, "TCPGroupAccessFiles", FALSE)) != NULL) {
    unsigned char matched = FALSE;

    /* NOTE: this gid_array is only necessary until Bug#1461 is fixed */
    array_header *gid_array = make_array(cmd->pool, 0, sizeof(gid_t));

    array_header *group_array = make_array(cmd->pool, 0, sizeof(char *));

    while (access_conf) {
      if (pr_auth_getgroups(cmd->pool, user, &gid_array, &group_array) < 1) {
        pr_log_debug(DEBUG3, MOD_WRAP_VERSION
          ": no supplemental groups found for user '%s'", user);

      } else {

        /* Check the group expression -- don't forget the offset, to skip
         * the access file names strings in argv
         */
        if (wrap_eval_expression(((char **) access_conf->argv) + 2,
            group_array)) {
          pr_log_debug(DEBUG4, MOD_WRAP_VERSION
            ": matched TCPGroupAccessFiles expression");
          matched = TRUE;
          break;
        }
      }

      access_conf = find_config_next(access_conf, access_conf->next,
        CONF_PARAM, "TCPGroupAccessFiles", FALSE);
    }

    if (!matched)
      access_conf = NULL;
  }

  /* Finally for globally-applicable access files.  Only one such directive
   * is allowed.
   */
  if (!access_conf) {
    access_conf = find_config(conf ? conf->subset : CURRENT_CONF,
      CONF_PARAM, "TCPAccessFiles", FALSE);
  }

  if (access_conf) {
    hosts_allow_table = (char *) access_conf->argv[0];
    hosts_deny_table = (char *) access_conf->argv[1];
  }

  /* Now, check the retrieved filename, and see if it requires a login-time
   * file.
   */
  if (hosts_allow_table != NULL && hosts_allow_table[0] == '~' &&
      hosts_allow_table[1] == '/') {
    char *allow_real_table = NULL;

    allow_real_table = wrap_get_user_table(cmd, user, hosts_allow_table);

    if (!wrap_is_usable_file(allow_real_table)) {
      pr_log_pri(PR_LOG_WARNING, MOD_WRAP_VERSION
        ": configured TCPAllowFile %s is unusable", hosts_allow_table);
      hosts_allow_table = NULL;

    } else
      hosts_allow_table = allow_real_table;
  }

  if (hosts_deny_table != NULL && hosts_deny_table[0] == '~' &&
      hosts_deny_table[1] == '/') {
    char *deny_real_table = NULL;

    deny_real_table = dir_realpath(cmd->pool, hosts_deny_table);

    if (!wrap_is_usable_file(deny_real_table)) {
      pr_log_pri(PR_LOG_WARNING, MOD_WRAP_VERSION
        ": configured TCPDenyFile %s is unusable", hosts_deny_table);
      hosts_deny_table = NULL;

    } else 
      hosts_deny_table = deny_real_table;
  }

  /* Make sure that _both_ allow and deny TCPAccessFiles are present.
   * If not, log the missing file, and by default allow request to succeed.
   */
  if (hosts_allow_table != NULL && hosts_deny_table != NULL) {

    /* Most common case...nothing more necessary */

  } else if (hosts_allow_table == NULL && hosts_deny_table != NULL) {

    /* Log the missing file */
    pr_log_pri(PR_LOG_INFO, MOD_WRAP_VERSION ": no usable allow access file -- "
      "allowing connection");

    return DECLINED(cmd);

  } else if (hosts_allow_table != NULL && hosts_deny_table == NULL) {

    /* log the missing file */
    pr_log_pri(PR_LOG_INFO, MOD_WRAP_VERSION ": no usable deny access file -- "
      "allowing connection");

    return DECLINED(cmd);

  } else {

    /* Neither set -- assume the admin hasn't configured these directives
     * at all.
     */
    return DECLINED(cmd);
  }

  /* Log the names of the allow/deny files being used. */
  pr_log_pri(PR_LOG_DEBUG, MOD_WRAP_VERSION ": using access files: %s, %s",
    hosts_allow_table, hosts_deny_table);

  /* retrieve the user-defined syslog priorities, if any.  Fall back to the
   * defaults as seen in tcpd.h if not defined.
   */
  syslog_conf = find_config(main_server->conf, CONF_PARAM,
    "TCPAccessSyslogLevels", FALSE);

  if (syslog_conf) {
    allow_severity = (int) syslog_conf->argv[1];
    deny_severity = (int) syslog_conf->argv[2];

  } else {

    allow_severity = PR_LOG_INFO;
    deny_severity = PR_LOG_WARNING;
  }

  pr_log_debug(DEBUG4, MOD_WRAP_VERSION ": checking under service name '%s'",
    wrap_service_name);
  request_init(&request, RQ_DAEMON, wrap_service_name, RQ_FILE,
    session.c->rfd, 0);

  fromhost(&request);

  if (STR_EQ(eval_hostname(request.client), paranoid) ||
      !hosts_access(&request)) {
    char *denymsg = NULL;

    /* log the denied connection */
    wrap_log_request_denied(deny_severity, &request);

    /* check for AccessDenyMsg */
    if ((denymsg = (char *) get_param_ptr(TOPLEVEL_CONF, "AccessDenyMsg",
        FALSE)) != NULL)
      denymsg = sreplace(cmd->tmp_pool, denymsg, "%u", user, NULL);

    if (denymsg)
      return ERROR_MSG(cmd, R_530, denymsg);
    else
      return ERROR_MSG(cmd, R_530, "Access denied.");
  }

  /* If request is allowable, return DECLINED (for engine to act as if this
   * handler was never called, else ERROR (for engine to abort processing and
   * deny request.
   */
  wrap_log_request_allowed(allow_severity, &request);

  return DECLINED(cmd);
}
예제 #30
0
void
client_new(struct player_control *player_control,
	   int fd, const struct sockaddr *sa, size_t sa_length, int uid)
{
	static unsigned int next_client_num;
	struct client *client;
	char *remote;

	assert(player_control != NULL);
	assert(fd >= 0);

#ifdef HAVE_LIBWRAP
	if (sa->sa_family != AF_UNIX) {
		char *hostaddr = sockaddr_to_string(sa, sa_length, NULL);
		const char *progname = g_get_prgname();

		struct request_info req;
		request_init(&req, RQ_FILE, fd, RQ_DAEMON, progname, 0);

		fromhost(&req);

		if (!hosts_access(&req)) {
			/* tcp wrappers says no */
			g_log(G_LOG_DOMAIN, LOG_LEVEL_SECURE,
			      "libwrap refused connection (libwrap=%s) from %s",
			      progname, hostaddr);

			g_free(hostaddr);
			close_socket(fd);
			return;
		}

		g_free(hostaddr);
	}
#endif	/* HAVE_WRAP */

	if (client_list_is_full()) {
		g_warning("Max Connections Reached!");
		close_socket(fd);
		return;
	}

	client = g_new0(struct client, 1);
	client->player_control = player_control;

	client->channel = g_io_channel_new_socket(fd);
	/* GLib is responsible for closing the file descriptor */
	g_io_channel_set_close_on_unref(client->channel, true);
	/* NULL encoding means the stream is binary safe; the MPD
	   protocol is UTF-8 only, but we are doing this call anyway
	   to prevent GLib from messing around with the stream */
	g_io_channel_set_encoding(client->channel, NULL, NULL);
	/* we prefer to do buffering */
	g_io_channel_set_buffered(client->channel, false);

	client->source_id = g_io_add_watch(client->channel,
					   G_IO_IN|G_IO_ERR|G_IO_HUP,
					   client_in_event, client);

	client->input = fifo_buffer_new(4096);

	client->permission = getDefaultPermissions();
	client->uid = uid;

	client->last_activity = g_timer_new();

	client->cmd_list = NULL;
	client->cmd_list_OK = -1;
	client->cmd_list_size = 0;

	client->deferred_send = g_queue_new();
	client->deferred_bytes = 0;
	client->num = next_client_num++;

	client->send_buf_used = 0;

	client->subscriptions = NULL;
	client->messages = NULL;
	client->num_messages = 0;

	(void)send(fd, GREETING, sizeof(GREETING) - 1, 0);

	client_list_add(client);

	remote = sockaddr_to_string(sa, sa_length, NULL);
	g_log(G_LOG_DOMAIN, LOG_LEVEL_SECURE,
	      "[%u] opened from %s", client->num, remote);
	g_free(remote);
}