⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fakechroot.c

📁 功能强大的ftp服务器源代码
💻 C
字号:
#include <config.h>#define FAKECHROOT_FUNCS_DEFINITION 1#ifdef WITH_VIRTUAL_CHROOT# include "ftpd.h"# ifdef WITH_DMALLOC#  include <dmalloc.h># endifstatic char curdir[MAXPATHLEN];static char *chroot_base;static size_t chroot_len;int fakechroot(const char *path){    char *z;        if (path == NULL || *path == 0) {# ifdef EINVAL        errno = EINVAL;# endif        return -1;    }    free(chroot_base);    chroot_base = NULL;    if (path[0] == '/' && path[1] == 0) {   /* chroot("/") => no chroot */        return 0;    }    if ((chroot_base = strdup(path)) == NULL) {        return -1;    }    simplify(chroot_base);    z = chroot_base;    while (*z != 0) {        z++;    }    for (;;) {        z--;        if (z == chroot_base || *z != '/') {            break;        }        *z = 0;    }    if ((chroot_len = strlen(chroot_base)) >= sizeof curdir) {# ifdef ENAMETOOLONG        errno = ENAMETOOLONG;# endif        return -1;    }        return 0;}char *fakegetcwd(char *dir, size_t size){    char *curdirchr;    size_t s;             if (chroot_base == NULL) {        return getcwd(dir, size);    }    if (strncmp(curdir, chroot_base, chroot_len) != 0) {        abort();    }    curdirchr = curdir + chroot_len;    s = strlen(curdirchr);    if (s <= (size_t) 0U) {# ifdef EFAULT        errno = EFAULT;# endif        return NULL;    }    {        register char *sp = curdirchr + s - 1U;                while (sp != curdirchr && *sp == '/') {            *sp = 0;            s--;        }    }    s++;         if (s > size || s < (size_t) 2U) {# ifdef ENAMETOOLONG        errno = ENAMETOOLONG;# endif        return NULL;    }    memcpy(dir, curdirchr, s);        return curdirchr;}static int fakexlate(char *curdirtmp, size_t sizeof_curdirtmp, const char *dir){    char *sl;         size_t curdirlen;        if ((curdirlen = strlen(curdir)) >= sizeof_curdirtmp) {        return -1;    }    memcpy(curdirtmp, curdir, curdirlen + (size_t) 1U);    simplify(curdirtmp);    loop:    if (dir[0] == '.' && dir[1] == '.' &&        (dir[2] == 0 || dir[2] == '/')) {        if ((sl = strrchr(curdirtmp, '/')) != NULL) {            *sl = 0;        } else {            *curdirtmp = 0;        }        if (strncmp(curdirtmp, chroot_base, chroot_len) != 0 ||            curdirtmp[chroot_len] != '/') {            snprintf(curdirtmp, sizeof_curdirtmp, "%s/", chroot_base);        }        if (dir[0] == '.' && dir[1] == '.' && dir[2] == '/') {            dir += 3;            goto loop;        }    } else if (*dir == '/') {        snprintf(curdirtmp, sizeof_curdirtmp, "%s/", chroot_base);        dir++;        goto loop;    } else if (*dir != 0) {        size_t dirlen;        size_t curdirtmplen;                if ((dir[0] == '.' && dir[1] == '.' &&             (dir[2] == 0 || dir[2] == '/')) ||                        strstr(dir, "/../") != NULL) {            perm:# ifdef EPERM            errno = EPERM;# endif            return -1;        }        dirlen = strlen(dir) + (size_t) 1U;        if (dirlen >= (size_t) 4U &&            (dir[dirlen - 2U] == '.' && dir[dirlen - 3U] == '.' &&             dir[dirlen - 4U] == '/')) {            goto perm;        }        curdirtmplen = strlen(curdirtmp);        if (curdirtmplen + dirlen >= sizeof_curdirtmp) {# ifdef ENAMETOOLONG            errno = ENAMETOOLONG;# endif            return -1;        }        curdirtmp[curdirtmplen] = '/';        memcpy(curdirtmp + curdirtmplen + 1U, dir, dirlen);    }         simplify(curdirtmp);        return 0;}int fakechdir(const char *dir){    char curdirtmp[MAXPATHLEN];    size_t curdirtmplen;        if (chroot_base == NULL) {        return chdir(dir);    }    if (fakexlate(curdirtmp, sizeof curdirtmp, dir) != 0) {        return -1;    }    if (chdir(curdirtmp) != 0) {        return -1;    }    if ((curdirtmplen = strlen(curdirtmp)) >= sizeof curdir) {        return -1;    }    memcpy(curdir, curdirtmp, curdirtmplen + (size_t) 1U);        return 0;}int fakestat(const char *file, struct stat *st){    char curdirtmp[MAXPATHLEN];        if (chroot_base == NULL) {        return stat(file, st);    }    if (fakexlate(curdirtmp, sizeof curdirtmp, file) != 0) {        return -1;    }    return stat(curdirtmp, st);}int fakelstat(const char *file, struct stat *st){    char curdirtmp[MAXPATHLEN];        if (chroot_base == NULL) {        return lstat(file, st);    }    if (fakexlate(curdirtmp, sizeof curdirtmp, file) != 0) {        return -1;    }    return lstat(curdirtmp, st);}FILE *fakefopen(const char *file, const char *mode){    char curdirtmp[MAXPATHLEN];        if (chroot_base == NULL) {        return fopen(file, mode);    }    if (fakexlate(curdirtmp, sizeof curdirtmp, file) != 0) {        return NULL;    }    return fopen(curdirtmp, mode);}int fakeaccess(const char *file, mode_t mode){    char curdirtmp[MAXPATHLEN];        if (chroot_base == NULL) {        return access(file, mode);    }    if (fakexlate(curdirtmp, sizeof curdirtmp, file) != 0) {        return -1;    }    return access(curdirtmp, mode);}int fakeunlink(const char *file){    char curdirtmp[MAXPATHLEN];        if (chroot_base == NULL) {        return unlink(file);    }    if (fakexlate(curdirtmp, sizeof curdirtmp, file) != 0) {        return -1;    }    return unlink(curdirtmp);}DIR *fakeopendir(const char *file){    char curdirtmp[MAXPATHLEN];        if (chroot_base == NULL) {        return opendir(file);    }    if (fakexlate(curdirtmp, sizeof curdirtmp, file) != 0) {        return NULL;    }    return opendir(curdirtmp);}int fakechmod(const char *file, mode_t mode){    char curdirtmp[MAXPATHLEN];        if (chroot_base == NULL) {        return chmod(file, mode);    }    if (fakexlate(curdirtmp, sizeof curdirtmp, file) != 0) {        return -1;    }    return chmod(curdirtmp, mode);}int fakemkdir(const char *file, mode_t mode){    char curdirtmp[MAXPATHLEN];        if (chroot_base == NULL) {        return mkdir(file, mode);    }    if (fakexlate(curdirtmp, sizeof curdirtmp, file) != 0) {        return -1;    }    return mkdir(curdirtmp, mode);}int fakermdir(const char *file){    char curdirtmp[MAXPATHLEN];        if (chroot_base == NULL) {        return rmdir(file);    }    if (fakexlate(curdirtmp, sizeof curdirtmp, file) != 0) {        return -1;    }    return rmdir(curdirtmp);}# ifdef HAVE_UTIMEint fakeutime(const char *file, struct utimbuf *buf){    char curdirtmp[MAXPATHLEN];        if (chroot_base == NULL) {        return utime(file, buf);    }    if (fakexlate(curdirtmp, sizeof curdirtmp, file) != 0) {        return -1;    }    return utime(curdirtmp, buf);}# endif# ifdef HAVE_UTIMESint fakeutimes(const char *file, struct timeval *buf){    char curdirtmp[MAXPATHLEN];        if (chroot_base == NULL) {        return utimes(file, buf);    }    if (fakexlate(curdirtmp, sizeof curdirtmp, file) != 0) {        return -1;    }    return utimes(curdirtmp, buf);}# endifint fakechown(const char *file, uid_t uid, gid_t gid){    char curdirtmp[MAXPATHLEN];        if (chroot_base == NULL) {        return chown(file, uid, gid);    }    if (fakexlate(curdirtmp, sizeof curdirtmp, file) != 0) {        return -1;    }    return chown(file, uid, gid);}# ifdef HAVE_MKFIFOint fakemkfifo(const char *file, mode_t mode){     char curdirtmp[MAXPATHLEN];        if (chroot_base == NULL) {        return mkfifo(file, mode);    }    if (fakexlate(curdirtmp, sizeof curdirtmp, file) != 0) {        return -1;    }    return mkfifo(file, mode);}# endif# ifdef HAVE_MKNODint fakemknod(const char *file, mode_t mode, dev_t dev){    char curdirtmp[MAXPATHLEN];        if (chroot_base == NULL) {        return mknod(file, mode, dev);    }    if (fakexlate(curdirtmp, sizeof curdirtmp, file) != 0) {        return -1;    }    return mknod(file, mode, dev);}# endifint fakelink(const char *oldpath, const char *newpath){    char curdirtmp[MAXPATHLEN];    char curdirtmp2[MAXPATHLEN];             if (chroot_base == NULL) {        return link(oldpath, newpath);    }    if (fakexlate(curdirtmp, sizeof curdirtmp, oldpath) != 0 ||        fakexlate(curdirtmp2, sizeof curdirtmp2, newpath) != 0) {        return -1;    }    return link(curdirtmp, curdirtmp2);}int fakesymlink(const char *oldpath, const char *newpath){    char curdirtmp[MAXPATHLEN];    char curdirtmp2[MAXPATHLEN];             if (chroot_base == NULL) {        return symlink(oldpath, newpath);    }    if (fakexlate(curdirtmp, sizeof curdirtmp, oldpath) != 0 ||        fakexlate(curdirtmp2, sizeof curdirtmp2, newpath) != 0) {        return -1;    }    return symlink(curdirtmp, curdirtmp2);}int fakereadlink(const char *file, char *buf, size_t bufsiz){    char curdirtmp[MAXPATHLEN];        if (chroot_base == NULL) {        return readlink(file, buf, bufsiz);    }    if (fakexlate(curdirtmp, sizeof curdirtmp, file) != 0) {        return -1;    }    return readlink(file, buf, bufsiz);}int fakerename(const char *oldpath, const char *newpath){    char curdirtmp[MAXPATHLEN];    char curdirtmp2[MAXPATHLEN];             if (chroot_base == NULL) {        return rename(oldpath, newpath);    }    if (fakexlate(curdirtmp, sizeof curdirtmp, oldpath) != 0 ||        fakexlate(curdirtmp2, sizeof curdirtmp2, newpath) != 0) {        return -1;    }    return rename(curdirtmp, curdirtmp2);}/*  * Promotion of mode_t is problematic. For instance, on MacOS X, * mode_t is an unsigned short. */# if SIZEOF_MODE_T <= 0#  define VA_ARG_MODE_T unsigned int# elif SIZEOF_MODE_T <= SIZEOF_INT#  define VA_ARG_MODE_T unsigned int# elif SIZEOF_MODE_T <= SIZEOF_LONG#  define VA_ARG_MODE_T unsigned long# elif SIZEOF_MODE_T <= SIZEOF_LONG_LONG#  define VA_ARG_MODE_T unsigned long long# else#  define VA_ARG_MODE_T mode_t# endifint fakeopen(const char *file, int flags, ...){    va_list va;    mode_t mode;    char curdirtmp[MAXPATHLEN];        va_start(va, flags);    if (chroot_base == NULL) {        if ((flags & O_CREAT) != 0) {            mode = va_arg(va, VA_ARG_MODE_T);            va_end(va);            return open(file, flags, mode);        }        va_end(va);        return open(file, flags);    }    if (fakexlate(curdirtmp, sizeof curdirtmp, file) != 0) {        va_end(va);        return -1;    }    if ((flags & O_CREAT) != 0) {        mode = va_arg(va, VA_ARG_MODE_T);        va_end(va);                  return open(curdirtmp, flags, mode);    }    va_end(va);        return open(curdirtmp, flags);}char *fakerealpath(const char *file, char *resolved_path){    char curdirtmp[MAXPATHLEN];        if (chroot_base == NULL) {        return realpath(file, resolved_path);    }    if (fakexlate(curdirtmp, sizeof curdirtmp, file) != 0) {        return NULL;    }    return realpath(curdirtmp, resolved_path);}# if STATFS_TYPE == 1int fakestatvfs64(const char *path, STATFS_STRUCT *str)# elif STATFS_TYPE == 2int fakestatvfs(const char *path, STATFS_STRUCT *str)        # elif STATFS_TYPE == 3int fakestatfs(const char *path, STATFS_STRUCT *str)# endif            # if STATFS_TYPE > 0{    char curdirtmp[MAXPATHLEN];        if (chroot_base == NULL) {        return STATFS(path, str);    }    if (fakexlate(curdirtmp, sizeof curdirtmp, path) != 0) {        return -1;    }        return STATFS(curdirtmp, str);}# endif#elseextern signed char v6ready;#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -