コード例 #1
0
ファイル: tcpwrap.c プロジェクト: terralinux/systemd
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;
}
コード例 #2
0
ファイル: libwrap.c プロジェクト: nmacs/lm3s-uclinux
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);
}
コード例 #3
0
ファイル: service.c プロジェクト: larsks/cyrus-imapd-lks
static int libwrap_ask(struct request_info *r, int fd)
{
    int a;
    struct sockaddr_storage sin;
    socklen_t len = sizeof(sin);

    /* XXX: old FreeBSD didn't fill sockaddr correctly against AF_UNIX */
    sin.ss_family = AF_UNIX;

    /* is this a connection from the local host? */
    if (getpeername(fd, (struct sockaddr *) &sin, &len) == 0) {
	if (((struct sockaddr *)&sin)->sa_family == AF_UNIX) {
	    return 1;
	}
    }
    
    /* i hope using the sock_* functions are legal; it certainly makes
       this code very easy! */
    request_set(r, RQ_FILE, fd, 0);
    sock_host(r);

    a = hosts_access(r);
    if (!a) {
	syslog(deny_severity, "refused connection from %s", eval_client(r));
    }

    return a;
}
コード例 #4
0
ファイル: afsocket-source.c プロジェクト: jbfuzier/syslog-ng
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;
}
コード例 #5
0
ファイル: security.c プロジェクト: junxzm1990/rpcbind
int 
check_access(SVCXPRT *xprt, rpcproc_t proc, rpcprog_t prog, unsigned int rpcbvers)
{
	struct netbuf *caller = svc_getrpccaller(xprt);
	struct sockaddr *addr = (struct sockaddr *)caller->buf;
#ifdef LIBWRAP
	struct request_info req;
#endif

	/*
	 * The older PMAP_* equivalents have the same numbers, so
	 * they are accounted for here as well.
	 */
	switch (proc) {
	case RPCBPROC_SET:
	case RPCBPROC_UNSET:
		if (!insecure && !is_loopback(caller)) {
#ifdef RPCBIND_DEBUG
			  if (debugging)
			    fprintf(stderr, " declined (non-loopback sender) \n");
#endif
			if (verboselog)
				logit(log_severity, addr, proc, prog,
				    " declined (non-loopback sender)");
			return 0;
		}
		break;
	case RPCBPROC_GETADDR:
	case RPCBPROC_CALLIT:
	case RPCBPROC_INDIRECT:
	case RPCBPROC_DUMP:
	case RPCBPROC_GETTIME:
	case RPCBPROC_UADDR2TADDR:
	case RPCBPROC_TADDR2UADDR:
	case RPCBPROC_GETVERSADDR:
	case RPCBPROC_GETADDRLIST:
	case RPCBPROC_GETSTAT:
	default:
		break;
	}

#ifdef LIBWRAP
	if (addr->sa_family == AF_LOCAL)
		return 1;
	request_init(&req, RQ_DAEMON, "rpcbind", RQ_CLIENT_SIN, addr, 0);
	sock_methods(&req);
	if(!hosts_access(&req)) {

	  logit(deny_severity, addr, proc, prog, ": request from unauthorized host");
		return 0;
	}
#endif
	if (verboselog)
		logit(log_severity, addr, proc, prog, "");
    	return 1;
}
コード例 #6
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);
}
コード例 #7
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;
}
コード例 #8
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);
}
コード例 #9
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;
}
コード例 #10
0
ファイル: client.old.c プロジェクト: niubl/camera_project
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 */
}
コード例 #11
0
ファイル: stub_server.c プロジェクト: wl500g/usbip-no-glib
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;
}
コード例 #12
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);
}
コード例 #13
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;
}
コード例 #14
0
ファイル: driver.c プロジェクト: AhmadTux/DragonFlyBSD
/*
 * 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);
}
コード例 #15
0
ファイル: client.c プロジェクト: bohrasd/windowsrtdev
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 */
}
コード例 #16
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);
}
コード例 #17
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);
}
コード例 #18
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);
}
コード例 #19
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;
}
コード例 #20
0
ファイル: pptpmanager.c プロジェクト: AdrianBan/accel-pptpd
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;
}
コード例 #21
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);
}  
コード例 #22
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;
}
コード例 #23
0
int
main(int argc, char **argv)
{
	struct tftphdr *tp;
	struct passwd *pw;
	struct options *opt;
	struct sockaddr_in myaddr;
	struct sockaddr_in servaddr;
	int n = 0;
	int on = 1;
	int fd = 0;
	int pid, xx;
	int c;
	int setrv;
	int timeout = 900;	/* Default timeout */
	//	char *user = "******";	/* Default user */
	char *user = "******";	/* Default user */

	__progname = basename(argv[0]);

	openlog(__progname, LOG_PID | LOG_NDELAY, LOG_DAEMON);

	while ((c = getopt(argc, argv, "csu:r:t:")) != -1)
		switch (c) {
		case 'c':
			cancreate = 1;
			break;
		case 's':
			secure = 1;
			break;
		case 't':
		  timeout = atoi(optarg);
		  break;
		case 'u':
		  user = optarg;
		  break;
		case 'r':
		  for ( opt = options ; opt->o_opt ; opt++ ) {
		    if ( !strcasecmp(optarg, opt->o_opt) ) {
		      opt->o_opt = ""; /* Don't support this option */
		      break;
		    }
		  }
		  if ( !opt->o_opt ) {
		        syslog(LOG_ERR, "Unknown option: %s", optarg);
			exit(1);
		  }
		  break;

		default:
			usage();
			break;
		}

	for (; optind != argc; optind++) {
		if (dirs)
			dirs = realloc(dirs, (ndirs+2) * sizeof (char *));
		else
			dirs = calloc(ndirs+2, sizeof(char *));
		if (dirs == NULL) {
			syslog(LOG_ERR, "malloc: %m");
			exit(1);
		}			
		dirs[n++] = argv[optind];
		dirs[n] = NULL;
		ndirs++;
	}

	if (secure) {
		if (ndirs == 0) {
			syslog(LOG_ERR, "no -s directory");
			exit(1);
		}
		if (ndirs > 1) {
			syslog(LOG_ERR, "too many -s directories");
			exit(1);
		}
		if (chdir(dirs[0])) {
			syslog(LOG_ERR, "%s: %m", dirs[0]);
			exit(1);
		}
	}

	pw = getpwnam(user);
	if (!pw) {
		syslog(LOG_ERR, "no user %s: %m", user);
		exit(1);
	}

#if KAM_LATER   // not needed if not by inetd
	if (ioctl(fd, FIONBIO, &on) < 0) {
		syslog(LOG_ERR, "ioctl(FIONBIO): %m");
		exit(1);
	}
#else
	// bind to default tftp port
	if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
		exit(1);
	}
	//printf("fd=%d\n",fd);

        on = 1;
        setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void*)&on, sizeof(on));
	                                      
	bzero(&servaddr, sizeof(servaddr));     /* zero the struct */
	servaddr.sin_family = AF_INET;         /* host byte order */
	servaddr.sin_port = htons(IPPORT_TFTP);/* short, network byte order */
	servaddr.sin_addr.s_addr = INADDR_ANY; /* auto-fill with my IP */

	if (bind(fd, (struct sockaddr *)&servaddr, sizeof(struct sockaddr)) == -1) 
	{
	  	close(fd);
		exit(1);
	}
