bool httpPamVerifyUser(HttpConn *conn) { MprBuf *abilities; pam_handle_t *pamh; UserInfo info; struct pam_conv conv = { pamChat, &info }; struct group *gp; int res, i; mprAssert(conn->username); mprAssert(conn->password); mprAssert(!conn->encoded); info.name = (char*) conn->username; info.password = (char*) conn->password; pamh = NULL; if ((res = pam_start("login", info.name, &conv, &pamh)) != PAM_SUCCESS) { return 0; } if ((res = pam_authenticate(pamh, PAM_DISALLOW_NULL_AUTHTOK)) != PAM_SUCCESS) { pam_end(pamh, PAM_SUCCESS); mprLog(5, "httpPamVerifyUser failed to verify %s", conn->username); return 0; } pam_end(pamh, PAM_SUCCESS); mprLog(5, "httpPamVerifyUser verified %s", conn->username); if (!conn->user) { conn->user = mprLookupKey(conn->rx->route->auth->users, conn->username); } if (!conn->user) { Gid groups[32]; int ngroups; /* Create a temporary user with a abilities set to the groups */ ngroups = sizeof(groups) / sizeof(Gid); if ((i = getgrouplist(conn->username, 99999, groups, &ngroups)) >= 0) { abilities = mprCreateBuf(0, 0); for (i = 0; i < ngroups; i++) { if ((gp = getgrgid(groups[i])) != 0) { mprPutFmtToBuf(abilities, "%s ", gp->gr_name); } } mprAddNullToBuf(abilities); mprLog(5, "Create temp user \"%s\" with abilities: %s", conn->username, mprGetBufStart(abilities)); conn->user = httpCreateUser(conn->rx->route->auth, conn->username, 0, mprGetBufStart(abilities)); } } return 1; }
static void setChunkPrefix(MaQueue *q, MaPacket *packet) { if (packet->prefix) { return; } packet->prefix = mprCreateBuf(packet, 32, 32); /* * NOTE: prefixes don't count in the queue length. No need to adjust q->count */ if (maGetPacketLength(packet)) { mprPutFmtToBuf(packet->prefix, "\r\n%x\r\n", maGetPacketLength(packet)); } else { mprPutStringToBuf(packet->prefix, "\r\n0\r\n\r\n"); } }
static void setChunkPrefix(MaQueue *q, MaPacket *packet) { MaConn *conn; conn = q->conn; if (packet->prefix) { return; } packet->prefix = mprCreateBuf(packet, 32, 32); if (packet->count) { mprPutFmtToBuf(packet->prefix, "\r\n%x\r\n", packet->count); } else { mprPutStringToBuf(packet->prefix, "\r\n0\r\n\r\n"); } }
/* This will be enabled when caching is enabled for the route and there is no acceptable cache data to use. OR - manual caching has been enabled. */ static void outgoingCacheFilterService(HttpQueue *q) { HttpPacket *packet, *data; HttpConn *conn; HttpTx *tx; MprKey *kp; cchar *cachedData; ssize size; int foundDataPacket; conn = q->conn; tx = conn->tx; foundDataPacket = 0; cachedData = 0; if (tx->status < 200 || tx->status > 299) { tx->cacheBuffer = 0; } /* This routine will save cached responses to tx->cacheBuffer. It will also send cached data if the X-SendCache header is present. Normal caching is done by cacheHandler */ if (mprLookupKey(conn->tx->headers, "X-SendCache") != 0) { if (fetchCachedResponse(conn)) { mprLog(3, "cacheFilter: write cached content for '%s'", conn->rx->uri); cachedData = setHeadersFromCache(conn, tx->cachedContent); tx->length = slen(cachedData); } } for (packet = httpGetPacket(q); packet; packet = httpGetPacket(q)) { if (!httpWillNextQueueAcceptPacket(q, packet)) { httpPutBackPacket(q, packet); return; } if (packet->flags & HTTP_PACKET_HEADER) { if (!cachedData && tx->cacheBuffer) { /* Add defined headers to the start of the cache buffer. Separate with a double newline. */ mprPutFmtToBuf(tx->cacheBuffer, "X-Status: %d\n", tx->status); for (kp = 0; (kp = mprGetNextKey(tx->headers, kp)) != 0; ) { mprPutFmtToBuf(tx->cacheBuffer, "%s: %s\n", kp->key, kp->data); } mprPutCharToBuf(tx->cacheBuffer, '\n'); } } else if (packet->flags & HTTP_PACKET_DATA) { if (cachedData) { /* Using X-SendCache. Replace the data with the cached response. */ mprFlushBuf(packet->content); mprPutBlockToBuf(packet->content, cachedData, (ssize) tx->length); } else if (tx->cacheBuffer) { /* Save the response packet to the cache buffer. Will write below in saveCachedResponse. */ size = mprGetBufLength(packet->content); if ((tx->cacheBufferLength + size) < conn->limits->cacheItemSize) { mprPutBlockToBuf(tx->cacheBuffer, mprGetBufStart(packet->content), mprGetBufLength(packet->content)); tx->cacheBufferLength += size; } else { tx->cacheBuffer = 0; mprLog(3, "cacheFilter: Item too big to cache %d bytes, limit %d", tx->cacheBufferLength + size, conn->limits->cacheItemSize); } } foundDataPacket = 1; } else if (packet->flags & HTTP_PACKET_END) { if (cachedData && !foundDataPacket) { /* Using X-SendCache but there was no data packet to replace. So do the write here */ data = httpCreateDataPacket((ssize) tx->length); mprPutBlockToBuf(data->content, cachedData, (ssize) tx->length); httpPutPacketToNext(q, data); } else if (tx->cacheBuffer) { /* Save the cache buffer to the cache store */ saveCachedResponse(conn); } } httpPutPacketToNext(q, packet); } }
void maLogRequest(MaConn *conn) { MaHost *logHost, *host; MaResponse *resp; MaRequest *req; MprBuf *buf; char keyBuf[80], *timeText, *fmt, *cp, *qualifier, *value, c; int len; resp = conn->response; req = conn->request; host = req->host; logHost = host->logHost; if (logHost == 0) { return; } fmt = logHost->logFormat; if (fmt == 0) { return; } if (req->method == 0) { return; } len = MPR_MAX_URL + 256; buf = mprCreateBuf(resp, len, len); while ((c = *fmt++) != '\0') { if (c != '%' || (c = *fmt++) == '%') { mprPutCharToBuf(buf, c); continue; } switch (c) { case 'a': /* Remote IP */ mprPutStringToBuf(buf, conn->remoteIpAddr); break; case 'A': /* Local IP */ mprPutStringToBuf(buf, conn->sock->listenSock->ipAddr); break; case 'b': if (resp->bytesWritten == 0) { mprPutCharToBuf(buf, '-'); } else { mprPutIntToBuf(buf, resp->bytesWritten); } break; case 'B': /* Bytes written (minus headers) */ mprPutIntToBuf(buf, resp->bytesWritten - resp->headerSize); break; case 'h': /* Remote host */ mprPutStringToBuf(buf, conn->remoteIpAddr); break; case 'n': /* Local host */ mprPutStringToBuf(buf, req->parsedUri->host); break; case 'l': /* Supplied in authorization */ mprPutStringToBuf(buf, req->user ? req->user : "******"); break; case 'O': /* Bytes written (including headers) */ mprPutIntToBuf(buf, resp->bytesWritten); break; case 'r': /* First line of request */ mprPutFmtToBuf(buf, "%s %s %s", req->methodName, req->parsedUri->originalUri, req->httpProtocol); break; case 's': /* Response code */ mprPutIntToBuf(buf, resp->code); break; case 't': /* Time */ mprPutCharToBuf(buf, '['); timeText = mprFormatLocalTime(conn, mprGetTime(conn)); mprPutStringToBuf(buf, timeText); mprFree(timeText); mprPutCharToBuf(buf, ']'); break; case 'u': /* Remote username */ mprPutStringToBuf(buf, req->user ? req->user : "******"); break; case '{': /* Header line */ qualifier = fmt; if ((cp = strchr(qualifier, '}')) != 0) { fmt = &cp[1]; *cp = '\0'; c = *fmt++; mprStrcpy(keyBuf, sizeof(keyBuf), "HTTP_"); mprStrcpy(&keyBuf[5], sizeof(keyBuf) - 5, qualifier); mprStrUpper(keyBuf); switch (c) { case 'i': value = (char*) mprLookupHash(req->headers, keyBuf); mprPutStringToBuf(buf, value ? value : "-"); break; default: mprPutStringToBuf(buf, qualifier); } *cp = '}'; } else { mprPutCharToBuf(buf, c); } break; case '>': if (*fmt == 's') { fmt++; mprPutIntToBuf(buf, resp->code); } break; default: mprPutCharToBuf(buf, c); break; } } mprPutCharToBuf(buf, '\n'); mprAddNullToBuf(buf); mprWrite(logHost->accessLog, mprGetBufStart(buf), mprGetBufLength(buf)); }
int ejsXMLToString(Ejs *ejs, MprBuf *buf, EjsXML *node, int indentLevel) { EjsXML *xml, *child, *attribute, *elt; int sawElements, next; if (node->obj.var.visited) { return 0; } node->obj.var.visited = 1; if (node->kind == EJS_XML_LIST) { for (next = 0; (elt = mprGetNextItem(node->elements, &next)) != 0; ) { ejsXMLToString(ejs, buf, elt, indentLevel); } return 0; } mprAssert(ejsIsXML(node)); xml = (EjsXML*) node; switch (xml->kind) { case EJS_XML_ELEMENT: /* * XML object is complex (has elements) so return full XML content. */ if (indentLevel > 0) { mprPutCharToBuf(buf, '\n'); } indent(buf, indentLevel); mprPutFmtToBuf(buf, "<%s", xml->qname.name); if (xml->attributes) { for (next = 0; (attribute = mprGetNextItem(xml->attributes, &next)) != 0; ) { mprPutFmtToBuf(buf, " %s=\"%s\"", attribute->qname.name, attribute->value); } } sawElements = 0; if (xml->elements) { mprPutStringToBuf(buf, ">"); for (next = 0; (child = mprGetNextItem(xml->elements, &next)) != 0; ) { if (child->kind != EJS_XML_TEXT) { sawElements++; } /* Recurse */ if (ejsXMLToString(ejs, buf, child, indentLevel < 0 ? -1 : indentLevel + 1) < 0) { return -1; } } if (sawElements && indentLevel >= 0) { mprPutCharToBuf(buf, '\n'); indent(buf, indentLevel); } mprPutFmtToBuf(buf, "</%s>", xml->qname.name); } else { /* Solo */ mprPutStringToBuf(buf, "/>"); } break; case EJS_XML_COMMENT: mprPutCharToBuf(buf, '\n'); indent(buf, indentLevel); mprPutFmtToBuf(buf, "<!--%s -->", xml->value); break; case EJS_XML_ATTRIBUTE: /* * Only here when converting solo attributes to a string */ mprPutStringToBuf(buf, xml->value); break; case EJS_XML_TEXT: mprPutStringToBuf(buf, xml->value); break; } node->obj.var.visited = 0; return 0; }