예제 #1
0
pr_netio_stream_t *proxy_netio_open(pool *p, int strm_type, int fd, int mode) {
  int xerrno;
  pr_netio_stream_t *nstrm = NULL;
  pr_netio_t *curr_netio;

  curr_netio = proxy_netio_unset(strm_type, "netio_open");
  nstrm = pr_netio_open(p, strm_type, fd, mode);
  xerrno = errno;
  proxy_netio_set(strm_type, curr_netio);

  errno = xerrno;
  return nstrm;
}
예제 #2
0
파일: inet.c 프로젝트: Nakor78/proftpd
END_TEST

START_TEST (inet_copy_conn_test) {
  int fd = -1, sockfd = -1, port = INPORT_ANY;
  conn_t *conn, *conn2;
  const char *name;

  conn = pr_inet_copy_conn(NULL, NULL);
  fail_unless(conn == NULL, "Failed to handle null arguments");
  fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
    strerror(errno), errno);

  conn = pr_inet_copy_conn(p, NULL);
  fail_unless(conn == NULL, "Failed to handle null conn argument");
  fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
    strerror(errno), errno);

  conn = pr_inet_create_conn(p, sockfd, NULL, port, FALSE);
  fail_unless(conn != NULL, "Failed to create conn: %s", strerror(errno));

  conn2 = pr_inet_copy_conn(p, conn);
  fail_unless(conn2 != NULL, "Failed to copy conn: %s", strerror(errno));

  pr_inet_close(p, conn);
  pr_inet_close(p, conn2);

  conn = pr_inet_create_conn(p, sockfd, NULL, port, FALSE);
  fail_unless(conn != NULL, "Failed to create conn: %s", strerror(errno));

  name = "127.0.0.1";
  conn->remote_addr = pr_netaddr_get_addr(p, name, NULL);
  fail_unless(conn->remote_addr != NULL, "Failed to resolve '%s': %s",
    name, strerror(errno));
  conn->remote_name = pstrdup(p, name);
  conn->instrm = pr_netio_open(p, PR_NETIO_STRM_CTRL, fd, PR_NETIO_IO_RD);
  fail_unless(conn->instrm != NULL, "Failed to open ctrl reading stream: %s",
    strerror(errno));
  conn->outstrm = pr_netio_open(p, PR_NETIO_STRM_CTRL, fd, PR_NETIO_IO_WR);
  fail_unless(conn->instrm != NULL, "Failed to open ctrl writing stream: %s",
    strerror(errno));

  conn2 = pr_inet_copy_conn(p, conn);
  fail_unless(conn2 != NULL, "Failed to copy conn: %s", strerror(errno));

  mark_point();
  pr_inet_lingering_close(NULL, NULL, 0L);

  pr_inet_lingering_close(p, conn, 0L);
  pr_inet_close(p, conn2);

  conn = pr_inet_create_conn(p, sockfd, NULL, port, FALSE);
  fail_unless(conn != NULL, "Failed to create conn: %s", strerror(errno));

  conn->instrm = pr_netio_open(p, PR_NETIO_STRM_CTRL, fd, PR_NETIO_IO_RD);
  fail_unless(conn->instrm != NULL, "Failed to open ctrl reading stream: %s",
    strerror(errno));
  conn->outstrm = pr_netio_open(p, PR_NETIO_STRM_CTRL, fd, PR_NETIO_IO_WR);
  fail_unless(conn->instrm != NULL, "Failed to open ctrl writing stream: %s",
    strerror(errno));

  mark_point();
  pr_inet_lingering_abort(NULL, NULL, 0L);

  pr_inet_lingering_abort(p, conn, 0L);
}
예제 #3
0
END_TEST

