Пример #1
0
static void
processHeader(const char *  const fieldName,
              char *        const fieldValue,
              TSession *    const sessionP,
              const char ** const errorP,
              uint16_t *    const httpErrorCodeP) {
/*----------------------------------------------------------------------------
   We may modify *fieldValue, and we put pointers to *fieldValue and
   *fieldName into *sessionP.

   We must fix this some day.  *sessionP should point to individual
   malloc'ed strings.
-----------------------------------------------------------------------------*/
    *errorP = NULL;  /* initial assumption */

    if (xmlrpc_streq(fieldName, "connection")) {
        if (xmlrpc_strcaseeq(fieldValue, "keep-alive"))
            sessionP->requestInfo.keepalive = TRUE;
        else
            sessionP->requestInfo.keepalive = FALSE;
    } else if (xmlrpc_streq(fieldName, "host")) {
        if (sessionP->requestInfo.host) {
            xmlrpc_strfree(sessionP->requestInfo.host);
            sessionP->requestInfo.host = NULL;
        }
        parseHostPort(fieldValue, &sessionP->requestInfo.host,
                      &sessionP->requestInfo.port, errorP, httpErrorCodeP);
    } else if (xmlrpc_streq(fieldName, "from"))
        sessionP->requestInfo.from = fieldValue;
    else if (xmlrpc_streq(fieldName, "user-agent"))
        sessionP->requestInfo.useragent = fieldValue;
    else if (xmlrpc_streq(fieldName, "referer"))
        sessionP->requestInfo.referer = fieldValue;
    else if (xmlrpc_streq(fieldName, "range")) {
        if (xmlrpc_strneq(fieldValue, "bytes=", 6)) {
            bool succeeded;
            succeeded = ListAddFromString(&sessionP->ranges, &fieldValue[6]);
            if (!succeeded) {
                xmlrpc_asprintf(errorP, "ListAddFromString() failed for "
                                "\"range: bytes=...\" header value '%s'",
                                &fieldValue[6]);
                *httpErrorCodeP = 400;
            }
        }
    } else if (xmlrpc_streq(fieldName, "cookies")) {
        bool succeeded;
        succeeded = ListAddFromString(&sessionP->cookies, fieldValue);
        if (!succeeded) {
            xmlrpc_asprintf(errorP, "ListAddFromString() failed for "
                            "cookies: header value '%s'", fieldValue);
            *httpErrorCodeP = 400;
        }
    } else if (xmlrpc_streq(fieldName, "expect")) {
        if (xmlrpc_strcaseeq(fieldValue, "100-continue"))
            sessionP->continueRequired = TRUE;
    }
}
Пример #2
0
bool
RequestAuth(TSession *   const sessionP,
            const char * const credential,
            const char * const user,
            const char * const pass) {
/*----------------------------------------------------------------------------
   Authenticate requester, in a very simplistic fashion.

   If the request executing on session *sessionP specifies basic
   authentication (via Authorization header) with username 'user', password
   'pass', then return TRUE.  Else, return FALSE and set up an authorization
   failure response (HTTP response status 401) that says user must supply an
   identity in the 'credential' domain.

   When we return TRUE, we also set the username in the request info for the
   session to 'user' so that a future SessionGetRequestInfo can get it.
-----------------------------------------------------------------------------*/
    bool authorized;
    char * authHdrPtr;

    authHdrPtr = RequestHeaderValue(sessionP, "authorization");
    if (authHdrPtr) {
        const char * authType;
        NextToken((const char **)&authHdrPtr);
        GetTokenConst(&authHdrPtr, &authType);
        authType = GetToken(&authHdrPtr);
        if (authType) {
            if (xmlrpc_strcaseeq(authType, "basic")) {
                const char * userPass;
                char userPassEncoded[80];

                NextToken((const char **)&authHdrPtr);

                xmlrpc_asprintf(&userPass, "%s:%s", user, pass);
                xmlrpc_base64Encode(userPass, userPassEncoded);
                xmlrpc_strfree(userPass);

                if (xmlrpc_streq(authHdrPtr, userPassEncoded)) {
                    sessionP->requestInfo.user = strdup(user);
                    authorized = TRUE;
                } else
                    authorized = FALSE;
            } else
                authorized = FALSE;
        } else
            authorized = FALSE;
    } else
        authorized = FALSE;

    if (!authorized) {
        const char * hdrValue;
        xmlrpc_asprintf(&hdrValue, "Basic realm=\"%s\"", credential);
        ResponseAddField(sessionP, "WWW-Authenticate", hdrValue);

        xmlrpc_strfree(hdrValue);

        ResponseStatus(sessionP, 401);
    }
    return authorized;
}
Пример #3
0
static bool
ConfReadBool(const char * const token,
             bool *       const bP) {

    bool succeeded;

    if (xmlrpc_strcaseeq(token, "yes")) {
        *bP = TRUE;
        succeeded = TRUE;
    } else if (xmlrpc_strcaseeq(token, "no")) {
        *bP = FALSE;
        succeeded = TRUE;
    } else
        succeeded = FALSE;

    return succeeded;
}
Пример #4
0
static bool
ConfReadBool(const char * const token,
             bool *       const bP) {

    bool succeeded;

    if (xmlrpc_strcaseeq(token, "yes")) {
        *bP = true;
        succeeded = true;
    } else if (xmlrpc_strcaseeq(token, "no")) {
        *bP = false;
        succeeded = true;
    } else
        succeeded = false;

    return succeeded;
}
Пример #5
0
static void
processHeader(const char * const fieldName,
              char *       const fieldValue,
              TSession *   const sessionP,
              uint16_t *   const httpErrorCodeP) {
/*----------------------------------------------------------------------------
   We may modify *fieldValue, and we put pointers to *fieldValue and
   *fieldName into *sessionP.

   We must fix this some day.  *sessionP should point to individual
   malloc'ed strings.
-----------------------------------------------------------------------------*/
    *httpErrorCodeP = 0;  /* initial assumption */

    if (xmlrpc_streq(fieldName, "connection")) {
        if (xmlrpc_strcaseeq(fieldValue, "keep-alive"))
            sessionP->request_info.keepalive = TRUE;
        else
            sessionP->request_info.keepalive = FALSE;
    } else if (xmlrpc_streq(fieldName, "host"))
        parseHostPort(fieldValue, &sessionP->request_info.host,
                      &sessionP->request_info.port, httpErrorCodeP);
    else if (xmlrpc_streq(fieldName, "from"))
        sessionP->request_info.from = fieldValue;
    else if (xmlrpc_streq(fieldName, "user-agent"))
        sessionP->request_info.useragent = fieldValue;
    else if (xmlrpc_streq(fieldName, "referer"))
        sessionP->request_info.referer = fieldValue;
    else if (xmlrpc_streq(fieldName, "range")) {
        if (xmlrpc_strneq(fieldValue, "bytes=", 6)) {
            abyss_bool succeeded;
            succeeded = ListAddFromString(&sessionP->ranges, &fieldValue[6]);
            *httpErrorCodeP = succeeded ? 0 : 400;
        }
    } else if (xmlrpc_streq(fieldName, "cookies")) {
        abyss_bool succeeded;
        succeeded = ListAddFromString(&sessionP->cookies, fieldValue);
        *httpErrorCodeP = succeeded ? 0 : 400;
    }
}
Пример #6
0
abyss_bool
RequestAuth(TSession *   const sessionP,
            const char * const credential,
            const char * const user,
            const char * const pass) {
/*----------------------------------------------------------------------------
   Authenticate requester, in a very simplistic fashion.

   If the request executing on session *sessionP specifies basic
   authentication (via Authorization header) with username 'user', password
   'pass', then return true.  Else, return false and set up an authorization
   failure response (HTTP response status 401) that says user must supply an
   identity in the 'credential' domain.

   When we return true, we also set the username in the request info for the
   session to 'user' so that a future SessionGetRequestInfo can get it.
-----------------------------------------------------------------------------*/
    bool authorized;
    const char * authValue;

    authValue = RequestHeaderValue(sessionP, "authorization");
    if (authValue) {
        char * const valueBuffer = malloc(strlen(authValue));
            /* A buffer we can mangle as we parse the authorization: value */

        if (!authValue)
            /* Should return error, but we have no way to do that */
            authorized = false;
        else {
            const char * authType;
            char * authHdrPtr;

            strcpy(valueBuffer, authValue);
            authHdrPtr = &valueBuffer[0];

            NextToken((const char **)&authHdrPtr);
            GetTokenConst(&authHdrPtr, &authType);
            if (authType) {
                if (xmlrpc_strcaseeq(authType, "basic")) {
                    const char * userPass;
                    char userPassEncoded[80];

                    NextToken((const char **)&authHdrPtr);

                    xmlrpc_asprintf(&userPass, "%s:%s", user, pass);
                    xmlrpc_base64Encode(userPass, userPassEncoded);
                    xmlrpc_strfree(userPass);

                    if (xmlrpc_streq(authHdrPtr, userPassEncoded)) {
                        sessionP->requestInfo.user = xmlrpc_strdupsol(user);
                        authorized = true;
                    } else
                        authorized = false;
                } else
                    authorized = false;
            } else
                authorized = false;

            free(valueBuffer);
        }
    } else
        authorized = false;

    if (!authorized) {
        const char * hdrValue;
        xmlrpc_asprintf(&hdrValue, "Basic realm=\"%s\"", credential);
        ResponseAddField(sessionP, "WWW-Authenticate", hdrValue);

        xmlrpc_strfree(hdrValue);

        ResponseStatus(sessionP, 401);
    }
    return authorized;
}
Пример #7
0
abyss_bool
ConfReadServerFile(const char * const filename,
                   TServer *    const serverP) {

    struct _TServer * const srvP     = serverP->srvP;
    BIHandler *       const handlerP = srvP->builtinHandlerP;

    TFile * fileP;
    char z[512];
    char * p;
    unsigned int lineNum;
    TFileStat fs;

    if (!FileOpen(&fileP, filename, O_RDONLY))
        return FALSE;

    lineNum = 0;

    while (ConfReadLine(fileP, z, 512)) {
        ++lineNum;
        p = z;

        if (ConfNextToken(&p)) {
            const char * const option = ConfGetToken(&p);
            if (option) {
                ConfNextToken(&p);

                if (xmlrpc_strcaseeq(option, "port")) {
                    int32_t n;
                    if (ConfReadInt(p, &n, 1, 65535))
                        srvP->port = n;
                    else
                        TraceExit("Invalid port '%s'", p);
                } else if (xmlrpc_strcaseeq(option, "serverroot")) {
                    bool success;
                    chdirx(p, &success);
                    if (!success)
                        TraceExit("Invalid server root '%s'",p);
                } else if (xmlrpc_strcaseeq(option, "path")) {
                    if (FileStat(p, &fs))
                        if (fs.st_mode & S_IFDIR) {
                            HandlerSetFilesPath(handlerP, p);
                            continue;
                        }
                    TraceExit("Invalid path '%s'", p);
                } else if (xmlrpc_strcaseeq(option, "default")) {
                    const char * filename;
                    
                    while ((filename = ConfGetToken(&p))) {
                        HandlerAddDefaultFN(handlerP, filename);
                        if (!ConfNextToken(&p))
                            break;
                    }
                } else if (xmlrpc_strcaseeq(option, "keepalive")) {
                    int32_t n;
                    if (ConfReadInt(p, &n, 1, 65535))
                        srvP->keepalivemaxconn = n;
                    else
                        TraceExit("Invalid KeepAlive value '%s'", p);
                } else if (xmlrpc_strcaseeq(option, "timeout")) {
                    int32_t n;
                    if (ConfReadInt(p, &n, 1, 3600)) {
                        srvP->keepalivetimeout = n;
                        /* Must see what to do with that */
                        srvP->timeout = n;
                    } else
                        TraceExit("Invalid TimeOut value '%s'", p);
                } else if (xmlrpc_strcaseeq(option, "mimetypes")) {
                    MIMEType * mimeTypeP;
                    readMIMETypesFile(p, &mimeTypeP);
                    if (!mimeTypeP)
                        TraceExit("Can't read MIME Types file '%s'", p);
                    else
                        HandlerSetMimeType(handlerP, mimeTypeP);
                } else if (xmlrpc_strcaseeq(option,"logfile")) {
                    srvP->logfilename = strdup(p);
                } else if (xmlrpc_strcaseeq(option,"user")) {
                    parseUser(p, srvP);
                } else if (xmlrpc_strcaseeq(option, "pidfile")) {
                    parsePidfile(p, srvP);
                } else if (xmlrpc_strcaseeq(option, "advertiseserver")) {
                    if (!ConfReadBool(p, &srvP->advertise))
                        TraceExit("Invalid boolean value "
                                  "for AdvertiseServer option");
                } else
                    TraceExit("Invalid option '%s' at line %u",
                              option, lineNum);
            }
        }
    }

    FileClose(fileP);
    return TRUE;
}