diff -urN squid-1.1.17/src/Makefile.in squid/src/Makefile.in --- squid-1.1.17/src/Makefile.in Sat Aug 9 00:00:00 1997 +++ squid/src/Makefile.in Tue Jun 2 15:42:52 1998 @@ -17,11 +17,14 @@ USE_SPLAY_TREE = # -DUSE_SPLAY_TREE USE_BIN_TREE = # -DUSE_BIN_TREE RELOAD_INTO_IMS = # -DRELOAD_INTO_IMS +# SmartFilter Define +LOCAL_OPTS = -DSMARTFILTER DEFINES = $(HOST_OPT) $(AUTH_OPT) $(LOG_HDRS_OPT) \ $(ICMP_OPT) $(DELAY_HACK) $(USERAGENT_OPT) \ $(KILL_PARENT_OPT) $(USE_POLL_OPT) \ $(USE_SPLAY_TREE) $(USE_BIN_TREE) \ + $(LOCAL_OPTS) \ $(RELOAD_INTO_IMS) prefix = @prefix@ @@ -67,7 +70,7 @@ INCLUDE = -I. -I../include -I$(srcdir)/../include CFLAGS = $(AC_CFLAGS) $(INCLUDE) $(DEFINES) -SQUID_LIBS = -L../lib $(CRYPTLIB) $(REGEXLIB) -lmiscutil $(XTRA_LIBS) +SQUID_LIBS = -L../lib $(CRYPTLIB) $(REGEXLIB) -lmiscutil -lwebtrack $(XTRA_LIBS) CLIENT_LIBS = -L../lib -lmiscutil $(XTRA_LIBS) DNSSERVER_LIBS = -L../lib -lmiscutil $(XTRA_LIBS) FTPGET_LIBS = -L../lib -lmiscutil $(XTRA_LIBS) @@ -122,6 +125,7 @@ url.o \ useragent.o \ wais.o \ + smartfilter_squid.o \ $(XTRA_OBJS) DEFAULTS = \ @@ -253,6 +257,9 @@ echo "$(INSTALL_FILE) squid.conf $(sysconfdir)"; \ $(INSTALL_FILE) squid.conf $(sysconfdir); \ fi + $(INSTALL_FILE) smartfilter.conf $(sysconfdir) + $(INSTALL_FILE) smartfilter.site $(sysconfdir) + $(INSTALL_FILE) custom_error.html $(sysconfdir) install-pinger: @f=pinger; \ diff -urN squid-1.1.17/src/a squid/src/a --- squid-1.1.17/src/a Thu Jan 1 08:00:00 1970 +++ squid/src/a Wed Jun 3 14:02:01 1998 @@ -0,0 +1,27 @@ +WT_CAT_SEX,sx +WT_CAT_DRUGS,dr +WT_CAT_HATESPEECH,hs +WT_CAT_CRIME,cs +WT_CAT_WORTHLESS,os +WT_CAT_SALES,gb +WT_CAT_GAMBLING,pp +WT_CAT_PERSONAL,js +WT_CAT_JOBS,sp +WT_CAT_SPORTS,gm +WT_CAT_GAMES,hm +WT_CAT_HUMOR,aj +WT_CAT_ALTJRNL,et +WT_CAT_ENTERTAIN,ls +WT_CAT_LIFESTYLE,ex +WT_CAT_EXTREME,wt +WT_CAT_CHAT,ch +WT_CAT_INVESTMENTS,in +WT_CAT_GNEWS,nw +WT_CAT_OPINION,po +WT_CAT_DATING,mm +WT_CAT_ART,ac +WT_CAT_CULT,na +WT_CAT_NEWSSITE,oc +WT_CAT_SELFHELP,sh +WT_CAT_TRAVEL,tr +WT_CAT_NONESSENTIAL,ne diff -urN squid-1.1.17/src/cache_cf.c squid/src/cache_cf.c --- squid-1.1.17/src/cache_cf.c Fri Aug 22 03:17:00 1997 +++ squid/src/cache_cf.c Tue Jun 2 17:28:53 1998 @@ -208,6 +208,10 @@ #define DefaultOptionsEnablePurge 0 /* default off */ #define DefaultOptionsClientDb 1 /* default on */ #define DefaultOptionsQueryIcmp 0 /* default off */ +#ifdef SMARTFILTER +#define DefaultSmartFilterState 0 /* default off */ +#define DefaultSmartFilterConf "/etc/smartfilter.conf" +#endif int httpd_accel_mode = 0; /* for fast access */ @@ -864,6 +868,7 @@ GetInteger(i); if (i < 0) i = 0; + Config.Port.http = (u_short) i; } @@ -878,6 +883,32 @@ Config.Port.icp = (u_short) i; } +#ifdef SMARTFILTER +static void +parseSmartFilterStateLine(int *iptr) /* state is either off or on */ +{ + char *token; + token = strtok(NULL, w_space); + if (token == NULL) + self_destruct(); + if (!strcasecmp(token, "on")) + *iptr = 1; + else + *iptr = 0; +} + +static void +parseSmartFilterConfLine(void) +{ + char *token; + token = strtok(NULL, w_space); + if (token == NULL) + self_destruct(); + safe_free(Config.SmartFilterConf); + Config.SmartFilterConf = xstrdup(token); +} +#endif + static void parseVisibleHostnameLine(void) { @@ -1298,6 +1329,13 @@ else if (!strcmp(token, "outbound_address")) parseAddressLine(&Config.Addrs.tcp_outgoing); +#ifdef SMARTFILTER + else if (!strcmp(token, "smartfilter_state")) + parseSmartFilterStateLine(&Config.SmartFilterState); + + else if (!strcmp(token, "smartfilter_config")) + parseSmartFilterConfLine(); +#endif else if (!strcmp(token, "http_port") || !strcmp(token, "ascii_port")) parseHttpPortLine(); @@ -1616,6 +1654,10 @@ #ifdef RELOAD_INTO_IMS Config.Options.reload_into_ims = 0; #endif /* RELOAD_INTO_IMS */ +#ifdef SMARTFILTER + Config.SmartFilterState = DefaultSmartFilterState; + Config.SmartFilterConf = safe_xstrdup(DefaultSmartFilterConf); +#endif } static void diff -urN squid-1.1.17/src/cache_cf.h squid/src/cache_cf.h --- squid-1.1.17/src/cache_cf.h Fri Aug 8 00:00:00 1997 +++ squid/src/cache_cf.h Tue Jun 2 15:42:52 1998 @@ -161,6 +161,10 @@ int lifetimeShutdown; int connectTimeout; int cleanRate; +#ifdef SMARTFILTER + int SmartFilterState; + char *SmartFilterConf; +#endif int maxRequestSize; struct { u_short http; diff -urN squid-1.1.17/src/client_db.c squid/src/client_db.c --- squid-1.1.17/src/client_db.c Wed Mar 26 00:00:00 1997 +++ squid/src/client_db.c Fri Jun 5 09:58:19 1998 @@ -31,14 +31,20 @@ #include "squid.h" +struct _client_stats { + int result_hist[ERR_MAX]; + int n_requests; + unsigned long v_requests; + unsigned long v_hist[ERR_MAX]; +}; + typedef struct _client_info { char *key; struct client_info *next; struct in_addr addr; - struct { - int result_hist[ERR_MAX]; - int n_requests; - } Http, Icp; + struct _client_stats Http, Icp, HttpTotal, IcpTotal; + WT_TYPES WTcats; + char *login_name; } ClientInfo; int client_info_sz; @@ -54,6 +60,9 @@ c = xcalloc(1, sizeof(ClientInfo)); c->key = xstrdup(inet_ntoa(addr)); c->addr = addr; + c->WTcats = WT_NULLPARM; + c->login_name = NULL; + hash_join(client_table, (hash_link *) c); meta_data.client_info++; return c; @@ -92,6 +101,83 @@ } } +void +clientdbUpdateVol(struct in_addr addr, log_type log_type, u_short port, long bytes) +{ + char *key; + ClientInfo *c; + + if (!Config.Options.client_db) + return; + key=inet_ntoa(addr); + c=(ClientInfo *) hash_lookup(client_table,key); + if (c==NULL) c=clientdbAdd(addr); + if (c==NULL) debug_trap("clientdbUpdateVol: Failed to add entry"); + if (port==Config.Port.http) + { c->Http.v_requests+=bytes; + c->Http.v_hist[log_type]+=bytes; + } + else if (port==Config.Port.icp) + { c->Icp.v_requests+=bytes; + c->Icp.v_hist[log_type]+=bytes; + } +} + +WT_TYPES +clientdbGetCats(struct in_addr addr) +{ + char *key; + ClientInfo *c; + + if (!Config.Options.client_db) + return WT_NULLPARM; + key=inet_ntoa(addr); + c=(ClientInfo *) hash_lookup(client_table,key); + if (c==NULL) c=clientdbAdd(addr); + if (c==NULL) debug_trap("clientdbUpdateVol: Failed to add entry"); + return c->WTcats; +} + +void +clientdbSetCatsC(ClientInfo *c, char *catlist) +{ + if (!c) return; + if (c->WTcats != WT_NULLPARM) WT_FreeTypes(c->WTcats); + if (catlist && strlen(catlist)) { + c->WTcats = WT_AllocateTypes(); + if (c->WTcats != WT_NULLPARM) wtsetcats(c->WTcats, catlist); + } + else c->WTcats = WT_NULLPARM; + return; +} + +void +clientdbSetLogin(ClientInfo *c, char *login) +{ + if (c->login_name) free(c->login_name); + if (login && strlen(login)) { + c->login_name = xstrdup(login); + } + else c->login_name = NULL; + return; +} + +void +clientdbSetCats(struct in_addr addr, char *catlist) +{ + char *key; + ClientInfo *c; + + if (!Config.Options.client_db) + return; + key=inet_ntoa(addr); + c=(ClientInfo *) hash_lookup(client_table,key); + if (c==NULL) c=clientdbAdd(addr); + if (c==NULL) debug_trap("clientdbUpdateVol: Failed to add entry"); + clientdbSetCatsC(c,catlist); + return; +} + int clientdbDeniedPercent(struct in_addr addr) { @@ -110,39 +196,176 @@ } void -clientdbDump(StoreEntry * sentry) +clientdbStatsDump(StoreEntry *sentry, + struct _client_stats *Now, + struct _client_stats *Last, + struct _client_stats *StatsNow, + struct _client_stats *StatsLast, + char *desc) +{ unsigned long reqtot, errtot, vtot, cvtot; + log_type l; + + reqtot = Now->n_requests + Last->n_requests; + cvtot = (Now->v_requests/1000) + Last->v_requests; + + if (sentry) { + storeAppendPrintf(sentry, "{ %s Requests %9d %9d }\n",desc, + reqtot, Now->n_requests); + storeAppendPrintf(sentry, "{ %s Volume %9lu KB %9lu }\n",desc, + cvtot, Now->v_requests); + } + if (StatsNow) { + StatsNow->n_requests+=Now->n_requests; + StatsNow->v_requests+=Now->v_requests; + } + if (StatsLast) { + StatsLast->n_requests+=Last->n_requests; + StatsLast->v_requests+=Last->v_requests; + } + + for (l = LOG_TAG_NONE; l < ERR_MAX; l++) { + if (Now->result_hist[l]==0 && Last->result_hist[l] == 0) continue; + errtot = Now->result_hist[l] + Last->result_hist[l]; + vtot = (Now->v_hist[l]/1000) + Last->v_hist[l]; + if (sentry) storeAppendPrintf(sentry, + "{ %-20.20s %8lu KB %3d%% %7d %3d%% %8lu %3d%% %7d %3d%%}\n", + log_tags[l], + vtot, + percent(vtot,cvtot), + errtot, + percent(errtot,reqtot), + Now->v_hist[l], + percent(Now->v_hist[l],Now->v_requests), + Now->result_hist[l], + percent(Now->result_hist[l], Now->n_requests)); + if (StatsNow) { + StatsNow->v_hist[l] += Now->v_hist[l]; + StatsNow->result_hist[l] += Now->result_hist[l]; + } + if (StatsLast) { + StatsLast->v_hist[l] += Last->v_hist[l]; + StatsLast->result_hist[l]+= Last->result_hist[l]; + } + } +} + + +void +addstats(struct _client_stats *tot, + struct _client_stats *cur) +{ log_type l; + if (!tot || !cur) { + return; + } + + for (l=LOG_TAG_NONE; l < ERR_MAX; l++) + { tot->v_hist[l] += cur->v_hist[l]/1000; + tot->result_hist[l] += cur->result_hist[l]; + } + tot->n_requests += cur->n_requests; + tot->v_requests += cur->v_requests/1000; + memset(cur,0,sizeof(struct _client_stats)); +} + + +void +clientdbDump(StoreEntry * sentry, char *extrainfo) { - ClientInfo *c; - log_type l; +#define MASK_ONE_IP 0xFFFFFFFF + + ClientInfo *c, stats; + int resetvol=0, count=0, match=0; + char *maskp=NULL, *commands=NULL, *cmdp=NULL, *cmdp2=NULL; + struct in_addr ip,mask; + char tempstr[100]; + + mask.s_addr=MASK_ONE_IP; + ip.s_addr =0; + + /* extra info + format: ip_address/mask?command + command may be: + WTCAT=catlist : catlist = list of ban categories for this ip + WTCAT= : disable ban categories on this ip + LOGIN=name : login name of user on this ip + */ + if (extrainfo) { + if (*extrainfo=='-') { extrainfo++; resetvol=1; } + commands=strchr(extrainfo,'?'); + if (commands) *commands++='\0'; + maskp=strchr(extrainfo,'/'); + if (maskp) { *maskp++='\0'; mask.s_addr=inet_addr(maskp); } + ip.s_addr=inet_addr(extrainfo); + if (ip.s_addr==-1) ip.s_addr = 0; + else { + /* Guarantee that an entry will exist - that way any settings will + be applied to at least that address :-) + */ + c=(ClientInfo *) hash_lookup(client_table,extrainfo); + if (c==NULL) c=clientdbAdd(ip); + if (c==NULL) debug_trap("clientdbUpdateVol: Failed to add entry"); + + ip.s_addr &= mask.s_addr; + } + } + memset(&stats,0,sizeof(stats)); + storeAppendPrintf(sentry, "{Cache Clients:\n"); c = (ClientInfo *) hash_first(client_table); while (c) { - storeAppendPrintf(sentry, "{Address: %s}\n", c->key); - storeAppendPrintf(sentry, "{Name: %s}\n", fqdnFromAddr(c->addr)); - storeAppendPrintf(sentry, "{ ICP Requests %d}\n", - c->Icp.n_requests); - for (l = LOG_TAG_NONE; l < ERR_MAX; l++) { - if (c->Icp.result_hist[l] == 0) - continue; - storeAppendPrintf(sentry, - "{ %-20.20s %7d %3d%%}\n", - log_tags[l], - c->Icp.result_hist[l], - percent(c->Icp.result_hist[l], c->Icp.n_requests)); - } - storeAppendPrintf(sentry, "{ HTTP Requests %d}\n", - c->Http.n_requests); - for (l = LOG_TAG_NONE; l < ERR_MAX; l++) { - if (c->Http.result_hist[l] == 0) - continue; - storeAppendPrintf(sentry, - "{ %-20.20s %7d %3d%%}\n", - log_tags[l], - c->Http.result_hist[l], - percent(c->Http.result_hist[l], c->Http.n_requests)); - } + match=0; + if (ip.s_addr && (ip.s_addr==(inet_addr(c->key) & mask.s_addr))) match=1; + else if (c->login_name && extrainfo && strcmp(c->login_name,extrainfo)==0) match=1; + else if (extrainfo && !*extrainfo) match=1; + else if (!extrainfo) match=1; + if (match) { + if (mask.s_addr==MASK_ONE_IP) { + storeAppendPrintf(sentry, "{Address: %s}\n", c->key); + storeAppendPrintf(sentry, "{Name: %s}\n", fqdnFromAddr(c->addr)); + storeAppendPrintf(sentry, "{Login: %s}\n", (c->login_name?c->login_name:"")); + storeAppendPrintf(sentry, "{Filters: %s}\n", wtgetcats(c->WTcats, tempstr)); + + clientdbStatsDump(sentry, &c->Icp, &c->IcpTotal, + &stats.Icp, &stats.IcpTotal, " ICP"); + clientdbStatsDump(sentry, &c->Http, &c->HttpTotal, + &stats.Http, &stats.HttpTotal, "HTTP"); + storeAppendPrintf(sentry, "{}\n"); + count++; + } + else { clientdbStatsDump(NULL, &c->Icp, &c->IcpTotal, &stats.Icp, &stats.IcpTotal, ""); + clientdbStatsDump(NULL, &c->Http,&c->HttpTotal,&stats.Http,&stats.HttpTotal,""); + } + + if (resetvol) { + addstats(&c->HttpTotal,&c->Http); + addstats(&c->IcpTotal, &c->Icp); + } + cmdp=commands; + while (cmdp) { /* handle multiple items cgi-style - xxx=yyy&aaa=b */ + cmdp2=strchr(cmdp,'&'); + if (cmdp2) *cmdp2++='\0'; + if (strncasecmp(cmdp,"WTCAT=",6)==0) clientdbSetCatsC(c,cmdp+6); + else if (strncasecmp(cmdp,"LOGIN=",6)==0) clientdbSetLogin(c,cmdp+6); + else { /* should log unknown arg... */ } + cmdp=cmdp2; + } + } + c = (ClientInfo *) hash_next(client_table); + } + if (count>1) { storeAppendPrintf(sentry, "{}\n"); - c = (ClientInfo *) hash_next(client_table); - } + clientdbStatsDump(sentry, &stats.Icp, &stats.IcpTotal, NULL, NULL, " ICP Total"); + clientdbStatsDump(sentry, &stats.Http, &stats.HttpTotal, NULL, NULL, "HTTP Total"); + } + else if (mask.s_addr!=MASK_ONE_IP) { + storeAppendPrintf(sentry, "{Address: %s}\n", extrainfo); + storeAppendPrintf(sentry, "{Name: %s}\n", extrainfo); + + clientdbStatsDump(sentry, &stats.Icp, &stats.IcpTotal, NULL, NULL, " ICP"); + clientdbStatsDump(sentry, &stats.Http, &stats.HttpTotal, NULL, NULL, "HTTP"); + storeAppendPrintf(sentry, "{}\n"); + } + storeAppendPrintf(sentry, close_bracket); } + diff -urN squid-1.1.17/src/client_db.h squid/src/client_db.h --- squid-1.1.17/src/client_db.h Sat Dec 14 00:00:00 1996 +++ squid/src/client_db.h Tue Jun 2 19:27:07 1998 @@ -32,9 +32,12 @@ #define CLIENT_DB_H void clientdbInit _PARAMS((void)); -void clientdbUpdate _PARAMS((struct in_addr, log_type, u_short port)); -int clientdbDeniedPercent _PARAMS((struct in_addr)); -void clientdbDump _PARAMS((StoreEntry *)); +void clientdbUpdate _PARAMS((struct in_addr, log_type, u_short)); +int clientdbDeniedPercent _PARAMS((struct in_addr)); +void clientdbDump _PARAMS((StoreEntry *,char *)); +void clientdbUpdateVol _PARAMS((struct in_addr, log_type, u_short, long)); +WT_TYPES clientdbGetCats _PARAMS((struct in_addr)); +void clientdbSetCats _PARAMS((struct in_addr, char *)); extern int client_info_sz; #endif /* CLIENT_DB_H */ diff -urN squid-1.1.17/src/client_side.c squid/src/client_side.c --- squid-1.1.17/src/client_side.c Tue Aug 26 00:34:00 1997 +++ squid/src/client_side.c Fri Apr 3 19:31:56 1998 @@ -152,7 +152,8 @@ } if (icpState->aclChecklist == NULL) { icpState->aclChecklist = xcalloc(1, sizeof(aclCheck_t)); - icpState->aclChecklist->src_addr = icpState->peer.sin_addr; + /* icpState->aclChecklist->src_addr = icpState->peer.sin_addr; */ + icpState->aclChecklist->src_addr = icpState->acct_addr; icpState->aclChecklist->request = requestLink(icpState->request); browser = mime_get_header(icpState->request_hdr, "User-Agent"); if (browser != NULL) { @@ -540,6 +541,10 @@ icpState->log_type = LOG_TCP_REFRESH_HIT; hbuf = get_free_8k_page(); storeClientCopy(oldentry, 0, 8191, hbuf, &len, fd); + clientdbUpdateVol(icpState->peer.sin_addr, + icpState->log_type, + ntohs(icpState->me.sin_port), + len); if (oldentry->mem_obj->request == NULL) { oldentry->mem_obj->request = requestLink(mem->request); unlink_request = 1; diff -urN squid-1.1.17/src/comm.c squid/src/comm.c --- squid-1.1.17/src/comm.c Fri Aug 22 03:33:00 1997 +++ squid/src/comm.c Wed Apr 8 21:41:21 1998 @@ -1413,7 +1413,7 @@ char * fd_note(int fd, const char *s) -{ +{ if (s == NULL) return (fd_table[fd].ascii_note); xstrncpy(fd_table[fd].ascii_note, s, FD_ASCII_NOTE_SZ); diff -urN squid-1.1.17/src/custom_error.html squid/src/custom_error.html --- squid-1.1.17/src/custom_error.html Thu Jan 1 08:00:00 1970 +++ squid/src/custom_error.html Fri Jun 5 19:08:27 1998 @@ -0,0 +1,29 @@ + +SmartFilter: Access Denied + + + +