#endif
	/* This means we don't want to wait() for children */
	bsd_signal(SIGCHLD, SIG_IGN);

	
	// Set up signal handlers so we can clear up our child processes
//	signal(SIGTERM, signal_handler);
	signal(SIGHUP, signal_handler);
	signal(SIGINT, signal_handler);
	signal(SIGCHLD, signal_handler);
	signal(SIGKILL, signal_handler);

	xx = fork();

	if(xx==-1)
	{
		syslog(LOG_CRIT, "Could not fork() tftpd into background\n");
		closelog();
		close(fd);
		exit(1);
	}
	if(xx != 0) {	// Parent...
	  printf("tftp in background pid=%d\n",xx);
		exit(0);
	}

	do {
	  fromlen = sizeof (from);
	  //	  printf("recvfrom %d: ",fd);
#if KAM_LATER	  
	  n = myrecvfrom(fd, buf, sizeof (buf), 0,
			 (struct sockaddr *)&from, &fromlen,
			 &myaddr);
#else
	  bzero(&myaddr, sizeof(struct sockaddr_in));
	  myaddr.sin_family = AF_INET;
	  myaddr.sin_port   = htons(IPPORT_TFTP);
	  n = recvfrom(fd, buf, sizeof (buf), 0,
		       (struct sockaddr *)&from, &fromlen);
#endif
	  
	  if (n < 0) {
	    syslog(LOG_ERR, "recvfrom: %m");
	    exit(1);
	  }

	  //printf("%d bytes ",n);
#if KAM_LATER
//#ifdef HAVE_TCPWRAPPERS
	/* Verify if this was a legal request for us.  This has to be
	   done before the chroot, while /etc is still accessible. */
	  request_init(&wrap_request,
		       RQ_DAEMON, __progname,
		       RQ_FILE, fd,
		       RQ_CLIENT_SIN, &from,
		       RQ_SERVER_SIN, &myaddr,
		       0);
	  sock_methods(&wrap_request);
	  if ( hosts_access(&wrap_request) == 0 ) {
	    if ( deny_severity != -1 )
	      syslog(deny_severity, "connection refused from %s",
		     inet_ntoa(from.sin_addr));
	    exit(1);		/* Access denied */
	  } else if ( allow_severity != -1 ) {
	    syslog(allow_severity, "connect from %s",
		   inet_ntoa(from.sin_addr));
	  }
#endif
	/*
	 * Now that we have read the message out of the UDP
	 * socket, we fork and go back to listening to the
	 * socket.
	 */
	  pid = fork();
	  if (pid < 0) {
	    syslog(LOG_ERR, "fork: %m");
	    exit(1);		/* Return to inetd, just in case */
	  }
	} while ( pid > 0 );	/* Parent process continues... */

	/* Child process: handle the actual request here */

	/* Chroot and drop privileges */

	if (secure && chroot(".")) {
		syslog(LOG_ERR, "chroot: %m");
		exit(1);
	}

