=== modified file 'src/cf.data.pre' --- src/cf.data.pre 2014-05-04 15:34:46 +0000 +++ src/cf.data.pre 2014-05-04 16:38:53 +0000 @@ -3850,49 +3850,54 @@ ul User name from authentication ue User name from external acl helper ui User name from ident us User name from SSL credentials Client credentials. The exact meaning depends on the authentication scheme: For Basic authentication, it is the password; for Digest, the realm sent by the client; for NTLM and Negotiate, the client challenge or client credentials prefixed with "YR " or "KK ". HTTP related format codes: REQUEST [http::]rm Request method (GET/POST etc) [http::]>rm Request method from client [http::]ru Request URL from client [http::]rs Request URL scheme from client + [http::]rd Request URL domain from client - [http::]rp Request URL-Path excluding hostname - [http::]>rp Request URL-Path excluding hostname from client - [http::]rd Request URL domain sent to server or peer + [http::]>rP Request URL port from client + [http::]rp Request URL path excluding hostname from client + [http::]rv Request protocol version from client [http::]h Original received request header. + [http::]>h Original received request header. Usually differs from the request header sent by Squid, although most fields are often preserved. Accepts optional header field name/value filter argument using name[:[separator]element] format. [http::]>ha Received request header after adaptation and redirection (pre-cache REQMOD vectoring point). Usually differs from the request header sent by Squid, although most fields are often preserved. Optional header name argument as for >h RESPONSE [http::]Hs HTTP status code sent to the client [http::]h [http::]mt MIME content type === modified file 'src/external_acl.cc' --- src/external_acl.cc 2014-04-27 07:59:17 +0000 +++ src/external_acl.cc 2014-05-06 11:08:47 +0000 @@ -31,40 +31,41 @@ * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. * */ #include "squid.h" #include "acl/Acl.h" #include "acl/FilledChecklist.h" #include "cache_cf.h" #include "client_side.h" #include "comm/Connection.h" #include "ConfigParser.h" #include "ExternalACL.h" #include "ExternalACLEntry.h" #include "fde.h" +#include "format/ByteCode.h" #include "helper.h" #include "HttpHeaderTools.h" #include "HttpReply.h" #include "HttpRequest.h" #include "ip/tools.h" #include "MemBuf.h" #include "mgr/Registration.h" #include "rfc1738.h" #include "SquidConfig.h" #include "SquidString.h" #include "SquidTime.h" #include "Store.h" #include "tools.h" #include "URL.h" #include "wordlist.h" #if USE_OPENSSL #include "ssl/support.h" #endif #if USE_AUTH #include "auth/Acl.h" @@ -133,89 +134,41 @@ #if USE_AUTH /** * Configuration flag. May only be altered by the configuration parser. * * Indicates that all uses of this external_acl_type helper require authentication * details to be processed. If none are available its a fail match. */ bool require_auth; #endif enum { QUOTE_METHOD_SHELL = 1, QUOTE_METHOD_URL } quote; Ip::Address local_addr; }; struct _external_acl_format { - enum format_type { - EXT_ACL_UNKNOWN, -#if USE_AUTH - EXT_ACL_LOGIN, -#endif -#if USE_IDENT - EXT_ACL_IDENT, -#endif - EXT_ACL_SRC, - EXT_ACL_SRCPORT, -#if USE_SQUID_EUI - EXT_ACL_SRCEUI48, - EXT_ACL_SRCEUI64, -#endif - EXT_ACL_MYADDR, - EXT_ACL_MYPORT, - EXT_ACL_URI, - EXT_ACL_DST, - EXT_ACL_PROTO, - EXT_ACL_PORT, - EXT_ACL_PATH, - EXT_ACL_METHOD, - - EXT_ACL_HEADER_REQUEST, - EXT_ACL_HEADER_REQUEST_MEMBER, - EXT_ACL_HEADER_REQUEST_ID, - EXT_ACL_HEADER_REQUEST_ID_MEMBER, - - EXT_ACL_HEADER_REPLY, - EXT_ACL_HEADER_REPLY_MEMBER, - EXT_ACL_HEADER_REPLY_ID, - EXT_ACL_HEADER_REPLY_ID_MEMBER, - -#if USE_OPENSSL - EXT_ACL_USER_CERT, - EXT_ACL_USER_CA_CERT, - EXT_ACL_USER_CERT_RAW, - EXT_ACL_USER_CERTCHAIN_RAW, -#endif -#if USE_AUTH - EXT_ACL_EXT_USER, -#endif - EXT_ACL_EXT_LOG, - EXT_ACL_TAG, - EXT_ACL_ACLNAME, - EXT_ACL_ACLDATA, - EXT_ACL_PERCENT, - EXT_ACL_END - } type; + Format::ByteCode_t type; external_acl_format *next; char *header; char *member; char separator; http_hdr_type header_id; }; /* FIXME: These are not really cbdata, but it is an easy way * to get them pooled, refcounted, accounted and freed properly... */ CBDATA_TYPE(external_acl); CBDATA_TYPE(external_acl_format); static void free_external_acl_format(void *data) { external_acl_format *p = static_cast(data); safe_free(p->header); } @@ -237,92 +190,79 @@ helperShutdown(p->theHelper); delete p->theHelper; p->theHelper = NULL; } while (p->lru_list.tail) external_acl_cache_delete(p, static_cast(p->lru_list.tail->data)); if (p->cache) hashFreeMemory(p->cache); } /** * Parse the External ACL format %<{.*} and %>{.*} token(s) to pass a specific * request or reply header to external helper. * \param header - the token being parsed (without the identifying prefix) \param type - format enum identifier for this element, pulled from identifying prefix \param format - structure to contain all the info about this format element. */ void -parse_header_token(external_acl_format *format, char *header, const _external_acl_format::format_type type) +parse_header_token(external_acl_format *format, char *header, const Format::ByteCode_t type) { /* header format */ char *member, *end; /** Cut away the closing brace */ end = strchr(header, '}'); if (end && strlen(end) == 1) *end = '\0'; else self_destruct(); member = strchr(header, ':'); if (member) { /* Split in header and member */ *member = '\0'; ++member; if (!xisalnum(*member)) { format->separator = *member; ++member; } else { format->separator = ','; } format->member = xstrdup(member); - if (type == _external_acl_format::EXT_ACL_HEADER_REQUEST) - format->type = _external_acl_format::EXT_ACL_HEADER_REQUEST_MEMBER; + if (type == Format::LFT_ADAPTED_REQUEST_HEADER) + format->type = Format::LFT_ADAPTED_REQUEST_HEADER_ELEM; else - format->type = _external_acl_format::EXT_ACL_HEADER_REQUEST_MEMBER; + format->type = Format::LFT_REPLY_HEADER_ELEM; + } else { format->type = type; } format->header = xstrdup(header); format->header_id = httpHeaderIdByNameDef(header, strlen(header)); - - if (format->header_id != -1) { - if (member) { - if (type == _external_acl_format::EXT_ACL_HEADER_REQUEST) - format->type = _external_acl_format::EXT_ACL_HEADER_REQUEST_ID_MEMBER; - else - format->type = _external_acl_format::EXT_ACL_HEADER_REPLY_ID_MEMBER; - } else { - if (type == _external_acl_format::EXT_ACL_HEADER_REQUEST) - format->type = _external_acl_format::EXT_ACL_HEADER_REQUEST_ID; - else - format->type = _external_acl_format::EXT_ACL_HEADER_REPLY_ID; - } - } } void parse_externalAclHelper(external_acl ** list) { external_acl *a; char *token; external_acl_format **p; CBDATA_INIT_TYPE_FREECB(external_acl, free_external_acl); CBDATA_INIT_TYPE_FREECB(external_acl_format, free_external_acl_format); a = cbdataAlloc(external_acl); /* set defaults */ a->ttl = DEFAULT_EXTERNAL_ACL_TTL; a->negative_ttl = -1; a->cache_size = 256*1024; a->children.n_max = DEFAULT_EXTERNAL_ACL_CHILDREN; a->children.n_startup = a->children.n_max; @@ -404,118 +344,118 @@ if (a->negative_ttl == -1) a->negative_ttl = a->ttl; /* Parse format */ p = &a->format; while (token) { external_acl_format *format; /* stop on first non-format token found */ if (*token != '%') break; format = cbdataAlloc(external_acl_format); if (strncmp(token, "%{", 2) == 0) { // deprecated. but assume the old configs all referred to request headers. debugs(82, DBG_PARSE_NOTE(DBG_IMPORTANT), "WARNING: external_acl_type format %{...} is being replaced by %>ha{...} for : " << token); - parse_header_token(format, (token+2), _external_acl_format::EXT_ACL_HEADER_REQUEST); + parse_header_token(format, (token+2), Format::LFT_ADAPTED_REQUEST_HEADER); } else if (strncmp(token, "%>{", 3) == 0) { debugs(82, DBG_PARSE_NOTE(DBG_IMPORTANT), "WARNING: external_acl_type format %>{...} is being replaced by %>ha{...} for : " << token); - parse_header_token(format, (token+3), _external_acl_format::EXT_ACL_HEADER_REQUEST); + parse_header_token(format, (token+3), Format::LFT_ADAPTED_REQUEST_HEADER); } else if (strncmp(token, "%>ha{", 5) == 0) { - parse_header_token(format, (token+3), _external_acl_format::EXT_ACL_HEADER_REQUEST); + parse_header_token(format, (token+3), Format::LFT_ADAPTED_REQUEST_HEADER); } else if (strncmp(token, "%<{", 3) == 0) { debugs(82, DBG_PARSE_NOTE(DBG_IMPORTANT), "WARNING: external_acl_type format %<{...} is being replaced by %type = _external_acl_format::EXT_ACL_LOGIN; + format->type = Format::LFT_USER_LOGIN; a->require_auth = true; #endif } #if USE_IDENT else if (strcmp(token, "%IDENT") == 0 || strcmp(token, "%ui") == 0) - format->type = _external_acl_format::EXT_ACL_IDENT; + format->type = Format::LFT_USER_IDENT; #endif else if (strcmp(token, "%SRC") == 0 || strcmp(token, "%>a") == 0) - format->type = _external_acl_format::EXT_ACL_SRC; + format->type = Format::LFT_CLIENT_IP_ADDRESS; else if (strcmp(token, "%SRCPORT") == 0 || strcmp(token, "%>p") == 0) - format->type = _external_acl_format::EXT_ACL_SRCPORT; + format->type = Format::LFT_CLIENT_PORT; #if USE_SQUID_EUI else if (strcmp(token, "%SRCEUI48") == 0) - format->type = _external_acl_format::EXT_ACL_SRCEUI48; + format->type = Format::LFT_EXT_ACL_CLIENT_EUI48; else if (strcmp(token, "%SRCEUI64") == 0) - format->type = _external_acl_format::EXT_ACL_SRCEUI64; + format->type = Format::LFT_EXT_ACL_CLIENT_EUI64; #endif else if (strcmp(token, "%MYADDR") == 0 || strcmp(token, "%la") == 0) - format->type = _external_acl_format::EXT_ACL_MYADDR; + format->type = Format::LFT_LOCAL_LISTENING_IP; else if (strcmp(token, "%MYPORT") == 0 || strcmp(token, "%lp") == 0) - format->type = _external_acl_format::EXT_ACL_MYPORT; + format->type = Format::LFT_LOCAL_LISTENING_PORT; else if (strcmp(token, "%URI") == 0 || strcmp(token, "%>ru") == 0) - format->type = _external_acl_format::EXT_ACL_URI; - else if (strcmp(token, "%DST") == 0) - format->type = _external_acl_format::EXT_ACL_DST; - else if (strcmp(token, "%PROTO") == 0) - format->type = _external_acl_format::EXT_ACL_PROTO; - else if (strcmp(token, "%PORT") == 0) - format->type = _external_acl_format::EXT_ACL_PORT; + format->type = Format::LFT_CLIENT_REQ_URI; + else if (strcmp(token, "%DST") == 0 || strcmp(token, "%>rd") == 0) + format->type = Format::LFT_CLIENT_REQ_URLDOMAIN; + else if (strcmp(token, "%PROTO") == 0 || strcmp(token, "%>rs") == 0) + format->type = Format::LFT_CLIENT_REQ_URLSCHEME; + else if (strcmp(token, "%PORT") == 0) // XXX: add a logformat token + format->type = Format::LFT_CLIENT_REQ_URLPORT; else if (strcmp(token, "%PATH") == 0 || strcmp(token, "%>rp") == 0) - format->type = _external_acl_format::EXT_ACL_PATH; + format->type = Format::LFT_CLIENT_REQ_URLPATH; else if (strcmp(token, "%METHOD") == 0 || strcmp(token, "%>rm") == 0) - format->type = _external_acl_format::EXT_ACL_METHOD; + format->type = Format::LFT_CLIENT_REQ_METHOD; #if USE_OPENSSL else if (strcmp(token, "%USER_CERT") == 0) - format->type = _external_acl_format::EXT_ACL_USER_CERT_RAW; + format->type = Format::LFT_EXT_ACL_USER_CERT_RAW; else if (strcmp(token, "%USER_CERTCHAIN") == 0) - format->type = _external_acl_format::EXT_ACL_USER_CERTCHAIN_RAW; + format->type = Format::LFT_EXT_ACL_USER_CERTCHAIN_RAW; else if (strncmp(token, "%USER_CERT_", 11) == 0) { - format->type = _external_acl_format::EXT_ACL_USER_CERT; + format->type = Format::LFT_EXT_ACL_USER_CERT; format->header = xstrdup(token + 11); } else if (strncmp(token, "%USER_CA_CERT_", 11) == 0) { - format->type = _external_acl_format::EXT_ACL_USER_CA_CERT; + format->type = Format::LFT_EXT_ACL_USER_CA_CERT; format->header = xstrdup(token + 11); } else if (strncmp(token, "%CA_CERT_", 11) == 0) { debugs(82, DBG_PARSE_NOTE(DBG_IMPORTANT), "WARNING: external_acl_type %CA_CERT_* code is obsolete. Use %USER_CA_CERT_* instead"); - format->type = _external_acl_format::EXT_ACL_USER_CA_CERT; + format->type = Format::LFT_EXT_ACL_USER_CA_CERT; format->header = xstrdup(token + 11); } #endif #if USE_AUTH - else if (strcmp(token, "%EXT_USER") == 0) - format->type = _external_acl_format::EXT_ACL_EXT_USER; + else if (strcmp(token, "%EXT_USER") == 0 || strcmp(token, "%ue") == 0) + format->type = Format::LFT_USER_EXTERNAL; #endif - else if (strcmp(token, "%EXT_LOG") == 0) - format->type = _external_acl_format::EXT_ACL_EXT_LOG; - else if (strcmp(token, "%TAG") == 0) - format->type = _external_acl_format::EXT_ACL_TAG; + else if (strcmp(token, "%EXT_LOG") == 0 || strcmp(token, "%ea") == 0) + format->type = Format::LFT_EXT_LOG; + else if (strcmp(token, "%TAG") == 0 || strcmp(token, "%et") == 0) + format->type = Format::LFT_TAG; else if (strcmp(token, "%ACL") == 0) - format->type = _external_acl_format::EXT_ACL_ACLNAME; + format->type = Format::LFT_EXT_ACL_NAME; else if (strcmp(token, "%DATA") == 0) - format->type = _external_acl_format::EXT_ACL_ACLDATA; + format->type = Format::LFT_EXT_ACL_DATA; else if (strcmp(token, "%%") == 0) - format->type = _external_acl_format::EXT_ACL_PERCENT; + format->type = Format::LFT_PERCENT; else { debugs(0, DBG_CRITICAL, "ERROR: Unknown Format token " << token); self_destruct(); } *p = format; p = &format->next; token = ConfigParser::NextToken(); } /* There must be at least one format token */ if (!a->format) self_destruct(); /* helper */ if (!token) self_destruct(); wordlistAdd(&a->cmdline, token); @@ -556,101 +496,94 @@ storeAppendPrintf(sentry, " children-max=%d", node->children.n_max); if (node->children.n_startup != 1) storeAppendPrintf(sentry, " children-startup=%d", node->children.n_startup); if (node->children.n_idle != (node->children.n_max + node->children.n_startup) ) storeAppendPrintf(sentry, " children-idle=%d", node->children.n_idle); if (node->children.concurrency) storeAppendPrintf(sentry, " concurrency=%d", node->children.concurrency); if (node->cache) storeAppendPrintf(sentry, " cache=%d", node->cache_size); if (node->quote == external_acl::QUOTE_METHOD_SHELL) storeAppendPrintf(sentry, " protocol=2.5"); for (format = node->format; format; format = format->next) { switch (format->type) { - case _external_acl_format::EXT_ACL_HEADER_REQUEST: - case _external_acl_format::EXT_ACL_HEADER_REQUEST_ID: - storeAppendPrintf(sentry, " %%>{%s}", format->header); + case Format::LFT_ADAPTED_REQUEST_HEADER: + storeAppendPrintf(sentry, " %%>ha{%s}", format->header); break; - case _external_acl_format::EXT_ACL_HEADER_REQUEST_MEMBER: - case _external_acl_format::EXT_ACL_HEADER_REQUEST_ID_MEMBER: - storeAppendPrintf(sentry, " %%>{%s:%s}", format->header, format->member); + case Format::LFT_ADAPTED_REQUEST_HEADER_ELEM: + storeAppendPrintf(sentry, " %%>ha{%s:%s}", format->header, format->member); break; - case _external_acl_format::EXT_ACL_HEADER_REPLY: - case _external_acl_format::EXT_ACL_HEADER_REPLY_ID: - storeAppendPrintf(sentry, " %%<{%s}", format->header); + case Format::LFT_REPLY_HEADER: + storeAppendPrintf(sentry, " %%header); break; - case _external_acl_format::EXT_ACL_HEADER_REPLY_MEMBER: - case _external_acl_format::EXT_ACL_HEADER_REPLY_ID_MEMBER: - storeAppendPrintf(sentry, " %%<{%s:%s}", format->header, format->member); + case Format::LFT_REPLY_HEADER_ELEM: + storeAppendPrintf(sentry, " %%header, format->member); break; -#define DUMP_EXT_ACL_TYPE(a) \ - case _external_acl_format::EXT_ACL_##a: \ - storeAppendPrintf(sentry, " %%%s", #a); \ - break + #define DUMP_EXT_ACL_TYPE_FMT(a, fmt, ...) \ - case _external_acl_format::EXT_ACL_##a: \ + case Format::LFT_##a: \ storeAppendPrintf(sentry, fmt, ##__VA_ARGS__); \ break #if USE_AUTH - DUMP_EXT_ACL_TYPE(LOGIN); + DUMP_EXT_ACL_TYPE_FMT(USER_LOGIN," %%ul"); #endif #if USE_IDENT - DUMP_EXT_ACL_TYPE(IDENT); + DUMP_EXT_ACL_TYPE_FMT(USER_IDENT," %%ui"); #endif - - DUMP_EXT_ACL_TYPE(SRC); - DUMP_EXT_ACL_TYPE(SRCPORT); + DUMP_EXT_ACL_TYPE_FMT(CLIENT_IP_ADDRESS," %%>a"); + DUMP_EXT_ACL_TYPE_FMT(CLIENT_PORT," %%>p"); #if USE_SQUID_EUI - DUMP_EXT_ACL_TYPE(SRCEUI48); - DUMP_EXT_ACL_TYPE(SRCEUI64); + DUMP_EXT_ACL_TYPE_FMT(EXT_ACL_CLIENT_EUI48," %%SRCEUI48"); + DUMP_EXT_ACL_TYPE_FMT(EXT_ACL_CLIENT_EUI64," %%SRCEUI64"); #endif - - DUMP_EXT_ACL_TYPE(MYADDR); - DUMP_EXT_ACL_TYPE(MYPORT); - DUMP_EXT_ACL_TYPE(URI); - DUMP_EXT_ACL_TYPE(DST); - DUMP_EXT_ACL_TYPE(PROTO); - DUMP_EXT_ACL_TYPE(PORT); - DUMP_EXT_ACL_TYPE(PATH); - DUMP_EXT_ACL_TYPE(METHOD); + DUMP_EXT_ACL_TYPE_FMT(LOCAL_LISTENING_IP," %%>la"); + DUMP_EXT_ACL_TYPE_FMT(LOCAL_LISTENING_PORT," %%>lp"); + DUMP_EXT_ACL_TYPE_FMT(CLIENT_REQ_URI," %%>ru"); + DUMP_EXT_ACL_TYPE_FMT(CLIENT_REQ_URLDOMAIN," %%>rd"); + DUMP_EXT_ACL_TYPE_FMT(CLIENT_REQ_URLSCHEME," %%>rs"); + DUMP_EXT_ACL_TYPE_FMT(CLIENT_REQ_URLPORT," %%>rP"); + DUMP_EXT_ACL_TYPE_FMT(CLIENT_REQ_URLPATH," %%>rp"); + DUMP_EXT_ACL_TYPE_FMT(CLIENT_REQ_METHOD," %%>rm"); #if USE_OPENSSL - DUMP_EXT_ACL_TYPE_FMT(USER_CERT_RAW, " %%USER_CERT_RAW"); - DUMP_EXT_ACL_TYPE_FMT(USER_CERTCHAIN_RAW, " %%USER_CERTCHAIN_RAW"); - DUMP_EXT_ACL_TYPE_FMT(USER_CERT, " %%USER_CERT_%s", format->header); - DUMP_EXT_ACL_TYPE_FMT(USER_CA_CERT, " %%USER_CA_CERT_%s", format->header); + DUMP_EXT_ACL_TYPE_FMT(EXT_ACL_USER_CERT_RAW, " %%USER_CERT_RAW"); + DUMP_EXT_ACL_TYPE_FMT(EXT_ACL_USER_CERTCHAIN_RAW, " %%USER_CERTCHAIN_RAW"); + DUMP_EXT_ACL_TYPE_FMT(EXT_ACL_USER_CERT, " %%USER_CERT_%s", format->header); + DUMP_EXT_ACL_TYPE_FMT(EXT_ACL_USER_CA_CERT, " %%USER_CA_CERT_%s", format->header); #endif #if USE_AUTH - DUMP_EXT_ACL_TYPE(EXT_USER); + DUMP_EXT_ACL_TYPE_FMT(USER_EXTERNAL," %%ue"); #endif - DUMP_EXT_ACL_TYPE(EXT_LOG); - DUMP_EXT_ACL_TYPE(TAG); + DUMP_EXT_ACL_TYPE_FMT(EXT_LOG," %%ea"); + DUMP_EXT_ACL_TYPE_FMT(TAG," %%et"); + DUMP_EXT_ACL_TYPE_FMT(EXT_ACL_NAME," %%ACL"); + DUMP_EXT_ACL_TYPE_FMT(EXT_ACL_DATA," %%DATA"); DUMP_EXT_ACL_TYPE_FMT(PERCENT, " %%%%"); default: fatal("unknown external_acl format error"); break; } } for (word = node->cmdline; word; word = word->next) storeAppendPrintf(sentry, " %s", word->key); storeAppendPrintf(sentry, "\n"); } } void free_externalAclHelper(external_acl ** list) { while (*list) { external_acl *node = *list; *list = node->next; @@ -963,258 +896,248 @@ static char * makeExternalAclKey(ACLFilledChecklist * ch, external_acl_data * acl_data) { static MemBuf mb; char buf[256]; int first = 1; wordlist *arg; external_acl_format *format; HttpRequest *request = ch->request; HttpReply *reply = ch->reply; mb.reset(); bool data_used = false; for (format = acl_data->def->format; format; format = format->next) { const char *str = NULL; String sb; switch (format->type) { #if USE_AUTH - case _external_acl_format::EXT_ACL_LOGIN: + case Format::LFT_USER_LOGIN: // if this ACL line was the cause of credentials fetch // they may not already be in the checklist if (ch->auth_user_request == NULL && ch->request) ch->auth_user_request = ch->request->auth_user_request; if (ch->auth_user_request != NULL) str = ch->auth_user_request->username(); break; #endif #if USE_IDENT - case _external_acl_format::EXT_ACL_IDENT: + case Format::LFT_USER_IDENT: str = ch->rfc931; if (!str || !*str) { // if we fail to go async, we still return NULL and the caller // will detect the failure in ACLExternal::match(). (void)ch->goAsync(IdentLookup::Instance()); return NULL; } break; #endif - case _external_acl_format::EXT_ACL_SRC: + case Format::LFT_CLIENT_IP_ADDRESS: str = ch->src_addr.toStr(buf,sizeof(buf)); break; - case _external_acl_format::EXT_ACL_SRCPORT: + case Format::LFT_CLIENT_PORT: snprintf(buf, sizeof(buf), "%d", request->client_addr.port()); str = buf; break; #if USE_SQUID_EUI - case _external_acl_format::EXT_ACL_SRCEUI48: + case Format::LFT_EXT_ACL_CLIENT_EUI48: if (request->clientConnectionManager.valid() && request->clientConnectionManager->clientConnection != NULL && request->clientConnectionManager->clientConnection->remoteEui48.encode(buf, sizeof(buf))) str = buf; break; - case _external_acl_format::EXT_ACL_SRCEUI64: + case Format::LFT_EXT_ACL_CLIENT_EUI64: if (request->clientConnectionManager.valid() && request->clientConnectionManager->clientConnection != NULL && request->clientConnectionManager->clientConnection->remoteEui64.encode(buf, sizeof(buf))) str = buf; break; #endif - case _external_acl_format::EXT_ACL_MYADDR: + case Format::LFT_LOCAL_LISTENING_IP: str = request->my_addr.toStr(buf, sizeof(buf)); break; - case _external_acl_format::EXT_ACL_MYPORT: + case Format::LFT_LOCAL_LISTENING_PORT: snprintf(buf, sizeof(buf), "%d", request->my_addr.port()); str = buf; break; - case _external_acl_format::EXT_ACL_URI: + case Format::LFT_CLIENT_REQ_URI: str = urlCanonical(request); break; - case _external_acl_format::EXT_ACL_DST: + case Format::LFT_CLIENT_REQ_URLDOMAIN: str = request->GetHost(); break; - case _external_acl_format::EXT_ACL_PROTO: + case Format::LFT_CLIENT_REQ_URLSCHEME: str = request->url.getScheme().c_str(); break; - case _external_acl_format::EXT_ACL_PORT: + case Format::LFT_CLIENT_REQ_URLPORT: snprintf(buf, sizeof(buf), "%d", request->port); str = buf; break; - case _external_acl_format::EXT_ACL_PATH: + case Format::LFT_CLIENT_REQ_URLPATH: str = request->urlpath.termedBuf(); break; - case _external_acl_format::EXT_ACL_METHOD: + case Format::LFT_CLIENT_REQ_METHOD: { const SBuf &s = request->method.image(); sb.append(s.rawContent(), s.length()); } str = sb.termedBuf(); break; - case _external_acl_format::EXT_ACL_HEADER_REQUEST: - sb = request->header.getByName(format->header); - str = sb.termedBuf(); - break; - - case _external_acl_format::EXT_ACL_HEADER_REQUEST_ID: - sb = request->header.getStrOrList(format->header_id); - str = sb.termedBuf(); - break; - - case _external_acl_format::EXT_ACL_HEADER_REQUEST_MEMBER: - sb = request->header.getByNameListMember(format->header, format->member, format->separator); + case Format::LFT_ADAPTED_REQUEST_HEADER: + if (format->header_id == -1) + sb = request->header.getByName(format->header); + else + sb = request->header.getStrOrList(format->header_id); str = sb.termedBuf(); break; - case _external_acl_format::EXT_ACL_HEADER_REQUEST_ID_MEMBER: - sb = request->header.getListMember(format->header_id, format->member, format->separator); + case Format::LFT_ADAPTED_REQUEST_HEADER_ELEM: + if (format->header_id == -1) + sb = request->header.getByNameListMember(format->header, format->member, format->separator); + else + sb = request->header.getListMember(format->header_id, format->member, format->separator); str = sb.termedBuf(); break; - case _external_acl_format::EXT_ACL_HEADER_REPLY: + case Format::LFT_REPLY_HEADER: if (reply) { - sb = reply->header.getByName(format->header); + if (format->header_id == -1) + sb = reply->header.getByName(format->header); + else + sb = reply->header.getStrOrList(format->header_id); str = sb.termedBuf(); } break; - case _external_acl_format::EXT_ACL_HEADER_REPLY_ID: + case Format::LFT_REPLY_HEADER_ELEM: if (reply) { - sb = reply->header.getStrOrList(format->header_id); + if (format->header_id == -1) + sb = reply->header.getByNameListMember(format->header, format->member, format->separator); + else + sb = reply->header.getListMember(format->header_id, format->member, format->separator); str = sb.termedBuf(); } break; - case _external_acl_format::EXT_ACL_HEADER_REPLY_MEMBER: - if (reply) { - sb = reply->header.getByNameListMember(format->header, format->member, format->separator); - str = sb.termedBuf(); - } - break; - - case _external_acl_format::EXT_ACL_HEADER_REPLY_ID_MEMBER: - if (reply) { - sb = reply->header.getListMember(format->header_id, format->member, format->separator); - str = sb.termedBuf(); - } - break; #if USE_OPENSSL - case _external_acl_format::EXT_ACL_USER_CERT_RAW: + case Format::LFT_EXT_ACL_USER_CERT_RAW: if (ch->conn() != NULL && Comm::IsConnOpen(ch->conn()->clientConnection)) { SSL *ssl = fd_table[ch->conn()->clientConnection->fd].ssl; if (ssl) str = sslGetUserCertificatePEM(ssl); } break; - case _external_acl_format::EXT_ACL_USER_CERTCHAIN_RAW: + case Format::LFT_EXT_ACL_USER_CERTCHAIN_RAW: if (ch->conn() != NULL && Comm::IsConnOpen(ch->conn()->clientConnection)) { SSL *ssl = fd_table[ch->conn()->clientConnection->fd].ssl; if (ssl) str = sslGetUserCertificateChainPEM(ssl); } break; - case _external_acl_format::EXT_ACL_USER_CERT: + case Format::LFT_EXT_ACL_USER_CERT: if (ch->conn() != NULL && Comm::IsConnOpen(ch->conn()->clientConnection)) { SSL *ssl = fd_table[ch->conn()->clientConnection->fd].ssl; if (ssl) str = sslGetUserAttribute(ssl, format->header); } break; - case _external_acl_format::EXT_ACL_USER_CA_CERT: + case Format::LFT_EXT_ACL_USER_CA_CERT: if (ch->conn() != NULL && Comm::IsConnOpen(ch->conn()->clientConnection)) { SSL *ssl = fd_table[ch->conn()->clientConnection->fd].ssl; if (ssl) str = sslGetCAAttribute(ssl, format->header); } break; #endif #if USE_AUTH - case _external_acl_format::EXT_ACL_EXT_USER: + case Format::LFT_USER_EXTERNAL: str = request->extacl_user.termedBuf(); break; #endif - case _external_acl_format::EXT_ACL_EXT_LOG: + case Format::LFT_EXT_LOG: str = request->extacl_log.termedBuf(); break; - case _external_acl_format::EXT_ACL_TAG: + case Format::LFT_TAG: str = request->tag.termedBuf(); break; - case _external_acl_format::EXT_ACL_ACLNAME: + case Format::LFT_EXT_ACL_NAME: str = acl_data->name; break; - case _external_acl_format::EXT_ACL_ACLDATA: + case Format::LFT_EXT_ACL_DATA: data_used = true; for (arg = acl_data->arguments; arg; arg = arg->next) { if (!first) sb.append(" ", 1); if (acl_data->def->quote == external_acl::QUOTE_METHOD_URL) { const char *quoted = rfc1738_escape(arg->key); sb.append(quoted, strlen(quoted)); } else { static MemBuf mb2; mb2.init(); strwordquote(&mb2, arg->key); sb.append(mb2.buf, mb2.size); mb2.clean(); } first = 0; } break; - case _external_acl_format::EXT_ACL_PERCENT: + case Format::LFT_PERCENT: str = "%"; break; - case _external_acl_format::EXT_ACL_UNKNOWN: - case _external_acl_format::EXT_ACL_END: + default: + // TODO: replace this function with Format::assemble() + // For now die on unsupported logformat codes. fatal("unknown external_acl format error"); break; } if (str) if (!*str) str = NULL; if (!str) str = "-"; if (!first) mb.append(" ", 1); if (acl_data->def->quote == external_acl::QUOTE_METHOD_URL) { const char *quoted = rfc1738_escape(str); mb.append(quoted, strlen(quoted)); } else { strwordquote(&mb, str); } === modified file 'src/format/ByteCode.h' --- src/format/ByteCode.h 2014-03-30 12:00:34 +0000 +++ src/format/ByteCode.h 2014-05-06 11:09:06 +0000 @@ -41,66 +41,71 @@ /* client connection local squid.conf details */ LFT_LOCAL_LISTENING_IP, LFT_LOCAL_LISTENING_PORT, /*LFT_LOCAL_LISTENING_NAME, (myportname) */ /* server TCP connection remote end details */ LFT_SERVER_IP_ADDRESS, LFT_SERVER_FQDN_OR_PEER_NAME, LFT_SERVER_PORT, /* server TCP connection local end details */ LFT_SERVER_LOCAL_IP, LFT_SERVER_LOCAL_IP_OLD_27, LFT_SERVER_LOCAL_PORT, LFT_SERVER_LOCAL_TOS, LFT_SERVER_LOCAL_NFMARK, /* original Request-Line details recieved from client */ LFT_CLIENT_REQ_METHOD, LFT_CLIENT_REQ_URI, + LFT_CLIENT_REQ_URLSCHEME, LFT_CLIENT_REQ_URLDOMAIN, + LFT_CLIENT_REQ_URLPORT, LFT_CLIENT_REQ_URLPATH, /* LFT_CLIENT_REQ_QUERY, */ LFT_CLIENT_REQ_VERSION, /* Request-Line details recieved from client (legacy, filtered) */ LFT_REQUEST_METHOD, LFT_REQUEST_URI, LFT_REQUEST_URLPATH_OLD_31, /*LFT_REQUEST_QUERY, */ LFT_REQUEST_VERSION_OLD_2X, LFT_REQUEST_VERSION, /* request header details pre-adaptation */ LFT_REQUEST_HEADER, LFT_REQUEST_HEADER_ELEM, LFT_REQUEST_ALL_HEADERS, /* request header details post-adaptation */ LFT_ADAPTED_REQUEST_HEADER, LFT_ADAPTED_REQUEST_HEADER_ELEM, LFT_ADAPTED_REQUEST_ALL_HEADERS, /* Request-Line details sent to the server/peer */ LFT_SERVER_REQ_METHOD, LFT_SERVER_REQ_URI, + LFT_SERVER_REQ_URLSCHEME, + LFT_SERVER_REQ_URLDOMAIN, + LFT_SERVER_REQ_URLPORT, LFT_SERVER_REQ_URLPATH, /*LFT_SERVER_REQ_QUERY, */ LFT_SERVER_REQ_VERSION, /* request meta details */ LFT_CLIENT_REQUEST_SIZE_TOTAL, LFT_CLIENT_REQUEST_SIZE_HEADERS, /*LFT_REQUEST_SIZE_BODY, */ /*LFT_REQUEST_SIZE_BODY_NO_TE, */ /* original Status-Line details recieved from server */ // XXX: todo /* Status-Line details sent to the client */ // XXX: todo /* response Status-Line details (legacy, filtered) */ LFT_HTTP_SENT_STATUS_CODE_OLD_30, LFT_HTTP_SENT_STATUS_CODE, LFT_HTTP_RECEIVED_STATUS_CODE, @@ -186,35 +191,46 @@ LFT_ICAP_REQ_ALL_HEADERS, LFT_ICAP_REP_HEADER, LFT_ICAP_REP_HEADER_ELEM, LFT_ICAP_REP_ALL_HEADERS, LFT_ICAP_TR_RESPONSE_TIME, LFT_ICAP_IO_TIME, LFT_ICAP_OUTCOME, LFT_ICAP_STATUS_CODE, #endif LFT_CREDENTIALS, #if USE_OPENSSL LFT_SSL_BUMP_MODE, LFT_SSL_USER_CERT_SUBJECT, LFT_SSL_USER_CERT_ISSUER, #endif LFT_NOTE, - LFT_PERCENT /* special string cases for escaped chars */ + LFT_PERCENT, /* special string cases for escaped chars */ + + // TODO assign permanent bytecode and tokens for these + LFT_EXT_ACL_USER_CERT_RAW, + LFT_EXT_ACL_USER_CERTCHAIN_RAW, + LFT_EXT_ACL_USER_CERT, + LFT_EXT_ACL_USER_CA_CERT, + LFT_EXT_ACL_CLIENT_EUI48, + LFT_EXT_ACL_CLIENT_EUI64, + LFT_EXT_ACL_NAME, + LFT_EXT_ACL_DATA + } ByteCode_t; /// Quoting style for a format output. enum Quoting { LOG_QUOTE_NONE = 0, LOG_QUOTE_QUOTES, LOG_QUOTE_MIMEBLOB, LOG_QUOTE_URL, LOG_QUOTE_RAW }; } // namespace Format #endif /* _SQUID_FMT_BYTECODE_H */ === modified file 'src/format/Format.cc' --- src/format/Format.cc 2014-04-30 09:41:25 +0000 +++ src/format/Format.cc 2014-05-06 11:09:18 +0000 @@ -914,47 +914,61 @@ break; case LFT_CLIENT_REQ_METHOD: if (al->request) { const SBuf &s = al->request->method.image(); sb.append(s.rawContent(), s.length()); out = sb.termedBuf(); quote = 1; } break; case LFT_CLIENT_REQ_URI: // original client URI if (al->request) { out = urlCanonical(al->request); quote = 1; } break; + case LFT_CLIENT_REQ_URLSCHEME: + if (al->request) { + out = al->request->url.getScheme().c_str(); + quote = 1; + } + break; + case LFT_CLIENT_REQ_URLDOMAIN: if (al->request) { out = al->request->GetHost(); quote = 1; } break; + case LFT_CLIENT_REQ_URLPORT: + if (al->request) { + outint = al->request->port; + doint = 1; + } + break; + case LFT_REQUEST_URLPATH_OLD_31: case LFT_CLIENT_REQ_URLPATH: if (al->request) { out = al->request->urlpath.termedBuf(); quote = 1; } break; case LFT_CLIENT_REQ_VERSION: if (al->request) { snprintf(tmp, sizeof(tmp), "%d.%d", (int) al->request->http_ver.major, (int) al->request->http_ver.minor); out = tmp; } break; case LFT_REQUEST_METHOD: if (al->_private.method_str) // ICP, HTCP method code out = al->_private.method_str; else { const SBuf &s = al->http.method.image(); @@ -974,40 +988,61 @@ out = tmp; break; case LFT_SERVER_REQ_METHOD: if (al->adapted_request) { const SBuf &s = al->adapted_request->method.image(); sb.append(s.rawContent(), s.length()); out = sb.termedBuf(); quote = 1; } break; case LFT_SERVER_REQ_URI: // adapted request URI sent to server/peer if (al->adapted_request) { out = urlCanonical(al->adapted_request); quote = 1; } break; + case LFT_SERVER_REQ_URLSCHEME: + if (al->adapted_request) { + out = al->adapted_request->url.getScheme().c_str(); + quote = 1; + } + break; + + case LFT_SERVER_REQ_URLDOMAIN: + if (al->adapted_request) { + out = al->adapted_request->GetHost(); + quote = 1; + } + break; + + case LFT_SERVER_REQ_URLPORT: + if (al->adapted_request) { + outint = al->adapted_request->port; + doint = 1; + } + break; + case LFT_SERVER_REQ_URLPATH: if (al->adapted_request) { out = al->adapted_request->urlpath.termedBuf(); quote = 1; } break; case LFT_SERVER_REQ_VERSION: if (al->adapted_request) { snprintf(tmp, sizeof(tmp), "%d.%d", (int) al->adapted_request->http_ver.major, (int) al->adapted_request->http_ver.minor); out = tmp; } break; case LFT_CLIENT_REQUEST_SIZE_TOTAL: outoff = al->http.clientRequestSz.messageTotal(); dooff = 1; break; @@ -1133,40 +1168,51 @@ if (al->notes != NULL && !al->notes->empty()) sb.append(al->notes->toString(separator)); out = sb.termedBuf(); quote = 1; } break; case LFT_CREDENTIALS: #if USE_AUTH if (al->request && al->request->auth_user_request != NULL) out = strOrNull(al->request->auth_user_request->credentialsStr()); #endif break; case LFT_PERCENT: out = "%"; break; + + // XXX: external_acl_type format codes are not yet output by this code + case LFT_EXT_ACL_USER_CERT_RAW: + case LFT_EXT_ACL_USER_CERTCHAIN_RAW: + case LFT_EXT_ACL_USER_CERT: + case LFT_EXT_ACL_USER_CA_CERT: + case LFT_EXT_ACL_CLIENT_EUI48: + case LFT_EXT_ACL_CLIENT_EUI64: + case LFT_EXT_ACL_NAME: + case LFT_EXT_ACL_DATA: + break; } if (dooff) { snprintf(tmp, sizeof(tmp), "%0*" PRId64, fmt->zero && fmt->widthMin >= 0 ? fmt->widthMin : 0, outoff); out = tmp; } else if (doint) { snprintf(tmp, sizeof(tmp), "%0*ld", fmt->zero && fmt->widthMin >= 0 ? fmt->widthMin : 0, outint); out = tmp; } if (out && *out) { if (quote || fmt->quote != LOG_QUOTE_NONE) { char *newout = NULL; int newfree = 0; switch (fmt->quote) { case LOG_QUOTE_NONE: newout = rfc1738_escape_unescaped(out); === modified file 'src/format/Token.cc' --- src/format/Token.cc 2014-04-30 09:41:25 +0000 +++ src/format/Token.cc 2014-05-04 16:47:23 +0000 @@ -64,53 +64,58 @@ {"un", LFT_USER_NAME}, {"ul", LFT_USER_LOGIN}, /*{ "ur", LFT_USER_REALM }, */ /*{ "us", LFT_USER_SCHEME }, */ {"ui", LFT_USER_IDENT}, {"ue", LFT_USER_EXTERNAL}, {"Hs", LFT_HTTP_SENT_STATUS_CODE_OLD_30}, {">Hs", LFT_HTTP_SENT_STATUS_CODE}, {"rm", LFT_CLIENT_REQ_METHOD}, {">ru", LFT_CLIENT_REQ_URI}, + {">rs", LFT_CLIENT_REQ_URLSCHEME}, {">rd", LFT_CLIENT_REQ_URLDOMAIN}, + {">rP", LFT_CLIENT_REQ_URLPORT}, {">rp", LFT_CLIENT_REQ_URLPATH}, /*{">rq", LFT_CLIENT_REQ_QUERY},*/ {">rv", LFT_CLIENT_REQ_VERSION}, {"rm", LFT_REQUEST_METHOD}, {"ru", LFT_REQUEST_URI}, /* doesn't include the query-string */ {"rp", LFT_REQUEST_URLPATH_OLD_31}, /* { "rq", LFT_REQUEST_QUERY }, * / / * the query-string, INCLUDING the leading ? */ {"rv", LFT_REQUEST_VERSION}, {"st", LFT_CLIENT_REQUEST_SIZE_TOTAL }, {">sh", LFT_CLIENT_REQUEST_SIZE_HEADERS }, /*{ ">sb", LFT_REQUEST_SIZE_BODY }, */ /*{ ">sB", LFT_REQUEST_SIZE_BODY_NO_TE }, */ {"