Access Denied

+ +The content you have requested contains material either unsuitable +or irrelevant for your use as configured in the filtering setup +on your account.

+ +This site was blocked by the following categories:
+%REASON + +

The SmartFilter system is currently under trial by MNS, so +some unexpected results may occur.

+ +You can set the categories filtered for your service through Client Services +on the MNS Home Page.

+ +If you discover a site or URL has been restricted for which you +have a business need, but do not want to enable the entire category, +record the URL for which you need access, +and request an exemption for that URL by E-mailing +mns@mns.net.au. +

+Generated by SmartFilter at proxy.mns.net.au + + diff -urN squid-1.1.17/src/custom_error.html.old squid/src/custom_error.html.old --- squid-1.1.17/src/custom_error.html.old Thu Jan 1 08:00:00 1970 +++ squid/src/custom_error.html.old Tue Jun 2 15:42:49 1998 @@ -0,0 +1,46 @@ + +Internet and WWW Acceptable Use Policy + + + +

Internet and WWW Acceptable Use Policy

+ +The Internet connection you are using was established for business use. +Use of this connection for non-business purposes is deemed an +unacceptable use under this policy. + +

Access restricted to proxy

+ +All browser access to the Internet for World Wide Web, +FTP (file transfer), and gopher is required by policy +to pass through a "proxy" machine that has been installed for this purpose. + +Browsers not configured to use the proxy will not be allowed +direct access to the Internet. + +

Logs are maintained

+ +Policy requires that logs of browser access to the Internet +be kept. These logs record when and where, and from what networked computer +Internet access has been allowed (or denied). Supervisors and authorized +network management personnel have access to these logs.

+ +Use of this proxy and its attached Internet connection indicates your +consent to usage monitoring and logging. + +

Non-business sites restricted

+ +In addition to keeping logs, the proxy may also restrict access +to certain sites that have been determined to have no valid business +purpose, or have been determined to contain objectionable material. + +Attempts to access these sites will result in the display of an error +message including the reason(s) a site has been restricted. + +

Exceptions made based on business need

