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

📄 minihttp.c

📁 安全开发库。含客户端建立ssl连接、签名、证书验证、证书发布和撤销等。编译用到nss
💻 C
📖 第 1 页 / 共 5 页
字号:
{    SSMStatus rv = SSM_SUCCESS;    char *c, d, *start;    PRInt32 numParams, i;    numParams = httpparse_count_params(req);    req->paramNames = (char **) PR_Calloc(numParams+1, sizeof(char *));    if (!req->paramNames)        goto loser;    req->paramValues = (char **) PR_Calloc(numParams+1, sizeof(char *));    if (!req->paramValues)        goto loser;    httpparse_unescape_param(req->params);    /* Put the params in their place. */    for(i=0, c = start = req->params; i < numParams; i++)    {        /* Get the parameter name. */        while((*c) && (*c != '=') && (*c != '&'))            c++;        req->paramNames[i] = start; /* name goes here */        if (*c == '\0')        {            /* reached end of params while looking for a name.               leave the value null, end. */            break;        }                /* save off the delimiter so that we can decide how to proceed */        d = *c;        /* null out the delimiter so that the param name is usable */        *c++ = '\0';        start = c;        if (d == '&')            /* found a name but no value. leave value null, loop back. */            continue;                /* Now, copy the value. */        req->paramValues[i] = start;        /* If we have more params to process,            tie off the end of this parameter value. */        if (i != (numParams-1))        {            while((*c) && (*c != '&')) /* (*c) check just to be safe */                {                       if (*c == '~')                        *c = '&';                    c++;                }            *c++ = '\0';            start = c; /* get ready to mark off next parameter */        }    }    goto done; loser:    PR_FREEIF(req->paramNames);    PR_FREEIF(req->paramValues); done:    return rv;}/* Parse an incoming request. */static SSMStatushttp_parse_request(HTTPRequest *req){    char *line, *chunk = req->reqbuf;    char *b, *e; /* beginning and end of something we want */    char *p; /* beginning of params */    SECItem tmpItem = {siBuffer, NULL, 0};    while ((line = nextLine(&chunk)) != NULL)    {        /* Is it a request we're interested in? */        if (!STRNCASECMP(line, "GET ", 4))        {            SSM_DEBUG("Parsing GET request: `%s'\n", line);            /* Parse the GET request. */            b = strchr(line, ' ');            e = strrchr(line, ' ');            if (!b)                SSM_DEBUG("Couldn't find beginning of file!");            if (!e)                SSM_DEBUG("Couldn't find end of file!");            if ((!b) || (!e))                continue;            while ((IS_WHITESPACE(*b)) && (b < e)) b++;            while ((IS_WHITESPACE(*e)) && (b < e)) e--;            e++;            *e = '\0';            if (*b == '/') b++; /* move past the first slash */            req->handlerName = b; /* this is the command handler */            SSM_DEBUG("Base ref: `%s'.\n", req->handlerName);            p = strchr(b, '?');            if (p)            {                *p++ = '\0';                req->params = p;                SSM_DEBUG("Params: `%s'.\n",                           req->params ? req->params : "(none)");                httpparse_parse_params(req);            }            continue;        }        /* If we get here, then we assume we have a header with a colon           in it (i.e. a header line other than the GET).            We're interested in anything after the colon. */        b = strchr(line, ':');        if (!b)            /* Dunno what to do, ignore this line */            continue;        do        {            b++;        }        while (IS_WHITESPACE(*b));        if (!STRNCASECMP(line, "User-Agent", 10))        {            SSM_DEBUG("Found User-Agent: `%s'.\n", b);            req->agent = b;        }        else if (!STRNCASECMP(line, "Accept-Language", 15))        {            SSM_DEBUG("Found Accept-Language: `%s'.\n", b);            req->language = b;            /* REMOVED CALL */;        }        else if (!STRNCASECMP(line, "Accept-Charset", 14))        {            SSM_DEBUG("Found Accept-Charset: `%s'.\n", b);            req->charset = b;            /* REMOVED CALL */;        }        else if (!STRNCASECMP(line, "Referer", 7)) {            /* Make the new request inherit the same target as              * its referer             */            req->referer = b;        }        else if (!STRNCASECMP(line, "Authorization", 13))        {            SECStatus srv;            SSM_DEBUG("Found Authorization: `%s'.\n", b);            /* If the auth type is basic, process the auth info. */            if (!STRNCASECMP(b, "Basic", 5))            {                PRIntn len;                /* move to the auth info itself */                while ((*b) && (!IS_WHITESPACE(*b))) b++;                while ((*b) && (IS_WHITESPACE(*b))) b++;                /* decode base-64. */                srv = ATOB_ConvertAsciiToItem(&tmpItem, b);                if (srv == SECSuccess)                {                    /* We need to copy the ascii over and NULL                     * terminate it correctly becuase the                     * Base64 decoder doesn't guarantee that.                     */                    char *w = (char *) PR_Malloc(tmpItem.len+1);                                        PL_strncpy(w, (char *) tmpItem.data, tmpItem.len);                    w[tmpItem.len] = '\0';                    SSM_DEBUG("Decoded auth: '%s'.\n", w);                    PR_Free(tmpItem.data);                    tmpItem.data = (unsigned char *) w;                    len = tmpItem.len;                    /*                        divide control RID (username) and nonce (password).                       ### mwelch - I walk manually through this because                       the string isn't null-terminated.                    */                    while((len > 0) && (*w != ':'))                    {                        w++;                        len--;                    }                    if (len > 0)                    {                        PRIntn ridLen = tmpItem.len-len;                        req->ctrlrid = (char *) PR_CALLOC(ridLen+1);                        req->password = (char *) PR_CALLOC(len+1);                        if (req->ctrlrid)                        {                            strncpy(req->ctrlrid, (char *) tmpItem.data, (unsigned long) ridLen);                            SSM_DEBUG("ctrlrid: %s\n", req->ctrlrid);                        }                        else                            SSM_DEBUG("Couldn't allocate a ctrlrid.\n");                        if (req->password)                        {                            /* Skip over the colon separating rid and nonce. */                            strncpy(req->password, ++w, --len);                            SSM_DEBUG("password: %s\n", req->password);                        }                        else                            SSM_DEBUG("Couldn't allocate a password.\n");                    }                    else                        SSM_DEBUG("Couldn't find ':' in between ctrlrid and password.\n");                    SECITEM_FreeItem(&tmpItem, PR_FALSE);                }                else                    SSM_DEBUG("srv %ld decoding basic auth info.\n", (long) srv);            }            else                SSM_HTTPReportError(req, HTTP_UNAUTHORIZED);        }    }    return SSM_SUCCESS;}/* Read an HTTP request. */SSMStatushttp_read_request(PRFileDesc *sock, HTTPRequest **returnReq){    PRIntn read;    PRBool detectEOR = PR_FALSE; /* Have we detected the end of the request? */    char buf[LINESIZE];    SSMStatus rv = SSM_SUCCESS;    PRUint32 tail;    HTTPRequest *req = NULL;    if (!sock || !returnReq)    {        rv = PR_INVALID_ARGUMENT_ERROR;        goto loser;    }    /* Set up the request object. */    req = http_request_create(sock);    if (!req) goto loser;    /* Get the request in chunks. */    while(!detectEOR)    {        PR_SetError(0, 0); /* reset so that error detect below works */        read = PR_Recv(sock, buf, LINESIZE, 0, PR_INTERVAL_NO_TIMEOUT);        if (read <= 0)        {            rv = PR_GetError();            if (rv == PR_SUCCESS) rv = PR_GetOSError();            goto loser;        }        /* Add the latest bits onto the end of the request */        rv = http_request_add_chunk(req, buf, read);        if (rv != SSM_SUCCESS) goto loser;        /* Look for LF+LF, CR+CR, CR+LF+CR+LF, or (heh) LF+CR+LF+CR.           If we find any of these, it means that we have the end of           request. */        (void) memcpy((char *) &tail, &(req->reqbuf[req->slen-4]), 4);        /* Do the four-byte comparisons first, they're easier           and more common */        if ((tail == 0x0d0a0d0a) || (tail == 0x0a0d0a0d))            detectEOR = PR_TRUE;        else         {            /* Look for CR+CR or LF+LF. */            tail &= 0x0000FFFF;            if ((tail == 0x00000d0d) || (tail == 0x00000a0a))                detectEOR = PR_TRUE;        }    }    /* duplicate the buffer, use one copy for parsing */    req->rawreqbuf = (char *) PR_CALLOC(req->slen+1);    if (!req->rawreqbuf) goto loser;    (void) memcpy(req->rawreqbuf, req->reqbuf, req->slen+1);    goto done; loser:    if (rv == SSM_SUCCESS) rv = SSM_FAILURE; done:    if (returnReq) *returnReq = req;    return rv;}SSMStatusSSM_HTTPParamValue(HTTPRequest *req, const char *key, char **value){    PRUint32 i;    SSMStatus rv = SSM_FAILURE;    if (!value)       return rv;    *value = NULL; /* in case we fail */    for(i=0; i < req->numParams; i++)    {        if (req->paramNames[i] && (!PL_strcmp(req->paramNames[i], key)))        {            *value = req->paramValues[i];            rv = SSM_SUCCESS;            break;        }    }    if (rv != SSM_SUCCESS)        SSM_DEBUG("HTTPParamValue: Error %d attempting to get parameter '%s'.\n"                  , rv, key);    return rv;}static SSMStatushttp_authenticate(HTTPRequest *req){    SSMStatus rv = SSM_FAILURE;    SSMResource *res;    SSMControlConnection *ctrlconn = NULL;#ifdef ALLOW_STANDALONE    if (standalone)    {        PR_ASSERT(standalone_conn);        req->ctrlconn = standalone_conn;        SSM_DEBUG("authenticate: Standalone mode, passing through.\n");        return SSM_SUCCESS;    }#endif    /* do we have auth information? */    if ((req->ctrlrid) && (req->password))    {        /* Get the control connection object. */        rv = SSM_RIDTextToResource(req, req->ctrlrid, &res);        if (rv == SSM_SUCCESS)        {            ctrlconn = (SSMControlConnection *) res;            req->ctrlconn = ctrlconn;            /* Verify restype and nonce. */            if ((!SSM_IsAKindOf(res, SSM_RESTYPE_CONTROL_CONNECTION))                || (PL_strcmp(req->password, ctrlconn->m_nonce)))            {                SSM_DEBUG("------------------------------\n");                SSM_DEBUG("Password doesn't match nonce.\n");                SSM_DEBUG("Nonce: %s\n", ctrlconn->m_nonce);                SSM_DEBUG("Submitted password: %s\n", req->password);                SSM_DEBUG("------------------------------\n");                PR_ASSERT(!"Couldn't authenticate this connection\n");                rv = SSM_FAILURE;            }        }        else            SSM_DEBUG("authenticate: Couldn't find a control connection.\n");    }    else    {        if (!req->ctrlrid)            SSM_DEBUG("authenticate: No ctrlrid available.\n");        else if (!req->password)            SSM_DEBUG("authenticate: No password available.\n");    }    if (rv != SSM_SUCCESS)        req->httprv = HTTP_UNAUTHORIZED;    else        req->ctrlconn = ctrlconn; /* type must check out */    return rv;}/* Returns the suffix of the filename, if it exists. */char *http_find_suffix(HTTPRequest *req){    char *result = NULL;    char *c;    c = req->filename;    if (!c) return result;    while(*c && (*c != '.'))        c++;    if (*c)        result = ++c;    else        result = NULL;    return result;}static SSMStatushttp_spool_file(HTTPRequest *req){    SSMStatus rv = SSM_FAILURE;    char *path = NULL;    PRFileDesc *fl = NULL;    char *type;    char buf[256];    PRInt32 numbytes;    path = PR_smprintf("%s%s", PSM_DOC_DIR, req->handlerName);    if (!path)     {        rv = PR_GetError();        goto done;    }    fl = PR_Open(path, PR_RDONLY, 0);    if (!fl)    {        rv = PR_GetError();        goto done;    }    /* We have the file open. Send the file type. */    if (PL_strstr(path, ".gif") || PL_strstr(path, ".GIF"))        type = "image/gif";    else        type = "text/html";    rv = SSM_HTTPSendOKHeader(req, "", type);    /* Send its contents back to the user. */    while(1)    {        PRInt32 frv;        

⌨️ 快捷键说明

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