Пример #1
0
static int
ipv6_parse_main(struct mystr* p_out_str, const struct mystr* p_in_str)
{
  static struct mystr s_lhs_str;
  static struct mystr s_rhs_str;
  struct str_locate_result loc_ret;
  str_copy(&s_lhs_str, p_in_str);
  while (!str_isempty(&s_lhs_str))
  {
    str_split_char(&s_lhs_str, &s_rhs_str, ':');
    if (str_isempty(&s_lhs_str))
    {
      return 0;
    }
    loc_ret = str_locate_char(&s_lhs_str, '.');
    if (loc_ret.found)
    {
      if (!ipv4_parse_dotquad(p_out_str, &s_lhs_str))
      {
        return 0;
      }
    }
    else if (!ipv6_parse_hex(p_out_str, &s_lhs_str))
    {
      return 0;
    }
    str_copy(&s_lhs_str, &s_rhs_str);
  }
  return 1;
}
Пример #2
0
static enum EVSFPrivopLoginResult
handle_anonymous_login(struct vsf_session* p_sess,
                       const struct mystr* p_pass_str)
{
  if (!str_isempty(&p_sess->banned_email_str) &&
      str_contains_line(&p_sess->banned_email_str, p_pass_str))
  {
    return kVSFLoginFail;
  }
  if (!str_isempty(&p_sess->email_passwords_str) &&
      (!str_contains_line(&p_sess->email_passwords_str, p_pass_str) ||
       str_isempty(p_pass_str)))
  {
    return kVSFLoginFail;
  }
  /* Store the anonymous identity string */
  str_copy(&p_sess->anon_pass_str, p_pass_str);
  if (str_isempty(&p_sess->anon_pass_str))
  {
    str_alloc_text(&p_sess->anon_pass_str, "?");
  }
  /* "Fix" any characters which might upset the log processing */
  str_replace_char(&p_sess->anon_pass_str, ' ', '_');
  str_replace_char(&p_sess->anon_pass_str, '\n', '?');
  {
    struct mystr ftp_username_str = INIT_MYSTR;
    str_alloc_text(&ftp_username_str, tunable_ftp_username);
    setup_username_globals(p_sess, &ftp_username_str);
    str_free(&ftp_username_str);
  }
  str_free(&p_sess->banned_email_str);
  str_free(&p_sess->email_passwords_str);
  return kVSFLoginAnon;
}
Пример #3
0
const unsigned char*
vsf_sysutil_parse_uchar_string_sep(
  const struct mystr* p_str, char sep, unsigned char* p_items,
  unsigned int items)
{
  static struct mystr s_tmp_str;
  unsigned int i;
  str_copy(&s_tmp_str, p_str);
  for (i=0; i<items; i++)
  {
    static struct mystr s_rhs_sep_str;
    int this_number;
    /* This puts a single separator delimited field in tmp_str */
    str_split_char(&s_tmp_str, &s_rhs_sep_str, sep);
    /* Sanity - check for too many or two few dots! */
    if ( (i < (items-1) && str_isempty(&s_rhs_sep_str)) ||
         (i == (items-1) && !str_isempty(&s_rhs_sep_str)))
    {
      return 0;
    }
    this_number = str_atoi(&s_tmp_str);
    if (this_number < 0 || this_number > 255)
    {
      return 0;
    }
    /* If this truncates from int to uchar, we don't care */
    p_items[i] = (unsigned char) this_number;
    /* The right hand side of the comma now becomes the new string to
     * breakdown
     */
    str_copy(&s_tmp_str, &s_rhs_sep_str);
  }
  return p_items;
}
Пример #4
0
static void
handle_site_chmod(struct vsf_session* p_sess, struct mystr* p_arg_str)
{
  static struct mystr s_chmod_file_str;
  unsigned int perms;
  int retval;
  if (str_isempty(p_arg_str))
  {
    vsf_cmdio_write(p_sess, FTP_BADCMD, "SITE CHMOD needs 2 arguments.");
    return;
  }
  str_split_char(p_arg_str, &s_chmod_file_str, ' ');
  if (str_isempty(&s_chmod_file_str))
  {
    vsf_cmdio_write(p_sess, FTP_BADCMD, "SITE CHMOD needs 2 arguments.");
    return;
  }
  /* Don't worry - our chmod() implementation only allows 0 - 0777 */
  perms = str_octal_to_uint(p_arg_str);
  retval = str_chmod(&s_chmod_file_str, perms);
  if (vsf_sysutil_retval_is_error(retval))
  {
    vsf_cmdio_write(p_sess, FTP_FILEFAIL, "SITE CHMOD command failed.");
  }
  else
  {
    vsf_cmdio_write(p_sess, FTP_CHMODOK, "SITE CHMOD command ok.");
  }
}
Пример #5
0
static int
sort_compare_common(const void* p1, const void* p2, int reverse)
{
  const struct mystr* p_cmp1;
  const struct mystr* p_cmp2;
  const struct mystr_list_node* p_node1 = (const struct mystr_list_node*) p1;
  const struct mystr_list_node* p_node2 = (const struct mystr_list_node*) p2;
  if (!str_isempty(&p_node1->sort_key_str))
  {
    p_cmp1 = &p_node1->sort_key_str;
  }
  else
  {
    p_cmp1 = &p_node1->str;
  }
  if (!str_isempty(&p_node2->sort_key_str))
  {
    p_cmp2 = &p_node2->sort_key_str;
  }
  else
  {
    p_cmp2 = &p_node2->str;
  }

  if (reverse)
  {
    return str_strcmp(p_cmp2, p_cmp1);
  }
  else
  {
    return str_strcmp(p_cmp1, p_cmp2);
  }
}
Пример #6
0
static void
handle_port(struct vsf_session* p_sess)
{
  static struct mystr s_tmp_str;
  unsigned short the_port;
  unsigned char vals[6];
  int i;
  pasv_cleanup(p_sess);
  port_cleanup(p_sess);
  str_copy(&s_tmp_str, &p_sess->ftp_arg_str);
  for (i=0; i<6; i++)
  {
    static struct mystr s_rhs_comma_str;
    int this_number;
    /* This puts a single , delimited field in tmp_str */
    str_split_char(&s_tmp_str, &s_rhs_comma_str, ',');
    /* Sanity - check for too many or two few commas! */
    if ( (i<5 && str_isempty(&s_rhs_comma_str)) ||
         (i==5 && !str_isempty(&s_rhs_comma_str)))
    {
      vsf_cmdio_write(p_sess, FTP_BADCMD, "Illegal PORT command.");
      return;
    }
    this_number = str_atoi(&s_tmp_str);
    if (this_number < 0 || this_number > 255)
    {
      vsf_cmdio_write(p_sess, FTP_BADCMD, "Illegal PORT command.");
      return;
    }
    /* If this truncates from int to uchar, we don't care */
    vals[i] = (unsigned char) this_number;
    /* The right hand side of the comma now becomes the new string to
     * breakdown
     */
    str_copy(&s_tmp_str, &s_rhs_comma_str);
  }
  the_port = vals[4] << 8;
  the_port |= vals[5];
  vsf_sysutil_sockaddr_alloc_ipv4(&p_sess->p_port_sockaddr);
  vsf_sysutil_sockaddr_set_ipv4addr(p_sess->p_port_sockaddr, vals);
  vsf_sysutil_sockaddr_set_port(p_sess->p_port_sockaddr, the_port);
  /* SECURITY:
   * 1) Reject requests not connecting to the control socket IP
   * 2) Reject connects to privileged ports
   */
  if (!tunable_port_promiscuous)
  {
    if (!vsf_sysutil_sockaddr_addr_equal(p_sess->p_remote_addr,
                                         p_sess->p_port_sockaddr) ||
        vsf_sysutil_is_port_reserved(the_port))
    {
      vsf_cmdio_write(p_sess, FTP_BADCMD, "Illegal PORT command.");
      port_cleanup(p_sess);
      return;
    }
  }
  vsf_cmdio_write(p_sess, FTP_PORTOK,
                  "PORT command successful. Consider using PASV.");
}
Пример #7
0
Файл: str.c Проект: hollow/lucid
int str_path_isabs(const char *str)
{
	int abs = 1;

	if (str_isempty(str))
		return 0;

	if (*str != '/')
		return 0;

	strtok_t _st, *st = &_st, *p;

	if (!strtok_init_str(st, str, "/", 0))
		return -1;

	strtok_for_each(st, p) {
		if (str_equal(p->token, ".") || str_equal(p->token, "..") ||
		    !str_isgraph(p->token)) {
			abs = 0;
			break;
		}
	}

	strtok_free(st);

	return abs;
}
Пример #8
0
result_t cmp_anim_modify(struct cmp_obj* obj, struct allocator* alloc, struct allocator* tmp_alloc,
    void* data, cmphandle_t cur_hdl)
{
    result_t r;
    struct cmp_anim* a = (struct cmp_anim*)data;

    uint filehash = hash_str(a->filepath);
    int reload = (a->filepathhash == filehash);
    cmp_anim_destroydata(obj, a, cur_hdl, !reload);
    a->filepathhash = filehash;

    a->alloc = alloc;
    if (str_isempty(a->filepath))
        return RET_OK;

    if (!reload)
        a->clip_hdl = rs_load_animreel(a->filepath, 0);

    if (a->clip_hdl == INVALID_HANDLE)
        return RET_FAIL;

    /* bind */
    r = cmp_anim_bind(obj, a, alloc, tmp_alloc, cur_hdl);
    if (IS_FAIL(r)) {
        err_sendtolog(TRUE);
        log_print(LOG_WARNING, "binding anim-set failed");
        return RET_FAIL;
    }

    return RET_OK;
}
Пример #9
0
int credentials_charset_is_valid(char *str_non_ascii)
{
    char reject[] = " :@\"|\\/=+<>[]*?,;";

    return str_isempty(str_non_ascii) ||
	strcspn(str_non_ascii, reject) == strlen(str_non_ascii);
}
Пример #10
0
int
vsf_access_check_file_visible(const struct mystr* p_filename_str)
{
  static struct mystr s_access_str;

  if (!tunable_hide_file)
  {
    return 1;
  }
  if (str_isempty(&s_access_str))
  {
    str_alloc_text(&s_access_str, tunable_hide_file);
  }
  if (vsf_filename_passes_filter(p_filename_str, &s_access_str))
  {
    return 0;
  }
  else
  {
    struct str_locate_result loc_res =
      str_locate_str(p_filename_str, &s_access_str);
    if (loc_res.found)
    {
      return 0;
    }
  }
  return 1;
}
Пример #11
0
static void
handle_pass_command(struct vsf_session* p_sess)
{
  if (str_isempty(&p_sess->user_str))
  {
    vsf_cmdio_write(p_sess, FTP_NEEDUSER, "Login with USER first.");
    return;
  }
  /* These login calls never return if successful */
  if (tunable_one_process_model)
  {
    vsf_one_process_login(p_sess, &p_sess->ftp_arg_str);
  }
  else
  {
    vsf_two_process_login(p_sess, &p_sess->ftp_arg_str);
  }
  vsf_cmdio_write(p_sess, FTP_LOGINERR, "Login incorrect.");
  if (++p_sess->login_fails >= tunable_max_login_fails)
  {
    vsf_sysutil_exit(0);
  }
  str_empty(&p_sess->user_str);
  /* FALLTHRU if login fails */
}
Пример #12
0
static void
handle_rnto(struct vsf_session* p_sess)
{
  int retval;
  /* If we didn't get a RNFR, throw a wobbly */
  if (str_isempty(&p_sess->rnfr_filename_str))
  {
    vsf_cmdio_write(p_sess, FTP_NEEDRNFR,
                    "RNFR required first.");
    return;
  }
  /* NOTE - might overwrite destination file. Not a concern because the same
   * could be accomplished with DELE.
   */
  retval = str_rename(&p_sess->rnfr_filename_str, &p_sess->ftp_arg_str);
  /* Clear the RNFR filename; start the two stage process again! */
  str_free(&p_sess->rnfr_filename_str);
  if (retval == 0)
  {
    vsf_cmdio_write(p_sess, FTP_RENAMEOK, "Rename successful.");
  }
  else
  {
    vsf_cmdio_write(p_sess, FTP_FILEFAIL, "Rename failed.");
  }
}
Пример #13
0
void
vsf_cmdio_get_cmd_and_arg(struct vsf_session* p_sess, struct mystr* p_cmd_str,
                          struct mystr* p_arg_str, int set_alarm)
{
  /* Prepare an alarm to timeout the session.. */
  if (set_alarm)
  {
    vsf_cmdio_set_alarm(p_sess);
  }
  /* Blocks */
  control_getline(p_cmd_str, p_sess);
  str_split_char(p_cmd_str, p_arg_str, ' ');
  str_upper(p_cmd_str);
  if (tunable_log_ftp_protocol)
  {
    static struct mystr s_log_str;
    if (str_equal_text(p_cmd_str, "PASS"))
    {
      str_alloc_text(&s_log_str, "PASS <password>");
    }
    else
    {
      str_copy(&s_log_str, p_cmd_str);
      if (!str_isempty(p_arg_str))
      {
        str_append_char(&s_log_str, ' ');
        str_append_str(&s_log_str, p_arg_str);
      }
    }
    vsf_log_line(p_sess, kVSFLogEntryFTPInput, &s_log_str);
  }
}
Пример #14
0
Файл: str.c Проект: hollow/lucid
char *str_path_dirname(const char *path)
{
	/* empty string or '..' */
	if (str_isempty(path) || str_equal(path, ".."))
		return str_dup(".");

	/* skip prefixing '/' but preserve exactly one */
	while (*path && *(path+1) && *path == '/' && *(path+1) == '/')
		path++;

	int found = 0;
	char *p, *buf = str_dup(path);

	while ((p = str_rchr(buf, '/', str_len(buf)))) {
		/* remove trailing slash */
		if (p[1] == 0 && p != buf)
			*p = 0;

		/* no basename was found until yet */
		else if (!found) {
			*p = 0;
			found = 1;
		}

		/* a basename was found and no trailing slash anymore */
		else
			break;
	}

	char *dn;

	/* path consists only of basename and slashes */
	if (str_isempty(buf))
		dn = str_dup("/");

	/* path is relative or absolute, basename was stripped */
	else if (p)
		dn = str_dup(buf);

	/* path is relative, no basename was stripped */
	else
		dn = str_dup(".");

	free(buf);

	return dn;
}
Пример #15
0
static void
handle_user_command(struct vsf_session* p_sess)
{
  /* SECURITY: If we're in anonymous only-mode, immediately reject
   * non-anonymous usernames in the hope we save passwords going plaintext
   * over the network
   */
  int is_anon = 1;
  str_copy(&p_sess->user_str, &p_sess->ftp_arg_str);
  str_upper(&p_sess->ftp_arg_str);
  if (!str_equal_text(&p_sess->ftp_arg_str, "FTP") &&
      !str_equal_text(&p_sess->ftp_arg_str, "ANONYMOUS"))
  {
    is_anon = 0;
  }
  if (!tunable_local_enable && !is_anon)
  {
    vsf_cmdio_write(
      p_sess, FTP_LOGINERR, "This FTP server is anonymous only.");
    str_empty(&p_sess->user_str);
    return;
  }
  if (is_anon && p_sess->control_use_ssl && !tunable_allow_anon_ssl)
  {
    vsf_cmdio_write(
      p_sess, FTP_LOGINERR, "Anonymous sessions may not use encryption.");
    str_empty(&p_sess->user_str);
    return;
  }
  if (tunable_ssl_enable && !is_anon && !p_sess->control_use_ssl &&
      tunable_force_local_logins_ssl)
  {
    vsf_cmdio_write(
      p_sess, FTP_LOGINERR, "Non-anonymous sessions must use encryption.");
    str_empty(&p_sess->user_str);
    return;
  }
  if (!str_isempty(&p_sess->userlist_str))
  {
    int located = str_contains_line(&p_sess->userlist_str, &p_sess->user_str);
    if ((located && tunable_userlist_deny) ||
        (!located && !tunable_userlist_deny))
    {
      vsf_cmdio_write(p_sess, FTP_LOGINERR, "Permission denied.");
      str_empty(&p_sess->user_str);
      return;
    }
  }
  if (is_anon && tunable_no_anon_password)
  {
    /* Fake a password */
    str_alloc_text(&p_sess->ftp_arg_str, "<no password>");
    handle_pass_command(p_sess);
  }
  else
  {
    vsf_cmdio_write(p_sess, FTP_GIVEPWORD, "Please specify the password.");
  }
}
Пример #16
0
/* tests whether this is a valid phone number, digits and hyphen are allowed */
int str_is_phone_number(char *s)
{
    /* TODO: Why not use str_re? */
    if (str_isempty(s))
	return 0;
    for (; isdigit((int)*s) || *s == '-'; s++);
    return !!*s;
}
Пример #17
0
/* vg.remove(string group, string name) */
xmlrpc_value *m_vg_remove(xmlrpc_env *env, xmlrpc_value *p, void *c)
{
	LOG_TRACEME

	xmlrpc_value *params;
	char *group, *name;
	int rc, gid = 0;
	xid_t xid;

	params = method_init(env, p, c, VCD_CAP_AUTH, 0);
	method_return_if_fault(env);

	xmlrpc_decompose_value(env, params,
			"{s:s,s:s,*}",
			"group", &group,
			"name",  &name);
	method_return_if_fault(env);

	if (!validate_group(group))
		method_return_faultf(env, MEINVAL,
				"invalid group value: %s", group);

	if (str_equal(group, "all"))
		method_return_faultf(env, MEINVAL,
				"cannot remove reserved group '%s'", group);

	if (!(gid = vxdb_getgid(group)))
		method_return_fault(env, MENOVG);

	if (!str_isempty(name)) {
		if (!validate_name(name))
			method_return_faultf(env, MEINVAL,
					"invalid name value: %s", name);

		if (!(xid = vxdb_getxid(name)))
			method_return_fault(env, MENOVPS);

		rc = vxdb_exec(
				"DELETE FROM xid_gid_map WHERE xid = %d AND gid = %d",
				xid, gid);
	}

	else {
		rc = vxdb_exec(
				"BEGIN EXCLUSIVE TRANSACTION;"
				"DELETE FROM xid_gid_map WHERE gid = %d;"
				"DELETE FROM groups WHERE gid = %d;"
				"COMMIT TRANSACTION;",
				gid, gid);
	}

	if (rc != VXDB_OK)
		method_return_vxdb_fault(env);

	return xmlrpc_nil_new(env);
}
Пример #18
0
struct h3d_anim_clip* import_loadclips(const char* json_filepath, uint frame_cnt,
    OUT uint* clip_cnt)
{
    /* return default clips, which is the whole animation */
    if (str_isempty(json_filepath)) {
        *clip_cnt = 1;
        return import_defaultclip(frame_cnt);
    }

    char* json_data = util_readtextfile(json_filepath, mem_heap());
    if (json_data == NULL)  {
        printf(TERM_BOLDYELLOW "Warning: could not open JSON file '%s' for clips,"
            " reseting to default", json_filepath);
        *clip_cnt = 1;
        return import_defaultclip(frame_cnt);
    }

    json_t jroot = json_parsestring(json_data);
    FREE(json_data);
    if (jroot == NULL)  {
        printf(TERM_BOLDYELLOW "Warning: could not read JSON file '%s' for clips,"
            " reseting to default", json_filepath);
        *clip_cnt = 1;
        return import_defaultclip(frame_cnt);
    }

    /* */
    json_t jclips = jroot;
    uint cnt = json_getarr_count(jclips);
    if (cnt == 0)   {
        printf(TERM_BOLDYELLOW "Warning: no clip defined in JSON file '%s',"
            " switching to default", json_filepath);
        *clip_cnt = 1;
        return import_defaultclip(frame_cnt);
    }

    struct h3d_anim_clip* clips = (struct h3d_anim_clip*)ALLOC(sizeof(struct h3d_anim_clip)*cnt, 0);
    ASSERT(clips);

    for (uint i = 0; i < cnt; i++)    {
        json_t jclip = json_getarr_item(jclips, i);

        strcpy(clips[i].name, json_gets_child(jclip, "name", "[noname]"));
        clips[i].start = minui(json_geti_child(jclip, "start", 0), frame_cnt-1);
        clips[i].end = minui(json_geti_child(jclip, "end", frame_cnt), frame_cnt);
        clips[i].looped = json_getb_child(jclip, "looped", FALSE);
    }

    json_destroy(jroot);

    *clip_cnt = cnt;
    return clips;
}
Пример #19
0
void
vsf_parseconf_load_file(const char* p_filename)
{
  struct mystr config_file_str = INIT_MYSTR;
  struct mystr config_setting_str = INIT_MYSTR;
  struct mystr config_value_str = INIT_MYSTR;
  unsigned int str_pos = 0;
  int retval;
  if (!p_filename)
  {
    p_filename = s_p_saved_filename;
  }
  else
  {
    if (s_p_saved_filename)
    {
      vsf_sysutil_free((char*)s_p_saved_filename);
    }
    s_p_saved_filename = vsf_sysutil_strdup(p_filename);
  }
  if (!p_filename)
  {
    bug("null filename in vsf_parseconf_load_file");
  }
  if (!s_strings_copied)
  {
    s_strings_copied = 1;
    /* A minor hack to make sure all strings are malloc()'ed so we can free
     * them at some later date. Specifically handles strings embedded in the
     * binary.
     */
    copy_string_settings();
  }
  retval = str_fileread(&config_file_str, p_filename, VSFTP_CONF_FILE_MAX);
  if (vsf_sysutil_retval_is_error(retval))
  {
    die("cannot open config file");
  }
  while (str_getline(&config_file_str, &config_setting_str, &str_pos))
  {
    if (str_isempty(&config_setting_str) ||
        str_get_char_at(&config_setting_str, 0) == '#')
    {
      continue;
    }
    /* Split into name=value pair */
    str_split_char(&config_setting_str, &config_value_str, '=');
    handle_config_setting(&config_setting_str, &config_value_str);
  }
  str_free(&config_file_str);
  str_free(&config_setting_str);
  str_free(&config_value_str);
}
Пример #20
0
static void
prepend_path_to_filename(struct mystr* p_str)
{
  static struct mystr s_tmp_str;
  /* Only prepend current working directory if the incoming filename is
   * relative
   */
  str_empty(&s_tmp_str);
  if (str_isempty(p_str) || str_get_char_at(p_str, 0) != '/')
  {
    str_getcwd(&s_tmp_str);
    /* Careful to not emit // if we are in directory / (common with chroot) */
    if (str_isempty(&s_tmp_str) ||
        str_get_char_at(&s_tmp_str, str_getlen(&s_tmp_str) - 1) != '/')
    {
      str_append_char(&s_tmp_str, '/');
    }
  }
  str_append_str(&s_tmp_str, p_str);
  str_copy(p_str, &s_tmp_str);
}
Пример #21
0
void
vsf_sysutil_setproctitle(const char* p_text)
{
  struct mystr proctitle_str = INIT_MYSTR;
  str_copy(&proctitle_str, &s_proctitle_prefix_str);
  if (!str_isempty(&proctitle_str))
  {
    str_append_text(&proctitle_str, ": ");
  }
  str_append_text(&proctitle_str, p_text);
  vsf_sysutil_setproctitle_internal(str_getbuf(&proctitle_str));
  str_free(&proctitle_str);
}
Пример #22
0
Файл: str.c Проект: hollow/lucid
char *str_path_concat(const char *dirname, const char *basename)
{
	char *path = 0;

	if (str_len(basename) > 1 && memcmp(basename, "./", 2) == 0)
		basename += 2;

	if (str_isempty(dirname) || str_path_isdot(basename))
		return 0;

	_lucid_asprintf(&path, "%s/%s", dirname, basename);

	return path;
}
Пример #23
0
static void
emit_greeting(struct vsf_session* p_sess)
{
  struct mystr str_log_line = INIT_MYSTR;
  /* Check for client limits (standalone mode only) */
  if (tunable_max_clients > 0 &&
      p_sess->num_clients > tunable_max_clients)
  {
    str_alloc_text(&str_log_line, "Connection refused: too many sessions.");
    vsf_log_line(p_sess, kVSFLogEntryConnection, &str_log_line);
    vsf_cmdio_write_noblock(p_sess, FTP_TOO_MANY_USERS,
                    "There are too many connected users, please try later.");
    vsf_sysutil_exit(0);
  }
  if (tunable_max_per_ip > 0 &&
      p_sess->num_this_ip > tunable_max_per_ip)
  {
    str_alloc_text(&str_log_line,
                   "Connection refused: too many sessions for this address.");
    vsf_log_line(p_sess, kVSFLogEntryConnection, &str_log_line);
    vsf_cmdio_write_noblock(p_sess, FTP_IP_LIMIT,
        "There are too many connections from your internet address.");
    vsf_sysutil_exit(0);
  }
  if (!p_sess->tcp_wrapper_ok)
  {
    str_alloc_text(&str_log_line,
                   "Connection refused: tcp_wrappers denial.");
    vsf_log_line(p_sess, kVSFLogEntryConnection, &str_log_line);
    vsf_cmdio_write_noblock(p_sess, FTP_IP_DENY, "Service not available.");
    vsf_sysutil_exit(0);
  }
  vsf_log_line(p_sess, kVSFLogEntryConnection, &str_log_line);
  if (!str_isempty(&p_sess->banner_str))
  {
    vsf_banner_write(p_sess, &p_sess->banner_str, FTP_GREET);
    str_free(&p_sess->banner_str);
    vsf_cmdio_write(p_sess, FTP_GREET, "");
  }
  else if (tunable_ftpd_banner == 0)
  {
    vsf_cmdio_write(p_sess, FTP_GREET, "(vsFTPd " VSF_VERSION 
                    ")");
  }
  else
  {
    vsf_cmdio_write(p_sess, FTP_GREET, tunable_ftpd_banner);
  }
}
Пример #24
0
static void
emit_greeting(struct vsf_session* p_sess)
{
  if (!str_isempty(&p_sess->banner_str))
  {
    vsf_banner_write(p_sess, &p_sess->banner_str, FTP_GREET);
    str_free(&p_sess->banner_str);
    vsf_cmdio_write(p_sess, FTP_GREET, "");
  }
  else if (tunable_ftpd_banner == 0)
  {
    vsf_cmdio_write(p_sess, FTP_GREET, "(vsFTPd " VSF_VERSION 
                    ")");
  }
  else
  {
    vsf_cmdio_write(p_sess, FTP_GREET, tunable_ftpd_banner);
  }
}
Пример #25
0
void
vsf_cmdio_get_cmd_and_arg(struct vsf_session* p_sess, struct mystr* p_cmd_str,
                          struct mystr* p_arg_str, int set_alarm)
{
  /* Prepare an alarm to timeout the session.. */
  if (set_alarm)
  {
    vsf_cmdio_set_alarm(p_sess);
  }
  /* Blocks */
  control_getline(p_cmd_str, p_sess);
  /* View a single space as a command of " ", which although a useless command,
   * permits the caller to distinguish input of "" from " ".
   */
  if (str_getlen(p_cmd_str) == 1 && str_get_char_at(p_cmd_str, 0) == ' ')
  {
    str_empty(p_arg_str);
  }
  else
  {
    str_split_char(p_cmd_str, p_arg_str, ' ');
  }
  str_upper(p_cmd_str);
  if (tunable_log_ftp_protocol)
  {
    static struct mystr s_log_str;
    if (str_equal_text(p_cmd_str, "PASS"))
    {
      str_alloc_text(&s_log_str, "PASS <password>");
    }
    else
    {
      str_copy(&s_log_str, p_cmd_str);
      if (!str_isempty(p_arg_str))
      {
        str_append_char(&s_log_str, ' ');
        str_append_str(&s_log_str, p_arg_str);
      }
    }
    vsf_log_line(p_sess, kVSFLogEntryFTPInput, &s_log_str);
  }
}
Пример #26
0
Файл: str.c Проект: hollow/lucid
char *str_path_basename(const char *path)
{
	/* empty string */
	if (str_isempty(path))
		return str_dup(".");

	/* skip prefixing '/' */
	while (*path && *path == '/')
		path++;

	/* string consisting entirely of '/' */
	if (!*path)
		return str_dup("/");

	char *p, *buf = str_dup(path);

	while ((p = str_rchr(buf, '/', str_len(buf)))) {
		/* remove trailing lash */
		if (p[1] == 0 && p != buf)
			*p = 0;

		/* no trailing slash anymore */
		else
			break;
	}

	char *bn;

	/* if a non-trailing slash was found, return everything after it */
	if (p)
		bn = str_dup(p + 1);

	/* otherwise buf already contains basename */
	else
		bn = str_dup(buf);

	free(buf);

	return bn;
}
Пример #27
0
static void
handle_site_umask(struct vsf_session* p_sess, struct mystr* p_arg_str)
{
  static struct mystr s_umask_resp_str;
  if (str_isempty(p_arg_str))
  {
    /* Empty arg => report current umask */
    str_alloc_text(&s_umask_resp_str, "Your current UMASK is ");
    str_append_text(&s_umask_resp_str,
                    vsf_sysutil_uint_to_octal(vsf_sysutil_get_umask()));
  }
  else
  {
    /* Set current umask */
    unsigned int new_umask = str_octal_to_uint(p_arg_str);
    vsf_sysutil_set_umask(new_umask);
    str_alloc_text(&s_umask_resp_str, "UMASK set to ");
    str_append_text(&s_umask_resp_str,
                    vsf_sysutil_uint_to_octal(vsf_sysutil_get_umask()));
  }
  vsf_cmdio_write_str(p_sess, FTP_UMASKOK, &s_umask_resp_str);
}
Пример #28
0
void
str_replace_text(struct mystr* p_str, const char* p_from, const char* p_to)
{
  static struct mystr s_lhs_chunk_str;
  static struct mystr s_rhs_chunk_str;
  unsigned int lhs_len;
  str_copy(&s_lhs_chunk_str, p_str);
  str_free(p_str);
  do
  {
    lhs_len = str_getlen(&s_lhs_chunk_str);
    str_split_text(&s_lhs_chunk_str, &s_rhs_chunk_str, p_from);
    /* Copy lhs to destination */
    str_append_str(p_str, &s_lhs_chunk_str);
    /* If this was a 'hit', append the 'to' text */
    if (str_getlen(&s_lhs_chunk_str) < lhs_len)
    {
      str_append_text(p_str, p_to);
    }
    /* Current rhs becomes new lhs */
    str_copy(&s_lhs_chunk_str, &s_rhs_chunk_str);
  } while (!str_isempty(&s_lhs_chunk_str));
}
Пример #29
0
Файл: str.c Проект: hollow/lucid
int str_path_isdot(const char *str)
{
	int found = 0;

	if (str_isempty(str))
		return 0;

	strtok_t _st, *st = &_st, *p;

	if (!strtok_init_str(st, str, "/", 0))
		return 0;

	strtok_for_each(st, p) {
		if (str_equal(p->token, ".") || str_equal(p->token, "..")) {
			found = 1;
			break;
		}
	}

	strtok_free(st);

	return found;
}
Пример #30
0
void
vsf_one_process_start(struct vsf_session* p_sess)
{
  unsigned int caps = 0;
  if (tunable_chown_uploads)
  {
    caps |= kCapabilityCAP_CHOWN;
  }
  if (tunable_connect_from_port_20)
  {
    caps |= kCapabilityCAP_NET_BIND_SERVICE;
  }
  {
    struct mystr user_name = INIT_MYSTR;
    struct mystr chdir_str = INIT_MYSTR;
    str_alloc_text(&user_name, tunable_ftp_username);
    if (tunable_anon_root)
    {
      str_alloc_text(&chdir_str, tunable_anon_root);
    }
    if (tunable_run_as_launching_user)
    {
      if (!str_isempty(&chdir_str))
      {
        (void) str_chdir(&chdir_str);
      }
    }
    else
    {
      vsf_secutil_change_credentials(&user_name, 0, &chdir_str, caps,
          VSF_SECUTIL_OPTION_CHROOT | VSF_SECUTIL_OPTION_USE_GROUPS);
    }
    str_free(&user_name);
    str_free(&chdir_str);
  }
  init_connection(p_sess);
}