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

📄 ftp_parser.c

📁 功能强大的ftp服务器源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <config.h>#include "ftpd.h"#include "dynamic.h"#include "ftpwho-update.h"#include "globals.h"#include "messages.h"#ifdef WITH_DIRALIASES# include "diraliases.h"#endif#ifdef WITH_TLS# include "tls.h"#endif#ifdef WITH_DMALLOC# include <dmalloc.h>#endifstatic void antiidle(void){    if (noopidle == (time_t) -1) {        noopidle = time(NULL);    } else {        if ((time(NULL) - noopidle) > (time_t) idletime_noop) {            die(421, LOG_INFO, MSG_TIMEOUT_NOOP, (unsigned long) idletime_noop);        }    }    }/*  * Introduce a random delay, to avoid guessing existing user names by * mesuring delay. It's especially true when LDAP is used. * No need to call usleep2() because we are root at this point. */static void randomdelay(void){    usleep(rand() % 15000UL);          /* dummy... no need for arc4 */}/*  * Simple but fast command-line reader. We break the FTP protocol here, * because we deny access to files with strange characters in their name. * Now, I seriously doubt that clients should be allowed to upload files * with carriage returns, bells, cursor moves and other fancy stuff in the * names. It can indirectly lead to security flaws with scripts, it's * annoying for the sysadmin, it can be a client error, it can bring unexpected * results on some filesystems, etc. So control chars are replaced by "_". * Better be safe than 100% RFC crap compliant but unsafe. If you really want * RFC compliance, define RFC_CONFORMANT_PARSER. But I will hate you. *  * RFC_CONFORMANT_LINES is another thing that clients should implement * properly (and it's trivial to do) : lines must be ended with \r\n . * Guess what ?  * Some broken clients are just sending \n ... Grrrrrrrrrrrr !!!!!!!!!!!!!!! *  * -Frank. */int sfgets(void){    fd_set rs;    struct timeval tv;    ssize_t readen;    signed char seen_r = 0;    static size_t scanned;    static size_t readend;        if (scanned > (size_t) 0U) {       /* support pipelining */        readend -= scanned;                memmove(cmd, cmd + scanned, readend);   /* safe */        scanned = (size_t) 0U;    }    tv.tv_sec = idletime;    tv.tv_usec = 0;            FD_ZERO(&rs);    while (scanned < cmdsize) {        if (scanned >= readend) {      /* nothing left in the buffer */            FD_SET(0, &rs);            while (select(1, &rs, NULL, NULL, &tv) <= 0 && errno == EINTR);            if (FD_ISSET(0, &rs) == 0) {                return -1;            }            if (readend >= cmdsize) {                break;            }#ifdef WITH_TLS            if (tls_cnx != NULL) {                while ((readen = SSL_read                        (tls_cnx, cmd + readend, cmdsize - readend))                       < (ssize_t) 0 && errno == EINTR);            } else#endif            {                while ((readen = read(0, cmd + readend, cmdsize - readend))                       < (ssize_t) 0 && errno == EINTR);            }            if (readen <= (ssize_t) 0) {                return -2;            }            readend += readen;            if (readend > cmdsize) {                return -2;            }        }#ifdef RFC_CONFORMANT_LINES        if (seen_r != 0) {#endif            if (cmd[scanned] == '\n') {#ifndef RFC_CONFORMANT_LINES                if (seen_r != 0) {#endif                    cmd[scanned - 1U] = 0;#ifndef RFC_CONFORMANT_LINES                } else {                    cmd[scanned] = 0;                }#endif                if (++scanned >= readend) {   /* non-pipelined command */                    scanned = readend = (size_t) 0U;                }                return 0;            }            seen_r = 0;#ifdef RFC_CONFORMANT_LINES        }#endif        if (ISCTRLCODE(cmd[scanned])) {            if (cmd[scanned] == '\r') {                seen_r = 1;            }#ifdef RFC_CONFORMANT_PARSER                   /* disabled by default, intentionnaly */            else if (cmd[scanned] == 0) {                cmd[scanned] = '\n';            }#else            /* replace control chars with _ */            cmd[scanned] = '_';                #endif        }        scanned++;    }    die(421, LOG_WARNING, MSG_LINE_TOO_LONG);   /* don't remove this */        return 0;                         /* to please GCC */}/* Replace extra spaces before and after a string with '_' */#ifdef MINIMAL# define revealextraspc(X) (X)#elsestatic char *revealextraspc(char * const s_){    register unsigned char *s = (unsigned char *) s_;    register unsigned char *sn;        if (s == NULL) {        return s_;    }    simplify(s_);    while (*s != 0U && isspace(*s)) {        *s++ = '_';    }    if (*s == 0U) {        return s_;    }    sn = s;    do {        sn++;    } while (*sn != 0U);    do {        sn--;                if (!isspace(*sn)) {            break;        }        *sn = '_';    } while (sn != s);        return s_;}#endifvoid parser(void){    char *arg;#ifndef MINIMAL    char *sitearg;#endif    size_t n;    for (;;) {        xferfd = -1;        if (state_needs_update != 0) {            state_needs_update = 0;            setprogname("pure-ftpd (IDLE)");#ifdef FTPWHO            if (shm_data_cur != NULL) {                ftpwho_lock();                shm_data_cur->state = FTPWHO_STATE_IDLE;                *shm_data_cur->filename = 0;                ftpwho_unlock();            }#endif        }        doreply();        alarm(idletime * 2);        switch (sfgets()) {        case -1:#ifdef BORING_MODE	    die(421, LOG_INFO, MSG_TIMEOUT);#else            die(421, LOG_INFO, MSG_TIMEOUT_PARSER);#endif        case -2:            return;        }#ifdef DEBUG        if (debug != 0) {            addreply(0, "%s", cmd);        }#endif        n = (size_t) 0U;        while ((isalpha((unsigned char) cmd[n]) || cmd[n] == '@') &&               n < cmdsize) {            cmd[n] = (char) tolower((unsigned char) cmd[n]);            n++;        }        if (n >= cmdsize) {            /* overparanoid, it should never happen */            die(421, LOG_WARNING, MSG_LINE_TOO_LONG);        }        if (n == (size_t) 0U) {            nop:            addreply_noformat(500, "?");            continue;        }#ifdef SKIP_COMMAND_TRAILING_SPACES                while (isspace((unsigned char) cmd[n]) && n < cmdsize) {            cmd[n++] = 0;        }        arg = cmd + n;                while (cmd[n] != 0 && n < cmdsize) {            n++;        }        n--;        while (isspace((unsigned char) cmd[n])) {            cmd[n--] = 0;        }#else        if (cmd[n] == 0) {            arg = cmd + n;        } else if (isspace((unsigned char) cmd[n])) {            cmd[n] = 0;            arg = cmd + n + 1;        } else {            goto nop;        }#endif        if (logging != 0) {#ifdef DEBUG            logfile(LOG_DEBUG, MSG_DEBUG_COMMAND " [%s] [%s]",                   cmd, arg);#else            logfile(LOG_DEBUG, MSG_DEBUG_COMMAND " [%s] [%s]",                   cmd, strcmp(cmd, "pass") ? arg : "<*>");#endif        }        /*         * antiidle() is called with dummy commands, usually used by clients         * who are wanting extra idle time. We give them some, but not too much.         * When we jump to wayout, the idle timer is not zeroed. It means that         * we didn't issue an 'active' command like RETR.         */        #ifndef MINIMAL        if (!strcmp(cmd, "noop") || !strcmp(cmd, "allo")) {            antiidle();            donoop();            goto wayout;        }#endif        if (!strcmp(cmd, "user")) {#ifdef WITH_TLS            if (enforce_tls_auth > 1 && tls_cnx == NULL) {                die(421, LOG_WARNING, MSG_TLS_NEEDED);            }#endif            douser(arg);        } else if (!strcmp(cmd, "acct")) {            addreply(202, MSG_WHOAREYOU);        } else if (!strcmp(cmd, "pass")) {            if (guest == 0) {                randomdelay();            }            dopass(arg);        } else if (!strcmp(cmd, "quit")) {            addreply(221, MSG_GOODBYE,                     (unsigned long long) ((uploaded + 1023ULL) / 1024ULL),                     (unsigned long long) ((downloaded + 1023ULL) / 1024ULL));            return;        } else if (!strcmp(cmd, "syst")) {            antiidle();            addreply_noformat(215, "UNIX Type: L8");            goto wayout;#ifdef WITH_TLS        } else if (enforce_tls_auth > 0 &&                   !strcmp(cmd, "auth") && !strcasecmp(arg, "tls")) {            addreply_noformat(234, "AUTH TLS OK.");            doreply();            if (tls_cnx == NULL) {                (void) tls_init_new_session();

⌨️ 快捷键说明

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