START_TEST (inet_connect_ipv4_test) {
  int res;
  conn_t *conn;
  const pr_netaddr_t *addr;

  mark_point();
  res = proxy_inet_connect(NULL, NULL, NULL, 0);
  fail_unless(res < 0, "Failed to handle null pool");
  fail_unless(errno == EINVAL, "Expected EINVAL (%d), got '%s' (%d)", EINVAL,
    strerror(errno), errno);

  mark_point();
  res = proxy_inet_connect(p, NULL, NULL, 0);
  fail_unless(res < 0, "Failed to handle null conn");
  fail_unless(errno == EINVAL, "Expected EINVAL (%d), got '%s' (%d)", EINVAL,
    strerror(errno), errno);

  conn = pr_inet_create_conn(p, -1, NULL, INPORT_ANY, FALSE);
  fail_unless(conn != NULL, "Failed to create conn: %s", strerror(errno));

  mark_point();
  res = proxy_inet_connect(p, conn, NULL, 0);
  fail_unless(res < 0, "Failed to handle null addr");
  fail_unless(errno == EINVAL, "Expected EINVAL (%d), got '%s' (%d)", EINVAL,
    strerror(errno), errno);

  addr = pr_netaddr_get_addr(p, "127.0.0.1", NULL);
  fail_unless(addr != NULL, "Failed to resolve '127.0.0.1': %s",
    strerror(errno));

  mark_point();
  res = proxy_inet_connect(p, conn, addr, 80);
  fail_unless(res < 0, "Connected to 127.0.0.1#80 unexpectedly");
  fail_unless(errno == ECONNREFUSED,
    "Expected ECONNREFUSED (%d), got '%s' (%d)", ECONNREFUSED,
    strerror(errno), errno);
  proxy_inet_close(p, conn);

  /* Try connecting to Google's DNS server. */

  addr = pr_netaddr_get_addr(p, "8.8.8.8", NULL);
  fail_unless(addr != NULL, "Failed to resolve '8.8.8.8': %s",
    strerror(errno));

  conn = pr_inet_create_conn(p, -1, NULL, INPORT_ANY, FALSE);
  fail_unless(conn != NULL, "Failed to create conn: %s", strerror(errno));

  mark_point();
  res = proxy_inet_connect(p, conn, addr, 53);
  fail_if(res < 0, "Failed to connect to 8.8.8.8#53: %s", strerror(errno));

  mark_point();
  proxy_inet_close(p, conn);

  /* Now start supplying in/out streams. */

  conn = pr_inet_create_conn(p, -1, NULL, INPORT_ANY, FALSE);
  fail_unless(conn != NULL, "Failed to create conn: %s", strerror(errno));

  conn->instrm = pr_netio_open(p, PR_NETIO_STRM_CTRL, -1, PR_NETIO_IO_RD);
  fail_unless(conn->instrm != NULL, "Failed to open ctrl reading stream: %s",
    strerror(errno));

  mark_point();
  res = proxy_inet_connect(p, conn, addr, 53);
  fail_if(res < 0, "Failed to connect to 8.8.8.8#53: %s", strerror(errno));

  mark_point();
  proxy_inet_close(p, conn);

  conn = pr_inet_create_conn(p, -1, NULL, INPORT_ANY, FALSE);
  fail_unless(conn != NULL, "Failed to create conn: %s", strerror(errno));

  conn->instrm = pr_netio_open(p, PR_NETIO_STRM_CTRL, -1, PR_NETIO_IO_RD);
  fail_unless(conn->instrm != NULL, "Failed to open ctrl reading stream: %s",
    strerror(errno));

  conn->outstrm = pr_netio_open(p, PR_NETIO_STRM_OTHR, -1, PR_NETIO_IO_WR);
  fail_unless(conn->outstrm != NULL, "Failed to open othr writing stream: %s",
    strerror(errno));

  mark_point();
  res = proxy_inet_connect(p, conn, addr, 53);
  fail_if(res < 0, "Failed to connect to 8.8.8.8#53: %s", strerror(errno));

  mark_point();
  proxy_inet_close(p, conn);

}
예제 #4
0
END_TEST

