Пример #1
0
server_rec *pr_parser_server_ctxt_open(const char *addrstr) {
  server_rec *s;
  pool *p;

  p = make_sub_pool(permanent_pool);
  pr_pool_tag(p, "<VirtualHost> Pool");

  s = (server_rec *) pcalloc(p, sizeof(server_rec));
  s->pool = p;
  s->config_type = CONF_VIRTUAL;
  s->sid = ++parser_sid;
  s->notes = pr_table_nalloc(p, 0, 8);

  /* TCP KeepAlive is enabled by default, with the system defaults. */
  s->tcp_keepalive = palloc(s->pool, sizeof(struct tcp_keepalive));
  s->tcp_keepalive->keepalive_enabled = TRUE;
  s->tcp_keepalive->keepalive_idle = -1;
  s->tcp_keepalive->keepalive_count = -1;
  s->tcp_keepalive->keepalive_intvl = -1;

  /* Have to make sure it ends up on the end of the chain, otherwise
   * main_server becomes useless.
   */
  xaset_insert_end(*parser_server_list, (xasetmember_t *) s);
  s->set = *parser_server_list;
  if (addrstr) {
    s->ServerAddress = pstrdup(s->pool, addrstr);
  }

  /* Default server port */
  s->ServerPort = pr_inet_getservport(s->pool, "ftp", "tcp");

  (void) pr_parser_server_ctxt_push(s);
  return s;
}
Пример #2
0
static void create_main_server(void) {
  pool *main_pool;

  main_pool = make_sub_pool(permanent_pool);
  pr_pool_tag(main_pool, "testsuite#main_server pool");

  server_list = xaset_create(main_pool, NULL);

  main_server = (server_rec *) pcalloc(main_pool, sizeof(server_rec));
  xaset_insert(server_list, (xasetmember_t *) main_server);

  main_server->pool = main_pool;
  main_server->conf = xaset_create(main_pool, NULL);
  main_server->set = server_list;
  main_server->sid = 1;
  main_server->notes = pr_table_nalloc(main_pool, 0, 8);

  /* TCP KeepAlive is enabled by default, with the system defaults. */
  main_server->tcp_keepalive = palloc(main_server->pool,
    sizeof(struct tcp_keepalive));
  main_server->tcp_keepalive->keepalive_enabled = TRUE;
  main_server->tcp_keepalive->keepalive_idle = -1;
  main_server->tcp_keepalive->keepalive_count = -1;
  main_server->tcp_keepalive->keepalive_intvl = -1;

  main_server->ServerName = "Test Server";
  main_server->ServerPort = 21;
}
Пример #3
0
static pr_netio_stream_t *netio_stream_alloc(pool *parent_pool) {
  pool *netio_pool = NULL;
  pr_netio_stream_t *nstrm = NULL;

  if (!parent_pool) {
    errno = EINVAL;
    return NULL;
  }

  netio_pool = make_sub_pool(parent_pool);
  nstrm = pcalloc(netio_pool, sizeof(pr_netio_stream_t));

  nstrm->strm_pool = netio_pool;
  nstrm->strm_fd = -1;
  nstrm->strm_mode = 0;
  nstrm->strm_flags = 0;
  nstrm->strm_buf = NULL;
  nstrm->strm_data = NULL;
  nstrm->strm_errno = 0;

  /* This table will not contain that many entries, so a low number
   * of chains should suffice.
   */
  nstrm->notes = pr_table_nalloc(nstrm->strm_pool, 0, 4);

  return nstrm;
}
Пример #4
0
int proxy_ftp_sess_get_feat(pool *p, struct proxy_session *proxy_sess) {
    pool *tmp_pool;
    int res, xerrno = 0;
    cmd_rec *cmd;
    pr_response_t *resp;
    unsigned int resp_nlines = 0;
    char *feats, *token;
    size_t token_len = 0;

    tmp_pool = make_sub_pool(p);

    cmd = pr_cmd_alloc(tmp_pool, 1, C_FEAT);
    res = proxy_ftp_ctrl_send_cmd(tmp_pool, proxy_sess->backend_ctrl_conn, cmd);
    if (res < 0) {
        xerrno = errno;

        pr_trace_msg(trace_channel, 4,
                     "error sending %s to backend: %s", (char *) cmd->argv[0],
                     strerror(xerrno));
        destroy_pool(tmp_pool);

        errno = xerrno;
        return -1;
    }

    resp = proxy_ftp_ctrl_recv_resp(tmp_pool, proxy_sess->backend_ctrl_conn,
                                    &resp_nlines);
    if (resp == NULL) {
        xerrno = errno;

        pr_trace_msg(trace_channel, 4,
                     "error receiving %s response from backend: %s", (char *) cmd->argv[0],
                     strerror(xerrno));
        destroy_pool(tmp_pool);

        errno = xerrno;
        return -1;
    }

    if (resp->num[0] != '2') {
        pr_trace_msg(trace_channel, 4,
                     "received unexpected %s response code %s from backend",
                     (char *) cmd->argv[0], resp->num);

        /* Note: If the UseProxyProtocol ProxyOption is enabled, AND if the
         * response message mentions a "PROXY" command, we might read an
         * error response here that is NOT actually for the FEAT command we just
         * sent.
         *
         * A backend FTP server which does not understand the PROXY protocol
         * will treat it as a normal FTP command, and respond.  And that will
         * put us, the client, out of lockstep with the server, for how do we know
         * that we need to read that error response FIRST, then send another
         * command?
         */

        destroy_pool(tmp_pool);
        errno = EPERM;
        return -1;
    }

    proxy_sess->backend_features = pr_table_nalloc(p, 0, 4);

    feats = resp->msg;
    token = pr_str_get_token2(&feats, (char *) feat_crlf, &token_len);
    while (token != NULL) {
        pr_signals_handle();

        if (token_len > 0) {
            /* The FEAT response lines in which we are interested all start with
             * a single space, per RFC spec.  Ignore any other lines.
             */
            if (token[0] == ' ') {
                char *key, *val, *ptr;

                /* Find the next space in the string, to delimit our key/value pairs. */
                ptr = strchr(token + 1, ' ');
                if (ptr != NULL) {
                    key = pstrndup(p, token + 1, ptr - token - 1);
                    val = pstrdup(p, ptr + 1);

                } else {
                    key = pstrdup(p, token + 1);
                    val = pstrdup(p, "");
                }

                pr_table_add(proxy_sess->backend_features, key, val, 0);
            }
        }

        feats = token + token_len + 1;
        token = pr_str_get_token2(&feats, (char *) feat_crlf, &token_len);
    }

    destroy_pool(tmp_pool);
    return 0;
}
Пример #5
0
int proxy_db_open(pool *p, const char *table_path, const char *schema_name) {
  int res;
  pool *tmp_pool;
  const char *stmt;

  if (p == NULL ||
      table_path == NULL) {
    errno = EINVAL;
    return -1;
  }

  /* If we already have a database handle open, then attach the given
   * path to our handle.  Otherwise, open/create the database file first.
   */

  if (proxy_dbh == NULL) {
    res = sqlite3_open(table_path, &proxy_dbh);
    if (res != SQLITE_OK) {
      pr_log_debug(DEBUG0, MOD_PROXY_VERSION
        ": error opening SQLite database '%s': %s", table_path,
        sqlite3_errmsg(proxy_dbh));
      errno = EPERM;
      return -1;
    }

    /* Tell SQLite to only use in-memory journals.  This is necessary for
     * working properly when a chroot is used.  Note that the MEMORY journal
     * mode of SQLite is supported only for SQLite-3.6.5 and later.
     */
    res = sqlite3_exec(proxy_dbh, "PRAGMA journal_mode = MEMORY;", NULL, NULL,
      NULL);
    if (res != SQLITE_OK) {
      pr_trace_msg(trace_channel, 2,
        "error setting MEMORY journal mode on SQLite database '%s': %s",
        table_path, sqlite3_errmsg(proxy_dbh));
    }

    if (pr_trace_get_level(trace_channel) >= PROXY_DB_SQLITE_TRACE_LEVEL) {
      sqlite3_trace(proxy_dbh, db_trace, NULL);
    }

    prepared_stmts = pr_table_nalloc(db_pool, 0, 4);
  }

  tmp_pool = make_sub_pool(p);

  stmt = pstrcat(tmp_pool, "ATTACH DATABASE '", table_path, "' AS ",
    schema_name, ";", NULL);
  res = sqlite3_exec(proxy_dbh, stmt, NULL, NULL, NULL);
  if (res != SQLITE_OK) {
    pr_trace_msg(trace_channel, 2,
      "error attaching database '%s' (as '%s') to existing SQLite handle "
      "using '%s': %s", table_path, schema_name, stmt,
      sqlite3_errmsg(proxy_dbh));
    destroy_pool(tmp_pool);
    errno = EPERM;
    return -1;
  }

  destroy_pool(tmp_pool);
  return 0;
}