#ifdef HAVE_SETREGID
	setrv = setregid(pw->pw_gid, pw->pw_gid);
#else
	setrv = setegid(pw->pw_gid) || setgid(pw->pw_gid);
#endif

#ifdef HAVE_SETREUID
	setrv = setrv || setreuid(pw->pw_uid, pw->pw_uid);
#else
	/* Important: setuid() must come first */
	setrv = setrv || setuid(pw->pw_uid) ||
	  (geteuid() != pw->pw_uid && seteuid(pw->pw_uid));
#endif

	if ( setrv ) {
	  syslog(LOG_ERR, "cannot drop privileges: %m");
	  exit(1);
	}

	/* Close file descriptors we don't need */

	from.sin_family = AF_INET;
	alarm(0);
#if KAM_LATER
	close(fd);
	close(1);
#endif

	/* Process the request... */

	peer = socket(AF_INET, SOCK_DGRAM, 0);
	if (peer < 0) {
		syslog(LOG_ERR, "socket: %m");
		exit(1);
	}
	myaddr.sin_port = htons(0); /* We want a new local port */
	if (bind(peer, (struct sockaddr *)&myaddr, sizeof (myaddr)) < 0) {
		syslog(LOG_ERR, "bind: %m");
		exit(1);
	}
	if (connect(peer, (struct sockaddr *)&from, sizeof(from)) < 0) {
		syslog(LOG_ERR, "connect: %m");
		exit(1);
	}
	tp = (struct tftphdr *)buf;
	tp->th_opcode = ntohs(tp->th_opcode);
	if (tp->th_opcode == RRQ || tp->th_opcode == WRQ) {
	  tftp(tp, n);
	}
	exit(0);
}
コード例 #24
0
int main( int argc, char *argv[] )
{
    char *fn = "main()";
    char f_randfile[ PATH_MAX ];
    int listensd;                      /* socket descriptor we'll bind to */
    int clientsd;                      /* incoming socket descriptor */
    int addrlen;
    struct sockaddr_in srvaddr;
    struct sockaddr_in cliaddr;
    pthread_t ThreadId;                /* thread id of each incoming conn */
    pthread_t RecycleThread;           /* used just for the recycle thread */
    pthread_attr_t attr;               /* generic thread attribute struct */
    int rc, i, fd;
    unsigned int ui;
    pid_t pid;                         /* used just for a fork call */
    struct linger lingerstruct;        /* for the socket reuse stuff */
    int flag;                          /* for the socket reuse stuff */
    ICC_Struct *ICC_tptr;
    extern char *optarg;
    extern int optind;
    char ConfigFile[ MAXPATHLEN ];     /* path to our config file */
#ifdef HAVE_LIBWRAP
    struct request_info r;             /* request struct for libwrap */
#endif

    flag = 1;
    ConfigFile[0] = '\0';

    /*
     * Ignore signals we don't want to die from but we don't care enough
     * about to catch.
     */
    signal( SIGPIPE, SIG_IGN );
    signal( SIGHUP, SIG_IGN );


    while (( i = getopt( argc, argv, "f:h" ) ) != EOF )
    {
        switch( i )
        {
        case 'f':
            /* user specified a config filename */
            strncpy( ConfigFile, optarg, sizeof ConfigFile -1 );
            ConfigFile[ sizeof ConfigFile - 1 ] = '\0';
            syslog( LOG_INFO, "%s: Using configuration file '%s'",
                    fn, ConfigFile );
            break;

        case 'h':
            Usage();
            exit( 0 );

        case '?':
            Usage();
            exit( 1 );
        }
    }


    /*
     * Make sure we know which config file to use and then set our config
     * options.
     */
    if ( ! ConfigFile[0] )
    {
        strncpy( ConfigFile, DEFAULT_CONFIG_FILE, sizeof ConfigFile -1 );
        ConfigFile[ sizeof ConfigFile - 1 ] = '\0';
        syslog( LOG_INFO, "%s: Using default configuration file '%s'.",
                fn, ConfigFile );
    }

    SetConfigOptions( ConfigFile );
    SetLogOptions();

    /*
     * Just for logging purposes, are we doing SELECT caching or not?
     */
    if ( PC_Struct.enable_select_cache )
        syslog( LOG_INFO, "%s: SELECT caching is enabled", fn );
    else
        syslog( LOG_INFO, "%s: SELECT caching is disabled", fn );

#ifdef HAVE_LIBWRAP
    /*
     * Set our tcpd service name
     */
    if (service = strrchr(argv[0], '/'))
        service++;
    else
        service = argv[0];
#endif

    /*
     * Initialize some stuff.
     */
    rc = pthread_mutex_init(&mp, NULL);
    if ( rc )
    {
        syslog(LOG_ERR, "%s: pthread_mutex_init() returned error [%d] initializing main mutex.  Exiting.", fn, rc );
        exit( 1 );
    }

    rc = pthread_mutex_init(&trace, NULL);
    if ( rc )
    {
        syslog(LOG_ERR, "%s: pthread_mutex_init() returned error [%d] initializing trace mutex.  Exiting.", fn, rc );
        exit( 1 );
    }

    TraceUser[0] = '\0';

    syslog( LOG_INFO, "%s: Allocating %d IMAP connection structures.",
            fn, PC_Struct.cache_size );

    ICC_free = (ICC_Struct *)malloc( ( sizeof ( ICC_Struct ) )
                                     * PC_Struct.cache_size );

    if ( ! ICC_free )
    {
        syslog(LOG_ERR, "%s: malloc() failed to allocate [%d] IMAPConnectionContext structures: %s", fn, PC_Struct.cache_size, strerror( errno ) );
        exit( 1 );
    }

    memset( ICC_free, 0, sizeof ( ICC_Struct ) * PC_Struct.cache_size );

    ICC_tptr = ICC_free;

    /*
     * Bug fixed by Gary Mills <*****@*****.**>.  I was pre-incrementing
     * ICC_tptr and then assigning.  I guess gcc evaluates the expression
     * incorrectly, since I never had a problem with this.  Gary had the
     * problem with cc, so it's fixed here.
     */
    for ( ui = 0; ui < PC_Struct.cache_size - 1; ui++ )
    {
        ICC_tptr->next = ICC_tptr + 1;
        ICC_tptr++;
    }

    memset( ICC_HashTable, 0, sizeof ICC_HashTable );

    ServerInit();

    /* detach from our parent if necessary */
    if (! (getppid() == 1) && ( ! PC_Struct.foreground_mode ) )
    {
        syslog( LOG_INFO, "%s: Configured to run in background mode.", fn );

        if ( (pid = fork()) < 0)
        {
            syslog(LOG_ERR, "%s: initial call to fork() failed: %s", fn, strerror(errno));
            exit( 1 );
        }
        else if ( pid > 0)
        {
            exit( 0 );
        }

        if (setsid() == -1)
        {
            syslog(LOG_WARNING, "%s: setsid() failed: %s",
                   fn, strerror(errno));
        }
        if ( (pid = fork()) < 0)
        {
            syslog(LOG_ERR, "%s: secondary call to fork() failed: %s", fn,
                   strerror(errno));
            exit( 1 );
        }
        else if ( pid > 0)
        {
            exit( 0 );
        }
    }
    else
    {
        syslog( LOG_INFO, "%s: Configured to run in foreground mode.", fn );
    }


    SetBannerAndCapability();

    if ( PC_Struct.login_disabled || PC_Struct.force_tls )
    {
        syslog( LOG_INFO, "%s: Enabling STARTTLS.", fn );
#if HAVE_LIBSSL
        if ( PC_Struct.support_starttls )
        {
            /* Initialize SSL_CTX */
            SSL_library_init();

            /* Need to seed PRNG, too! */
            if ( RAND_egd( ( RAND_file_name( f_randfile, sizeof( f_randfile ) ) == f_randfile ) ? f_randfile : "/.rnd" ) )
            {
                /* Not an EGD, so read and write it. */
                if ( RAND_load_file( f_randfile, -1 ) )
                    RAND_write_file( f_randfile );
            }

            SSL_load_error_strings();
            tls_ctx = SSL_CTX_new( TLSv1_client_method() );
            if ( tls_ctx == NULL )
            {
                syslog(LOG_ERR, "%s: Failed to create new SSL_CTX.  Exiting.", fn);
                exit( 1 );
            }

            /* Work around all known bugs */
            SSL_CTX_set_options( tls_ctx, SSL_OP_ALL );

            if ( ! SSL_CTX_load_verify_locations( tls_ctx,
                                                  PC_Struct.tls_ca_file,
                                                  PC_Struct.tls_ca_path ) ||
                    ! SSL_CTX_set_default_verify_paths( tls_ctx ) )
            {
                syslog(LOG_ERR, "%s: Failed to load CA data.  Exiting.", fn);
                exit( 1 );
            }

            if ( ! set_cert_stuff( tls_ctx,
                                   PC_Struct.tls_cert_file,
                                   PC_Struct.tls_key_file ) )
            {
                syslog(LOG_ERR, "%s: Failed to load cert/key data.  Exiting.", fn);
                exit( 1 );
            }

            SSL_CTX_set_verify(tls_ctx, SSL_VERIFY_NONE, verify_callback);
        }
        else
#endif /* HAVE_LIBSSL */
        {
            /* We're screwed!  We won't be able to login without SASL */
            syslog(LOG_ERR, "%s: IMAP server has LOGINDISABLED and we can't do STARTTLS.  Exiting.", fn);
            exit( 1 );
        }
    }

    memset( (char *) &srvaddr, 0, sizeof srvaddr );
    srvaddr.sin_family = PF_INET;
    if ( !PC_Struct.listen_addr )
    {
        srvaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    }
    else
    {
        srvaddr.sin_addr.s_addr = inet_addr( PC_Struct.listen_addr );
        if ( srvaddr.sin_addr.s_addr  == -1 )
        {
            syslog( LOG_ERR, "%s: bad bind address: '%s' specified in config file.  Exiting.", fn, PC_Struct.listen_addr );
            exit( 1 );
        }
    }


    syslog(LOG_INFO, "%s: Binding to tcp %s:%d", fn, PC_Struct.listen_addr ?
           PC_Struct.listen_addr : "*", PC_Struct.listen_port );
    srvaddr.sin_port = htons(PC_Struct.listen_port);

    listensd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
    if ( listensd == -1 )
    {
        syslog(LOG_ERR, "%s: socket() failed: %s", fn, strerror(errno));
        exit( 1 );
    }

    setsockopt(listensd, SOL_SOCKET, SO_REUSEADDR, (void *)&flag,
               sizeof(flag));
    lingerstruct.l_onoff = 1;
    lingerstruct.l_linger = 5;
    setsockopt(listensd, SOL_SOCKET, SO_LINGER, (void *)&lingerstruct,
               sizeof(lingerstruct));

    if ( PC_Struct.send_tcp_keepalives )
    {
        lingerstruct.l_onoff = 1;
        syslog( LOG_INFO, "%s: Enabling SO_KEEPALIVE.", fn );
        setsockopt( listensd, SOL_SOCKET, SO_KEEPALIVE, (void *)&lingerstruct.l_onoff, sizeof lingerstruct.l_onoff );
    }


    if ( bind(listensd, (struct sockaddr *)&srvaddr, sizeof( srvaddr ) ) < 0 )
    {
        syslog(LOG_ERR, "%s: bind() failed: %s", fn, strerror(errno) );
        exit( 1 );
    }

    /*
     * Create and mmap() our stat file while we're still root.  Since it's
     * configurable, we want to make sure we do this as root so there's the
     * greatest possibility that we'll have permission to write where we
     * need to.
     */
    syslog( LOG_INFO, "%s: Using global statistics file '%s'", fn,
            PC_Struct.stat_filename );

    fd = open( PC_Struct.stat_filename, O_RDWR | O_CREAT, S_IREAD | S_IWRITE );
    if ( fd == -1 )
    {
        syslog(LOG_ERR, "%s: open() failed for '%s': %s -- Exiting.", fn,
               PC_Struct.stat_filename, strerror( errno ) );
        exit( 1 );
    }

    if ( ( ftruncate( fd, sizeof( IMAPCounter_Struct ) ) ) == -1 )
    {
        syslog(LOG_ERR, "%s: ftruncate() failed: %s -- Exiting.",
               fn, strerror( errno ) );
        exit( 1 );
    }

    IMAPCount = ( IMAPCounter_Struct *)mmap( 0, sizeof( IMAPCounter_Struct ),
                PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0 );

    if ( IMAPCount == MAP_FAILED )
    {
        syslog(LOG_ERR, "%s: mmap() failed: %s -- Exiting.",
               fn, strerror( errno ) );
        exit( 1 );
    }

    memset( IMAPCount, 0, sizeof( IMAPCounter_Struct ) );
    IMAPCount->StartTime = time( 0 );
    IMAPCount->CountTime = time( 0 );

    if ( BecomeNonRoot() )
        exit( 1 );

    /* some misc thread setup */
    rc = pthread_attr_init( &attr );
    if ( rc )
    {
        syslog(LOG_ERR, "%s: pthread_attr_init() failed: [%d]\n", fn, rc);
        exit( 1 );
    }

    rc = pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_DETACHED );
    if ( rc )
    {
        syslog(LOG_ERR, "%s: pthread_attr_setdetachstate() failed: [%d]\n",
               fn, rc);
        exit( 1 );
    }

    /* launch a recycle thread before we loop */
    pthread_create( &RecycleThread, &attr, (void *)ICC_Recycle_Loop, NULL );

    syslog(LOG_INFO, "%s: Launched ICC recycle thread with id %d",
           fn, RecycleThread );

    /*
     * Now start listening and accepting connections.
     */
    if ( listen(listensd, MAX_CONN_BACKLOG) < 0)
    {
        syslog( LOG_ERR, "%s: listen() failed: %s -- Exiting",
                fn, strerror(errno));
        exit( 1 );
    }

    syslog( LOG_INFO, "%s: Normal server startup.", fn );

    /*
     * Main server loop
     */
    for ( ;; )
    {
        /*
         * Bug fixed by Gary Mills <*****@*****.**>.  I forgot
         * to initialize addrlen.
         */
        addrlen = sizeof cliaddr;
        clientsd = accept( listensd, (struct sockaddr *)&cliaddr, &addrlen );
        if ( clientsd == -1 )
        {
            syslog(LOG_WARNING, "%s: accept() failed: %s -- retrying",
                   fn, strerror(errno));
            sleep( 1 );
            continue;
        }

#ifdef HAVE_LIBWRAP
        request_init(&r, RQ_DAEMON, service, 0);
        request_set(&r, RQ_FILE, clientsd, 0);
        sock_host(&r);
        if (!hosts_access(&r))
        {
            shutdown(clientsd, SHUT_RDWR);
            close(clientsd);
            syslog(deny_severity, "refused connection from %s", eval_client(&r));
            continue;
        }
#endif

        IMAPCount->TotalClientConnectionsAccepted++;
        IMAPCount->CurrentClientConnections++;

        if ( IMAPCount->CurrentClientConnections >
                IMAPCount->PeakClientConnections )
            IMAPCount->PeakClientConnections = IMAPCount->CurrentClientConnections;

        pthread_create( &ThreadId, &attr, (void *)HandleRequest, (void *)clientsd );

    }
}
コード例 #25
0
int my_hosts_access(struct request_info *req)
{
  return hosts_access(req);
}
コード例 #26
0
ファイル: nrpe.c プロジェクト: Honwhy/icinga-nrpe-ipv6
/* 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
ファイル: 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 */
}
コード例 #28
0
ファイル: xio-tcpwrap.c プロジェクト: dest-unreach/socat2
/* returns -1 if forbidden, 0 if no tcpwrap check, or 1 if explicitely allowed
   */