+ +If you discover a site or URL has been restricted for which you +have a business need, record the URL for which to which you need access, +and request an exemption for that URL. + + diff -urN squid-1.1.17/src/http.c squid/src/http.c --- squid-1.1.17/src/http.c Fri Aug 8 00:00:00 1997 +++ squid/src/http.c Tue Oct 21 14:04:00 1997 @@ -771,6 +771,8 @@ strcat(viabuf, s); strcat(viabuf, ", "); continue; + } else if (strncasecmp(xbuf, "X-Acct-To:", 10) == 0) { + continue; } else if (strncasecmp(xbuf, "X-Forwarded-For:", 16) == 0) { for (s = xbuf + 16; *s && isspace(*s); s++); if (strlen(fwdbuf) + strlen(s) < 4000) diff -urN squid-1.1.17/src/icp.c squid/src/icp.c --- squid-1.1.17/src/icp.c Thu Oct 9 06:18:00 1997 +++ squid/src/icp.c Tue Jun 2 21:38:55 1998 @@ -283,7 +283,7 @@ HTTPCacheInfo->proto_count(HTTPCacheInfo, icpState->request ? icpState->request->protocol : PROTO_NONE, icpState->log_type); - clientdbUpdate(icpState->peer.sin_addr, + clientdbUpdate(icpState->acct_addr, icpState->log_type, ntohs(icpState->me.sin_port)); } @@ -363,6 +363,21 @@ BIT_SET(request->flags, REQ_NOCACHE); BIT_SET(request->flags, REQ_RANGE); } + if ((t = mime_get_header(request_hdr, "X-Acct-To"))) { + struct in_addr addr; + addr.s_addr=inet_addr(t); + if (addr.s_addr!=-1) { char buf[FD_ASCII_NOTE_SZ+25]; + icpState->acct_addr = addr; + icpState->peer.sin_addr = addr; + /* icpState->acct_addr.s_addr &= Config.Addrs.client_netmask.s_addr; */ + + /* make note of this for file handle listings... */ + strcpy(buf, inet_ntoa(icpState->acct_addr)); + strcat(buf, ", "); + strcat(buf, fd_note(icpState->fd, NULL)); + fd_note(icpState->fd, buf); + } + } if (mime_get_header(request_hdr, "Authorization")) BIT_SET(request->flags, REQ_AUTH); if (request->login[0] != '\0') @@ -510,6 +525,10 @@ icpSendERRORComplete, (void *) icpState, put_free_4k_page); + clientdbUpdateVol(icpState->acct_addr, + icpState->log_type, + ntohs(icpState->me.sin_port), + buf_len); } #if LOG_FULL_HEADERS @@ -567,6 +586,10 @@ icp_maybe_remember_reply_hdr(icpState); #endif /* LOG_FULL_HEADERS */ icpState->out_offset += len; + clientdbUpdateVol(icpState->acct_addr, + icpState->log_type, + ntohs(icpState->me.sin_port), + len); if (icpState->request->method == METHOD_HEAD) { if ((p = mime_headers_end(buf))) { *p = '\0'; @@ -703,6 +726,10 @@ icpHandleIMSComplete, icpState, xfree); + clientdbUpdateVol(icpState->acct_addr, + icpState->log_type, + ntohs(icpState->me.sin_port), + strlen(reply)); return COMM_OK; } @@ -772,6 +799,10 @@ icpSendERRORComplete, icpState, xfree); + clientdbUpdateVol(icpState->acct_addr, + icpState->log_type, + ntohs(icpState->me.sin_port), + strlen(reply)); return; } /* yes, continue */ @@ -961,6 +992,9 @@ clientdbUpdate(queue->address.sin_addr, queue->logcode, Config.Port.icp); + clientdbUpdateVol(queue->address.sin_addr, + queue->logcode, + Config.Port.icp,queue->len); if (!Config.Options.log_udp) return; HTTPCacheInfo->log_append(HTTPCacheInfo, @@ -1535,6 +1569,7 @@ sock, len, inet_ntoa(from.sin_addr)); + neighborUpdateVol(&from.sin_addr,1,len); #ifdef ICP_PACKET_DUMP icpPktDump(buf); #endif @@ -1753,6 +1788,22 @@ icpSendERROR(fd, ERR_INVALID_URL, wbuf, icpState, 400); return; } + +#ifdef SMARTFILTER + if (Config.SmartFilterState) { + if (smartfilter_check_url(fd, icpState) == URL_ALLOWED) { + debug(61, 2, "clientReadRequest: SmartFilter allowed the url\n"); + } + else { + debug(61, 2, "clientReadRequest: SmartFilter blocked the url\n"); + return; + } + } + else { + debug(61, 5, "clientReadRequest: SmartFilter disabled\n"); + } +#endif + safe_free(icpState->log_url); icpState->log_url = xstrdup(urlCanonicalClean(request)); request->http_ver = icpState->http_ver; @@ -1883,11 +1934,13 @@ icpState->peer = peer; icpState->log_addr = peer.sin_addr; icpState->log_addr.s_addr &= Config.Addrs.client_netmask.s_addr; + icpState->acct_addr = peer.sin_addr; + /* icpState->acct_addr.s_addr &= Config.Addrs.client_netmask.s_addr; */ icpState->me = me; icpState->entry = NULL; icpState->fd = fd; icpState->ident.fd = -1; - fd_note(fd, inet_ntoa(icpState->log_addr)); + fd_note(fd, inet_ntoa(icpState->acct_addr)); meta_data.misc += ASCII_INBUF_BLOCKSIZE; commSetSelect(fd, COMM_SELECT_LIFETIME, @@ -2092,10 +2145,12 @@ icpState->peer = peer; icpState->log_addr = peer.sin_addr; icpState->log_addr.s_addr &= Config.Addrs.client_netmask.s_addr; + icpState->acct_addr = peer.sin_addr; + /* icpState->acct_addr.s_addr &= Config.Addrs.client_netmask.s_addr; */ icpState->me = me; icpState->entry = NULL; icpState->fd = fd; - fd_note(fd, inet_ntoa(icpState->log_addr)); + fd_note(fd, inet_ntoa(icpState->acct_addr)); meta_data.misc += ASCII_INBUF_BLOCKSIZE; comm_add_close_handler(fd, icpStateFree, diff -urN squid-1.1.17/src/icp.h squid/src/icp.h --- squid-1.1.17/src/icp.h Fri Jul 11 00:00:00 1997 +++ squid/src/icp.h Tue Jun 2 15:42:52 1998 @@ -187,6 +187,7 @@ struct sockaddr_in peer; struct sockaddr_in me; struct in_addr log_addr; + struct in_addr acct_addr; struct timeval start; int accel; int size; /* hack for CONNECT which doesnt use sentry */ diff -urN squid-1.1.17/src/main.c squid/src/main.c --- squid-1.1.17/src/main.c Thu Oct 9 01:09:00 1997 +++ squid/src/main.c Tue Jun 2 15:42:52 1998 @@ -317,6 +317,9 @@ void shut_down(int sig) { +#ifdef SMARTFILTER + smartfilter_free(); +#endif shutdown_pending = sig == SIGINT ? -1 : 1; debug(1, 1, "Preparing for shutdown after %d connections\n", ntcpconn + nudpconn); @@ -503,6 +506,9 @@ static void mainReinitialize(void) { +#ifdef SMARTFILTER + smartfilter_free(); +#endif debug(1, 0, "Restarting Squid Cache (version %s)...\n", version_string); /* Already called serverConnectionsClose and ipcacheShutdownServers() */ neighborsDestroy(); @@ -516,6 +522,9 @@ ftpInitialize(); if (theOutIcpConnection >= 0 && (!httpd_accel_mode || Config.Accel.withProxy)) neighbors_open(theOutIcpConnection); +#ifdef SMARTFILTER + smartfilter_init(); +#endif debug(1, 0, "Ready to serve requests.\n"); } @@ -618,6 +627,9 @@ eventAdd("ipcache_purgelru", (EVH) ipcache_purgelru, NULL, 10); } first_time = 0; +#ifdef SMARTFILTER + smartfilter_init(); +#endif } int diff -urN squid-1.1.17/src/neighbors.c squid/src/neighbors.c --- squid-1.1.17/src/neighbors.c Fri Aug 22 03:17:00 1997 +++ squid/src/neighbors.c Tue Oct 21 14:04:00 1997 @@ -129,6 +129,8 @@ static u_short echo_port; static int NLateReplies = 0; +static unsigned long DirectVolume=0, ParentVolumeHttp=0, ParentVolumeIcp=0; +static unsigned long LastDirectVol=0, LastParentVolHttp=0, LastParentVolIcp=0; static struct { int n; @@ -193,6 +195,55 @@ } } return NULL; +} + +void +neighborUpdateVol(struct in_addr *addr, u_short port, long len) +{ peer *p; + int j; + + for (p=Peers.peers_head; p; p=p->next) { + for (j=0; jn_addresses; j++) { + if (addr->s_addr==p->addresses[j].s_addr) + { + debug(15,2,"neighborUpdateVol: %s:%d : %lu bytes\n", + inet_ntoa(p->addresses[0]),port,len); + if (!port) { p->stats.v_fetches+=len; + ParentVolumeHttp +=len; + } + else { p->stats.v_icp +=len; + ParentVolumeIcp +=len; + } + return; + } + } + } + DirectVolume+=len; +} + +void GetIntakeVolume(unsigned long *direct, + unsigned long *http, + unsigned long *icp, + int reset) +{ *direct= DirectVolume; + *http = ParentVolumeHttp; + *icp = ParentVolumeIcp; + if (reset) { + LastDirectVol+=DirectVolume/1000; + LastParentVolHttp+=ParentVolumeHttp/1000; + LastParentVolIcp+=ParentVolumeIcp/1000; + DirectVolume=0; + ParentVolumeHttp=0; + ParentVolumeIcp=0; + } +} + +void GetLastIntakeVolume(unsigned long *direct, + unsigned long *http, + unsigned long *icp) +{ *direct= LastDirectVol; + *http = LastParentVolHttp; + *icp = LastParentVolIcp; } void diff -urN squid-1.1.17/src/neighbors.h squid/src/neighbors.h --- squid-1.1.17/src/neighbors.h Fri Aug 22 03:17:00 1997 +++ squid/src/neighbors.h Tue Oct 21 14:04:00 1997 @@ -166,19 +166,24 @@ #define PEER_MAX_ADDRESSES 10 #define RTT_AV_FACTOR 1000 -struct _peer { - char *host; - neighbor_t type; - struct sockaddr_in in_addr; - struct { + +struct _peer_stats { int pings_sent; int pings_acked; int ack_deficit; int fetches; + unsigned long v_fetches; + unsigned long v_icp; int rtt; int counts[ICP_OP_END]; int ignored_replies; - } stats; +}; + +struct _peer { + char *host; + neighbor_t type; + struct sockaddr_in in_addr; + struct _peer_stats stats, last_stats; u_short icp_port; u_short http_port; int icp_version; @@ -255,6 +260,9 @@ extern void peerDestroy _PARAMS((peer * e)); extern char *neighborTypeStr _PARAMS((const peer * e)); extern void peerCheckConnectStart _PARAMS((peer *)); +extern void neighborUpdateVol _PARAMS((struct in_addr *, u_short, long)); +extern void GetIntakeVolume _PARAMS((unsigned long *,unsigned long *,unsigned long *, int reset)); +extern void GetLastIntakeVolume _PARAMS((unsigned long *,unsigned long *,unsigned long *)); extern const char *hier_strings[]; diff -urN squid-1.1.17/src/objcache.c squid/src/objcache.c --- squid-1.1.17/src/objcache.c Wed Mar 26 00:00:00 1997 +++ squid/src/objcache.c Wed Jun 3 18:11:46 1998 @@ -127,7 +127,7 @@ struct _cachemgr_passwd *next; }; -static ObjectCacheData *objcache_url_parser _PARAMS((const char *url)); +static ObjectCacheData *objcache_url_parser _PARAMS((const char *url, char *extrainfo)); static int objcache_CheckPassword _PARAMS((ObjectCacheData *)); static char *objcachePasswdGet _PARAMS((cachemgr_passwd ** a, objcache_op op)); @@ -142,7 +142,7 @@ (1 << MGR_CONFIG_FILE); static objcache_op -objcacheParseRequest(const char *buf) +objcacheParseRequest(const char *buf, char *extrainfo) { objcache_op op = MGR_NONE; if (!strcmp(buf, "shutdown")) @@ -183,8 +183,16 @@ op = MGR_LOG_VIEW; else if (!strcmp(buf, "parameter")) op = MGR_CONFIG; + else if (!strncmp(buf, "server_list/",12)) + { op = MGR_SERVER_LIST_IP; + if (extrainfo) strncpy(extrainfo,buf+12,100); + } else if (!strcmp(buf, "server_list")) op = MGR_SERVER_LIST; + else if (!strncmp(buf, "client_list/",12)) + { op = MGR_CLIENT_LIST_IP; + if (extrainfo) strncpy(extrainfo,buf+12,100); + } else if (!strcmp(buf, "client_list")) op = MGR_CLIENT_LIST; else if (!strcmp(buf, "squid.conf")) @@ -194,7 +202,7 @@ static ObjectCacheData * -objcache_url_parser(const char *url) +objcache_url_parser(const char *url, char *extrainfo) { int t; LOCAL_ARRAY(char, host, MAX_URL); @@ -208,7 +216,7 @@ } obj = xcalloc(1, sizeof(ObjectCacheData)); strcpy(obj->passwd, t == 3 ? password : "nopassword"); - obj->op = objcacheParseRequest(request); + obj->op = objcacheParseRequest(request,extrainfo); return obj; } @@ -233,9 +241,10 @@ static const char *const BADPassword = "Incorrect password, sorry.\n"; ObjectCacheData *data = NULL; int complete_flag = 1; + char extrainfo[101]=""; debug(16, 3, "objectcacheStart: '%s'\n", url); - if ((data = objcache_url_parser(url)) == NULL) { + if ((data = objcache_url_parser(url,extrainfo)) == NULL) { storeAbort(entry, "Invalid objcache syntax.\n"); entry->expires = squid_curtime + STAT_TTL; safe_free(data); @@ -245,9 +254,10 @@ data->reply_fd = fd; data->entry = entry; entry->expires = squid_curtime + STAT_TTL; - debug(16, 1, "CACHEMGR: %s requesting '%s'\n", + debug(16, 1, "CACHEMGR: %s requesting '%s' info: '%s'\n", fd_table[fd].ipaddr, - objcacheOpcodeStr[data->op]); + objcacheOpcodeStr[data->op], + extrainfo); /* Check password */ if (objcache_CheckPassword(data) != 0) { debug(16, 1, "WARNING: Incorrect Cachemgr Password!\n"); @@ -321,10 +331,16 @@ HTTPCacheInfo->parameter_get(HTTPCacheInfo, entry); break; case MGR_SERVER_LIST: - HTTPCacheInfo->server_list(HTTPCacheInfo, entry); + HTTPCacheInfo->server_list(HTTPCacheInfo, entry, extrainfo); + break; + case MGR_SERVER_LIST_IP: + HTTPCacheInfo->server_list(HTTPCacheInfo, entry, extrainfo); break; case MGR_CLIENT_LIST: - clientdbDump(entry); + clientdbDump(entry,extrainfo); + break; + case MGR_CLIENT_LIST_IP: + clientdbDump(entry,extrainfo); break; case MGR_CONFIG_FILE: HTTPCacheInfo->squid_get_start(HTTPCacheInfo, entry); @@ -369,7 +385,7 @@ q->actions = ~0; continue; } - op = objcacheParseRequest(w->key); + op = objcacheParseRequest(w->key,NULL); if (op <= MGR_NONE || op >= MGR_MAX) { debug(16, 0, "objcachePasswdAdd: Invalid operation: '%s'\n", w->key); continue; diff -urN squid-1.1.17/src/objcache_opcodes.h squid/src/objcache_opcodes.h --- squid-1.1.17/src/objcache_opcodes.h Sat Dec 14 00:00:00 1996 +++ squid/src/objcache_opcodes.h Wed Jun 3 18:23:10 1998 @@ -31,6 +31,7 @@ typedef enum { MGR_NONE, MGR_CLIENT_LIST, + MGR_CLIENT_LIST_IP, MGR_CONFIG, MGR_CONFIG_FILE, MGR_DNSSERVERS, @@ -51,6 +52,7 @@ MGR_REMOVE, MGR_REPLY_HDRS, MGR_SERVER_LIST, + MGR_SERVER_LIST_IP, MGR_SHUTDOWN, MGR_UTILIZATION, MGR_VM_OBJECTS, @@ -61,6 +63,7 @@ { "NONE", "client_list", + "client_list/ip", "config", "config_file", "dnsservers", @@ -81,6 +84,7 @@ "remove", "reply_headers", "server_list", + "server_list/ip", "shutdown", "utilization", "vm_objects", diff -urN squid-1.1.17/src/proto.c squid/src/proto.c --- squid-1.1.17/src/proto.c Fri Aug 22 03:25:00 1997 +++ squid/src/proto.c Tue Oct 21 14:04:00 1997 @@ -584,6 +584,7 @@ #endif if (e) { e->stats.fetches++; + entry->mem_obj->source=e->in_addr.sin_addr; return proxyhttpStart(url, request, entry, e); } else if (request->protocol == PROTO_HTTP) { return httpStart(url, request, request_hdr, request_hdr_sz, entry); diff -urN squid-1.1.17/src/smartfilter.conf squid/src/smartfilter.conf --- squid-1.1.17/src/smartfilter.conf Thu Jan 1 08:00:00 1970 +++ squid/src/smartfilter.conf Tue Jun 2 15:42:49 1998 @@ -0,0 +1,66 @@ +# +# Smartfilter Configuration File +# +# Identify below the full path and name of the +# Control List file +# +controlfile /etc/wtcontrol +domainresolvedfile /etc/wtcntldr +# +# For Squid redirect function specify a url to be used to +# redirect blocked requests +#redirecturl http://put.site.here/error.html +# +# +# Identify below the full path and name of the local, site-specific +# file to augment the full Control List (optional) +# +sitefile /etc/smartfilter.site +# +# errorfile is used by SmartFilter for Squid patch to +# present a custom error message on a rejected request +#errorfile /etc/custom_error.html +# +# This optional parameter specifies the error message to be +# displayed to the user. +# +# The %REASON keyword (also optional) will be replaced by +# the category descriptions. +# +errortext categories: %REASON are restricted. +# +# The following "#restrict" lines control which Control List +# categories are forbidden. The category description (in quotes) +# at the end of each line specifies the category +# description to be inserted, as appropriate, in the position +# specified by the %REASON keyword in the errortext parameter +# +restrict sx "Sex" #1 +restrict dr "Illegal Drugs" #2 +restrict hs "Hate Speech" #3 +restrict cs "Criminal Skills" #4 +restrict wt "Worthless" #5 +restrict os "On-line Sales" #6 +restrict gb "Gambling" #7 +restrict pp "Personal Ads" #8 +restrict js "Job Search" #9 +restrict sp "Sports" #10 +restrict gm "Games and Fun" #11 +restrict hm "Humor" #12 +restrict aj "Alternative Journal" #13 +restrict et "Entertainment" #14 +restrict ls "Personal, Alternative Lifestyle" #15 +restrict ex "Extreme, Gross,Indecent Content" #16 +restrict ch "Chat Web" #17 +restrict in "Investments Information" #18 +restrict nw "General News" #19 +restrict po "Poltics, Opinion, Religion" #20 +restrict mm "Dating and Introduction Service" #21 +restrict ac "Art and Culture" #22 +restrict oc "Cult/Occult" #23 +restrict na "Usenet News Site" #24 +restrict sh "Self Help" #25 +restrict tr "Travel" #26 +restrict ne "Non-Essential" #27 +# +# End of config file diff -urN squid-1.1.17/src/smartfilter.site squid/src/smartfilter.site --- squid-1.1.17/src/smartfilter.site Thu Jan 1 08:00:00 1970 +++ squid/src/smartfilter.site Tue Jun 2 15:42:49 1998 @@ -0,0 +1,97 @@ +# +# Smartfilter Site Overrides/Excemptions File +# +# Local Additions/Exemptions to the SmartFilter Control List +# +# Entries in this file, which is loaded at startup, take +# precedence over entries in the Smartfilter Control List. +# +# Sites, parts of sites (i.e. a directory path within a site), or +# individual URLs canbe specified. +# +# To exempt follow the site, path or URL specification with the word +# EXEMPT. +# +# To add a site, path, or URL to one or more categories that are +# restricted, follow the site, path or URL specification with +# A comma-delimited string of two-letter category codes, as shown +# below. +# +# format of file is +# +# Column 1 - the URL (ex: http://www.test.com/ ) +# Column 2 - Blank +# Column 3 - for restrict action a list of category +# codes, comma seperated, NO spaces. +# Category codes - +# aj - alternative journal +# ac - art/culture +# ch - chat site/gateway +# cs - criminal skills +# dr - drugs +# et - entertainment +# ex - extreme +# gb - gambling +# gm - games & fun +# hm - humor +# hs - hate speech +# in - investing +# js - job search +# ls - lifestyle +# mm - dating/match making +# na - usenet access +# ne - non-essential +# nw - general news +# oc - cult/occult +# os - online sales/merchandising +# pp - personal pages +# po - politics/opinion +# sh - self help +# sp - sports +# sx - sex +# tr - travel +# wt - worthless + +# +# for exemption action the word exempt +# +# Examples: +# (Note: these fictitious examples assume all categories shown are restricted +# in the WebTrack NP configuration file) +# +# Restricting an entire site: +# +http://sexstuff.com sx,os +# +# Restricting an entire site using a dotted decimal address: +# +http://123.456.78.9 sx,os +# +# Restricting part of a site (all URLs beginning with specified path): +# +http://www.university.edu/computerscience/~joecollege/PICS/Girls sx,pp +# +# Restricting part of a site using dotted decimal addressing (all URLs +beginning with specified path): +# +http://123.456.78.9/computerscience/~joecollege/PICS/Girls sx,pp +# +# Restricting a single URL without blocking the rest of a site: +# +http://www.bigco.com/HR/jobs.html js +# +# +# Exempting an entire site: +# +http://www.asexysite.com exempt +# +# Exempting a path without exempting the balance of the site: +# +http://www.sexmag.com/articles exempt +# +# Exempting an individual URL without exempting the balance of the site: +# +http://www.sexmag.com/HumanResources/jobs/photographer.htm exempt +# +#END Site File + diff -urN squid-1.1.17/src/smartfilter_squid.c squid/src/smartfilter_squid.c --- squid-1.1.17/src/smartfilter_squid.c Thu Jan 1 08:00:00 1970 +++ squid/src/smartfilter_squid.c Fri Jun 5 09:36:20 1998 @@ -0,0 +1,711 @@ + +/* + * smartfilter_squid.c - an interface between Squid and SmartFilter + * + * + */ + +/* + * Copyright (c) 1998. Secure Computing Corp. + * All rights reserved. + */ + +#include "squid.h" + +#define MAX_LINE 1024 + +#define CATDESC struct cat_desc +CATDESC { + CATDESC *CTnext; /* Adr of next */ + int CTapidesc; /* API category code */ + int CTcategory; /* Category code T or F */ + char CTwtcat[4]; /* WebTrack 2 char category code */ + char CTsitedesc[1]; /* Site description */ +}; + +/* + CAT_MAP replaces those horrible long if ... then .... else + statements that were originally in here.... +*/ +struct CAT_MAP { + int CTapidesc; + char CTwtcat[4]; +}; +static struct CAT_MAP cat_map[]={ + { WT_CAT_SEX, "sx"}, + { WT_CAT_DRUGS, "dr"}, + { WT_CAT_HATESPEECH, "hs"}, + { WT_CAT_CRIME, "cs"}, + { WT_CAT_WORTHLESS, "os"}, + { WT_CAT_SALES, "gb"}, + { WT_CAT_GAMBLING, "pp"}, + { WT_CAT_PERSONAL, "js"}, + { WT_CAT_JOBS, "sp"}, + { WT_CAT_SPORTS, "gm"}, + { WT_CAT_GAMES, "hm"}, + { WT_CAT_HUMOR, "aj"}, + { WT_CAT_ALTJRNL, "et"}, + { WT_CAT_ENTERTAIN, "ls"}, + { WT_CAT_LIFESTYLE, "ex"}, + { WT_CAT_EXTREME, "wt"}, + { WT_CAT_CHAT, "ch"}, + { WT_CAT_INVESTMENTS, "in"}, + { WT_CAT_GNEWS, "nw"}, + { WT_CAT_OPINION, "po"}, + { WT_CAT_DATING, "mm"}, + { WT_CAT_ART, "ac"}, + { WT_CAT_CULT, "na"}, + { WT_CAT_NEWSSITE, "oc"}, + { WT_CAT_SELFHELP, "sh"}, + { WT_CAT_TRAVEL, "tr"}, + { WT_CAT_NONESSENTIAL, "ne"}, + { 0, "" } + }; + +static char * default_error_msg (int code, int method, const char *url, const char *client,const char *reason); +static char * load_custom_error_file (char *filepath); + +static WT_SERVICE WTserv = WT_NULLPARM; +static WT_TYPES WTtype = WT_NULLPARM; +static WT_TYPES WTcat = WT_NULLPARM; +static WT_TYPES WTwork = WT_NULLPARM; +static CATDESC *WTdesc = (CATDESC * ) WT_NULLPARM; +static char *WTerrtext = NULL; +static char *WTerrfile = NULL; +static char *WTcustom_errtext = NULL; /* we read the custom error file into here */ +static char err_message[MAX_LINE]; +static int WTfailcnt = 0; +static int WTexpired = FALSE; + + +int wtcattonum(char *wtcat) +{ struct CAT_MAP *c=cat_map; + while (c->CTapidesc && strcmp(c->CTwtcat,wtcat)) c++; + return c->CTapidesc; +} + +char *wtnumtocat(int apidesc) +{ struct CAT_MAP *c=cat_map; + while (c->CTapidesc && c->CTapidesc!=apidesc) c++; + return c->CTwtcat; +} + +char *wtgetcats(WT_TYPES *WTtypes, char *buf) +{ struct CAT_MAP *c=cat_map; + char *bufend; + *buf='\0'; + if (WTtypes == WT_NULLPARM) return buf; + + while (c->CTapidesc) { + if (WT_TestThisCategory(WTtypes, c->CTapidesc) == WTISSET) { + strcat(buf,c->CTwtcat); + strcat(buf,","); + } + c++; + } + bufend=buf+strlen(buf); + if (bufend>buf) bufend--; + if (*bufend==',') *bufend='\0'; + return buf; +} + +/* set category discriptions based on what is in the configuration file */ +static void wtsetcatdesc( char *wtcat, char *sitedesc, int apidesc, int catyn ) +{ + CATDESC *workdesc; + int i; + + for ( i = 1; i < strlen( sitedesc ); i++ ) + { + if ( *(sitedesc + i ) == '"' ) + { + break; + } + } + i--; /* Back up from last quote */ + workdesc = calloc( 1, sizeof( CATDESC) + i ); + if ( workdesc ) + { + strncpy( workdesc->CTwtcat, wtcat, sizeof( workdesc->CTwtcat) -1 ); + strncpy( workdesc->CTsitedesc, sitedesc+1, i ); + workdesc->CTapidesc = apidesc; + workdesc->CTcategory = catyn; + workdesc->CTnext = WTdesc; + WTdesc = workdesc; + } + +} + +/* check and get description to cat onto the err_message */ +static void wtfindcat( int category, char *workarea, int catyn ) +{ + CATDESC *workdesc; + + for ( workdesc = WTdesc; workdesc; workdesc = workdesc->CTnext ) + { + if ( ( workdesc->CTapidesc == category ) && + ( workdesc->CTcategory == catyn ) ) + { + strcat( workarea, workdesc->CTsitedesc ); + strcat( workarea, "," ); + return; + } + } +} + + +/* generate the errtext output string based on info in the configuration file */ +static char *wtmakeerr( int iscategory, WT_TYPES WTwork, char *errtext, char *workarea ) +{ + char *workchar, *errreason; + + if ( errtext == NULL ) + return( NULL ); + errreason = strstr( errtext, "%REASON" ); + if ( errreason == NULL ) + { + return( errtext ); + } + errreason += 7; + strcpy( workarea, errtext ); + workchar = strstr( workarea, "%REASON" ); + *workchar = '\0'; + strcat( workarea," "); + if ( iscategory ) + { struct CAT_MAP *c=cat_map; + while (c->CTapidesc) { + if ( WT_TestThisCategory( WTwork, c->CTapidesc ) == WTISSET ) + wtfindcat( c->CTapidesc, workarea, TRUE ); + c++; + } + } + else + { + if ( WT_TestThisControl( WTwork, WT_CONTROL_DDD ) == WTISSET ) + wtfindcat( WT_CONTROL_DDD, workarea, FALSE ); + if ( WT_TestThisControl( WTwork, WT_CONTROL_UNCATPERSONAL ) == WTISSET ) + wtfindcat( WT_CONTROL_UNCATPERSONAL, workarea, FALSE ); + + } + if ( workarea[strlen(workarea) - 1] == ',' ) + workarea[strlen(workarea) - 1] = '\0'; + strcat( workarea, errreason ); + return( workarea ); +} + + + +/* set and return the first category matched */ +static int wtsetcat( WT_TYPES *WTtype, char *parm2 ) +{ struct CAT_MAP *c=cat_map; + + while (c->CTapidesc && strstr(parm2, c->CTwtcat)==0) c++; + if (c->CTapidesc) WT_SetThisCategory( WTtype, c->CTapidesc); + return c->CTapidesc; +} + +/* set all categories matched */ +// static +void wtsetcats( WT_TYPES *WTtype, char *parm2 ) +{ struct CAT_MAP *c=cat_map; + + while (c->CTapidesc) { + if (strstr( parm2, c->CTwtcat)) + WT_SetThisCategory( WTtype, c->CTapidesc ); + c++; + } +} + + +/****************************************** + * Local Function to update local site file + * + * Input is name of local site file + * + * format of file is + * - the URL (ex: http://www.test.com/ ) + * - Blank + * - for restrict action a list of category + * codes, comma seperated, NO spaces. + * Category codes - sx - sex + * dr - drugs + * hs - hate speech + * cs - criminal skills + * os - online sales/merchandising + * gb - gambling + * pp - personal pages + * js - job search + * sp - sports + * gm - games + * hm - humor + * aj - alternative journal + * et - entertainment + * ls - lifestyle + * ex - extreme + * wt - worthless + * ch - chat gateway + * in - investing + * nw - general news + * po - politics, opinion, religion + * mm - dating + * ac - art culture + * na - usenet news access + * oc - occult/cults + * sh - self help + * tr - travel + * ne - non-essential + * for exemption action the word exempt + * + * Returns - True for OK + * False for failure + ******************************************/ + +/* load the site-specific exemptions and restrictions */ +static int wtloadsitelist( WT_SERVICE wthandle, char *localfile ) +{ + int workint; + FILE *fhandle; /* File handle */ + WT_TYPES WebTrackTypes; /* types */ + char workbuf[1024]; /* Input buffer */ + char url[1024]; /* Input url */ + char categoryinfo[1024]; /* category info */ + + debug(61, 5, "SmartFilter wtloadsitelist: loading site list from %s\n", localfile); + + WebTrackTypes = WT_AllocateTypes(); + if ( WebTrackTypes == NULL ) + { + return( FALSE ); + } + fhandle = fopen( localfile, "r" ); + if ( fhandle == NULL ) + { + return( FALSE ); + } + + while ( fgets( workbuf, sizeof( workbuf ), fhandle ) ) + { + /* Clear the Types object */ + WT_ClearTypes( WebTrackTypes ); + if ( workbuf[0] == '#' ) + continue; + + workint = sscanf( workbuf, "%s%s", url, categoryinfo); + if ( workint > 0 ) + { + /* Set type of entry to path */ + WT_SetThisControl( WebTrackTypes, WT_CONTROL_PATH ); + /* Set categories */ + if ( strcasecmp( categoryinfo, "exempt" ) == 0 ) + { + WT_SetThisControl( WebTrackTypes, WT_CONTROL_EXEMPT ); + } + else + { + WT_SetThisControl( WebTrackTypes, WT_CONTROL_RESTRICT ); + + /* Note: Colin changed this from wtsetcat() to wtsetcats() to + * allow one site to be in multiple categories in the site list + */ + wtsetcats( WebTrackTypes, categoryinfo ); + } + if ( WT_UpdateSiteList( wthandle, url, WebTrackTypes ) != 0 ) + { + fclose( fhandle ); + return( FALSE ); + } + } + } + WT_FreeTypes( WebTrackTypes ); + fclose( fhandle ); + return( TRUE ); +} + +/* Used to free static array on restart */ +void smartfilter_free() +{ + CATDESC *workdesc; + + debug(61, 0, "Disabling SmartFilter\n"); + debug(61, 5, "SmartFilter: freeing up resources\n"); + Config.SmartFilterState = 0; + + while ( WTdesc ) + { + workdesc = WTdesc->CTnext; + free( WTdesc ); + WTdesc = workdesc; + } + if ( WTerrtext ) + { + free( WTerrtext ); + WTerrtext = NULL; + } + WT_FreeTypes( WTtype ); + WT_FreeTypes( WTcat ); + WT_FreeTypes( WTwork ); + WT_FreeService( WTserv ); + WTserv = WT_NULLPARM; + WTtype = WT_NULLPARM; + WTcat = WT_NULLPARM; + WTwork = WT_NULLPARM; + WTfailcnt = 0; + WTexpired = FALSE; +} + +/* initialize SmartFilter and load settings from configuration file + * returns zero if all is well, -1 if problems found + */ +int smartfilter_init() +{ + /* Working variables */ + FILE *f; + char *workchar; + char buf[MAX_LINE]; + char parm1[MAX_LINE]; + char parm2[MAX_LINE]; + char parm3[MAX_LINE]; + char sitef[MAX_LINE]; + char cntlf[MAX_LINE]; + char dnrfile[MAX_LINE]; + int workint; + + if (Config.SmartFilterState) { + debug(61, 5, "Initializing SmartFilter\n"); + } + else { + debug(61, 5, "SmartFilter init: SmartFilter disabled\n"); + return 0; + } + + memset( sitef, 0, MAX_LINE ); + memset( cntlf, 0, MAX_LINE ); + memset( dnrfile, 0, MAX_LINE ); + + debug(61, 5, "SmartFilter init: config file is %s\n", Config.SmartFilterConf); + + if(!Config.SmartFilterConf) { + debug(61, 0, "SmartFilter init: missing parameter to webtrack_init (need file)\n"); + smartfilter_free(); + return -1; + } + f = fopen(Config.SmartFilterConf, "r"); + + /* Did we open it? */ + if(!f) { + debug(61, 0, "SmartFilter init: can't open config file, disabling SmartFilter\n"); + smartfilter_free(); + return -1; + } + WTserv = WT_Init(); + if ( WTserv == WT_NULLPARM ) + { + debug(61, 0, "SmartFilter init: can't Initialize, disabling SmartFilter\n"); + fclose(f); + smartfilter_free(); + return -1; + } + WTtype = WT_AllocateTypes(); + if ( WTtype == WT_NULLPARM ) + { + debug(61, 0, "SmartFilter init: can't Allocate WTtype\n"); + fclose(f); + smartfilter_free(); + return -1; + } + WTcat = WT_AllocateTypes(); + if ( WTcat == WT_NULLPARM ) + { + debug(61, 0, "SmartFilter init: can't Allocate WTcat\n"); + fclose(f); + smartfilter_free(); + return -1; + } + WTwork = WT_AllocateTypes(); + if ( WTwork == WT_NULLPARM ) + { + debug(61, 0, "SmartFilter init: can't Allocate WTwork\n"); + fclose(f); + smartfilter_free(); + return -1; + } + /* Process config file */ + while(fgets(buf, MAX_LINE, f)) + { /* Blast linefeed that stdio helpfully leaves on there */ + buf[strlen(buf) - 1] = '\0'; + sscanf(buf,"%s%s%s",parm1, parm2, parm3); + if ( strcmp( parm1, "controlfile") == 0 ) + { + strcpy(cntlf, parm2 ); + } + else if ( strcmp( parm1, "sitefile") == 0 ) + { + strcpy(sitef, parm2 ); + } + else if ( strcmp( parm1, "domainresolvedfile") == 0 ) + { + strcpy(dnrfile, parm2 ); + } + else if ( strcmp( parm1, "restrict") == 0 ) + { + workint = wtsetcat( WTtype, parm2 ); + if ( ( workchar = strchr( buf, '"' ) ) != NULL ) + { + wtsetcatdesc( parm2, workchar, workint, TRUE ); + } + } + else if ( strcmp( parm1, "describe") == 0 ) + { workint=wtcattonum(parm2); + if (workint && (workchar=strchr(buf,'"') ) != NULL ) + wtsetcatdesc( parm2, workchar, workint, TRUE ); + } + else if ( strcmp( parm1, "dotteddecimal") == 0 ) + { + if ( strcmp( parm2, "forbid" ) == 0 ) + { + WT_SetThisControl( WTtype, WT_CONTROL_DDD ); + if ( ( workchar = strchr( buf, '"' ) ) != NULL ) + { + wtsetcatdesc( "ddd", workchar, WT_CONTROL_DDD, FALSE ); + } + } + } + else if ( strcmp( parm1, "uncatpersonal") == 0 ) + { + if ( strcmp( parm2, "forbid" ) == 0 ) + { + WT_SetThisControl( WTtype, WT_CONTROL_UNCATPERSONAL ); + if ( ( workchar = strchr( buf, '"' ) ) != NULL ) + { + wtsetcatdesc( "ucp", workchar, WT_CONTROL_UNCATPERSONAL, FALSE ); + } + } + } + else if ( strcmp( parm1, "errortext") == 0 ) + { + workint = strlen( &buf[10] ) + 1; /* Len of line past errortext */ + WTerrtext = calloc( 1, workint ); + strcpy( WTerrtext, &buf[10] ); + } + else if ( strcmp( parm1, "errorfile") == 0 ) + { + workint = strlen( &buf[10] ) + 1; /* Len of line past errorfile */ + WTerrfile = calloc( 1, workint ); + strcpy( WTerrfile, &buf[10] ); + } + else if ( strlen(buf) > 2 && buf[0] != '#' ) { + debug(61, 0, "SmartFilter init: unknown config: %s\n", buf); + } + } + fclose(f); /* finished reading configuration file */ + if ( strlen( cntlf ) == 0 ) + { + debug(61, 0, "SmartFilter init: Control List not specified\n"); + smartfilter_free(); + return -1; + } + debug(61, 5, "SmartFilter init: Control List is %s\n", cntlf); + if ( (workint = WT_LoadControlList( WTserv, WTtype, cntlf )) != 0 ) + { + if ( workint == WTERROLD ) + { + debug(61, 1, "SmartFilter init Warning: Control List is Old\n"); + } + else + { + if ( workint == WTERREXPIRED ) + { + debug(61, 0, "SmartFilter init: Control List Expired\n"); + WTexpired = TRUE; + } + else + { + debug(61, 0, "SmartFilter init: Unable to load Control List\n"); + } + smartfilter_free(); + return -1; + } + } + debug(61, 5, "SmartFilter init: Control List loaded OK\n"); + + if ( strlen( dnrfile ) > 0 ) + { + debug(61, 5, "SmartFilter init: Resolved List is %s\n", dnrfile); + + /* If loading DNR file dont do dotted decimal stuff */ + if ( (workint = WT_LoadDomainResolvedList( WTserv, WTtype, dnrfile )) != 0 ) + { + if ( workint == WTERROLD ) + { + debug(61, 1, "SmartFilter init Warning: Resolved List is Old\n"); + WT_ClearThisControl( WTtype, WT_CONTROL_DDD ); + } + else + { + if ( workint == WTERREXPIRED ) + { + debug(61, 0, "SmartFilter init: Resolved List Expired\n"); + } + else + { + debug(61, 0, "SmartFilter init: Unable to load Resolved List\n"); + } + } + } + else + { + WT_ClearThisControl( WTtype, WT_CONTROL_DDD ); + } + } + if ( strlen( sitef ) > 0 ) + { + debug(61, 5, "SmartFilter init: Site List is %s\n", sitef); + if ( wtloadsitelist( WTserv, sitef ) != TRUE ) + { + debug(61, 0, "SmartFilter init: Unable to load Site File\n"); + smartfilter_free(); + return -1; + } + } + + if ( WTerrfile != NULL ) { + if ( (WTcustom_errtext = load_custom_error_file ( WTerrfile )) == NULL ) { + debug(61, 0, "SmartFilter init: unable to load error file %s\n", WTerrfile); + } + debug(61, 5, "SmartFilter init: loaded error file %s\n", WTerrfile); + } + + debug(61, 0, "SmartFilter init: Initialized and enabled\n"); + return 0; +} + +#define SMARTFILTER_DENIAL_HEADER "\ +HTTP/1.0 %d ERROR: Access Denied by Site Administrator\r\nContent-type: text/html\r\n\r\n" + +char categorizedUrl[MAX_LINE]; + +/* check the URL with SmartFilter, returns URL_ALLOWED or URL_DISALLOWED */ +int smartfilter_check_url( int fd, void * data) +{ + icpStateData *icpState = data; + char *wbuf = NULL; + char *errtext; + int retcode; + WT_TYPES WTtmp = WT_NULLPARM; + + if ( WTexpired ) { + if ( ( WTfailcnt == 0 ) || ( (WTfailcnt % 1000 ) == 0 ) ) { + debug(61, 5, "SmartFilter: smartfilter_check_url: Control List has expired\n"); + } + WTfailcnt++; + return URL_ALLOWED; + } + + if(!WTserv) { + /* Init not done, let it go */ + debug(61, 5, "SmartFilter: smartfilter_check_url: not initialized\n"); + return URL_ALLOWED; + } + + debug(61, 5, "SmartFilter: smartfilter_check_url: url is %s\n", icpState->url); + + WTtmp = clientdbGetCats(icpState->acct_addr); + if (WTtmp == WT_NULLPARM) WTtmp = WTtype; /* start with the default policy */ + + if ( ( retcode = WT_CategorizeUrl (WTserv, icpState->url, WTcat, + categorizedUrl, MAX_LINE )) == WTFOUND ) { + /* URL Found in list */ + if ( WT_TestThisControl(WTcat, WT_CONTROL_EXEMPT) == WTISSET ) { + /* Site is exempt */ + debug(61, 5, "SmartFilter: smartfilter_check_url: exempted\n"); + return URL_ALLOWED; + } + if ( WT_CategoryAndCategory( WTtmp, WTcat, WTwork ) != WTISSET ) { + debug(61, 5, "SmartFilter: smartfilter_check_url: not this category\n"); + return URL_ALLOWED; + } + else { + /* We use code 403 for denials; not 400, and not 200. The RFC says: + * RFC 2068, Hypertext Transfer Protocol -- HTTP/1.1, January 1997 + * 403 Forbidden + * The server understood the request, but is refusing to fulfill it. + * Authorization will not help and the request SHOULD NOT be repeated. + */ + icpState->http_code = 403; + + if (WTcustom_errtext != NULL) { + sprintf(tmp_error_buf, + SMARTFILTER_DENIAL_HEADER, + icpState->http_code); + errtext = tmp_error_buf + strlen(tmp_error_buf); + errtext = wtmakeerr (TRUE, WTwork, WTcustom_errtext, errtext); + wbuf = tmp_error_buf; /* send the custom error file */ + } + else { + errtext = wtmakeerr (TRUE, WTwork, WTerrtext, err_message); + wbuf = default_error_msg(icpState->http_code, icpState->method, + icpState->url, fd_table[fd].ipaddr, errtext); + } + debug(61, 5, "SmartFilter: smartfilter_check_url: blocked due to %s\n", errtext); + icpSendERROR(fd, LOG_TCP_DENIED, wbuf, icpState, icpState->http_code); + return URL_DISALLOWED; + } + } + else { + if ( retcode == WTERREXPIRED ) { + WTexpired = TRUE; + debug(61, 5, "SmartFilter: smartfilter_check_url: Control List is Expired\n"); + } + debug(61, 5, "SmartFilter: smartfilter_check_url: allowed\n"); + return URL_ALLOWED; + } +} + +/* stat the file to see how big it is, malloc a buffer that size, read file into buf */ +static char *load_custom_error_file (char *filepath) +{ + int fd; + char *buf; + struct stat filestats; + + if (stat(filepath, &filestats) < 0) { + debug(61, 0, "SmartFilter: Unable to stat custom error file %s\n", filepath); + return NULL; + } + if ((fd = open ( filepath, O_RDONLY)) == -1) { + debug(61, 0, "SmartFilter: Unable to open custom error file %s\n", filepath); + return NULL; + } + debug(61, 5, "SmartFilter: load_custom_error_file: file is %s, size %d\n", + filepath, filestats.st_size); + if ((buf = (char*) malloc(filestats.st_size)) == NULL) { + debug(61, 0, "SmartFilter: failed to malloc %d bytes for error file\n", filestats.st_size); + return NULL; + } + if (read(fd, buf, filestats.st_size) != filestats.st_size) { + debug(61, 0, "SmartFilter: failed to read custom error file\n"); + return NULL; + } + return buf; +} + +/* generate an error screen based on the src ip and err_message */ +static char * default_error_msg(int code, int method, const char *url, const char *client,const char *reason) +{ + sprintf(tmp_error_buf, + SMARTFILTER_DENIAL_HEADER + "ERROR: Access Denied by Site Administrator\n" + "