START_TEST (inet_listen_test) {
  int res;
  conn_t *conn;

  mark_point();
  res = proxy_inet_listen(NULL, NULL, 0, 0);
  fail_unless(res < 0, "Failed to handle null arguments");
  fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
    strerror(errno), errno);

  mark_point();
  res = proxy_inet_listen(p, NULL, 0, 0);
  fail_unless(res < 0, "Failed to handle null conn");
  fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
    strerror(errno), errno);

  conn = pr_inet_create_conn(p, -1, NULL, INPORT_ANY, FALSE);
  fail_unless(conn != NULL, "Failed to create conn: %s", strerror(errno));

  mark_point();
  res = proxy_inet_listen(p, conn, 5, 0);
  fail_unless(res == 0, "Failed to listen on conn: %s", strerror(errno));

  mark_point();
  proxy_inet_close(p, conn);

  /* Now start providing in/out streams. */

  conn = pr_inet_create_conn(p, -1, NULL, INPORT_ANY, FALSE);
  fail_unless(conn != NULL, "Failed to create conn: %s", strerror(errno));

  conn->instrm = pr_netio_open(p, PR_NETIO_STRM_CTRL, -1, PR_NETIO_IO_RD);
  fail_unless(conn->instrm != NULL, "Failed to open ctrl reading stream: %s",
    strerror(errno));

  mark_point();
  res = proxy_inet_listen(p, conn, 5, 0);
  fail_unless(res == 0, "Failed to listen on conn: %s", strerror(errno));

  mark_point();
  proxy_inet_close(p, conn);

  conn = pr_inet_create_conn(p, -1, NULL, INPORT_ANY, FALSE);
  fail_unless(conn != NULL, "Failed to create conn: %s", strerror(errno));

  conn->instrm = pr_netio_open(p, PR_NETIO_STRM_CTRL, -1, PR_NETIO_IO_RD);
  fail_unless(conn->instrm != NULL, "Failed to open ctrl reading stream: %s",
    strerror(errno));

  conn->outstrm = pr_netio_open(p, PR_NETIO_STRM_OTHR, -1, PR_NETIO_IO_WR);
  fail_unless(conn->outstrm != NULL, "Failed to open othr writing stream: %s",
    strerror(errno));

  mark_point();
  res = proxy_inet_listen(p, conn, 5, 0);
  fail_unless(res == 0, "Failed to listen on conn: %s", strerror(errno));

  mark_point();
  proxy_inet_close(p, conn);
}
예제 #5
0
파일: ident.c 프로젝트: proftpd/proftpd
char *pr_ident_lookup(pool *p, conn_t *c) {
  char *ret = "UNKNOWN";
  pool *tmp_pool = NULL;
  conn_t *ident_conn = NULL, *ident_io = NULL;
  char buf[256] = {'\0'}, *tok = NULL, *tmp = NULL;
  int timerno, i = 0;
  int ident_port = pr_inet_getservport(p, "ident", "tcp");

  tmp_pool = make_sub_pool(p);
  ident_timeout = 0;
  nstrm = NULL;

  if (ident_port == -1) {
    destroy_pool(tmp_pool);
    return pstrdup(p, ret);
  }

  /* Set up our timer before going any further. */
  timerno = pr_timer_add(PR_TUNABLE_TIMEOUTIDENT, -1, NULL,
    (callback_t) ident_timeout_cb, "ident lookup");
  if (timerno <= 0) {
    destroy_pool(tmp_pool);
    return pstrdup(p, ret);
  }

  ident_conn = pr_inet_create_connection(tmp_pool, NULL, -1, c->local_addr,
    INPORT_ANY, FALSE);
  pr_inet_set_nonblock(tmp_pool, ident_conn);

  i = pr_inet_connect_nowait(tmp_pool, ident_conn, c->remote_addr, ident_port);
  if (i < 0) {
    int xerrno = errno;

    pr_timer_remove(timerno, ANY_MODULE);
    pr_inet_close(tmp_pool, ident_conn);
    pr_trace_msg(trace_channel, 5, "connection to %s, port %d failed: %s",
      pr_netaddr_get_ipstr(c->remote_addr), ident_port, strerror(xerrno));

    destroy_pool(tmp_pool);

    errno = xerrno;
    return pstrdup(p, ret);
  }

  if (!i) {
    /* Not yet connected. */
    nstrm = pr_netio_open(p, PR_NETIO_STRM_OTHR, ident_conn->listen_fd,
      PR_NETIO_IO_RD);
    pr_netio_set_poll_interval(nstrm, 1);

    switch (pr_netio_poll(nstrm)) {

      /* Aborted, timed out */
      case 1: {
        if (ident_timeout) {
          pr_timer_remove(timerno, ANY_MODULE);
          pr_netio_close(nstrm);
          pr_inet_close(tmp_pool, ident_conn);

          pr_trace_msg(trace_channel, 5, "lookup timed out, returning '%s'",
            ret);
          destroy_pool(tmp_pool);
          return pstrdup(p, ret);
        }
        break;
      }

      /* Error. */
      case -1: {
        int xerrno = errno;

        pr_timer_remove(timerno, ANY_MODULE);
        pr_netio_close(nstrm);
        pr_inet_close(tmp_pool, ident_conn);

        pr_trace_msg(trace_channel, 6, "lookup failed (%s), returning '%s'",
          strerror(xerrno), ret);
        destroy_pool(tmp_pool);

        errno = xerrno;
        return pstrdup(p, ret);
      }

      /* Connected. */
      default: {
        ident_conn->mode = CM_OPEN;

        if (pr_inet_get_conn_info(ident_conn, ident_conn->listen_fd) < 0) {
          int xerrno = errno;

          pr_timer_remove(timerno, ANY_MODULE);
          pr_netio_close(nstrm);
          pr_inet_close(tmp_pool, ident_conn);

          pr_trace_msg(trace_channel, 2,
            "lookup timed out (%s), returning '%s'", strerror(xerrno), ret);
          destroy_pool(tmp_pool);

          errno = xerrno;
          return pstrdup(p, ret);
        }
        break;
      }
    }
  }

  ident_io = pr_inet_openrw(tmp_pool, ident_conn, NULL, PR_NETIO_STRM_OTHR,
    -1, -1, -1, FALSE);
  if (ident_io == NULL) {
    int xerrno = errno;

    pr_timer_remove(timerno, ANY_MODULE);
    pr_inet_close(tmp_pool, ident_conn);

    pr_trace_msg(trace_channel, 3, "failed opening read/write connection: %s",
      strerror(xerrno));
    destroy_pool(tmp_pool);

    errno = xerrno;
    return pstrdup(p, ret);
  }

  nstrm = ident_io->instrm;

  pr_inet_set_nonblock(tmp_pool, ident_io);
  pr_netio_set_poll_interval(ident_io->instrm, 1);
  pr_netio_set_poll_interval(ident_io->outstrm, 1);

  pr_netio_printf(ident_io->outstrm, "%d, %d\r\n", c->remote_port,
    c->local_port);

  /* If the timer fires while in netio_gets(), netio_gets() will simply return
   * either a partial string, or NULL.  This works because ident_timeout_cb
   * aborts the stream from which we are reading.  netio_set_poll_interval() is
   * used to make sure significant delays don't occur on systems that
   * automatically restart syscalls after the SIGALRM signal.
   */

  pr_trace_msg(trace_channel, 4, "reading response from remote ident server");

  if (pr_netio_gets(buf, sizeof(buf), ident_io->instrm)) {
    strip_end(buf, "\r\n");

    pr_trace_msg(trace_channel, 6, "received '%s' from remote ident server",
      buf);

    tmp = buf;
    tok = get_token(&tmp, ":");
    if (tok && (tok = get_token(&tmp, ":"))) {
      while (*tok && isspace((int) *tok)) {
        pr_signals_handle();
        tok++;
      }
      strip_end(tok, " \t");

      if (strcasecmp(tok, "ERROR") == 0) {
        if (tmp) {
          while (*tmp && isspace((int) *tmp)) {
            pr_signals_handle();
            tmp++;
          }
	  strip_end(tmp, " \t");
          if (strcasecmp(tmp, "HIDDEN-USER") == 0)
            ret = "HIDDEN-USER";
        }

      } else if (strcasecmp(tok, "USERID") == 0) {
        if (tmp && (tok = get_token(&tmp, ":"))) {
          if (tmp) {
            while (*tmp && isspace((int) *tmp)) {
              pr_signals_handle();
              tmp++;
            }
            strip_end(tmp, " \t");
            ret = tmp;
          }
        }
      }
    }
  }

  pr_timer_remove(timerno, ANY_MODULE);
  pr_inet_close(tmp_pool, ident_io);
  pr_inet_close(tmp_pool, ident_conn);
  destroy_pool(tmp_pool);

  return pstrdup(p, ret);
}