int xio_tcpwrap_check(xiosingle_t *xfd, union sockaddr_union *us,
		      union sockaddr_union *them) {
   char *save_hosts_allow_table, *save_hosts_deny_table;
   struct request_info ri;
#if WITH_IP6
   char clientaddr[INET6_ADDRSTRLEN] = "", serveraddr[INET6_ADDRSTRLEN] = "";
#else
   char clientaddr[INET_ADDRSTRLEN] = "", serveraddr[INET_ADDRSTRLEN] = "";
#endif
   int allow;

   if (!xfd->para.socket.ip.dolibwrap) {
      return 0;
   }
   if (us == NULL || them == NULL)  { return -1; }

#if defined(HAVE_HOSTS_ALLOW_TABLE)
   save_hosts_allow_table = hosts_allow_table;
   if (xfd->para.socket.ip.hosts_allow_table) {
      Debug1("hosts_allow_table = \"%s\"",
	     xfd->para.socket.ip.hosts_allow_table);
      hosts_allow_table = xfd->para.socket.ip.hosts_allow_table;
   }
#endif /* defined(HAVE_HOSTS_ALLOW_TABLE) */
#if defined(HAVE_HOSTS_DENY_TABLE)
   save_hosts_deny_table  = hosts_deny_table;
   if (xfd->para.socket.ip.hosts_deny_table) {
      Debug1("hosts_deny_table = \"%s\"",
	     xfd->para.socket.ip.hosts_deny_table);
      hosts_deny_table  = xfd->para.socket.ip.hosts_deny_table;
   }
#endif /* defined(HAVE_HOSTS_DENY_TABLE) */

   hosts_access_verbose = 32767;
   if (inet_ntop(them->soa.sa_family,
#if WITH_IP6
		 them->soa.sa_family==PF_INET6 ?
		 (void *)&them->ip6.sin6_addr :
#endif
		 (void *)&them->ip4.sin_addr,
		 clientaddr, sizeof(clientaddr)) == NULL) {
      Warn1("inet_ntop(): %s", strerror(errno));
   }
   if (inet_ntop(us->soa.sa_family,
#if WITH_IP6
		 us->soa.sa_family==PF_INET6 ?
		 (void *)&us->ip6.sin6_addr : 
#endif
		 (void *)&us->ip4.sin_addr,
		 serveraddr, sizeof(serveraddr)) == NULL) {
      Warn1("inet_ntop(): %s", strerror(errno));
   }
   Debug7("request_init(%p, RQ_FILE, %d, RQ_CLIENT_SIN, {%s:%u}, RQ_SERVER_SIN, {%s:%u}, RQ_DAEMON, \"%s\", 0",
	   &ri, xfd->rfd, clientaddr,
	   ntohs(((struct sockaddr_in *)them)->sin_port),
	   serveraddr, ntohs(us->ip4.sin_port),
	   xfd->para.socket.ip.libwrapname?xfd->para.socket.ip.libwrapname:(char *)diag_get_string('p'));
   request_init(&ri, RQ_FILE, xfd->rfd,
		RQ_CLIENT_SIN, them,
		RQ_SERVER_SIN, &us->soa,
		RQ_DAEMON, xfd->para.socket.ip.libwrapname?xfd->para.socket.ip.libwrapname:(char *)diag_get_string('p'), 0);
   Debug("request_init() ->");

   Debug1("sock_methods(%p)", &ri);
   sock_methods(&ri);
   Debug("sock_methods() ->");

   Debug1("hosts_access(%p)", &ri);
   allow = hosts_access(&ri);
   Debug1("hosts_access() -> %d", allow);

#if defined(HAVE_HOSTS_ALLOW_TABLE)
   hosts_allow_table = save_hosts_allow_table;
#endif
#if defined(HAVE_HOSTS_DENY_TABLE)
   hosts_deny_table  = save_hosts_deny_table;
#endif
   if (allow == 0) {
      return -1;
   }
   return 1;
}
コード例 #29
0
ファイル: driver.c プロジェクト: AhmadTux/DragonFlyBSD
/*
 * 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");
}
コード例 #30
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;
}