ERROR: Access Denied by Site Administrator

\n" + "

Sorry, you are not currently allowed to request:\n" + "

    %s
\n" + "

From: %s\n" + "

Reason:
\n" + "

  %s
\n" + "Please contact the administrator\n" + "if you believe this is incorrect.\n" + "

%s\n" + "


\n
Generated by %s/%s@%s
\n\n", + code, categorizedUrl, client, reason, Config.adminEmail, Config.errHtmlText, + appname, version_string, getMyHostname()); + return tmp_error_buf; +} diff -urN squid-1.1.17/src/smartfilter_squid.h squid/src/smartfilter_squid.h --- squid-1.1.17/src/smartfilter_squid.h Thu Jan 1 08:00:00 1970 +++ squid/src/smartfilter_squid.h Wed Jun 3 15:22:12 1998 @@ -0,0 +1,23 @@ + +/* + * Smartfilter Plugin for Squid Proxy Server + * + * + * Copyright 1996-98 - Secure Computing Corp. + * + * This software is covered under terms of a + * non-disclosure agreement. + * + */ + +#include "webtrack.h" + +#define URL_ALLOWED 1 +#define URL_DISALLOWED 2 + +extern void smartfilter_free(); +extern int smartfilter_init(); +extern int smartfilter_check_url(int fd, void *data); +extern void wtsetcats(WT_TYPES *WTtype, char *parm2); +extern char *wtgetcats(WT_TYPES *WTtype, char *buf); + diff -urN squid-1.1.17/src/squid.conf.pre.in squid/src/squid.conf.pre.in --- squid-1.1.17/src/squid.conf.pre.in Fri Aug 8 00:00:00 1997 +++ squid/src/squid.conf.pre.in Tue Jun 2 16:07:29 1998 @@ -2,6 +2,9 @@ # # $Id: squid.conf.pre.in,v 1.93.2.13 1997/08/07 20:38:02 wessels Exp $ # +# +smartfilter_state on +smartfilter_config /usr/local/squid/etc/smartfilter.conf # TAG: http_port # The port number where squid will listen for HTTP client diff -urN squid-1.1.17/src/squid.h squid/src/squid.h --- squid-1.1.17/src/squid.h Sun Jun 1 00:00:00 1997 +++ squid/src/squid.h Tue Jun 2 15:42:52 1998 @@ -64,6 +64,10 @@ #define FD_SETSIZE SQUID_MAXFD #endif +#ifdef SMARTFILTER +#include "smartfilter_squid.h" +#endif + #if HAVE_UNISTD_H #include #endif diff -urN squid-1.1.17/src/stat.c squid/src/stat.c --- squid-1.1.17/src/stat.c Fri Aug 22 03:29:00 1997 +++ squid/src/stat.c Tue Oct 21 14:04:00 1997 @@ -151,7 +151,7 @@ static void proto_newobject _PARAMS((cacheinfo *, protocol_t, int, int)); static void proto_purgeobject _PARAMS((cacheinfo *, protocol_t, int)); static void proto_touchobject _PARAMS((cacheinfo *, protocol_t, int)); -static void server_list _PARAMS((const cacheinfo *, StoreEntry *)); +static void server_list _PARAMS((const cacheinfo *, StoreEntry *, char *extrainfo)); static void squidReadEndHandler _PARAMS((int, int, squid_read_data_t *)); static void squid_get_start _PARAMS((const cacheinfo *, StoreEntry *)); static void statFiledescriptors _PARAMS((StoreEntry *)); @@ -548,11 +548,19 @@ } static void -server_list(const cacheinfo * obj, StoreEntry * sentry) +server_list(const cacheinfo * obj, StoreEntry * sentry, char *extrainfo) { peer *e = NULL; struct _domain_ping *d = NULL; icp_opcode op; + unsigned long http_tot=0,icp_tot=0, + last_http_tot=0,last_icp_tot=0, + last_direct=0,direct=0,reset=0; + + if (extrainfo && *extrainfo=='-') { + extrainfo++; + reset=1; + } storeAppendPrintf(sentry, open_bracket); @@ -561,6 +569,10 @@ for (e = getFirstPeer(); e; e = getNextPeer(e)) { if (e->host == NULL) fatal_dump("Found an peer without a hostname!"); + http_tot+=e->stats.v_fetches; + icp_tot +=e->stats.v_icp; + last_http_tot+=e->last_stats.v_fetches; + last_icp_tot +=e->last_stats.v_icp; storeAppendPrintf(sentry, "\n{%-11.11s: %s/%d/%d}\n", neighborTypeStr(e), e->host, @@ -574,9 +586,16 @@ storeAppendPrintf(sentry, "{PINGS ACKED: %8d %3d%%}\n", e->stats.pings_acked, percent(e->stats.pings_acked, e->stats.pings_sent)); - storeAppendPrintf(sentry, "{FETCHES : %8d %3d%%}\n", + storeAppendPrintf(sentry, "{ICP Vol : %8lu Kb %8lu Kb}\n", + e->last_stats.v_icp + (e->stats.v_icp/1000), + e->stats.v_icp/1000); + storeAppendPrintf(sentry, "{FETCHES : %8d %8d %3d%%}\n", + e->last_stats.fetches + e->stats.fetches, e->stats.fetches, percent(e->stats.fetches, e->stats.pings_acked)); + storeAppendPrintf(sentry, "{FETCH Vol : %8lu KB %8lu Kb}\n", + e->last_stats.v_fetches + (e->stats.v_fetches/1000), + e->stats.v_fetches/1000); storeAppendPrintf(sentry, "{IGNORED : %8d %3d%%}\n", e->stats.ignored_replies, percent(e->stats.ignored_replies, e->stats.pings_acked)); @@ -601,7 +620,30 @@ storeAppendPrintf(sentry, "!%s ", d->domain); } storeAppendPrintf(sentry, close_bracket); /* } */ - } + if (reset) { + e->last_stats.v_icp +=e->stats.v_icp/1000; + e->last_stats.v_fetches+=e->stats.v_fetches/1000; + e->last_stats.fetches +=e->stats.fetches; + e->stats.v_icp=0; + e->stats.v_fetches=0; + e->stats.fetches=0; + } + } + GetLastIntakeVolume(&last_direct,&last_http_tot,&last_icp_tot); + GetIntakeVolume(&direct,&http_tot,&icp_tot,reset); + icp_tot/=1000; + http_tot/=1000; + direct/=1000; + storeAppendPrintf(sentry, "{}\n{}\n"); + storeAppendPrintf(sentry, "{Total Parent volume: ICP: %10lu Kb %10lu Kb}\n", + last_icp_tot+icp_tot, icp_tot); + storeAppendPrintf(sentry, "{ :HTTP: %10lu Kb %10lu Kb}\n", + last_http_tot+http_tot, http_tot); + storeAppendPrintf(sentry, "{Direct Volume : %10lu Kb %10lu Kb}\n", + last_direct+direct, direct); + storeAppendPrintf(sentry, "{Total Cache Volume : %10lu Kb %10lu Kb}\n", + last_icp_tot+icp_tot + last_http_tot+http_tot + last_direct+direct, + icp_tot+http_tot+direct); storeAppendPrintf(sentry, close_bracket); } diff -urN squid-1.1.17/src/stat.h squid/src/stat.h --- squid-1.1.17/src/stat.h Fri Jun 6 00:00:00 1997 +++ squid/src/stat.h Tue Oct 21 14:04:00 1997 @@ -167,7 +167,7 @@ /* get a parameter object */ void (*parameter_get) (const struct _cacheinfo * c, StoreEntry * sentry); - void (*server_list) (const struct _cacheinfo * c, StoreEntry * sentry); + void (*server_list) (const struct _cacheinfo * c, StoreEntry * sentry, char *extrainfo); /* get a total bytes for object in cache */ diff -urN squid-1.1.17/src/store.c squid/src/store.c --- squid-1.1.17/src/store.c Sat Oct 18 07:22:00 1997 +++ squid/src/store.c Tue Oct 21 20:57:00 1997 @@ -990,6 +990,7 @@ store_mem_size += len; mem->data->mem_append(mem->data, data, len); mem->e_current_len += len; + if (e->mem_status != SWAPPING_IN) neighborUpdateVol(&mem->source,0,len); } if (e->store_status != STORE_ABORTED && !BIT_TEST(e->flag, DELAY_SENDING)) InvokeHandlers(e); @@ -1128,6 +1129,8 @@ storeSwapFullPath(e->swap_file_number, NULL)); debug(20, 0, " --> Only read %d bytes\n", mem->e_current_len); + debug(20, 0, " Marking entry for release....\n"); + BIT_SET(e->flag, RELEASE_REQUEST); } e->lock_count++; /* lock while calling handler */ InvokeHandlers(e); /* once more after mem_status state change */ diff -urN squid-1.1.17/src/store.h squid/src/store.h --- squid-1.1.17/src/store.h Fri Aug 8 00:00:00 1997 +++ squid/src/store.h Tue Oct 21 14:04:00 1997 @@ -1,7 +1,4 @@ - - - /* * $Id: store.h,v 1.80.2.9 1997/08/07 22:48:57 wessels Exp $ * @@ -187,6 +184,7 @@ int e_lowest_offset; struct _store_client *clients; int nclients; + struct in_addr source; u_num32 swap_offset; @@ -335,3 +333,4 @@ extern unsigned long store_mem_size; #endif + diff -urN squid-1.1.17/src/tools.c squid/src/tools.c --- squid-1.1.17/src/tools.c Fri Aug 22 03:33:00 1997 +++ squid/src/tools.c Tue Jun 2 17:23:27 1998 @@ -502,10 +502,16 @@ if (geteuid() != 0) return; /* Started as a root, check suid option */ - if (Config.effectiveUser == NULL) + + if (Config.effectiveUser == NULL) { + debug(0,0, "Effective user not defined%s\n", ""); return; - if ((pwd = getpwnam(Config.effectiveUser)) == NULL) + } + if ((pwd = getpwnam(Config.effectiveUser)) == NULL) { + debug(0,0, "Effective UID not valid!%s\n", ""); + debug(0,0, "User %s not valid\n", Config.effectiveUser); return; + } if (Config.effectiveGroup && (grp = getgrnam(Config.effectiveGroup))) { if (setgid(grp->gr_gid) < 0) debug(50, 1, "leave_suid: setgid: %s\n", xstrerror()); diff -urN squid-1.1.17/src/url.c squid/src/url.c --- squid-1.1.17/src/url.c Wed Jul 30 00:00:00 1997 +++ squid/src/url.c Tue Oct 21 21:42:00 1997 @@ -191,6 +191,17 @@ } } +/* ok, i THINK it's the trashed URLs in requets that are killing my squid... */ +/* watch out for em, and scrap em */ + +int valid_url(char *url) +{ unsigned char *p=url; + if (!p) return 0; + while (*p>31 && *p<0x7F) p++; + if (*p) return 0; + return 1; +} + request_t * urlParse(method_t method, char *url) { @@ -205,6 +216,11 @@ int l; proto[0] = host[0] = urlpath[0] = login[0] = '\0'; + if (!valid_url(url)) { + debug(23, 0, "urlParse: eek! toasted URL! %s\n",url); + return NULL; + } + if ((l = strlen(url)) + Config.appendDomainLen > (MAX_URL - 1)) { /* terminate so it doesn't overflow other buffers */ *(url + (MAX_URL >> 1)) = '\0'; @@ -216,9 +232,16 @@ if (sscanf(url, "%[^:]:%d", host, &port) < 1) return NULL; } else { - if (sscanf(url, "%[^:]://%[^/]%s", proto, host, urlpath) < 2) - return NULL; - protocol = urlParseProtocol(proto); + if (sscanf(url, "%[^:]://%[^/]%s", proto, host, urlpath) < 2) + { if (url[0]=='/') url++; + if (sscanf(url, "%[^/]%s", host, urlpath)<1) + return NULL; + if (strncasecmp(host,"www.",4)==0) strcpy(proto,"http"); + else if (strncasecmp(host,"ftp.",4)==0) strcpy(proto,"ftp"); + else if (strncasecmp(host,"gopher.",7)==0) strcpy(proto,"gopher"); + else strcpy(proto,"http"); + } + protocol = urlParseProtocol(proto); port = urlDefaultPort(protocol); /* Is there any login informaiton? */ if ((t = strrchr(host, '@'))) { @@ -304,6 +327,8 @@ request->urlpath); break; } + if (!valid_url(buf)) + debug(23, 0, "urlCanonical: eek! we toasted a URL!\n"); return buf; } diff -urN squid-1.1.17/src/webtrack.h squid/src/webtrack.h --- squid-1.1.17/src/webtrack.h Thu Jan 1 08:00:00 1970 +++ squid/src/webtrack.h Tue Jun 2 15:42:49 1998 @@ -0,0 +1,338 @@ + + /*********************************************************************** + * * + * WebTrack(tm) API Library * + * * + * Copyright 1996-97 - Webster Network Strategies, Inc. * + * * + * * + * * + ***********************************************************************/ + + +/* Define for exports */ +#if defined(WIN32) || defined(WNSNLM) +#define WNS_PUBLIC __declspec(dllexport) +#else +#define WNS_PUBLIC extern +#endif + +/* Linkage Definition */ +#ifdef WNSOS2 +#define WNS_LINKAGE _System +#else +#define WNS_LINKAGE +#endif + +#define WTRESTRICT 1 +#define WTEXEMPT 2 +#define WTNORMAL 3 +#define WTDISABLE 4 +#define WTENABLE 5 +#define WTALLOW 6 +#define WTALLOWOFF 7 +#define WTDISALLOW 8 +#define WTRESOLVE 9 +#define WTISSET 10 +#define WTNOTSET 11 +#define WTFOUND 12 +#define WTFOUNDTRUNC 13 +#define WTNOTFOUND 14 +#define WTNORESTRICT 15 + +/* ERROR CODES */ +#define WTERRBASE 1000 +#define WTERROK 0 +#define WTERRIO 1+WTERRBASE +#define WTERRTRUNC 2+WTERRBASE +#define WTERROPEN 3+WTERRBASE +#define WTERRINVHANDLE 4+WTERRBASE +#define WTERRNULL 5+WTERRBASE +#define WTERRINVCATEGORY 6+WTERRBASE +#define WTERRINVCNTL 7+WTERRBASE +#define WTERRNOSTORE 8+WTERRBASE +#define WTERRINVALID 9+WTERRBASE +#define WTERRINVURL 10+WTERRBASE +#define WTERRNOSITE 11+WTERRBASE +#define WTERROLD 12+WTERRBASE +#define WTERREXPIRED 13+WTERRBASE +#define WTERRDNS 14+WTERRBASE + +/* DATA TYPES */ +typedef void *WT_TYPES; +typedef void *WT_SERVICE; +typedef unsigned char WT_TYPEAREA[32]; +#define WT_NULLPARM ( (void *) 0 ) +typedef unsigned char WT_BIZHOURS[7][24]; +typedef enum { + WT_CAT_SEX = 1, + WT_CAT_DRUGS, + WT_CAT_HATESPEECH, + WT_CAT_CRIME, + WT_CAT_WORTHLESS, + WT_CAT_SALES, + WT_CAT_GAMBLING, + WT_CAT_PERSONAL, + WT_CAT_JOBS, + WT_CAT_SPORTS, + WT_CAT_GAMES, + WT_CAT_HUMOR, + WT_CAT_ALTJRNL, + WT_CAT_ENTERTAIN, + WT_CAT_LIFESTYLE, + WT_CAT_EXTREME, + WT_CAT_CHAT, /* Chat Gateway */ + WT_CAT_INVESTMENTS, /* Investing Information */ + WT_CAT_GNEWS, /* General News */ + WT_CAT_OPINION, /* Politics, Opinion, Religion */ + WT_CAT_DATING, /* Dating and Introduction Service */ + WT_CAT_ART, /* Art and Culture */ + WT_CAT_CULT, /* Cult/Occult */ + WT_CAT_NEWSSITE, /* UseNet News Site on Web */ + WT_CAT_SELFHELP, /* Self Help */ + WT_CAT_TRAVEL, /* Travel */ + WT_CAT_NONESSENTIAL /* Site Defined */ + } WT_CATEGORY_SPECIFIC; + +typedef enum { + WT_CONTROL_EXEMPT = 1, + WT_CONTROL_RESTRICT, + WT_CONTROL_DDD, + WT_CONTROL_UNCATPERSONAL, + WT_CONTROL_NEWSBACK, + WT_CONTROL_UNAPPROVED, + WT_CONTROL_RESTRICTEDWORD, + WT_CONTROL_RESTRICTEDSEARCH, + WT_CONTROL_LOCAL, + WT_CONTROL_SITE, + WT_CONTROL_PATH, + WT_CONTROL_URL, + WT_CONTROL_BIZHOURS, + WT_CONTROL_CGI, + WT_CONTROL_RESOLVE, + WT_CONTROL_RESTRICTEDFILE + } WT_CONTROL_SPECIFIC; + +/* + * Defines for WT_TypeToBit function + */ +#define WT_BIT_NONESSENTIAL 0x1 +#define WT_BIT_ALTJRNL 0x2 +#define WT_BIT_ART 0x4 +#define WT_BIT_CHAT 0x8 +#define WT_BIT_CRIME 0x10 +#define WT_BIT_CULT 0x20 +#define WT_BIT_DATING 0x40 +#define WT_BIT_ENTERTAIN 0x80 +#define WT_BIT_EXTREME 0x100 +#define WT_BIT_GAMES 0x200 +#define WT_BIT_GNEWS 0x400 +#define WT_BIT_HATESPEECH 0x800 +#define WT_BIT_HUMOR 0x1000 +#define WT_BIT_DRUGS 0x2000 +#define WT_BIT_INVESTMENTS 0x4000 +#define WT_BIT_JOBS 0x8000 +#define WT_BIT_WORTHLESS 0x10000 +#define WT_BIT_GAMBLING 0x20000 +#define WT_BIT_SALES 0x40000 +#define WT_BIT_LIFESTYLE 0x80000 +#define WT_BIT_PERSONAL 0x100000 +#define WT_BIT_OPINION 0x200000 +#define WT_BIT_SELFHELP 0x400000 +#define WT_BIT_SEX 0x800000 +#define WT_BIT_SPORTS 0x1000000 +#define WT_BIT_TRAVEL 0x2000000 +#define WT_BIT_NEWSSITE 0x4000000 + + + + /* Initialize environment */ + WNS_PUBLIC WT_TYPES WNS_LINKAGE WT_Init(); + + /* Free environment */ + WNS_PUBLIC int WNS_LINKAGE WT_FreeService( WT_SERVICE ); + + /* Set IP Address Option On */ + WNS_PUBLIC int WNS_LINKAGE WT_SetIPOption( WT_SERVICE , int); + + /* Set Notify Old List on caturl Option On */ + WNS_PUBLIC int WNS_LINKAGE WT_SetOldOption( WT_SERVICE, int); + + /* Init Category Flags Object storage */ + WNS_PUBLIC void WNS_LINKAGE WT_InitTypeArea( void * ); + + /* Obtain Category Flags Object */ + WNS_PUBLIC WT_TYPES WNS_LINKAGE WT_AllocateTypes( void ); + + /* Free Category Flags Object */ + WNS_PUBLIC int WNS_LINKAGE WT_FreeTypes( WT_TYPES ); + + /* Clear The Category Flags Object */ + WNS_PUBLIC int WNS_LINKAGE WT_ClearTypes( WT_TYPES ); + + /* Convert Category Flags Category info to bit string */ + WNS_PUBLIC unsigned long WNS_LINKAGE WT_TypeToBit( WT_TYPES ); + + /* Clear A Specific Category Flags Indicator */ + WNS_PUBLIC int WNS_LINKAGE WT_ClearThisCategory( WT_TYPES, + WT_CATEGORY_SPECIFIC ); + + /* Set All Category Flags Indicator */ + WNS_PUBLIC int WNS_LINKAGE WT_SetAllCategory( WT_TYPES ); + + /* Set A Specific Category Flags Indicator */ + WNS_PUBLIC int WNS_LINKAGE WT_SetThisCategory( WT_TYPES, + WT_CATEGORY_SPECIFIC ); + + /* Test A Specific Category Flags Indicator */ + WNS_PUBLIC int WNS_LINKAGE WT_TestThisCategory( WT_TYPES, + WT_CATEGORY_SPECIFIC ); + + /* Test A Set of Specific Category Flags Indicators */ + WNS_PUBLIC int WNS_LINKAGE WT_CategoryAndCategory( WT_TYPES, + WT_TYPES, + WT_TYPES ); + + /* Set All Control Flags Indicator */ + WNS_PUBLIC int WNS_LINKAGE WT_SetAllControl( WT_TYPES ); + + /* Clear A Specific Control Flags Indicator */ + WNS_PUBLIC int WNS_LINKAGE WT_ClearThisControl( WT_TYPES, + WT_CONTROL_SPECIFIC ); + + /* Set A Specific Control Flags Indicator */ + WNS_PUBLIC int WNS_LINKAGE WT_SetThisControl( WT_TYPES, + WT_CONTROL_SPECIFIC ); + + /* Test A Specific Control Flags Indicator */ + WNS_PUBLIC int WNS_LINKAGE WT_TestThisControl( WT_TYPES, + WT_CONTROL_SPECIFIC ); + + /* Test A Set of Specific Control Flags Indicators */ + WNS_PUBLIC int WNS_LINKAGE WT_ControlAndControl( WT_TYPES, + WT_TYPES, + WT_TYPES ); + + /* Test A Set of Specific Control Flags Indicators */ + WNS_PUBLIC int WNS_LINKAGE WT_ControlOrControl( WT_TYPES, + WT_TYPES, + WT_TYPES ); + + /* Check URL against WebTrack Control List */ + WNS_PUBLIC int WNS_LINKAGE WT_CategorizeUrl( WT_SERVICE, + char *, + WT_TYPES, + char *, + int + ); + + /* Set Shared Memory Routine Addresses */ + WNS_PUBLIC int WNS_LINKAGE WT_SharedMemRoutines( WT_SERVICE, + void *, + void *(*getroutine)( void *, char *, long), + void (*freeroutine)( void *, char *, void *) + ); + + /* Set Mapped File Routine Addresses */ + WNS_PUBLIC int WNS_LINKAGE WT_MappedFileRoutines( WT_SERVICE, + void *, + void *(*maproutine)( void *, char *, char *), + void (*unmaproutine)( void *, char *, void *) + ); + + /* Load WebTrack Control List */ + WNS_PUBLIC int WNS_LINKAGE WT_LoadControlList( WT_SERVICE, + WT_TYPES, + char * + ); + + /* Load Domain Resolved Control List */ + WNS_PUBLIC int WNS_LINKAGE WT_LoadDomainResolvedList( WT_SERVICE, + WT_TYPES, + char * + ); + + /* Get WebTrack Control List Status*/ + WNS_PUBLIC int WNS_LINKAGE WT_ControlListStatus( WT_SERVICE ); + + /* Get WebTrack Control List Age*/ + WNS_PUBLIC int WNS_LINKAGE WT_ControlListAge( WT_SERVICE , long *); + + /* Get WebTrack Resolved Control List Age*/ + WNS_PUBLIC int WNS_LINKAGE WT_ResolvedListAge( WT_SERVICE , long *); + + /* Get WebTrack Resolved Control List Status*/ + WNS_PUBLIC int WNS_LINKAGE WT_ResolvedListStatus( WT_SERVICE ); + + + /* Update WebTrack Site Specific Control List */ + WNS_PUBLIC int WNS_LINKAGE WT_UpdateSiteList( WT_SERVICE, + char *, + WT_TYPES + ); + + + /* WebTrack Environment Built-In Function Calls */ + + /* Check URL against WebTrack Environment */ + WNS_PUBLIC int WNS_LINKAGE WT_Env_UrlCheck( WT_SERVICE, + char *, + char *, + WT_TYPES, + WT_TYPES, + WT_TYPES + ); + + /* Set WebTrack Business Hours Option */ + WNS_PUBLIC int WNS_LINKAGE WT_Env_SetBusinessHours( WT_SERVICE, + WT_BIZHOURS * + ); + + /* Set WebTrack Category Restrictions */ + WNS_PUBLIC int WNS_LINKAGE WT_Env_RegularRestrictions( WT_SERVICE, + WT_TYPES, + int + ); + + /* Set WebTrack Non-Business Hours Category Restrictions */ + WNS_PUBLIC int WNS_LINKAGE WT_Env_NonBusinessRestrictions( WT_SERVICE, + WT_TYPES, + int + ); + + /* Set WebTrack News Back Door Processing Option */ + WNS_PUBLIC int WNS_LINKAGE WT_Env_NewsBackDoor( WT_SERVICE, + char *, + char *, + int + ); + + /* Set WebTrack Search Site Processing Option */ + WNS_PUBLIC int WNS_LINKAGE WT_Env_SearchSite( WT_SERVICE, + char *, + char *, + int + ); + + /* Set WebTrack Restricted Search Word Processing Option */ + WNS_PUBLIC int WNS_LINKAGE WT_Env_RestrictedSearchWord( WT_SERVICE, + char *, + WT_TYPES, + int + ); + + /* Set WebTrack Exempted Domain Processing Option */ + WNS_PUBLIC int WNS_LINKAGE WT_Env_ExemptedDomain( WT_SERVICE, + char *, + int + ); + + /* Set WebTrack Forbidden File Type Processing Option */ + WNS_PUBLIC int WNS_LINKAGE WT_Env_ForbidFileType( WT_SERVICE, + char *, + int + ); + + /* Parse a URL */ + WNS_PUBLIC int WNS_LINKAGE WT_ParseUrl( char *, char *); +