예제 #1
0
파일: support.c 프로젝트: predever/proftpd
char *dir_canonical_vpath(pool *p, const char *path) {
  char buf[PR_TUNABLE_PATH_MAX + 1]  = {'\0'};
  char work[PR_TUNABLE_PATH_MAX + 1] = {'\0'};

  if (p == NULL ||
      path == NULL) {
    errno = EINVAL;
    return NULL;
  }

  if (*path == '~') {
    if (pr_fs_interpolate(path, work, sizeof(work)-1) != 1) {
      if (pr_fs_dircat(work, sizeof(work), pr_fs_getvwd(), path) < 0) {
        return NULL;
      }
    }

  } else {
    if (pr_fs_dircat(work, sizeof(work), pr_fs_getvwd(), path) < 0) {
      return NULL;
    }
  }

  pr_fs_clean_path(work, buf, sizeof(buf)-1);
  return pstrdup(p, buf);
}
예제 #2
0
파일: support.c 프로젝트: netdna/proftpd
/* dir_best_path() creates the "most" fully canonicalized path possible
 * (i.e. if path components at the end don't exist, they are ignored).
 */
char *dir_best_path(pool *p, const char *path) {
  char workpath[PR_TUNABLE_PATH_MAX + 1] = {'\0'};
  char realpath_buf[PR_TUNABLE_PATH_MAX + 1] = {'\0'};
  char *target = NULL, *ntarget;
  int fini = 0;

  if (*path == '~') {
    if (pr_fs_interpolate(path, workpath, sizeof(workpath)-1) != 1) {
      if (pr_fs_dircat(workpath, sizeof(workpath), pr_fs_getcwd(), path) < 0)
        return NULL;
    }

  } else {
    if (pr_fs_dircat(workpath, sizeof(workpath), pr_fs_getcwd(), path) < 0)
      return NULL;
  }

  pr_fs_clean_path(pstrdup(p, workpath), workpath, sizeof(workpath)-1);

  while (!fini && *workpath) {
    if (pr_fs_resolve_path(workpath, realpath_buf,
        sizeof(realpath_buf)-1, 0) != -1)
      break;

    ntarget = strrchr(workpath, '/');
    if (ntarget) {
      if (target) {
        if (pr_fs_dircat(workpath, sizeof(workpath), workpath, target) < 0)
          return NULL;
      }

      target = ntarget;
      *target++ = '\0';

    } else
      fini++;
  }

  if (!fini && *workpath) {
    if (target) {
      if (pr_fs_dircat(workpath, sizeof(workpath), realpath_buf, target) < 0)
        return NULL;

    } else
      sstrncpy(workpath, realpath_buf, sizeof(workpath));

  } else {
    if (pr_fs_dircat(workpath, sizeof(workpath), "/", target) < 0)
      return NULL;
  }

  return pstrdup(p, workpath);
}
예제 #3
0
파일: support.c 프로젝트: predever/proftpd
/* Takes a directory and returns its absolute version.  ~username references
 * are appropriately interpolated.  "Absolute" includes a _full_ reference
 * based on the root directory, not upon a chrooted dir.
 */
char *dir_abs_path(pool *p, const char *path, int interpolate) {
  char *res = NULL;

  if (p == NULL ||
      path == NULL) {
    errno = EINVAL;
    return NULL;
  }

  if (interpolate) {
    char buf[PR_TUNABLE_PATH_MAX+1];

    memset(buf, '\0', sizeof(buf));
    switch (pr_fs_interpolate(path, buf, sizeof(buf)-1)) {
      case -1:
        return NULL;

      case 0:
        /* Do nothing; path exists */
        break;

      case 1:
        /* Interpolation occurred; make a copy of the interpolated path. */
        path = pstrdup(p, buf);
        break;
    }
  }

  if (*path != '/') {
    if (session.chroot_path) {
      res = pdircat(p, session.chroot_path, pr_fs_getcwd(), path, NULL);

    } else {
      res = pdircat(p, pr_fs_getcwd(), path, NULL);
    }

  } else {
    if (session.chroot_path) {
      if (strncmp(path, session.chroot_path,
          strlen(session.chroot_path)) != 0) {
        res = pdircat(p, session.chroot_path, path, NULL);
 
      } else {
        res = pstrdup(p, path);
      }
 
    } else {
      res = pstrdup(p, path);
    }
  }

  return res;
}
예제 #4
0
파일: rfc4716.c 프로젝트: Nakor78/proftpd
static sftp_keystore_t *filestore_open(pool *parent_pool,
    int requested_key_type, const char *store_info, const char *user) {
  int xerrno;
  sftp_keystore_t *store;
  pool *filestore_pool;
  struct filestore_data *store_data;
  pr_fh_t *fh;
  char buf[PR_TUNABLE_PATH_MAX+1], *path;
  struct stat st;

  filestore_pool = make_sub_pool(parent_pool);
  pr_pool_tag(filestore_pool, "SFTP File-based Keystore Pool");

  store = pcalloc(filestore_pool, sizeof(sftp_keystore_t));
  store->keystore_pool = filestore_pool;

  /* Open the file.  The given path (store_info) may need to be
   * interpolated.
   */
  session.user = (char *) user;

  memset(buf, '\0', sizeof(buf));
  switch (pr_fs_interpolate(store_info, buf, sizeof(buf)-1)) {
    case 1:
      /* Interpolate occurred; make a copy of the interpolated path. */
      path = pstrdup(filestore_pool, buf);
      break;

    default:
      /* Otherwise, use the path as is. */
      path = pstrdup(filestore_pool, store_info);
      break;
  }

  session.user = NULL;

  PRIVS_ROOT
  fh = pr_fsio_open(path, O_RDONLY|O_NONBLOCK);
  xerrno = errno;
  PRIVS_RELINQUISH

  if (fh == NULL) {
    destroy_pool(filestore_pool);
    errno = xerrno;
    return NULL;
  }

  if (pr_fsio_set_block(fh) < 0) {
   xerrno = errno;

    destroy_pool(filestore_pool);
    (void) pr_fsio_close(fh);

    errno = xerrno;
    return NULL;
  }

  /* Stat the opened file to determine the optimal buffer size for IO. */
  memset(&st, 0, sizeof(st));
  if (pr_fsio_fstat(fh, &st) < 0) {
    xerrno = errno;

    destroy_pool(filestore_pool);
    (void) pr_fsio_close(fh);

    errno = xerrno;
    return NULL;
  }

  if (S_ISDIR(st.st_mode)) {
    destroy_pool(filestore_pool);
    (void) pr_fsio_close(fh);

    errno = EISDIR;
    return NULL;
  }

  fh->fh_iosz = st.st_blksize;

  store_data = pcalloc(filestore_pool, sizeof(struct filestore_data));
  store->keystore_data = store_data;

  store_data->path = path;
  store_data->fh = fh;
  store_data->lineno = 0;

  store->store_ktypes = requested_key_type;

  switch (requested_key_type) {
    case SFTP_SSH2_HOST_KEY_STORE:
      store->verify_host_key = filestore_verify_host_key;
      break;

    case SFTP_SSH2_USER_KEY_STORE:
      store->verify_user_key = filestore_verify_user_key; 
      break;
  }

  store->store_close = filestore_close;
  return store;
}