Você está na página 1de 153

UNIVERSIDADE IBIRAPUERA CURSO DE CINCIA DA COMPUTAO PROJETO SQUID Trabalho apresentado Universidade Ibirapuera para obteno do ttulo de Bacharel

l em Cin cia da Computao Cristiano F. Reis 574132 Gerson Raimundo 608415 Gilberto T. Do Carmo 568508 So Paulo 2006

Dedicatria Este trabalho foi desenvolvimento em conjunto de trs bons amigos de faculdade que se conheceram e tornaram-se bom amigos, e dedicam todo o seu contedo para os seu s Familiares. Agradecimentos Agradecemos ao nosso querido orientador Cristiano Toniolo e Fabio Cabrini que no s indicou o melhor caminho a ser seguido, e colocou a disposio toda a sua ateno e a toda comunidade Linux que desenvolveu este grande projeto. Resumo Este trabalho apresenta um estudo a respeito dos servidores Proxy, e do desempen ho do Squid, um servidor Proxy Livre, que possui caractersticas que o tornam um d os melhores. feito um detalhamento a respeito de sua implementao e como ele usado como servidor de Proxy e sistemas para esta finalidade. Apesar das operaes do mesm o, (contm um problema em especifico que o seu desempenho no recebimento de um nmer o elevado de requisies). Este o objetivo deste trabalho, onde apresentamos solues pa ra a resoluo desta deficincia. Palavras-Chaves: Proxy, Squid, algoritmos de ordenao e busca.

Abstract This work presents a study regarding the Proxy servers, in of the performance of the Squid, Free a Proxy server, that possesss characteristics that become it on e of the best ones. A detailing regarding its implementation is made and as it i s used as serving of Proxy and systems for this purpose. Despite the operations of exactly, (it contains a problem in I specify that it is its performance in th e act of receiving of a high number of solicitations). This is the objective of this work, where we present solutions for the resolution of this deficiency. Keywords: Proxy, Squid, algorithms of ordinance and search.

Sumrio 1 Introduo........................................................................ ...........................................................01 1.1 Objetivo...... ................................................................................ ..................................... 03 1.2 Estrutura.......................... ................................................................................ ............... .03 Captulo 2 Proxy.............................................. ............................................................................. 04 2.1 - Origem do Proxy.......................................................... .................... ............................04 2.2 - Tipos de Proxy......... ................................................................................ ..................... .05 2.2.1 Squid........................................... .............................................................................. . 06 2.2.2 - Delegate............................................................. .................. ...................................07 2.2.3 Oops.............. ................................................................................ ............................ .08 2.2.4 Dansguardian............................. ............................................................................... .09 2.3 - Principais Caractersticas dos Proxy.................................... ......................................... .10 2.3.1 - Proxy Transparente........ ................................................................................ ......... .10 2.3.2 - Proxy Controlado.......................................... .......................................................... 11 2.4 - Proxy Transp arente X Proxy Controlado....................................................... ............... 11 2.5 2.4.1 - Vantagens do Proxy Transparente.................. ...................................................... 11 2.4.2 - Desvantagens d o Proxy Transparente................................. ........................... ........12 2.4.3 - Vantagens do Proxy Controlado................................ ................................................. 13 2.4.4 - Desvantagens do Pro xy Controlado................................................................... ........ 13 2.5 - Arquitetura do Proxy.......................................... ........................................................... 13 2.5.1 Cache...... ................................................................................ ................................... 13 2.5.2 Autenticao........................... ................................................................................ ... 14 2.5.3 - Listas de controles de acesso.................................... .......... ...................................14 2.5.4 - Proxy para SSL.......... ................................................................................ ................. 14 Captulo 3 Squid............................................. .............................................................................. 1 5 3.1 - Caractersticas do Proxy Squid............................................ ......................................... 16 3.1.1 - Restries de acesso........... ................................................ ................................ ....16 3.1.2 - Arquivo de configurao.............................................. .............................................. 18 3.1.3 - Funo do Proxy squid..... ................................................................................ .......... 18 3.1.4 - Progresso do Squid........................................ ............................................................. 19 3.1.5 - Tipos d e protocolos.................................................................... ................................ 19 3.1.6 - Proxy transparente no Squid......... ............................................................................. 19 3.1.7 - Listas de controle de acesso........................................... ............................................ 20 3.2 - Squid como servidor....... ................................................................................ ............... 24 3.3 - Estrutura de Hardware.................................. ................................... ..........................25 3.4 Tags........ ................................................................................ ....................................... 26 3.5 - Referncias de conexo............. ................................................................................ .... 26 3.6 Vantagens...........................................................

........................................................... 28 Captulo 4 - Conhec endo Algumas Solues............................................................... .................. 29 4.1 Configurao.............................................. ..................................................................... 29 4.2 Hdp arm............................................................................. .............................................. 29 4.3 - Banco de Dados.......... ................................................................................ ..................... 29 4.4 - Alterao do Cdigo fonte.............................. ................................................................. 30 4.5 - Compi lao do Kernel..................................................................... ................................ 30 Captulo 5 - Aplicando a soluo escolhida........ ......................................... ..............................31 5.1 A Escolha....................................................................... .................................................. 31 5.2 - Desenvolvendo a Soluo. ............................................................... ................. ...........31 5.3 - Detalhamento do processo.................................... ........................................................... 32

5.4 - Introduo ao Perl............................................................ ............................................. 34 5.4.1 - Caractersticas do Perl.. ................................................................................ .... 35 5.5 - Introduo ao PostgreSQL.............................................. ...............................................36 5.6 - Outras solues aplicadas... ................................................................................ ........... 37 5.6.1 - HDparm................................................... ............................. .........................37 5.6.2 Kernel........... ................................................................................ .................. 39 Captulo 6 Concluso.......................................... ..........................................................................42 Lis ta de anexos.................................................................... ............................................................. 43 Referncias...... ................................................................................ ................................................. 49 1 - Introduo A popularizao da Web1 tem provocado srios problemas de desempenho nos acessos Inter net, de forma que a reduo do tempo tem se tornado um fator extremamente relevante. O nmero de usurios que se conectam na rede cresce de forma acentuada. O tempo par a se recuperar um documento Web depende de determinados fatores (tipo de conexo, tamanho do documento, localizao do mesmo). Para minimizar as conseqncias deste cresc imento, alguns mtodos podem ser adotados como a utilizao de um servidor mais rpido, alterao dos meios fsicos (Cabos, Roteadores, Switches, etc.) de forma que se aument e a banda. Contudo, isto alm de no ser economicamente vivel, pode no resolver o prob lema, uma vez que so numerosos os fatores que envolvem uma nica transao Web. Alterna tivas como o cache de pginas Web, espelhamento de arquivos entre outros tm sido ap licados para resolver determinadas situaes inerentes rede. O procedimento de impla ntao de um sistema de cache de navegao que armazene localmente objetos como pginas HT ML2 (HyperText Markup Language), imagens e arquivos da Internet, podem melhorar a qualidade do servio fornecido aos usurios. Os servidores de Proxy ajudam a dimin uir de forma significativa o tempo mdio de acesso a pginas e a transferncia de arqu ivos, porque muitos deles (pginas Web, arquivos, fotos, etc.) so requisitados mais de uma vez, entretanto, exceto na primeira vez estas requisies so feitas remotamen te, ou seja, as pginas so carregadas direto do servidor que esto hospedadas, caso c ontrrio s requisies so atendidas de forma local. 1 2 Web: Rede de computadores na Internet que fornece informao em forma de hipertexto. HTML: um dispositivo de acesso rpido, interno a um sistema, que serve de interme dirio entre um operador de um processo e o dispositivo de armazenamento. De uma forma geral os visualizadores de pginas Web conhecidos como browsers fazem conexo direta com os servidores remotos. Entretanto, eles podem ser configurados para se conectar a um servidor Proxy. Assim, quando um usurio requisitar uma pgin a, o browser primeiramente verifica seu cache local. Se a pgina URL1 no encontrada , ele a requisita para o servidor Proxy local. Se este tm a cpia e ela no expirou, ele a retorna imediatamente, caracterizando desta forma o conceito de cache hit. Caso esta no esteja no cache, ele entrar em contato com o servidor remoto e far a transferncia, mantendo uma cpia opcional em seu cache e enviando uma cpia para a mqu ina do usurio, neste caso, haver o que chamamos de conceito cache miss. Uma das fu nes do Proxy denominada de Filtro. Este filtro usado para permitir ou negar o aces so Internet ou a determinados sites, ou seja, controle de contedo. Administradore s podem criar regras conforme suas polticas de segurana para filtrar requisies basea das no endereo IP 2

(Internet Protocol) do cliente, domnios, redes e URL do objeto requisitado, bloqu eando assim requisies consideradas imprprias a poltica adotada. Tais funcionalidades so usadas principalmente em escolas e em organizaes que utilizam o critrio de permi sso para o acesso a pginas que realmente sejam de seu interesse. O filtro podem co nter regras simples baseados em uma lista de pginas Web, bem como conter regras m ais complexas. 1 2 URL: o endereo de um recurso, disponvel em uma rede; seja a Internet, ou uma rede corporativa ou uma intranet. IP: um protocolo usado entre duas mquinas em rede pa ra encaminhamento dos dados. 1.1 - Objetivo O objetivo deste trabalho a implementao e a otimizao do Proxy Squid que apesar de fu ncionar de uma forma completa e atender determinadas necessidades apresenta um f ator relevante, que o seu desempenho quanto ao processamento de requisies ACL 1 (A ccess Control List). O seu desempenho se torna crtico quando a quantidade de usuri os conectados ao Proxy grande e ao carregar uma black-list muito grande que leva ele a travar, a partir desta quantidade ele passa a consumir um valor considerve l de memria, e para compensar tal situao, necessrio disponibilizar um computador mai s potente o que acaba onerando os custos significativamente, pois a cada demanda de processos necessrio ajustar o hardware. O Squid possue esta deficincia, o que estamos propondo minimizar esta situao aplicando solues que so a melhora do programa do Squid como um front-end ideal para a soluo e tambm melhorando a entrada e sada do disco rgido, e aplicando uma configurao ideal para o hardware diretamente no kerne l influenciando diretamente no desempenho do mesmo e diminuindo a sobrecarga da memria efetuada durante o trabalho do Proxy. 1.2 - Estrutura Para atingir este objetivo o trabalho foi estruturado da seguinte forma: Captulo 2: Proxy; Captulo 3: Squid; Captulo 4: Conhecendo algumas possveis solues; Captulo 5: Aplicando a soluo escolhida. 1 ACL: normalmente uma lista de princpios com os tipos de acesso definido para cada usurio ou grupo. Captulo 2 - Proxy 2.1 - Origem do Proxy

O Proxy surgiu da necessidade de conectar uma rede local Internet atravs de um co mputador da rede que compartilha sua conexo com as mquinas da rede. Conforme Peter (Thoeny 2002), se considerarmos que a rede local uma rede interna e a Internet uma rede externa, podemos dizer que o Proxy quem permite que outras mquinas tenha m acesso externo, ou seja, a conexo com a Internet. Geralmente, mquinas da rede in terna no possuem endereos vlidos na Internet, primeiro pelo fato da segurana nas red es privadas e tambm devido falta de IPs vlidos, portanto, no tm uma conexo direta com a Internet. Assim, toda solicitao de conexo de uma mquina da rede local para um host da Internet direcionada ao Proxy, este, por sua vez, realiza o contato com o ho st desejado, repassando a resposta da solicitao para a mquina da rede local. comum termos o Proxy como conexo direta com a Internet. Vejamos um exemplo de um esquem a de servidor Proxy. Figura 1. Figura 1 - Compartilhamento de Internet utilizando Proxy (Reis, 2006). 2.2 - Tipos de Proxy Existem vrios softwares diferentes com as caractersticas de Proxy, alguns mais esp ecializados em somente alguns protocolos, outros com mais funcionalidades, como filtragem de controle de contedo e firewall, outros mais especializados em otimiz ao de cache em RAM 1 ou disco rgido. Dentre os vrios Proxy existentes para o sistema operacional Linux, com pelo menos suporte HTTP2, HTTPS3 e FTP4, conforme citado por Peter Thoeny (2002) destaca-se Squid, Delegate, Dansguardian, Oops entre ou tros. 1 2 RAM: Randomic Access Memory HTTP: um protocolo da camada de "Aplicao" do modelo OS I, utilizado para transferncia de dados na Internet. 3 HTTPS: um protocolo da cam ada de "Aplicao" do modelo OSI, com implementao de segurana. 4 FTP: uma forma bastant e rpida e verstil de transferir arquivos, sendo uma das mais usadas na internet. 2.2.1 - Squid Foi originado de um projeto denominado Harvest entre o governo americano e a Uni versidade de Colorado. Atualmente o Proxy mais popular e mais usado como control e de

contedo, na qual possui vrios programadores como desenvolvedores do projeto pelo m undo. geralmente disponibilizado por padro pela maioria dos sistemas operacionais Linux, fornecendo todas as funcionalidades de um Proxy comum. Permite atuar com o Proxy para os protocolos HTTPS, HTTP, FTP e Gopher 1. Para outros protocolos c omo correio eletrnico (SMTP2 e POP3) e ICQ4. 1 Gopher: um protocolo de redes de computadores que foi desenhado para indexar rep ositrios de documentos na Internet. 2 SMTP: o padro de fato para envio de e-mail a travs da Internet. 3 POP: um protocolo utilizado no acesso remoto a uma caixa de correio eletrnico. 4 ICQ: um programa de comunicao instantnea pela Internet. 2.2.2 - Delegate Este tambm um Proxy interessante, de autoria de Yutaka Sato (2006), o Delegate um Proxy Server 5multiplataforma com relays e vrios protocolos de aplicao em TCP/IP o u em UDP/IP, incluindo o HTTP, FTP, Telnet1, NNTP2, SMTP3, IMAP4, LPR5, LDAP6, I CP7, DNS8, SSL9 e Socks10. O Delegate interliga uma comunicao entre usurios e clien tes, onde uma comunicao direta impossvel, ineficiente, ou inconveniente, conforme S ato (2006). 1

Telnet: um protocolo cliente-servidor de comunicaes usado para permitir a comunicao entre computadores ligados numa rede, baseado em TCP. 2 NNTP: um protocolo da in ternet para grupos de discusso da chamada usenet. 3 SMTP: um protocolo relativame nte simples, baseado em texto simples, em que um ou vrios destinatrios de uma mens agem so especificados, sendo depois a mensagem transferida. 4 IMAP: um protocolo de gerenciamento de correio eletrnico superior em recursos ao POP3 5 LPR: a porta de impresso em Linux. 6 LDAP: Servio de rede que disponibiliza integrao de senhas p ara qualquer servio. 7 ICP: Uma Infra-Estrutura de Chaves Pblicas um rgo ou inciativ a pblica ou privada para a organizao de uma estrutura de emisso de chaves pblicas. 8 DNS: um sistema de gerenciamento de nomes hierrquico. 9 SSL: um protocolo criptog rfico que provem comunicao segura na Internet para coisas como e-mail, navegao por pgi as, e outros tipos de transferncia de dados 10 Socks: um protocolo de internet qu e permite que aplicaes cliente-servidor usem transparentemente o servio de uma rede ao firewall.

2.2.3 - Oops um Proxy mais simples que os anteriores. Surgiu como uma alternativa ao Squid. O ops leve, embora, trata-se de um poderoso Proxy com cache. Suas principais carac tersticas conforme (Cipriano 2006), : HTTP/1.1 (ainda sem conexes persistentes) e F TP; Ele est pronto para servir pedidos imediatamente aps iniciado; Armazenamentos em disco so checados em segundo plano, enquanto servem pedidos diretamente da red e; Reconfigurao limpa em Sighup1 e sem sesses quebradas, novas configuraes aplicadas a novas conexes; Arquivo de configurao e ACLs fceis de ler e entender; Controle de l rgura de banda; Diversos tipos de mdulos existem como gerao de logs, acesso, sada, r elato de erros, filtragem de URL, etc; Objetos so armazenados em arquivos grandes e sem esquema de objeto por arquivo.

Esses arquivos grandes podem ser dispositivos como (/dev/hda). 1 Sighup: Define-se como a reinicializao de um processo sem a necessidade de reinici ar a mquina. 2.2.4 - Dansguardian uma ferramenta capaz de filtrar acessos a Internet com base em diferentes critrio s, possui filtros com as seguintes caractersticas, conforme descrito por Silva (2 006). Filtros de domnios ou URLs com um desempenho visivelmente superior a outras ferramentas; Filtros baseados em frases associadas pornografia ou consideradas i napropriadas; Filtros por figuras ou por tipo de contedos (MIME1); Filtros por ex tenso de arquivos, como: .exe, .dll, .scr, etc; Filtro com caractrsticas em que po ssvel bloquear ou limitar upload na Internet. A ferramenta difere da maioria disp onvel no mercado pelo fato de no funcionar apenas como filtro de URL, mas tambm com o um efetivo filtro de contedos de pginas Web. Pois, faz uma varredura do contedo d e cada pgina acessada por seus usurios e no somente uma liberao ou proibio do nome do ite ou da URL acessada. Este filtro de contedo funciona em conjunto com qualquer Proxy, podendo ser instalado em sistemas operacionais Linux, FreeBSD, OpenBSD, N etBSD, Mac OSX e Solaris. O Dansguardian no tem caractersticas de Proxy, portanto obrigatrio o uso de um servidor Proxy para que a ferramenta seja implementada, em bora ele tenha sido citado neste trabalho por ser relevante suas funes. Nas solues c omumente encontradas no mercado, o filtro de contedo recebe as requisies do navegad or do usurio, aplica as restries estabelecidas ou as excees configuradas e, em seguid a, passa a requisio para o Proxy. Este faz o seu papel que a intermediao entre o cli ente e o servidor a ser acessado. No processamento interno de arquivos contendo proibies e excees, existe uma ordem prestabelecida. 1 MIME: uma norma da Internet para o formato das mensagens de correio eletrnico . Apesar do Dansguardian no ter caractersticas de Proxy o mesmo foi citado apenas pa ra fim de conhecimento, uma vez que o objetivo deste trabalho demonstrar os dive rsos tipos de aplicaes para otimizao do Proxy Squid, procurando a melhor soluo para de sempenho do mesmo tornando-o to eficiente quanto o Dansguardian no processo de fi ltro de contedos, pois quando o Squid utiliza uma base muito extensa (Black-list1 ), consequentemente passa a utilizar muita memria e se torna lento demais sobreca rregando consideravelmente a rede. 2.3 - Principais Caractersticas dos Proxy Um exemplo muito comum de compartilhamento de Internet baseado em um servidor Pr oxy com duas interfaces de rede, geralmente um modem e uma interface Ethernet, s endo que a interface do modem a interface de sada para Internet, enquanto a inter face de rede, a interface de acesso s mquinas da rede local. O compartilhamento de Internet apresentado se refere ao

servio bsico de um Proxy. Mas um bom Proxy deve ainda prover vrias outras funcional idades complementares conforme Peter Thoeny (2002). Existem duas caractersticas p rincipais de Proxy, na qual so definidos, como Proxy Transparente e Proxy Control ado, conforme Martins (2006).

2.3.1 - Proxy Transparente Nele simplesmente feito um encaminhamento de pacotes vindos da Internet para uma mquina que esta na rede interna. Com o Proxy transparente no preciso configurar o navegador como por exemplo o Internet Explorer ou o Firefox, facilitando a admi nistrao da rede. Isto realizado atravs de configuraes no roteador ou no firewall padr da rede local, de forma que toda solicitao de trfego externo direcionada para o Pr oxy. Assim, o Proxy funciona de forma transparente para o usurio, sem necessidade de configurao. 1 Black-list: Arquivo contendo nome de sites proibidos. 2.3.2 - Proxy Controlado Esta uma caracterstica dos softwares especializados em agir como servidores Proxy , como o prprio Squid. Eles possuem certas opes que o Proxy Transparente para facil itar o controle de quem pode ou no utilizar o Proxy, e a sua configurao deve estar como padro em todos os browser com o IP do servidor Proxy. Conforme Thoeny (2002) , com ele tambm possvel implementar o controle de contedo com base em ACL (Access C ontrol List), ou seja listas de acesso previamente definidas. 2.4 - Proxy Transparente X Proxy Controlado Vantagens e desvantagens esto relacionadas com o seu tipo de caso, onde em uma si tuao hipottica voc poder ter uma empresa em que os administradores preferem colocar o IP do Proxy em cada mquina e tambm pode acontecer que em certos casos o administr ador de departamento de informtica deseja no colocar nenhuma informao nos navegadore s dos usurios, como um administrador de rede, vai ter que decidir qual tipo de Pr oxy utilizar e qual o melhor para a situao, vo existir casos em que um Proxy Transp arente vai oferecer o suficiente para as regras de certa empresa e vo existir cas os em que iro ser necessrio as funes que somente um Proxy controlado pode oferecer.

2.4.1 - Vantagens do Proxy Transparente mais simples de ser configurado quando j est habilitado no Kernel, quando no est hab ilitado no kernel o mesmo deve ser reinstalado com o suporte ativo para que seja usado. Programas como ICQ funcionam plenamente com ele e no precisa que as mquina s clientes sejam configuradas. Afinal de contas, qual a idia de Proxy transparent e? Sabemos que a traduo de Proxy para nossa lngua intermedirio, logo o intermedirio t ransparente o Proxy onde no necessrio a configurao do navegador. Tambm possvel at o Proxy transparente fazer com que todo o acesso do cliente Internet fique subme tido ao Proxy, ou seja, o cliente forado a utilizar o Proxy. Entre outras vantage ns, conforme citado por Martins (2006): No necessrio a configurao do navegador do cl iente, isto sem dvida bem vindo

em uma grande rede; Como j dito anteriormente, o uso do Proxy transparente fora o cliente a passar pelo Proxy; Com a configurao do Proxy transparente, todos os serv ios ficam disponveis aos seus clientes, lembrando que o Squid s trabalha com os pro tocolos HTTP e FTP. Configurado o Proxy transparente, voc pode fazer uso de outro s servios como: SSH, Telnet, E-mail, etc; Outro recurso do Proxy transparente que ele funciona como uma maneira de bloquear acesso evitando que aqueles usurios ma is espertos retirem as definies do Proxy de dentro do navegador, podendo assim vis itar sites proibidos; Com o Proxy transparente todas as requisies feitas porta 80 so automtica redirecionadas para a porta do Squid, e assim fica virtualmente impos svel de sair para a Internet. 2.4.2 - Desvantagens do Proxy Transparente Possui menos recursos que um Proxy Controlado. Precisa de configuraes no Kernel e, em alguns casos, necessria a recompilao do Kernel do sistema. No possui nenhuma seg urana de acesso e no possui um sistema de (caching), o que o torna mais lento em u ma rede. 2.4.3 - Vantagens do Proxy Controlado Com ele voc pode utilizar listas de controles de acesso (ACL s) para controlar qu em usa e quem no usa o seu Proxy, pode ser utilizado para uso com SSL, pode servi r para liberao de Internet mediante autenticao do usurio e, principalmente, possui um sistema de (caching), possuindo um desempenho na rede geralmente melhor, confor me Lima. 2.4.4 - Desvantagens do Proxy Controlado Alguns programas como ICQ e o protocolo SMTP no funcionam muito bem com ele. E ou tra particularidade a sua falta de segurana quanto estabilidade da conexo, pois qu alquer usurio das maquinas clientes podem remover as configuraes de Proxy, no entan to no ser possvel a sua navegao. 2.5 - Arquitetura do Proxy 2.5.1 - Cache Conforme descrito por Thoeny (2002) o Proxy permite armazenar nele prprio as pgina s visitadas com mais freqncia, ou seja, quando um usurio solicita um site na Intern et, o Proxy armazena o seu contedo em cache, juntamente com a sua data. Caso o us urio, depois de um certo tempo, solicite-a novamente, o Proxy obtm a data da pgina remota e caso no seja mais atual que a pgina que est em cache, este fornece para o cliente a pgina em cache, sem a necessidade de baixar novamente a pgina solicitada . Esta funcionalidade aumenta bastante o desempenho de acesso s pginas, uma vez qu e o acesso em cache local muito mais rpido que o acesso remoto.

2.5.2 - Autenticao Ao requisitar uma pgina ser exibido uma caixa solicitando ao usurio um login e uma senha, e com base nesta autenticao de regras estabelecidas pelas ACL o usurio poder ter ou no acesso a pgina requisitada. 2.5.3 - Listas de controles de acesso Tambm conhecidas como ACL s, permite que o administrador restrinja o acesso a det erminados sites baseados em critrios estipulados em listas de controles. Os critri os conforme descrito por Thoeny (2002) podem ser expressos em regras baseadas no login, palavras-chave na URL, palavras-chave no contedo do site, horrio de acesso , etc. 2.5.4 - Proxy para SSL Permite que um navegador e um servidor Web estabelea uma comunicao segura para real izar transaes. O SSL uma camada de criptografia do protocolo HTTP, por isto quando utilizados em conjunto chamado tambm de HTTPS (HTTP seguro). Capitulo 3 - Squid O Squid caracteriza-se em um software especializado, que faz operao de Proxy de We b e FTP, completamente livre e com excelente suporte para operao em servidores Lin ux. Com o Squid voc pode instalar um servidor Linux com acesso Internet, e fazer com que outras mquinas clientes (usando sistemas operacionais como: Linux, Window s ou outros) acessem pginas Web e sites FTP atravs do servidor Linux, as mquinas cl ientes precisam somente estar com os seus (gateway) padres apontados para o servi dor Proxy. O Squid d acesso a servios como HTTP, HTTPS e FTP. Mesmo em redes onde seria possvel instalar IP (masquerading), muitos administradores optam por limita r o acesso direto das mquinas internas Web, por vrias razes, entre as quais se incl uem a segurana e o controle de acesso (atravs de mecanismos de restrio e de Log). O recurso que mais atrai ateno no Squid o cache de pginas. Como em geral o Link entre as mquinas clientes e o servidor Proxy de alta velocidade (rede local ethernet o u similar) e o link entre o Proxy e a Web mais lento, bastante interessante poss ibilidade que o Squid oferece de armazenar localmente as ltimas pginas acessadas, de forma a no ter que buscar novamente na Internet uma pgina que tenha sido recent emente vista por outro usurio da mesma rede. Naturalmente voc pode configurar o te mpo de armazenamento de cada pgina no cache, e o protocolo HTTP tm recursos sufici entes para reconhecer pginas que no devem ser guardadas no cache e precisam ser bu scadas novamente a cada requisio. Devemos entender que um servio de Proxy exige bas tante memria e espao em disco rgido. O sistema deve ser dimensionado de forma adequ ada. 3.1 - Caractersticas do Proxy Squid O Controle de acesso uma das caracterstica do Squid muito til para administradores que

lidam diariamente com grandes acessos pblicos, que possuem o seu link Internet sa turado com acessos a sites remotos que no esto relacionados finalidade da sua rede e a possibilidade de definir listas de bloqueios para restries destes acessos ind evidos. 3.1.1 - Restries de acesso Voc pode definir listas de controle de acesso baseado no endereo de destino ou na origem da requisio. Assim, voc pode por exemplo definir que em uma escola alunos do laboratrio (A) no podem acessar determinados sites, enquanto que os alunos do lab oratrio (B) acessam sem restries. Utilizando um script externo de filtragem voc pode at mesmo criar regras baseadas no horrio de acesso. Desse jeito pode-se criar res tries especficas em determinadas horas, na qual se pode bloquear arquivos de vdeo e em outra tabela de horrio pode-se permitir. Por exemplo, as seguintes linhas no a rquivo (/etc/squid.conf) impediriam que qualquer pessoa da sua rede acesse sites , cuja URL contenha a palavra playboy e sexo: Tabela 1. acl porno url_regex play boy acl livre url_regex sexta http_access deny porno http_access allow livre htt p_access allow all Tabela 1 - Exemplo de uma acl (Reis, 2006). Ao contrrio de out ras tcnicas de conexo, como o roteamento simples e o IP (masquerading), normalment e o Proxy Squid exige alteraes na configurao do seu navegador Web. Cada navegador te m sua prpria maneira de configurar conforme citado por Campos(2006), mas de um mo do geral todos eles tm suporte a Proxy. Ao configurar um navegador ou um aplicati vo que estar utilizando um Proxy para estar conectando a Internet, automaticament e ele muda a sua forma de operao. Ao invs de tentar contatar diretamente os servido res Web da Internet, ele contata o Proxy e informa a ele a URL que deseja transf erir. O Proxy, por sua vez, contata o site da Internet e transfere o arquivo ou pgina desejados, entregando-os ao navegador que fez a requisio e armazenando uma cpi a temporria no Cache. De acordo com Campos(2006), caso algum outro computador da rede requisite a mesma pgina em um intervalo de tempo configurvel, ele ter a respos ta mais rpida. Se voc tiver um Proxy baseado no Squid, os computadores da rede loc al no precisam ter nenhuma forma de acesso direto Internet para entrar na Web e u sar o FTP. Sendo assim, voc pode concentrar seus esforos de segurana e administrao de rede na mquina que roda a Proxy, conforme Campos(2006). Uma das maiores vantagen s do Proxy sobre outras alternativas de conexo como o IP (masquerading) a existnci a do cache, que, quando bem configurado, maximiza o aproveitamento do seu canal de conexo com a Internet. Os documentos estticos (imagens, pginas HTML geradas esta ticamente) solicitados por qualquer uma das mquinas da sua rede ficam armazenados tambm no servidor, e caso outra mquina da rede solicite o mesmo documento, ele fo rnecido a partir do cache, economizando assim a sua banda com o provedor de Inte rnet, que normalmente de velocidade bem mais baixa do que a rede local que liga as mquinas clientes ao servidor Proxy. Outra vantagem importante o nvel de control e oferecido. O Squid permite criar regras avanadas de restrio de acesso, podendo de finir que determinados micros tero acesso irrestrito, outros podem acessar apenas um determinado conjunto de sites, e outros ainda podem acessar qualquer site. p ossvel restringir um determinado conjunto de sites cuja URL possua uma determinad a palavra ou expresso regular. Estas regras podem variar de acordo com o horrio,

permitindo a criao de regras que restrinjam o trfego no horrio de expediente, e libe rem nos horrios de menor demanda. 3.1.2 - Arquivo de Configurao A configurao do squid fica gravada em um arquivo chamado (squid.conf), geralmente no diretrio (/etc ou /etc/squid) dependendo do sistema operacional usado. As polti cas de acesso, ocupao de memria e quanto ao prazo de validade dos arquivos do cache so funes que esto definidas dentro do (squid.conf). Contudo, basta habilitar as funes neste arquivo. 3.1.3 - Funo do Proxy Squid O Squid depende da infra-estrutura de sua rede. Quando ele entrar em operao, as ro tas e interfaces de rede da mquina j devem estar ativadas, sejam elas sobre uma li nha discada, uma conexo atravs de um roteador dedicado, uma conexo sob demanda disc ada, rede local ou qualquer outra suportada pelo Linux de acordo com Campos (200 6). Conforme definio de Andrade (2006), o objetivo principal de um servidor Proxy possibilitar que mquinas de uma rede privada possam acessar uma rede pblica, como a Internet, sem que para isto tenham uma ligao direta com esta. O servidor Proxy c ostuma ser instalado em uma mquina que tenha acesso direto Internet, sendo que as demais efetuam as solicitaes atravs desta. Justamente, por isto, que este tipo de servidor chamado de Proxy, pois um procurador, ou seja, o sistema que faz solici taes em nome dos outros. Um servidor Proxy para o protocolo HTTP, por exemplo, pod e ter outras funcionalidades implementadas. Visto que todas as solicitaes de pginas efetuadas pelas mquinas da rede privada sero feitas atravs dele, muito til armazena r localmente as pginas que foram solicitadas, permitindo que os prximos acessos, e fetuados por quaisquer mquinas da rede, possam ser otimizados. Este conceito cham ado de (caching), na qual a pgina baixada imediatamente para o cliente a partir d o servidor Proxy, evitando ter que baix-la da Internet. 3.1.4 - Progresso do Squid O Squid est continuadamente melhorando sua performance, conforme Bastos (2006), a lm de adicionar novas caractersticas e ter uma excelente estabilidade em condies ext remas. Sua compatibilidade com vrias plataformas e a imensa gama de software para analisar logs, gerar relatrios, melhorar o desempenho e adicionar seguranas provi dos pela comunidade open source, combinados com ferramentas de administrao simplif icada e baseadas em Web agregam grande valor ao produto. Podemos ainda citar a c apacidade de clustering, transparent Proxy, cache de FTP e, claro, seu baixo cus to. O sistema totalmente aberto, possibilitando a sua otimizao nvel de cdigo fonte, alm da otimizao via configurao. 3.1.5 - Tipos de protocolos O Squid busca por comunicao TCP (Transmission Control Protocol) e Cache Protocol) em portas especficas. O TCP usado para comunicao entre clientes, e o ICP para conve rsa entre servidores de cache. Para cada servidor configurao do Squid precisa forn ecer uma nica porta sobre a qual o Squid requisies TCP ou ICP e ouvir as respostas. ICP (Internet webservers e ou cliente, a ir enviar as

O Squid trabalha apenas com FTP, Gopher e HTTP. O Squid, no configura acesso a em ails, ICQ, IRC, etc. Visto que no s funo do firewall trabalhar com o NAT (Network Ad dress Translation), como tambm no faz sentido criar caches de e-mails pessoais e m ensagens do ICQ. 3.1.6 - Proxy transparente no Squid Proxy Transparente um recurso muito til para evitar que os usurios removam as conf iguraes do Browser. Conforme Bastos (2006) os usurios sero obrigados a passar pelo P roxy, mesmo que as mquinas no estejam configuradas para tal. Extremamente recomend ado, principalmente em casos de bloqueio de sites ou limitao de banda. Experincias do grupo comprovam que usurios com um pouco mais de conhecimentos iro remover a co nfigurao de Proxy. Algumas pessoas desejam trabalhar ao mesmo tempo com autenticao e Proxy transparente. Isso possvel de ser feito com uma interao entre o firewall e u m CGI1.

3.1.7 - Listas de Controle de Acesso O conceito de ACL (Access Control Lists) utilizado no squid para estar controlan do o que cada usurio acessa no navegador. A ACL muito til, por nos permitir trabal har com nveis de acesso baseados em diversas informaes. No incomum que em uma instal ao do Squid algumas situaes podem acontecer, como exemplo poderamos citar a diretoria que pode acessar qualquer site, a gerncia que no pode acessar determinados sites e os funcionrios da fabrica que pode acessar apenas o site da empresa e de parcei ros. Graas ao uso de ACLs e um pouco de conhecimento, podemos fazer todas essas re stries. Todas as configuraes de usurios, grupos, horrios e sites so configuradas em AC . A ordem em que as ACLs aparecem muito importante, pois ao ser feita uma configu rao no arquivo fonte do Squid ele respeita a regra que vem primeiro ou o arquivo d e bloqueio, por isso a Acl que bloqueia os sites deve ser a primeira. Outra funo e ssencial no Squid e o suporte a autenticao que para isso se usa um recurso chamado de (ncsa_auth), que a alternativa mais simples. Ele est disponvel junto com o Squ id e pode ser implementado rapidamente. a soluo ideal para pequenas e mdias instalaes e redes com arquitetura de grupo de trabalho. 1 CGI: Consiste numa importante tecnologia que permite gerar pginas dinmicas permiti ndo a um navegador passar parmetros para um programa alojado num servidor web. Este um recurso bem interessante para controle pessoal de usurios, pois permite q ue voc crie ACLs individuais e gere logs de qualidade bem superior. Existem divers os mtodos de autenticao, sendo interessante averiguar exatamente o que ir precisar c om base no plano de regras. Para controlar o acesso por usurios e grupos, podemos configurar o Squid como PDC. O (smb_auth) l o arquivo (\netlogon\proxyauth) que por padro e localizado no Linux, e em um dos controladores de domnio previamente i nformado. Se a leitura desse arquivo retorna um (allow) ou permitido , ento o ace sso liberado. Caso contrrio se for um (deny) o acesso negado. Crie um arquivo cha mado (proxyauth) no compartilhamento NETLOGON de seu PDC (d preferncia ao primrio). Esse arquivo deve conter unicamente a palavra (allow) e d permisso de leitura par a os grupos e usurios que deseja permitir o acesso. O recurso de ACL externas mui to til para um tratamento melhorado de algum recurso que no compreendido por ACLs n ormais. Uma ACL externa pode ser escrita em qualquer linguagem. Ela deve sempre retornar um valor de confirmao para o (stdout) caso a condio seja satisfeita, ou ret ornar um erro para o (stdout), caso ela no seja satisfeita.

Para facilitar a vida dos usurios e do administrator, conforme citado por (Reguly 2006), podemos criar um arquivo de configurao automtica que ser colocado nos Browse rs dos clientes. Dessa forma todos tero seu Proxy reconfigurado dinamicamente em caso de mudanas, sem a necessidade de interveno em cada mquina. Esse arquivo deve se r acessvel via Web e, via de regra, chama-se (proxy.pac). A utilizao de sistemas de cache, como o Squid, tem se mostrado excelentes para aliviar certos sintomas, r eduzindo o trfego na rede e, conseqentemente, a latncia da mesma ou seja a perda de banda. Toda a idia por trs de um sistema de (caching) criar um grande banco de da dos onde os sites mais populares ou acessados recentemente sejam armazenados par a futuras consultas. Isso significa que se 10 usurios da sua rede tentarem acessa r um mesmo site ao mesmo tempo, somente uma das conexes realmente ir ser feita a e sse site. Todas as outras 9 vo se aproveitar do primeiro acesso e utilizar a pgina j em memria. Isso um enorme ganho de desempenho para seu backbone local e para o backbone do ISP1 onde o site est armazenado e tambm para o servidor que hospeda o mesmo. Com todas essas configuraes habilitadas e funcionando corretamente possvel d iminuir consideravelmente o fluxo de informaes na banda e controlar ao mximo o cont edo acessado pelos usurios. Podemos definir um Proxy ou cache da seguinte forma: V elocidade de acesso: A melhor forma de verificar se o seu cache est sendo eficien te pela velocidade. Um sistema de cache que no agrega velocidade no est cumprindo o seu papel; Disponibilidade: De nada adianta um sistema veloz disponvel apenas 2 horas por dia, ou mesmo que precise de um reboot a cada 2 semanas. Em casos de g randes instalaes, ainda preciso ir mais a fundo, buscando uma altssima disponibilid ade, como (Redundncia de servidores, backup, eliminao de ponto nico de falha); Trans parncia ou Ostensividade: So conceitos especficos e que se adaptam a cada caso. Gra ndes instalaes, ISPs e empresas no preocupadas com que seus usurios vem ou fazem na In ternet devem preferir a transparncia, onde o usurio desconhece ou no se sente afeta do (exceto pelo ganho de velocidade) pela presena de um cache. Por outro lado, em presas com uma poltica de segurana mais rgida, rgos com informaes crticas, ou mesmo p que queiram controlar o acesso de seus filhos a alguns sites, vo preferir a oste nsividade; 1 ISP: servio de acesso internet, agregando a ele outros servios relacionados, tais como "e-mail", "hospedagem de sites" ou blogs, entre outros. Capacidade de trabalhar com redes heterogneas: Ele capaz de trabalhar com diverso s tipos de redes e no sendo necessrio estar exclusivamente amarrado a de um fabric ante de Software ou de hardware, sendo assim ele se adapta a qualquer situao. Isso especialmente verdade quando no sabemos que tipo de plataforma iremos utilizar e m nossa instalao; Simplicidade: Deixando um pouco de lado o usurio e focando no adm inistrador, conforme citado por (Bastos 2006) preciso ter conscincia de que um si stema bom um sistema fcil de administrar. O mais rpido, mais disponvel e mais abran gente sistema de (caching) totalmente intil se somente uma pessoa no mundo souber lidar com ele. Cache hierrquico a extenso lgica do conceito de (caching). Um grupo de caches podem se beneficiar do compartilhamento de seus dados entre si de vria s formas. Isso facilmente explicvel quando pensamos em termos regionais. Como exe mplo podemos citar o de uma empresa estabelecida em um prdio, pela qual os

usurios desta empresa resolvem enviar uma requisio de acesso a um determinado site, ento repassado esta requisio ao Proxy mais prximo, na qual baixa-se diretamente as informaes sem precisar sair para a Internet para baix-la. Fica fcil de visualizar qu e se todas as empresas interligassem localmente seus Proxies, todas sairiam ganh ando. Na realidade, essa prtica entre pequenas empresas no existe. Mas quando fala mos de grandes empresas e grandes backbone, cada 1 MB economizado com (caching) 1 MB ganho em outros servios. Alm de trabalhar com o conceito de rvore conforme cit ado por (Bastos 2006), onde existe um cache principal e outros ligados a ele, o Squid trabalha tambm com um conceito parecido com grupo de trabalho, onde todos o s servidores se consultam mutuamente. Toda a comunicao entre os caches feita via I CP. O ICP foi desenvolvido como parte fundamental do projeto Harvest (Pai do Squ id). Seu objetivo prover um mtodo rpido e eficiente de obter-se comunicao entre serv idores cache. O ICP permite que um cache pergunte a outro se ele tem uma cpia vlid a de um determinado objeto, aumentando a possibilidade de encontrar aquele objet o j (cacheado). Adicionalmente, o ICP permite que requisies trafeguem entre servido res filhos em uma estrutura de rvore. Alm do controle de cache, o ICP tambm gera in dicaes do estado da rede. O no recebimento de uma resposta ICP normalmente indica q ue a rota est congestionada ou que outro Host no est ativo. Alm disso, a ordem de ch egada de uma resposta ICP pode indicar quais hosts esto com uma distncia lgica meno r ou com menos carga. As mensagens ICP so geralmente bem pequenas, com cerca de 6 6 bytes. Em uma estrutura hierrquica, normalmente tem-se mais trocas de mensagens ICP do que HTTP. Roteamento por domnio e outra caractersticas de configuraes do Squ id pode favorecer muito no desempenho. A configurao seria assim Tabela2: cache_hos t_domain cache 1 portalxpto.com cache_host_domain cache 2 portalxing.com cache_h ost_domain cache 3 portalling.com cache_host_domain cache 4 !portalxing.com ! po rtalxpto.com !portalling.com Tabela 2 Exemplo de configurao (Reis, 2006). Sendo qu e o cache 4 ser o responsvel por todos os domnios que no sejam os 3 anteriores. 3.2 - Squid como servidor Uma situao muito til, mas por vezes pouco explorada do Squid a sua capacidade de tr abalhar com Proxy reverso. Isso significa que, alm de armazenar objetos remotos, criando toda uma srie de vantagens j discutidas aqui, ele tambm pode armazenar obje tos de um servidor Web interno, aliviando seu uso e provendo maior segurana. 3.3 - Estrutura de Hardware Especificar o hardware uma etapa muito importante no incio do projeto. O ideal tr aar um perfil de como e de como ser em 1 ano o volume de uso desse hardware.

Ao escolher devemos sempre utilizar um hardware que permita atualizaes, especialme nte em memria e armazenamento. Instalar servidores j com todos os bancos de memria usados ou no mximo de seus recursos sempre evitar. Pequenas instalaes dispensam dis co rgido do tipo SCSI1, uma opo que j fica invivel em instalaes maiores. Conforme cita e Bastos (2006), ao utilizar RAID2, prefira o nvel 0 do que outros, visto que o m esmo feito para desempenho. interessante utilizar um disco rgido separado para os dados e para os logs do Squid. Se isso no for possvel, ao menos uma partio separada extremamente recomendada. Como normalmente, tanto os dados quanto os logs ficam abaixo do diretrio (/var), esse o ponto de montagem para essa partio. O desempenho das resolues DNS um ponto crtico e deve ser analisado como se segue. Em uma situao i deal, deveria existir um cache de DNS na mesma mquina ou em uma mquina muito prxima , para diminuir ao mximo o tempo de resoluo dos nomes. Em mltiplas rotas como em ins talaes com o ISP pode ser vantajoso definir suas rotas manualmente. J em empresas md ias ou grandes que utilizam links de baixo custo, como ADSL 3, o balanceamento d e carga nos links uma tima opo, conforme citado por Bastos (2006). 1 SCSI: A tecnologia criada para acelerar a taxa de transferncia de dados entre dis positivos de um computador, desde que tais perifricos sejam compatveis com o padro. 2 RAID: um meio de se criar uma unidade virtual composta por vrios discos indivi duais, com a finalidade de duplicao ou balanceamento. 3 ADSL: Asymmetric Digital Subscriber Line. 3.4 - Tags A seguir ser mostrado algumas tags de configurao do Squid. Alteraes bem feitas e pens adas podem trazer um grande ganho para a performance do cache, enquanto um erro de configurao pode impedir o Squid de trabalhar ou at mesmo remover muitas de suas funcionalidades. Estas configuraes so feitas editando o arquivo (squid.conf), local izado por padro no diretrio (/etc/squid/squid.conf). Http_port: Esta tag define qu al porta ou portas do servio do Squid estar aberta, por padro definida a 3128; Cach_ mem: Especifica o ideal a ser usado pelo Squid de memria, levar em considerao a qua ntidade de memria usada, por que ao ser setado valores extremamente altos os outr os servios do sistema operacional sero prejudicados; Cache_swap_low: Este parmetro especificado para quando o tamanho do diretrio de Swap j estiver no mnimo, por padro costuma-se inserir o valor de 90; Cache_swap_high: Esta outra tag para especifi car o tamanho do diretrio de Swap quando o mesmo j estiver no mximo, por padro costu ma-se inserir o valor de 95.

3.5 - Referncias de conexo Em conexes intermitentes o Squid pode operar em redes (dial-up) ou (demand-dial). O modo (off-line) ir funcionar para algumas destas redes, mas est longe de ser um a soluo ideal. Infelizmente muitas das funcionalidades do modo (off-line) do Squid parecem ter desaparecido durante o desenvolvimento da srie Squid 2.x. Na verso 2. 3 STABLE4, o modo (off-line) no tem quase nenhum efeito. Ter um cache no lado int ermitente do Link pode acabar com alguns dos problemas destas conexes, conforme V esperman (2006), dando acesso a informao que est em cache e assim reduzindo o uso d o Link. Sem as correes do (patche), o Squid pode funcionar razoavelmente bem em co nexes (dial-on-demand), mas discar cada vez que uma consulta tem que ser resolvid a pode influenciar consideravelmente no custo. O Squid foi projetado para conexes permanentes. Fazer o Squid funcionar em conexes intermitentes exige alteraes no mo do em que o Squid trabalha com as pginas Web antigas e pesquisas DNS antigas. As pginas so consideradas antigas quando o seu TTL 1(time to live) tiver sido expirad o. Muitas pginas Web possuem valores de validade em seus cabealhos informando at qu ando a pgina pode se considerada atualizada, e quando a mesma pode ser considerad a como pgina antiga. O Squid tambm possui informao padro de validade, se no h dados no cabealhos, o Squid configura os seus prprios. Pginas antigas so mantidas no cache. Se o cache ficar sem espao, as pginas antigas so descartadas em uma ordem (mais vel ha primeiro). Este algoritmo chamado LRU2(least recently used). Outros algoritmo s esto disponveis em verses mais atuais do Squid. Se mesmo assim voc estiver com pro blemas de espao no cache a recomendao e adquirir um novo disco rgido com bem mais es pao e mais memria. Pginas antigas que ficam no cache so validadas quando um cliente solicita a pgina. O Squid gasta uma solicitao, perguntando (Ei, esta pgina mudou?), e o servidor de origem ir responder com (Sim, aqui est nova pgina), ou (No, ela aind a boa). A pgina considerada recente novamente, seja uma nova pgina ou uma antiga. Este processo chamado de solicitao IMS, uma abreviao para (if modified since) que si gnifica, desde a ltima vez que o Squid verificou que a mesma recente. Pesquisas D NS tambm so armazenadas em cache, e possuem um TTL configurvel. Quando uma entrada cacheada de (Fully Qualified Domain Name), FQDN, ou uma entrada IP DNS expira, e la removida do cache. 1 TTL: Significa o nmero de mquinas que os pacotes podem demorar numa rede de comput adores antes de serem descartados. 2 LRU: Algoritmo Adaptativo de Substituio de Pgi nas. O modo (off-line) tambm nunca expira informaes de DNS que esteja no cache, e nunca renova pginas antigas. Isto no o que os usurios de (dial-up) e outros usurios com co nexes intermitentes querem. Usando a configurao no modificada do Squid, (offline_mod e on) que assinala ao Squid para nunca tentar uma validao, e (offline_mode off) qu e assinala uma operao normal.

3.6 - Vantagens O Squid est continuadamente melhorando a sua performance, alm de adicionar novas f uncionalidades e ter uma excelente estabilidade em condies extremas. Sua compatibi lidade com vrias plataformas e a imensa quantidade de softwares para analisar log s, gerar relatrios, melhorar o desempenho, bem como a adico de segurana providos pe la comunidade open source, combinados com ferramentas de administrao simplificada e baseadas em Web agregam grande valor ao produto. Podemos ainda citar a capacid ade de clustering, transparent proxy, cache de FTP e, claro, seu baixo custo. Capitulo 4 - Conhecendo Algumas Solues 4.1 - Configurao Esta idia surgiu da possibilidade de configurarmos o Squid de uma forma que o mes mo atinja o seu potencial mximo. Porm utilizando esta idia, iremos somente redefini r configuraes pr-existentes para que estas se encaixem no objetivo proposto. Nas pgi nas de anexos est o Squid proposto. 4.2 - HDparm Aumenta a taxa de transferncia de dados do discos rgidos IDE com o HDparm. Como as maiorias das distribuies Linux sempre adaptam o sistema operacional para que ele esteja totalmente compatvel, algumas vezes deixado de lado o desempenho do hardwa re e neste caso que entra programas como o HDparm. A taxa de transferncia de dado s quintuplica com o uso dos novos parmetros, se a compararmos com a configurao padro . O ganho de desempenho tende a ser muito grande mas o risco de perda de dados d iretamente proporcional a ele. A melhor proteo fazer primeiro um backup do sistema e somente depois realizar teste para se chegar a um valor ideal de (multcount) que significa a quantidade de setores que ele est lendo por vez. 4.3 - Banco de Dados Quando pensamos em uma soluo para resolver o problema proposto a principio a alter ao no cdigo fonte seria a opo mais vivel, no entanto, ao pesquisarmos e nos aprofundar mos mais no assunto descobrimos a vantagem de utilizao de bancos de dados. A vanta gem de utilizar o banco de dados que sua indexao interna mais rpida e dinmica, o que facilita a resposta do

Squid para com o navegador, ou seja, a capacidade de armazenar uma grande lista diretamente no disco rgido e no em memria como acontece normalmente. 4.4 - Alterao do Cdigo Fonte Uma das solues concentra a idia de alterao do cdigo fonte do Squid otimizando o mesmo, esta idia foi proviniente de um orientador. Como seria feita esta alterao?. Pesqui samos mtodos de ordenao e mtodos de busca para verificar qual deste mtodos seria o ma is rpido em relao ao utilizado no Squid, caso o algoritmo utilizado atualmente pelo Squid no apresentasse uma melhor caracterstica de perfomance, seria aplicado um ( patch) com a nossa implementao ou melhoramento da estrutura do prprio algoritmo j ex istente no cdigo fonte. 4.5 - Compilao do Kernel Uma das opes que pode ser implementada no sistema operacional Linux que se encontr a instalado o Squid, a compilao do Kernel com somente o necessrio, ou seja, com um ncleo (kernel) mais enxuto e dedicado, se torna evidente que o mesmo ficar mais rpi do pelo fato de no estar compartilhando outros recursos. Capitulo 5 - Aplicando a Soluo Escolhida 5.1 - A Escolha Optamos por utilizar um banco de dados para armazenar nossa (black-list) e desen volvemos um programa (Front-End), que faz a intermediao entre o banco de dados e o Squid. Este programa desenvolvido utilizando a linguagem de programao Perl, o ban co de dados que utilizamos para armazenar a nossa (black-list) o PostgreSQL. Den tro desta escolha inclumos como soluo requerida a implementao do HDparm e compilao do ernel e por ultimo inclumos nas listas de anexo o hardware ideal para a quantidad e de usurios. 5.2 - Desenvolvendo a soluo Utilizamos a linguagem de programao Perl, para servir como (front-end) para o banc o de dados que guardar a (black-list) do Squid. A vantagem de utilizar a linguage m Perl sua flexibilidade para trabalhar com qualquer banco de dados como: Oracle , Postgres, Mysql, Sqlite, etc. Foi feito alguns testes para conexo de banco de d ados utilizando linguagem de programao C para conectar ao banco de dados Postgres, mas devido falta de vrias bibliotecas que so necessrias para executar esta conexo a cabamos pesquisando outras linguagens e deparamos com a linguagem Perl, ela exce lente para a funo de conexo com banco de dados. A propriedade de conexo ser da seguin te forma: o Proxy Squid atravs de um recurso chamado (redirect_program) que uma t ag interna do software Squid, aponta para o script feito em Perl que nosso (fron t-end) e por sua vez o (front-end) faz um SELECT na lista (black-list) que est no banco de dados.

Vantagem sugerida que a (black-list - lista de URLs) no ser carregada na memria e si m no banco de dados, ento o Proxy Squid far toda a consulta de URLs diretamente em cima do banco de dados no sobrecarregando a memria do computador. Testamos o (fron t-end) feito em Perl com o banco de dados Postgres e seu funcionamento perfeito, foi constatado isso atravs de testes utilizando os seguintes parmetros tabela 3: 1 Inserimos dados no banco de dados; 2 Fizemos um select dos dados armazenados; 3 Exclumos os dados. Todo este processo feito atravs de um script Perl. O Perl uti liza uma biblioteca chamada DBI que facilita esta conexo com o banco de dados. Ta bela 3 O passos efetuados (Reis, 2006). 5.3 - Detalhamento do processo O primeiro passo foi criar o banco de dados e inserir no mesmo as URLs para serem consultadas futuramente. O banco de dados usado como dito anteriormente o Postg res, e foi definido com o nome de (Bdblack) para o banco, e sua tabela com o nom e (sites) com a seguinte estrutura tabela 4: create table sites (url varchar(300 ), domnio varchar (300)); Tabela 4 Como foi estruturado (Reis, 2006). Para o noss o (front-end) que ser o intermediador entre o Squid e o banco de dados criado pel a linguagem de programao Perl o nome dele (consulta.pl). O cdigo fonte segue abaixo com os devidos comentrios tabela 5. 1 - #!/usr/bin/perl 5.8.1 2 - use DBI; 3 - my $db = DBI->connect("dbi:Pg:dbname=bdblack","postgres", "123456"); 4 - print ("Site: "); 5 - chomp (my $url = <STDIN>); 6 - my $query = "SELECT * FROM sites WHERE url = $url OR dominio = $url "; 7 - my $res; #Vari avel para armazenar o retorno da consulta 1 ou 0 8 - $res = $db->do($query); 9 if ($res == 1){ 10 - print ("\nSite Bloqueado\n"); 11 - } 12 else { 13 - print ("\nSite Livre\n"); 14 - } 15 - $db -> disconnect(); 16 exit(); Tabela 5 O cdigo do front-end (Reis, 2006). Na linha um colocado o caminho para o executvel da lin guagem de programao Perl. A segunda linha chama a biblioteca DBI para fazer a cone xo entre o banco de dados e a linguagem de programao, a linha trs referencia a conexo com o banco de dados, as linhas quatro e cinco inserem dados para a busca. A li nha seis faz a consulta no banco de dados, ou seja, aqui esta os comando SQL. Na linha sete a resposta da consulta armazenada na varivel (res), logo o seu

contedo deve estar com 0 ou 1, 0 no encontrado ou 1 encontrado no banco de dados. A linha 8 executa a consulta e armazena o resultado em (res), em seguida da linh a nove a quatorze e demonstrado o resultado da consulta. As linhas quinze e deze sseis so responsveis pelo fechamento da consulta do Perl com o banco de dados. Log o depois de efetuado a consulta o valor encaminhado para uma rotina onde ser defi nido o que ser feito, se proibido o acesso a pgina requisitada pelo cliente (brows er) ou liberado o seu acesso. As regras de liberao ou proibio no so efetuadas pelo (fr ont-end), est definio responsabilidade do Squid com as suas ACLs. O programa citado acima ser usado para a busca no banco de dados. Quando a memria est muito cheia e c arregada de aplicativos, com uma base de dados muito extensa ela se torna muito lenta, o nosso objetivo colocar esta mesma base no Postgres e ao requisitar uma URL o Squid passa para o (consulta.pl) pesquisando no banco de dados, como se tr ata de muitos dados a pesquisa se torna bem mais rpida do que propriamente na memr ia. E foi isso que foi realizado. 5.4 - Introduo ao Perl A Linguagem Prtica de Extrao e Gerao de Relatrios (The Practical Extraction and Report Language) uma linguagem de programao estvel e multiplataforma, usada em aplicaes de misso crtica em todos os setores, e bastante usada para desenvolver aplicaes Web de todos os tipos, foi criada por Larry Wall em dezembro de 1987. A origem do Perl remonta ao (shell scripting, Awk e linguagem C), e est disponvel para praticamente todos os sistemas operacionais, mas usado mais comumente em sistemas Unix e com patveis. Perl uma das linguagens preferidas por administradores de sistema e auto res de aplicaes para a Web. especialmente verstil no processamento de cadeias (stri ngs), manipulao de texto e no (pattern matching) implementado atravs de expresses re gulares, alm de permitir tempos de desenvolvimento curtos. A linguagem Perl j foi portada para mais de 100 diferentes plataformas, e bastante usada em desenvolvim ento Web, finanas e bioinformtica. 5.4.1 Caractersticas do Perl No geral, a sintaxe de um programa em Perl se parece muito com a de um programa em C, existem variveis, expresses, atribuies, blocos de cdigo delimitados, estruturas de controle e sub-rotinas. Alm disso, Perl foi bastante influenciado pelas lingu agens de shell script, todas as variveis so precedidas por um cifro ($). Essa marcao permite identificar perfeitamente as variveis em um programa, aonde quer que elas estejam. Um dos melhores exemplos da utilidade desse recurso a interpolao de variv eis diretamente no contedo de strings. Perl tambm possui muitas funes integradas par a tarefas comuns como ordenao e acesso de arquivos em discos rgidos. A linguagem su porta estruturas de dados arbitrariamente complexas. Ela tambm possui recursos vi ndos da programao funcional (as funes so vistas como um outro valor qualquer para uma subrotina, por exemplo) e um modelo de programao orientada a objetos. Todas as ve rses de Perl possuem gerenciamento de memria automtico e tipamento dinmico. Os tipos e necessidades de cada objeto de dados no programa so determinados automaticamen te. A memria alocada ou liberada de acordo com o necessrio. A converso entre tipos de variveis feita automaticamente em tempo de execuo e converses ilegais so erros fat ais. Sua interface de integrao com base de dados (DBI) suporta muitos bancos de da dos, incluindo Oracle, Sybase, PostgreSQL, MySQL e outros. Perl permite programao procedural e orientada a objetos. Perl pode acessar bibliotecas externas em C e C++. O mdulo Perl (CGI.pm),

parte da distribuio padro de Perl, faz com que a manipulao de formulrios HTML seja mui to simples. Perl pode manipular dados encriptados, incluindo transaes de comrcio el etrnico. O pacote DBI do Perl faz com que a integrao com banco de dados Postgres se ja muito simples.

5.5 - Introduo ao PostgreSQL O PostgreSQL um sistema gerenciador de banco de dados objeto-relacional (SGBDOR1 ), baseado no POSTGRES Verso 4.2 desenvolvido pelo Departamento de Cincia da Compu tao da Universidade da Califrnia em Berkeley. O POSTGRES foi pioneiro em vrios conce itos que somente se tornaram disponveis muito mais tarde em alguns sistemas de ba nco de dados comerciais. O PostgreSQL um descendente de cdigo fonte aberto do cdig o original de Berkeley. So suportados o SQL-92 e o SQL-1999, alm de serem oferecid as muitas funcionalidades modernas, como: comandos complexos ; chaves estrangeir as; gatilhos; vises; integridade transacional; controle de simultaneidade multive rso. Alm disso, o PostgreSQL pode ser estendido pelo usurio de muitas maneiras como , por exemplo, adicionando novos: tipos de dados; funes; operadores; funes de agr mtodos de ndice; linguagens procedurais. Devido sua licena livre, o PostgreSQL pod e ser utilizado, modificado e distribudo por qualquer pessoa para qualquer finali dade, seja privada, comercial ou acadmica, livre de encargos. SGBDOR1: Sistema gerenciador de banco de dados objeto relacional. 5.6 - Outras solues aplicadas 5.6.1 - O HDparm Conforme a definio de (Thomas Wlfer 2004) o Hdparm essencial para prover desempenho em discos rgidos IDE em sistemas Linux recm-instalados, que no utiliza o total de possibilidades oferecidas pelo hardware. O Hdparm consegue modificar a configurao do disco rgido obtendo o mximo do mesmo. Atravs do comando (hdparm Tt /dev/hdaX) pod emos medir a velocidade do cache do disco (memria, processador e buffer) que dura nte a leitura de

informaes calcula os valores de desempenho do disco desconsiderando as informaes de dados do cache fornecendo uma medida eficiente do disco rgido que est sendo analis ado. recomendvel efetuar vrios testes, a fim de calcular uma mdia, entretanto neces srio que desabilitemos vrios servios no computador para que o mesmo no fique sobreca rregado durante os testes prejudicando a preciso dos dados analisados. Aplicando o HDparm de forma criteriosa podemos aumentar em at cinco vezes o desempenho do d isco rgido, algo ideal para aplicaes que necessitem de respostas altas. Algumas con troladoras suportam 32 bits e esto rodando em 16 bits, este suporte pode ser conf igurado com a opo (c), conforme segue (hdparm c1 mf6 /dev/hdaX), com este comando o s uporte a (I/0) configurado para o modo 1 que seria 32 bits, desta forma dobramos a taxa de transferncia de dados do disco rgido. Aplicando o comando (Hdparm d1 x66u1 m16 cd /dev/hdaX), obtemos resultados que demonstram grande desempenho do disco rgido, atravs da opo (d1) ativamos o (flag) de utilizao de acesso direto memria (u dma), a opo (x66) ativa o ULTRADMA, a opo (u1) desativa o mascaramento de outras inter rupes (umaskirq). Podemos observar que a taxa de transferncia de dados quintuplica com o uso de novos parmetros comparado a configurao padro do computador. Depois de e fetuar a configurao que aplica o desempenho do disco rgido atravs do HDparm devemos salvar a mesma para que a configurao no perca durante a reinicializao do sistema, bas ta utilizar um script de inicializao do sistema, chamado (rc.local) ou outro nome dependendo da distribuio para que toda a configurao fique de forma permanente, mas t alvez em algumas controladoras, realizado um parmetro chamado (IDE reset) pode-se ainda perder a configurao. Aplicando a opo (k1) no comando evitamos que tal reset se ja efetuado. A seguir apresentamos uma tabela feita com 3 discos rgidos, demonstr amos os dados que possuem valores surpreendente tabela 6. Disco Rgido ST3400I5A P erformance Veloc. Gravao Sem HDparm Cached reads -2.00 368.00 MBps seg Buffered di sk reads 52,1 MBps 3.01seg Cached reads -2.00 680.35 MBps seg Com HDparm 378,11 MBps 36,54 MBps 686.9 MBps 24.77 MBps SAMSUNG SV2001.4 Buffered disk reads 28.63 MBps 3.01 seg Tabela 6 Valores encontrados (Reis, 2006 ). 5.6.2 Kernel1 Para ganhar uma alta performance no sistema operacional Linux o ideal e compilar o Kernel (ncleo do sistema operacional, que faz a negociao entre Hardware e Softwa re), com um kernel compilado somente com o bsico, ou seja, com suporte no kernel somente aos hardware que esto disponveis na mquina, a velocidade em processamento a proveitada somente para as aplicaes em uso, memria fica alocada somente para os apl icativos e servios que o sistema operacional precisa. Os procedimento abaixo foi citado por Gustavo Paes (2004), o foco o kernel 2.6 com Linux Slackware 9, porm s eus conceitos podem ser levados para outras distribuies. Antes de

tudo, atualize o (Modutils/module-init-tools). necessario um conjunto novo de pr ogramas de gerenciamento de mdulos (modprobe, insmod, rmmod, etc), pois os que vm com o Slackware 9 no funcionam para o kernel 2.6.2 (Figura 1). 1 - Baixe o module -init-tools mais recente: ftp://ftp.kernel.org/pub/linux/kernel/people/rusty/mod ules/ 2. Descompacte o arquivo com: $ tar -xvzf module-init-tools-0.9.15-pre4.ta r.gz 3. Entre no diretrio que foi criado: $ cd module-init-tools-0.9.15-pre4 4. L eia o arquivo README se houver a necessidade. 5. Agora a hora de compilar: $ ./c onfigure --prefix=/ $ make moveold $ make $ su # make install 6.Usar programa (g enerate-modprobe.conf) e converta o /etc/modules.conf para /etc/modprobe.conf: # ./generate-modprobe.conf /etc/modprobe.conf Kernel1: entendido como o ncleo do Sistema Operacional ou, numa traduo literal, cer ne. NOTA: Os procedimentos a seguir devem ser executados pelo usurio root. 1. Baixe o kernel novo em: http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.2.tar.bz2 2. Descompacte-o na pasta /usr/src/: # cd /usr/src # tar -xvjf linux-2.6.2.tar. bz2 3. Recrie o link simblico "linux" apontando para a pasta do novo kernel: # ln -s /usr/src/linux-2.6.2 linux 4. Entre no diretrio /usr/src/linux: # cd /usr/scr /linux 5. Resete as configuraes do kernel: # make mrproper 6. Configure os mdulos d o seu kernel: # make xconfig Existem duas formas de carregar os dispositivos no kernel, como mdulo (tecla M) e como parte do kernel (tecla Y). Opte por carregar como mdulo, isto acelera a velocidade, isso necessita usar o (/etc/rc.d/rc.local) descrito acima ou o (/etc/modprobe.conf) para carregar os mdulos automaticamente . Em LOADABLE MODULE SUPPORT, habilite o carregamento automtico de mdulos, ele vai tentar carregar as dependncias de um mdulo que voc esteja tentando carregar; Em PR OCESSOR TYPE, escolha o processador, um kernel especfico para o processador bem m ais rpido e estvel que um de 486. Nessa ponto, tenha em mos o manual da placa me, pl aca de vdeo, placa de TV, modem, etc; Em NETWORK SUPPORT, habilite os drivers da placa de rede. No use o (i2c) como parte do kernel, isso da futuros problemas na compilao do kernel. Em SOUND, desabilite a placa de som, recomendamos tambm que na BIOS seja desabilitado Usb, Sound, Porta paralela.

Lembre-se na parte de sistemas de arquivos habilitar suporte ao EXT2, EXT3 e Rei serFS. Em CARACTER DEVICES, coloque os drivers para AGP. Recomendao de usar estes drivers como parte do kernel. Em ATA/ATAPI/M, habilite a emulao de SCSI, pois a ma ioria dos softwares de gravao para o GNU/Linux requerem que a gravadora esteja no modo SCSI. Em GRAPHIC SUPPORT, ative o suporte a frame buffer. Ainda em frame bu ffer, ative o VGA 16-Color e o VESA VGA, estes dois como parte do kernel; Ative o driver de sua placa de vdeo como mdulo (SIS, NVIDIA, ATI, etc), seno ficar difcil d e atualizar depois, principalmente no caso da NVIDIA. Em CONSOLE DISPLAY DRIVER SUPPORT, ative o VGA TEXT CONSOLE e o VIDEO MODE SELECTION SUPPORT. Ative o FRAM EBUFFER CONSOLE SUPPORT, selecione tambm SELECT COMPILEDIN FONTE e marque as font es 8x8, 8x16 e 4x6. Ative em LOGO CONFIGURATION todas as opes. 7. Limpe os arquivo s temporrios e de instalao: # make clean 8. Compile a imagem do kernel: # make bzIm age 9. Compile os mdulos do kernel (isso mesmo s um make): # make 10. Instale os md ulos do kernel: # make modules_install 11. Copie a imagem gerada para o /boot/: # cp /usr/src/linux-2.6.2/arch/i386/boot/bzImage /boot/linux-2.6.2 12. Edite o / etc/lilo.conf: # vi /etc/lilo.conf e inclua as seguintes linhas no arquivo: imag e=/boot/linux-2.6.2 label=Linux-2.6.2 read-only 13. Atualize o boot do sistema: # lilo Figura 1 Exemplo de configurao do Kernel (Reis, 2006). Captulo 6 - Concluso Durante a pesquisa encontramos algumas aplicaes, conforme descrio anterior que foram implementadas, a fim de aperfeioar o desempenho do Squid. No entanto a nossa apl icao principal foi com o banco de dados PostgreSQL, na qual demonstrou que a sua i mplementao com o Squid pode ser uma boa alternativa, tanto em desempenho quanto na economia de hardware. Nas pesquisas foram encontradas somente uma pessoa (Alvar o Mendes de Oliveira (2006) - Squid Plus com AD, redirector, controle de banda e relatrios) que implementou este mtodo com o banco de dados Mysql. Nossos testes d emonstraram que com um hardware especifico, compilando o kernel somente com o mni mo e no compartilhando servios, adicionando o recurso de HDparm corretamente ao di sco rgido, e com a implementao do uso do banco de dados o aumento na velocidade de transferncia e resposta do Squid aumentada.

O programa fez a busca no banco de dados e retornou ao Squid com maior velocidad e, isto , deixou-se de utilizar consideravelmente a memria fsica do equipamento (RA M) e passou-se a utilizar o disco rgido (HD) utilizando para isto softwares como o Postgres para responder as requisies com muito mais velocidade. Com tudo isto qu e apresentamos neste trabalho, podemos concluir que ao utilizar estas ferramenta s em conjunto (Front-end, HDparm, compilao de Kernel), podemos melhorar a performa nce do Squid sem alterar a estrutura do hardware. Assim sendo, com idias simples economizamos um investimento em hardware que era o nosso objetivo inicial. Lista de anexos Scripts utilizados para o front-end com Mysql Ligao Bases de Dados: #!/usr/bin/per l use DBI; #mdulo para acesso a bases de dados $database="test"; #identificador d a base de dados $username="g2c"; #utilizador da base de dados $password="teste"; #password do utilizador da base de dados $host="locahost"; #hostname da base de dados print "Content-type: text/plain\n\n"; print "A testar ligacao a BD\n\n"; # estabelecer a ligacao my $dbh = DBI->connect( "DBI:mysql:database=$database;ho st=$host", $username,$password); if ($dbh) { print "Ligado!\n"; } else { print " Erro na Ligacao!: $?, $!, $dbh\n"; } if ($dbh) { $dbh->disconnect; } exit(0); Cr iao de uma Tabela: #!/usr/bin/perl use DBI; $database="test"; $username="g2c"; $pa ssword="teste"; $host="localhost"; print "Content-type: text/plain\n\n";

print "\n"; my $dbh=DBI->connect( "DBI:mysql:database=$database;host=$host", $us ername,$password); if ($dbh) { print "Ligado!\n"; } else { print "Falha na Ligac ao: $?, $!, $dbh\n"; } $dbh->do( "CREATE TABLE squid (id INT NOT NULL AUTO_INCRE MENT, " . "url VARCHAR (200), PRIMARY KEY(id))") or print "Falha na criacao da t abela\n"; if ($dbh) { $dbh->disconnect; } exit(0); Remover uma Tabela: #!/usr/bi n/perl use DBI; $database="test"; $username="g2c"; $password="teste"; $host="loc alhost"; print "Content-type: text/plain\n\n"; print "\n"; my $dbh=DBI->connect( "DBI:mysql:database=$database;host=$host", $username,$password); if ($dbh) { pri nt "connected\n"; } else { print "not connected: $?, $!, $dbh\n"; } $dbh->do("DR OP TABLE squid") or print "Falha na eliminacao da tabela\n"; if ($dbh) { $dbh->d isconnect; } exit(0); Acesso aos Dados de uma Tabela: #!/usr/bin/perl use DBI; $ database="test"; $username="g2c"; $password="teste"; $host="localhost"; print "C ontent-type: text/html\n\n"; print "\n"; my $dbh=DBI->connect("DBI:mysql:databas e=$database;host=$host", $username,$password);

if ($dbh) { print "Ligado!\n"; } else { print "Erro na Ligacao!: $?, $!, $dbh\n" ; } my $sth=$dbh->prepare("SELECT * FROM squid"); $sth->execute(); while(my $ref = $sth->fetchrow_hashref()) { print "<tr><td>$ref->{ url }</td></tr>\n"; } prin t "</table>\n"; if ($dbh) { $dbh->disconnect; } exit(0); Criao de um Registo numa Tabela: #!/usr/bin/perl use DBI; $database="test"; $username="g2c"; $password="t este"; $host="localhost"; print "Content-type: text/plain\n\n"; print "\n"; my $ dbh=DBI->connect("DBI:mysql:database=$database;host=$host", $username,$password) ; if ($dbh) { print "Ligado!\n"; } else { print "Falha na Ligao: $?, $!, $dbh\n"; } $dbh->do("INSERT INTO squid VALUES( 4 , www.sex.com )") or print "Falha na ins ercao\n"; if ($dbh) { $dbh->disconnect; } exit(0); Comandos usados na criao das ta belas. ############Copiando os dados para a tabela###################### copy sq uid from /home/squid/squid.txt delimiter as , ; ############################# ################################### #########Criando a tabela direto no banco bd black################ psql -f tabelasites bdblack ############################## ################################### cat urls | awk -F "/" {print$1"/"$2","$2}

Hardware Recomendado Para Quantidade de Usuarios Configuracao Ideal * Quantidade de Usuarios Hardware Recomendado MotherBoard Memoria Processador Ate 50 ** HD I DE/SATA Placa de Rede Quantidade de Usuarios Hardware Recomendado MotherBoard Me moria Processador Ate 100 HD IDE/SATA Placa de Rede Quantidade de Usuarios Hardw are Recomendado MotherBoard Memoria Processador Ate 500 HD IDE/SATA/SCSI Placa d e Rede Quantidade de Usuarios Hardware Recomendado MotherBoard Memoria Processad or Ate 1000 HD IDE/SATA/SCSI Placa de Rede Configuracoes Intel ou Via 1 Gb Intel Celeron D 2.8 Ghz 40 Gb Intel ou Realtek C onfiguracoes Intel ou Via 1 Gb Intel Pentium 4 HT 3 Ghz 80 Gb Intel ou Realtek C onfiguracoes Intel ou Via 2 Gb Intel Pentium 4 HT 3.4 Ghz 120 Gb Intel ou Realte k Configuracoes Intel com Chipset Intel 3 Gb Intel Pentium 4 HT 3.4 Ghz 80 Gb In tel ou Realtek Quantidade 1 1 1 1 2 a3 Quantidade 1 1 1 1 3 Quantidade 1 2 1 1 3 Quantidade 1 3 2 2 3 Quantidade 1 3 2 2 3 Quantidade de Usuarios Hardware Recomendado Configuracoes MotherBoard Intel Xeon com Chipset Intel Memoria 4 Gb Processador Intel Xeon 3.4 Ghz Acima de 1000 HD /SATA/SCSI 120 Gb Placa de Rede Intel ou Realtek Obs: Jamais utilizar a motherbo rd com Chipset SIS *Considerando padroes que nao sejam altos de e-mail e pager v iew **Para 50 usurios /contas de e-mail: Celeron D 2.53Ghz com 1Gb de RAM, CDROM, HD de 40Gb, 2 placas de rede. (*) Com base no cenrio abaixo -50 usuarios logados simultneos link de 1Mbit -24 Mbytes de trfego de e-mails (Antivirus e AntiSpam) 72 hits hora no Webmail -840 Acesso hora POP

squid.conf http_port 3128 hierarchy_stoplist cgi-bin ? acl QUERY urlpath_regex c gi-bin \? no_cache deny QUERY cache_mem 32 MB cache_swap_low 90 cache_swap_high 95 maximum_object_size 4098 KB minimum_object_size 0 KB maximum_object_size_in_m emory 8 KB redirect_program /home/squid/consulta.pl cache_dir ufs /var/lib/squid /cache 100 16 256 cache_access_log /var/lib/squid/logs/access.log cache_log /var /lib/squid/logs/cache.log cache_store_log /var/lib/squid/logs/store.log pid_file name /var/lib/squid/logs/squid.pid client_netmask 255.255.255.0 dns_retransmit_i nterval 5 seconds dns_timeout 2 minutes dns_nameservers 192.168.170.1 refresh_pa ttern ^ftp: 1440 20% 10080 refresh_pattern ^gopher: 1440 0% 1440 refresh_pattern . 0 20% 4320 acl all src 0.0.0.0/0.0.0.0 acl manager proto cache_object acl loc alhost src 127.0.0.1/255.255.255.255 acl to_localhost dst 127.0.0.0/8 acl SSL_po rts port 443 563 acl Safe_ports port 80 # http acl Safe_ports port 21 # ftp acl Safe_ports port 443 563 # https, snews acl Safe_ports port 70 # gopher acl Safe_ ports port 210 # wais acl Safe_ports port 1025-65535 # unregistered ports acl Sa fe_ports port 280 # http-mgmt acl Safe_ports port 488 # gss-http acl Safe_ports port 591 # filemaker acl Safe_ports port 777 # multiling http acl CONNECT method CONNECT #Recommended minimum configuration: # # Only allow cachemgr access from localhost http_access allow manager localhost http_access deny manager # Deny r equests to unknown ports

http_access deny !Safe_ports # Deny CONNECT to other than SSL ports http_access deny CONNECT !SSL_ports emulate_httpd_log on ## Autenticacao ################### ############################## auth_param basic program /usr/libexec/ncsa_auth / etc/squid/passwd auth_param basic children 5 auth_param basic realm Entre com o USUARIO E SENHA! auth_param basic casesensitive off ##bloqueia por url########## ################## acl gruporestrito proxy_auth "/etc/squid/grprestrito" acl gru posacesso proxy_auth "/etc/squid/grpacessototal" acl bloqueios_url url_regex "/e tc/squid/siteproibido" acl formato_proibe urlpath_regex "/etc/squid/formatosproi bidos" ## Listas de acesso ########################### acl autenticacao proxy_au th REQUIRED http_access allow gruposacesso http_access deny bloqueios_url http_a ccess deny formato_proibe http_access allow gruporestrito http_reply_access allo w all acl our_networks src 192.168.170.0/24 http_access allow our_networks icp_a ccess allow all cache_mgr spekitru@yahoo.com.br visible_hostname spekitru.servid or.com.br error_directory /usr/share/squid/errors/Portuguese http_access deny al l

/* * $Id: acl.c,v 1.270.2.29 2004/09/25 11:56:16 hno Exp $ * * DEBUG: section 28 * * SQUID Web Proxy Cache * * Squid is the result of efforts by numerous indivi duals from * the Internet community; see the CONTRIBUTORS file for full * detail s. Many organizations have provided support for Squid s * development; see the S PONSORS file for full details. Squid is * Copyrighted (C) 2001 by the Regents of the University of * California; see the COPYRIGHT file for full details. Squid * incorporates software developed and/or copyrighted by other * sources; see the CREDITS file for full details. * * This program is free software; you can redis tribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the impli ed 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 t he Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 0211 1, USA. * */ #include "squid.h" http://www.squid-cache.org/ * --------------------------------------------------------Access Control * AUTHOR: Duane Wessels

#include "splay.h" static void aclParseDomainList(void *curlist); static void ac lParseUserList(void **current); static void aclParseIpList(void *curlist); stati c void aclParseIntlist(void *curlist); #if SQUID_SNMP static void aclParseWordLi st(void *curlist); #endif static void aclParseProtoList(void *curlist); static v oid aclParseMethodList(void *curlist); static void aclParseTimeSpec(void *curlis t); static void aclParseIntRange(void *curlist); static void aclDestroyTimeList( acl_time_data * data); static void aclDestroyIntRange(intrange *); static void a clLookupProxyAuthStart(aclCheck_t * checklist); static void aclLookupProxyAuthDo ne(void *data, char *result); static struct _acl *aclFindByName(const char *name ); static int aclMatchAcl(struct _acl *, aclCheck_t *); static int aclMatchTime( acl_time_data * data, time_t when); static int aclMatchUser(void *proxyauth_acl, char *user); static int aclMatchIp(void *dataptr, struct in_addr c); static int aclMatchDomainList(void *dataptr, const char *); static int aclMatchIntegerRang e(intrange * data, int i); #if SQUID_SNMP static int aclMatchWordList(wordlist * , const char *); #endif static void aclParseUserMaxIP(void *data); static void a clDestroyUserMaxIP(void *data); static wordlist *aclDumpUserMaxIP(void *data); s tatic int aclMatchUserMaxIP(void *, auth_user_request_t *, struct in_addr); stat ic void aclParseHeader(void *data); static void aclDestroyHeader(void *data); st atic squid_acl aclStrToType(const char *s); static int decode_addr(const char *, struct in_addr *, struct in_addr *);

static void aclCheck(aclCheck_t * checklist); static void aclCheckCallback(aclCh eck_t * checklist, allow_t answer); #if USE_IDENT static IDCB aclLookupIdentDone ; #endif static IPH aclLookupDstIPDone; static IPH aclLookupDstIPforASNDone; sta tic FQDNH aclLookupSrcFQDNDone; static FQDNH aclLookupDstFQDNDone; static EAH ac lLookupExternalDone; static wordlist *aclDumpIpList(void *); static wordlist *ac lDumpDomainList(void *data); static wordlist *aclDumpTimeSpecList(acl_time_data *); static wordlist *aclDumpRegexList(relist * data); static wordlist *aclDumpIn tlistList(intlist * data); static wordlist *aclDumpIntRangeList(intrange * data) ; static wordlist *aclDumpProtoList(intlist * data); static wordlist *aclDumpMet hodList(intlist * data); static SPLAYCMP aclIpAddrNetworkCompare; static SPLAYCM P aclIpNetworkCompare; static SPLAYCMP aclHostDomainCompare; static SPLAYCMP acl DomainCompare; static SPLAYWALKEE aclDumpIpListWalkee; static SPLAYWALKEE aclDum pDomainListWalkee; static SPLAYFREE aclFreeIpData; #if USE_ARP_ACL static void a clParseArpList(void *curlist); static int decode_eth(const char *asc, char *eth) ; static int aclMatchArp(void *dataptr, struct in_addr c); static wordlist *aclD umpArpList(void *); static SPLAYCMP aclArpCompare; static SPLAYWALKEE aclDumpArp ListWalkee; #endif static int aclCacheMatchAcl(dlink_list * cache, squid_acl acl type, void *data, char

*MatchParam); static squid_acl aclStrToType(const char *s) { if (!strcmp(s, "src ")) return ACL_SRC_IP; if (!strcmp(s, "dst")) return ACL_DST_IP; if (!strcmp(s, "myip")) return ACL_MY_IP; if (!strcmp(s, "domain")) return ACL_DST_DOMAIN; if ( !strcmp(s, "dstdomain")) return ACL_DST_DOMAIN; if (!strcmp(s, "srcdomain")) ret urn ACL_SRC_DOMAIN; if (!strcmp(s, "dstdom_regex")) return ACL_DST_DOM_REGEX; if (!strcmp(s, "srcdom_regex")) return ACL_SRC_DOM_REGEX; if (!strcmp(s, "time")) return ACL_TIME; if (!strcmp(s, "pattern")) return ACL_URLPATH_REGEX; if (!strcm p(s, "urlpath_regex")) return ACL_URLPATH_REGEX; if (!strcmp(s, "url_regex")) re turn ACL_URL_REGEX; if (!strcmp(s, "port")) return ACL_URL_PORT; if (!strcmp(s, "myport")) return ACL_MY_PORT; if (!strcmp(s, "maxconn")) return ACL_MAXCONN;

#if USE_IDENT if (!strcmp(s, "ident")) return ACL_IDENT; if (!strcmp(s, "ident_r egex")) return ACL_IDENT_REGEX; #endif if (!strncmp(s, "proto", 5)) return ACL_P ROTO; if (!strcmp(s, "method")) return ACL_METHOD; if (!strcmp(s, "browser")) re turn ACL_BROWSER; if (!strcmp(s, "referer_regex")) return ACL_REFERER_REGEX; if (!strcmp(s, "proxy_auth")) return ACL_PROXY_AUTH; if (!strcmp(s, "proxy_auth_reg ex")) return ACL_PROXY_AUTH_REGEX; if (!strcmp(s, "src_as")) return ACL_SRC_ASN; if (!strcmp(s, "dst_as")) return ACL_DST_ASN; #if SQUID_SNMP if (!strcmp(s, "sn mp_community")) return ACL_SNMP_COMMUNITY; #endif #if SRC_RTT_NOT_YET_FINISHED i f (!strcmp(s, "src_rtt")) return ACL_NETDB_SRC_RTT; #endif #if USE_ARP_ACL if (! strcmp(s, "arp")) return ACL_SRC_ARP; #endif if (!strcmp(s, "req_mime_type"))

return ACL_REQ_MIME_TYPE; if (!strcmp(s, "rep_mime_type")) return ACL_REP_MIME_T YPE; if (!strcmp(s, "rep_header")) return ACL_REP_HEADER; if (!strcmp(s, "req_he ader")) return ACL_REQ_HEADER; if (!strcmp(s, "max_user_ip")) return ACL_MAX_USE R_IP; if (!strcmp(s, "external")) return ACL_EXTERNAL; if (!strcmp(s, "urllogin" )) return ACL_URLLOGIN; return ACL_NONE; } const char * aclTypeToStr(squid_acl t ype) { if (type == ACL_SRC_IP) return "src"; if (type == ACL_DST_IP) return "dst "; if (type == ACL_MY_IP) return "myip"; if (type == ACL_DST_DOMAIN) return "dst domain"; if (type == ACL_SRC_DOMAIN) return "srcdomain"; if (type == ACL_DST_DOM _REGEX) return "dstdom_regex"; if (type == ACL_SRC_DOM_REGEX) return "srcdom_reg ex"; if (type == ACL_TIME) return "time";

if (type == ACL_URLPATH_REGEX) return "urlpath_regex"; if (type == ACL_URL_REGEX ) return "url_regex"; if (type == ACL_URL_PORT) return "port"; if (type == ACL_M Y_PORT) return "myport"; if (type == ACL_MAXCONN) return "maxconn"; #if USE_IDEN T if (type == ACL_IDENT) return "ident"; if (type == ACL_IDENT_REGEX) return "id ent_regex"; #endif if (type == ACL_PROTO) return "proto"; if (type == ACL_METHOD ) return "method"; if (type == ACL_BROWSER) return "browser"; if (type == ACL_RE FERER_REGEX) return "referer_regex"; if (type == ACL_PROXY_AUTH) return "proxy_a uth"; if (type == ACL_PROXY_AUTH_REGEX) return "proxy_auth_regex"; if (type == A CL_SRC_ASN) return "src_as"; if (type == ACL_DST_ASN) return "dst_as"; #if SQUID _SNMP if (type == ACL_SNMP_COMMUNITY) return "snmp_community";

#endif #if SRC_RTT_NOT_YET_FINISHED if (type == ACL_NETDB_SRC_RTT) return "src_r tt"; #endif #if USE_ARP_ACL if (type == ACL_SRC_ARP) return "arp"; #endif if (ty pe == ACL_REQ_MIME_TYPE) return "req_mime_type"; if (type == ACL_REP_MIME_TYPE) return "rep_mime_type"; if (type == ACL_REP_HEADER) return "rep_header"; if (typ e == ACL_REQ_HEADER) return "req_header"; if (type == ACL_MAX_USER_IP) return "m ax_user_ip"; if (type == ACL_EXTERNAL) return "external"; if (type == ACL_URLLOG IN) return "urllogin"; return "ERROR"; } static acl * aclFindByName(const char * name) { acl *a; for (a = Config.aclList; a; a = a->next) if (!strcasecmp(a->name , name)) return a; return NULL; }

static void aclParseIntlist(void *curlist) { intlist **Tail; intlist *q = NULL; char *t = NULL; for (Tail = curlist; *Tail; Tail = &((*Tail)->next)); while ((t = strtokFile())) { q = memAllocate(MEM_INTLIST); q->i = atoi(t); *(Tail) = q; Ta il = &q->next; } } static void aclParseIntRange(void *curlist) { intrange **Tail ; intrange *q = NULL; char *t = NULL; for (Tail = curlist; *Tail; Tail = &((*Tai l)->next)); while ((t = strtokFile())) { q = xcalloc(1, sizeof(intrange)); q->i = atoi(t); t = strchr(t, - ); if (t && *(++t)) q->j = atoi(t); else q->j = q->i ; *(Tail) = q; Tail = &q->next; } }

static void aclParseProtoList(void *curlist) { intlist **Tail; intlist *q = NULL ; char *t = NULL; protocol_t protocol; for (Tail = curlist; *Tail; Tail = &((*Ta il)->next)); while ((t = strtokFile())) { protocol = urlParseProtocol(t); q = me mAllocate(MEM_INTLIST); q->i = (int) protocol; *(Tail) = q; Tail = &q->next; } } static void aclParseMethodList(void *curlist) { intlist **Tail; intlist *q = NU LL; char *t = NULL; for (Tail = curlist; *Tail; Tail = &((*Tail)->next)); while ((t = strtokFile())) { q = memAllocate(MEM_INTLIST); q->i = (int) urlParseMethod (t); *(Tail) = q; Tail = &q->next; } } /* * Decode a ascii representation (asc) of a IP adress, and place

* adress and netmask information in addr and mask. * This function should NOT be called if asc is a hostname! */ static int decode_addr(const char *asc, struc t in_addr *addr, struct in_addr *mask) { u_num32 a; int a1 = 0, a2 = 0, a3 = 0, a4 = 0; switch (sscanf(asc, "%d.%d.%d.%d", &a1, &a2, &a3, &a4)) { case 4: /* a d otted quad */ if (!safe_inet_addr(asc, addr)) { debug(28, 0) ("decode_addr: unsa fe IP address: %s \n", asc); fatal("decode_addr: unsafe IP address"); } break; case 1: /* a significant bits value for a mask */ if (a1 >= 0 && a1 < 33) { addr ->s_addr = a1 ? htonl(0xfffffffful << (32 - a1)) : 0; break; } default: debug(28 , 0) ("decode_addr: Invalid IP address %s \n", asc); return 0; } if (mask != NU LL) { /* Guess netmask */ a = (u_num32) ntohl(addr->s_addr); if (!(a & 0xFFFFFFF Ful)) mask->s_addr = htonl(0x00000000ul); else if (!(a & 0x00FFFFFF)) mask->s_ad dr = htonl(0xFF000000ul); else if (!(a & 0x0000FFFF)) /* mask == NULL if called to decode a netmask */ /* This is not valid address */

mask->s_addr = htonl(0xFFFF0000ul); else if (!(a & 0x000000FF)) mask->s_addr = h tonl(0xFFFFFF00ul); else mask->s_addr = htonl(0xFFFFFFFFul); } return 1; } #define SCAN_ACL1 #define SCAN_ACL2 #define SCAN_ACL3 #define SCAN_ACL4 static a cl_ip_data * "%[0123456789.]-%[0123456789.]/%[0123456789.]" "%[0123456789.]-%[0123456789.]%c" "%[0123456789.]/%[0123456789.]" "%[0123456789.]%c" aclParseIpData(const char *t) { LOCAL_ARRAY(char, addr1, 256); LOCAL_ARRAY(char, addr2, 256); LOCAL_ARRAY(char, mask, 256); acl_ip_data *q = memAllocate(MEM_ACL _IP_DATA); acl_ip_data *r; acl_ip_data **Q; struct hostent *hp; char **x; char c ; debug(28, 5) ("aclParseIpData: %s\n", t); if (!strcasecmp(t, "all")) { q->addr 1.s_addr = 0; q->addr2.s_addr = 0; q->mask.s_addr = 0; return q; } if (sscanf(t, SCAN_ACL1, addr1, addr2, mask) == 3) {

(void) 0; } else if (sscanf(t, SCAN_ACL2, addr1, addr2, &c) == 2) { mask[0] = \ 0 ; } else if (sscanf(t, SCAN_ACL3, addr1, mask) == 2) { addr2[0] = \0 ; } else if (sscanf(t, SCAN_ACL4, addr1, &c) == 1) { addr2[0] = \0 ; mask[0] = \0 ; } else if (sscanf(t, "%[^/]/%s", addr1, mask) == 2) { addr2[0] = \0 ; } else if ( sscanf(t, "%s", addr1) == 1) { /* * Note, must use plain gethostbyname() here be cause at startup * ipcache hasn t been initialized */ if ((hp = gethostbyname(ad dr1)) == NULL) { debug(28, 0) ("aclParseIpData: Bad host/IP: %s \n", t); safe_f ree(q); return NULL; } Q = &q; for (x = hp->h_addr_list; x != NULL && *x != NULL ; x++) { if ((r = *Q) == NULL) r = *Q = memAllocate(MEM_ACL_IP_DATA); xmemcpy(&r ->addr1.s_addr, *x, sizeof(r->addr1.s_addr)); r->addr2.s_addr = 0; r->mask.s_add r = no_addr.s_addr; Q = &r->next; debug(28, 3) ("%s --> %s\n", addr1, inet_ntoa( r->addr1)); } return q; } else { debug(28, 0) ("aclParseIpData: Bad host/IP: %s \n", t); safe_free(q); return NULL; /* 255.255.255.255 */

} /* Decode addr1 */ if (!decode_addr(addr1, &q->addr1, &q->mask)) { debug(28, 0 ) ("%s line %d: %s\n", cfg_filename, config_lineno, config_input_line); debug(28 , 0) ("aclParseIpData: Ignoring invalid IP acl entry: unknown first address %s \n", addr1); safe_free(q); return NULL; } /* Decode addr2 */ if (*addr2 && !deco de_addr(addr2, &q->addr2, &q->mask)) { debug(28, 0) ("%s line %d: %s\n", cfg_fil ename, config_lineno, config_input_line); debug(28, 0) ("aclParseIpData: Ignorin g invalid IP acl entry: unknown second address %s \n", addr2); safe_free(q); re turn NULL; } /* Decode mask */ if (*mask && !decode_addr(mask, &q->mask, NULL)) { debug(28, 0) ("%s line %d: %s\n", cfg_filename, config_lineno, config_input_li ne); debug(28, 0) ("aclParseIpData: Ignoring invalid IP acl entry: unknown netma sk %s \n", mask); safe_free(q); return NULL; } if ((q->addr1.s_addr & q->mask.s _addr) != q->addr1.s_addr || (q->addr2.s_addr & q->mask.s_addr) != q->addr2.s_ad dr) debug(28, 0) ("aclParseIpData: WARNING: Netmask masks away part of the speci fied IP in %s \n", t); q->addr1.s_addr &= q->mask.s_addr; q->addr2.s_addr &= q>mask.s_addr; /* 1.2.3.4/255.255.255.0 --> 1.2.3.0 */

return q; } /******************/ /* aclParseIpList */ /******************/ stati c void aclParseIpList(void *curlist) { char *t = NULL; splayNode **Top = curlist ; acl_ip_data *q = NULL; while ((t = strtokFile())) { q = aclParseIpData(t); whi le (q != NULL) { *Top = splay_insert(q, *Top, aclIpNetworkCompare); q = q->next; } } } static void aclParseTimeSpec(void *curlist) { acl_time_data *q = NULL; ac l_time_data **Tail; int h1, m1, h2, m2; char *t = NULL; long weekbits = 0; for ( Tail = curlist; *Tail; Tail = &((*Tail)->next)); while ((t = strtokFile())) { if (*t < 0 || *t > 9 ) { /* assume its day-of-week spec */ while (*t) {

switch (*t++) { case S : weekbits |= ACL_SUNDAY; break; case M : weekbits |= A CL_MONDAY; break; case T : weekbits |= ACL_TUESDAY; break; case W : weekbits | = ACL_WEDNESDAY; break; case H : weekbits |= ACL_THURSDAY; break; case F : wee kbits |= ACL_FRIDAY; break; case A : weekbits |= ACL_SATURDAY; break; case D : weekbits |= ACL_WEEKDAYS; break; case - : /* ignore placeholder */ break; defa ult: debug(28, 0) ("%s line %d: %s\n", cfg_filename, config_lineno, config_input _line); debug(28, 0) ("aclParseTimeSpec: Bad Day %c \n", *t); break; } }

} else { /* assume its time-of-day spec */ if (sscanf(t, "%d:%d-%d:%d", &h1, &m1 , &h2, &m2) < 4) { debug(28, 0) ("%s line %d: %s\n", cfg_filename, config_lineno , config_input_line); debug(28, 0) ("aclParseTimeSpec: IGNORING Bad time range\n "); memFree(q, MEM_ACL_TIME_DATA); return; } q = memAllocate(MEM_ACL_TIME_DATA); q->start = h1 * 60 + m1; q->stop = h2 * 60 + m2; q->weekbits = weekbits; weekbi ts = 0; if (q->start > q->stop) { debug(28, 0) ("%s line %d: %s\n", cfg_filename , config_lineno, config_input_line); debug(28, 0) ("aclParseTimeSpec: IGNORING R eversed time range\n"); memFree(q, MEM_ACL_TIME_DATA); return; } if (q->weekbits == 0) q->weekbits = ACL_ALLWEEK; *(Tail) = q; Tail = &q->next; } } if (weekbits ) { q = memAllocate(MEM_ACL_TIME_DATA); q->start = 0 * 60 + 0; q->stop = 24 * 60 + 0; q->weekbits = weekbits; *(Tail) = q; Tail = &q->next; }

} void aclParseRegexList(void *curlist) { relist **Tail; relist *q = NULL; char *t = NULL; regex_t comp; int errcode; int flags = REG_EXTENDED | REG_NOSUB; for (Tail = curlist; *Tail; Tail = &((*Tail)->next)); while ((t = strtokFile())) { i f (strcmp(t, "-i") == 0) { flags |= REG_ICASE; continue; } if (strcmp(t, "+i") = = 0) { flags &= ~REG_ICASE; continue; } if ((errcode = regcomp(&comp, t, flags)) != 0) { char errbuf[256]; regerror(errcode, &comp, errbuf, sizeof errbuf); debu g(28, 0) ("%s line %d: %s\n", cfg_filename, config_lineno, config_input_line); d ebug(28, 0) ("aclParseRegexList: Invalid regular expression %s : %s\n", t, errb uf); continue; } q = memAllocate(MEM_RELIST); q->pattern = xstrdup(t); q->regex = comp; *(Tail) = q; Tail = &q->next;

} } static void aclParseHeader(void *data) { char *t; acl_hdr_data **hd = data; acl_hdr_data *q; t = strtokFile(); if (NULL == t) { debug(28, 0) ("%s line %d: % s\n", cfg_filename, config_lineno, config_input_line); debug(28, 0) ("aclParseHe ader: No data defined %s \n", t); return; } q = xcalloc(1, sizeof(acl_hdr_data) ); q->hdr_name = xstrdup(t); q->hdr_id = httpHeaderIdByNameDef(t, strlen(t)); ac lParseRegexList(q->reglist); if (!q->reglist) { debug(28, 0) ("%s line %d: %s\n" , cfg_filename, config_lineno, config_input_line); debug(28, 0) ("aclParseHeader : No pattern defined %s \n", t); aclDestroyHeader(&q); return; } while (*hd) hd = &(*hd)->next; *hd = q; } static int aclMatchHeader(acl_hdr_data * hdrs, const HttpHeader * hdr) { acl_hdr_data *hd;

for (hd = hdrs; hd; hd = hd->next) { int ret; String header; if (hd->hdr_id != 1) header = httpHeaderGetStrOrList(hdr, hd->hdr_id); else header = httpHeaderGet ByName(hdr, hd->hdr_name); if (!strBuf(header)) continue; ret = aclMatchRegex(hd ->reglist, strBuf(header)); stringClean(&header); if (ret) return 1; } return 0; } void aclDestroyHeader(void *data) { acl_hdr_data **acldata = data; while (*ac ldata) { acl_hdr_data *q = *acldata; *acldata = q->next; if (q->reglist) aclDest royRegexList((*acldata)->reglist); safe_free(q); } } static wordlist * aclDumpHe ader(acl_hdr_data * hd) { wordlist *W = NULL; relist *data = hd->reglist;

wordlistAdd(&W, httpHeaderNameById(hd->hdr_id)); while (data != NULL) { wordlist Add(&W, data->pattern); data = data->next; } return aclDumpRegexList(hd->reglist ); } #if SQUID_SNMP static void aclParseWordList(void *curlist) { char *t = NULL ; while ((t = strtokFile())) wordlistAdd(curlist, t); } #endif static void aclPa rseUserList(void **current) { char *t = NULL; acl_user_data *data; splayNode *To p = NULL; debug(28, 2) ("aclParseUserList: parsing user list\n"); t = strtokFile (); if (!t) { debug(28, 2) ("aclParseUserList: No data defined\n"); return; } de bug(28, 5) ("aclParseUserList: First token is %s\n", t); if (*current == NULL) { debug(28, 3) ("aclParseUserList: current is null. Creating\n"); *current = memA llocate(MEM_ACL_USER_DATA);

} data = *current; Top = data->names; if (strcmp("-i", t) == 0) { debug(28, 5) ( "aclParseUserList: Going case-insensitive\n"); data->flags.case_insensitive = 1; } else if (strcmp("REQUIRED", t) == 0) { debug(28, 5) ("aclParseUserList: REQUI RED-type enabled\n"); data->flags.required = 1; } else { if (data->flags.case_in sensitive) Tolower(t); Top = splay_insert(xstrdup(t), Top, (SPLAYCMP *) strcmp); } debug(28, 3) ("aclParseUserList: Case-insensitive-switch is %d\n", data->flag s.case_insensitive); /* we might inherit from a previous declaration */ debug(28 , 4) ("aclParseUserList: parsing user list\n"); while ((t = strtokFile())) { deb ug(28, 6) ("aclParseUserList: Got token: %s\n", t); if (data->flags.case_insensi tive) Tolower(t); Top = splay_insert(xstrdup(t), Top, (SPLAYCMP *) strcmp); } da ta->names = Top; } /**********************/ /* aclParseDomainList */ /**********************/ stati c void aclParseDomainList(void *curlist)

{ char *t = NULL; splayNode **Top = curlist; while ((t = strtokFile())) { Tolowe r(t); *Top = splay_insert(xstrdup(t), *Top, aclDomainCompare); } } void aclParse AclLine(acl ** head) { /* we re already using strtok() to grok the line */ char *t = NULL; acl *A = NULL; LOCAL_ARRAY(char, aclname, ACL_NAME_SZ); squid_acl acl type; int new_acl = 0; /* snarf the ACL name */ if ((t = strtok(NULL, w_space)) == NULL) { debug(28, 0) ("%s line %d: %s\n", cfg_filename, config_lineno, config _input_line); debug(28, 0) ("aclParseAclLine: missing ACL name.\n"); return; } x strncpy(aclname, t, ACL_NAME_SZ); /* snarf the ACL type */ if ((t = strtok(NULL, w_space)) == NULL) { debug(28, 0) ("%s line %d: %s\n", cfg_filename, config_lin eno, config_input_line); debug(28, 0) ("aclParseAclLine: missing ACL type.\n"); return; } if ((acltype = aclStrToType(t)) == ACL_NONE) {

debug(28, 0) ("%s line %d: %s\n", cfg_filename, config_lineno, config_input_line ); debug(28, 0) ("aclParseAclLine: Invalid ACL type %s \n", t); return; } if (( A = aclFindByName(aclname)) == NULL) { debug(28, 3) ("aclParseAclLine: Creating ACL %s \n", aclname); A = memAllocate(MEM_ACL); xstrncpy(A->name, aclname, ACL_ NAME_SZ); A->type = acltype; A->cfgline = xstrdup(config_input_line); new_acl = 1; } else { if (acltype != A->type) { debug(28, 0) ("aclParseAclLine: ACL %s a lready exists with different type, skipping.\n", A->name); return; } debug(28, 3 ) ("aclParseAclLine: Appending to %s \n", aclname); new_acl = 0; } /* * Here we set AclMatchedName in case we need to use it in a * warning message in aclDomai nCompare(). */ AclMatchedName = aclname; /* ugly */ switch (A->type) { case ACL_ SRC_IP: case ACL_DST_IP: case ACL_MY_IP: aclParseIpList(&A->data); break; case A CL_SRC_DOMAIN: case ACL_DST_DOMAIN: aclParseDomainList(&A->data);

break; case ACL_TIME: aclParseTimeSpec(&A->data); break; case ACL_URL_REGEX: cas e ACL_URLLOGIN: case ACL_URLPATH_REGEX: case ACL_BROWSER: case ACL_REFERER_REGEX : case ACL_SRC_DOM_REGEX: case ACL_DST_DOM_REGEX: case ACL_REQ_MIME_TYPE: case A CL_REP_MIME_TYPE: aclParseRegexList(&A->data); break; case ACL_REP_HEADER: case ACL_REQ_HEADER: aclParseHeader(&A->data); break; case ACL_SRC_ASN: case ACL_MAXC ONN: case ACL_DST_ASN: aclParseIntlist(&A->data); break; case ACL_MAX_USER_IP: a clParseUserMaxIP(&A->data); break; #if SRC_RTT_NOT_YET_FINISHED case ACL_NETDB_S RC_RTT: aclParseIntlist(&A->data); break; #endif case ACL_URL_PORT: case ACL_MY_ PORT: aclParseIntRange(&A->data);

break; #if USE_IDENT case ACL_IDENT: aclParseUserList(&A->data); break; case ACL _IDENT_REGEX: aclParseRegexList(&A->data); break; #endif case ACL_PROTO: aclPars eProtoList(&A->data); break; case ACL_METHOD: aclParseMethodList(&A->data); brea k; case ACL_PROXY_AUTH: if (authenticateSchemeCount() == 0) { debug(28, 0) ("acl ParseAclLine: IGNORING: Proxy Auth ACL %s \ because no authentication schemes were compiled.\n", A->cfgline); } else if (authenticateActiveSchemeCount() == 0) { debug(28, 0) ("aclParseAclLine: IGNORING: Proxy Auth ACL %s \ because no au thentication schemes are fully configured.\n", A->cfgline); } else { aclParseUse rList(&A->data); } break; case ACL_PROXY_AUTH_REGEX: if (authenticateSchemeCount () == 0) { debug(28, 0) ("aclParseAclLine: IGNORING: Proxy Auth ACL %s \ becau se no authentication schemes were compiled.\n", A->cfgline); } else if (authenti cateActiveSchemeCount() == 0) { debug(28, 0) ("aclParseAclLine: IGNORING: Proxy Auth ACL %s \ because no authentication schemes are fully configured.\n", A->c fgline); } else { aclParseRegexList(&A->data);

} break; #if SQUID_SNMP case ACL_SNMP_COMMUNITY: aclParseWordList(&A->data); bre ak; #endif #if USE_ARP_ACL case ACL_SRC_ARP: aclParseArpList(&A->data); break; # endif case ACL_EXTERNAL: aclParseExternal(&A->data); break; case ACL_NONE: case ACL_ENUM_MAX: fatal("Bad ACL type"); break; } /* * Clear AclMatchedName from our temporary hack */ AclMatchedName = NULL; if (!new_acl) return; if (A->data == N ULL) { debug(28, 0) ("aclParseAclLine: IGNORING invalid ACL: %s\n", A->cfgline); memFree(A, MEM_ACL); return; } /* append */ while (*head) head = &(*head)->next ; /* ugly */

*head = A; } /* does name lookup, returns page_id */ err_type aclGetDenyInfoPage (acl_deny_info_list ** head, const char *name) { acl_deny_info_list *A = NULL; a cl_name_list *L = NULL; A = *head; if (NULL == *head) return ERR_NONE; while (A) { L = A->acl_list; if (NULL == L) continue; while (L) { if (!strcmp(name, L->na me)) return A->err_page_id; L = L->next; } A = A->next; } return ERR_NONE; } /* does name lookup, returns if it is a proxy_auth acl */ int aclIsProxyAuth(const char *name) { acl *a; if (NULL == name) return 0; if ((a = aclFindByName(name))) /* empty list should never happen, but in case */ /* empty list */

return a->type == ACL_PROXY_AUTH || a->type == ACL_PROXY_AUTH_REGEX; return 0; } /* maex@space.net (05.09.96) * * * * * * */ void aclParseDenyInfoLine(acl_deny_i nfo_list ** head) { char *t = NULL; acl_deny_info_list *A = NULL; acl_deny_info_ list *B = NULL; acl_deny_info_list **T = NULL; acl_name_list *L = NULL; acl_name _list **Tail = NULL; /* first expect a page name */ if ((t = strtok(NULL, w_spac e)) == NULL) { debug(28, 0) ("%s line %d: %s\n", cfg_filename, config_lineno, co nfig_input_line); debug(28, 0) ("aclParseDenyInfoLine: missing error page para meter.\n"); return; } A = memAllocate(MEM_ACL_DENY_INFO_LIST); A->err_page_id = errorReservePageId(t); A->err_page_name = xstrdup(t); A->next = (acl_deny_info_l ist *) NULL; get the info for redirecting "access denied" to info pages TODO (pr obably ;-) currently there is no optimization for - more than one deny_info line with the same url - a check, whether the given acl really is defined - a check, whether an acl is added more than once for the same url

/* next expect a list of ACL names */ Tail = &A->acl_list; while ((t = strtok(NU LL, w_space))) { L = memAllocate(MEM_ACL_NAME_LIST); xstrncpy(L->name, t, ACL_NA ME_SZ); *Tail = L; Tail = &L->next; } if (A->acl_list == NULL) { debug(28, 0) (" %s line %d: %s\n", cfg_filename, config_lineno, config_input_line); debug(28, sk ipping\n"); memFree(A, MEM_ACL_DENY_INFO_LIST); return; } for (B = *head, T = he ad; B; T = &B->next, B = B->next); /* find the tail */ *T = A; } void aclParseAc cessLine(acl_access ** head) { char *t = NULL; acl_access *A = NULL; acl_access *B = NULL; acl_access **T = NULL; /* first expect either allow or deny */ if ((t = strtok(NULL, w_space)) == NULL) { debug(28, 0) ("%s line %d: %s\n", cfg_f ilename, config_lineno, config_input_line); debug(28, 0) ("aclParseAccessLine: m issing allow or deny .\n"); return; } 0) ("aclParseDenyInfoLine: deny_info li ne contains no ACL s,

A = cbdataAlloc(acl_access); if (!strcmp(t, "allow")) A->allow = 1; else if (!st rcmp(t, "deny")) A->allow = 0; else { debug(28, 0) ("%s line %d: %s\n", cfg_file name, config_lineno, config_input_line); debug(28, 0) ("aclParseAccessLine: expe cting allow or deny , got %s .\n", t); cbdataFree(A); return; } aclParseAclL ist(&A->acl_list); if (A->acl_list == NULL) { debug(28, 0) ("%s line %d: %s\n", cfg_filename, config_lineno, config_input_line); debug(28, 0) ("aclParseAccessLi ne: Access line contains no ACL s, skipping\n"); cbdataFree(A); return; } A->cfg line = xstrdup(config_input_line); /* Append to the end of this list */ for (B = *head, T = head; B; T = &B->next, B = B->next); *T = A; /* We lock _acl_access structures in aclCheck() */ } void aclParseAclList(acl_list ** head) { acl_list *L = NULL; acl_list **Tail = head; acl *a = NULL; char *t; /* sane name in the u se below */

/* next expect a list of ACL names, possibly preceeded * by ! for negation */ while ((t = strtok(NULL, w_space))) { L = memAllocate(MEM_ACL_LIST); L->op = 1; if (*t == ! ) { /* negated ACL */ L->op = 0; t++; } debug(28, 3) ("aclParseAcce ssLine: looking for ACL name %s \n", t); a = aclFindByName(t); if (a == NULL) { debug(28, 0) ("%s line %d: %s\n", cfg_filename, config_lineno, config_input_lin e); debug(28, 0) ("aclParseAccessLine: ACL name %s not found.\n", t); memFree( L, MEM_ACL_LIST); continue; } L->acl = a; *Tail = L; Tail = &L->next; } } /***** *********/ /* aclMatchIp */ /**************/ static int aclMatchIp(void *dataptr , struct in_addr c) { splayNode **Top = dataptr; acl_ip_data x; /* defaults to n on-negated */

/* * aclIpAddrNetworkCompare() takes two acl_ip_data pointers as * arguments, so we must create a fake one for the client s IP * address, and use a /32 netmask. However, the current code * probably only accesses the addr1 element of this ar gument, * so it might be possible to leave addr2 and mask unset. * XXX Could eli minate these repetitive assignments with a * static structure. */ x.addr1 = c; x .addr2 = any_addr; x.mask = no_addr; x.next = NULL; *Top = splay_splay(&x, *Top, aclIpAddrNetworkCompare); debug(28, 3) ("aclMatchIp: %s %s\n", inet_ntoa(c), splayLastResult ? "NOT found" : "found"); return !splayLastResult; } /********** ************/ /* aclMatchDomainList */ /**********************/ static int aclMa tchDomainList(void *dataptr, const char *host) { splayNode **Top = dataptr; if ( host == NULL) return 0; debug(28, 3) ("aclMatchDomainList: checking %s \n", hos t); *Top = splay_splay(host, *Top, aclHostDomainCompare); debug(28, 3) ("aclMatc hDomainList: %s %s\n", host, splayLastResult ? "NOT found" : "found"); return !splayLastResult; }

int aclMatchRegex(relist * data, const char *word) { relist *first, *prev; if (w ord == NULL) return 0; debug(28, 3) ("aclMatchRegex: checking %s \n", word); fi rst = data; prev = NULL; while (data) { debug(28, 3) ("aclMatchRegex: looking fo r %s \n", data->pattern); if (regexec(&data->regex, word, 0, 0, 0) == 0) { if ( prev != NULL) { /* shift the element just found to the second position * in the list */ prev->next = data->next; data->next = first->next; first->next = data; } return 1; } prev = data; data = data->next; } return 0; } static int aclMatchUs er(void *proxyauth_acl, char *user) { acl_user_data *data = (acl_user_data *) pr oxyauth_acl; splayNode *Top = data->names; debug(28, 7) ("aclMatchUser: user is %s, case_insensitive is %d\n",

user, data->flags.case_insensitive); debug(28, 8) ("Top is %p, Top->data is %s\n ", Top, (char *) (Top != NULL ? (Top)->data : "Unavailable")); if (user == NULL || strcmp(user, "-") == 0) return 0; if (data->flags.required) { debug(28, 7) (" aclMatchUser: user REQUIRED and auth-info present.\n"); return 1; } if (data->fl ags.case_insensitive) Top = splay_splay(user, Top, (SPLAYCMP *) strcasecmp); els e Top = splay_splay(user, Top, (SPLAYCMP *) strcmp); /* Top=splay_splay(user,Top ,(SPLAYCMP *)dumping_strcmp); */ debug(28, 7) ("aclMatchUser: returning %d,Top i s %p, Top->data is %s\n", !splayLastResult, Top, (char *) (Top ? Top->data : "Un available")); data->names = Top; return !splayLastResult; } /* ACL result cachin g routines */ /* * we lookup an acl s cached results, and if we cannot find the acl being * checked we check it and cache the result. This function is deliberat ly * generic to support caching of multiple acl types (but it needs to be more * generic still.... * The Match Param and the cache MUST be tied together by the calling routine. * You have been warned :-] * Also only Matchxxx that are of the form (void *, void *) can be used. * probably some ugly overloading _could_ be done but I ll leave that as an * exercise for the reader. Note that caching of t ime based acl s is not * wise due to no expiry occuring to the cache entries unt il the user expires

* or a reconfigure takes place. * RBC */ static int aclCacheMatchAcl(dlink_list * cache, squid_acl acltype, void *data, char *MatchParam) { int matchrv; acl_pro xy_auth_match_cache *auth_match; dlink_node *link; link = cache->head; while (li nk) { auth_match = link->data; if (auth_match->acl_data == data) { debug(28, 4) ("aclCacheMatchAcl: cache hit on acl %p \n", data); return auth_match->matchrv; } link = link->next; } auth_match = NULL; /* match the user in the acl. They ar e not cached. */ switch (acltype) { case ACL_PROXY_AUTH: matchrv = aclMatchUser( data, MatchParam); break; case ACL_PROXY_AUTH_REGEX: matchrv = aclMatchRegex(dat a, MatchParam); break; default: /* This is a fatal to ensure that aclCacheMatchA cl calls are _only_ * made for supported acl types */ fatal("aclCacheMatchAcl: u nknown or unexpected ACL type"); return 0; } auth_match = memAllocate(MEM_ACL_PR OXY_AUTH_MATCH); /* NOTREACHED */

auth_match->matchrv = matchrv; auth_match->acl_data = data; dlinkAddTail(auth_ma tch, &auth_match->link, cache); return matchrv; } void aclCacheMatchFlush(dlink_ list * cache) { acl_proxy_auth_match_cache *auth_match; dlink_node *link, *tmpli nk; link = cache->head; while (link) { auth_match = link->data; tmplink = link; link = link->next; dlinkDelete(tmplink, cache); memFree(auth_match, MEM_ACL_PROX Y_AUTH_MATCH); } } /* aclMatchProxyAuth can return two exit codes: * 0 : Authori sation for this ACL failed. (Did not match) * 1 : Authorisation OK. (Matched) */ static int aclMatchProxyAuth(void *data, auth_user_request_t * auth_user_reques t, aclCheck_t * checklist, squid_acl acltype) { /* checklist is used to register user name when identified, nothing else */ /* General program flow in proxy_aut h acls * 1. Consistency checks: are we getting sensible data * 2. Call the authe nticate* functions to establish a authenticated user * 4. look up the username i n acltype (and cache the result against the * username

*/ /* for completeness */ authenticateAuthUserRequestLock(auth_user_request); /* consistent parameters ? */ assert(authenticateUserAuthenticated(auth_user_reque st)); /* this ACL check completed */ authenticateAuthUserRequestUnlock(auth_user _request); /* check to see if we have matched the user-acl before */ return aclC acheMatchAcl(&auth_user_request->auth_user-> proxy_match_cache, acltype, data, a uthenticateUserRequestUsername(auth_user_request)); } CBDATA_TYPE(acl_user_ip_da ta); void aclParseUserMaxIP(void *data) { acl_user_ip_data **acldata = data; cha r *t = NULL; CBDATA_INIT_TYPE(acl_user_ip_data); if (*acldata) { debug(28, 1) (" Attempting to alter already set User max IP acl\n"); return; } *acldata = cbdata Alloc(acl_user_ip_data); t = strtokFile(); if (!t) goto error; debug(28, 5) ("ac lParseUserMaxIP: First token is %s\n", t); if (strcmp("-s", t) == 0) { debug(28, 5) ("aclParseUserMaxIP: Going strict\n"); (*acldata)->flags.strict = 1;

t = strtokFile(); if (!t) goto error; } (*acldata)->max = atoi(t); debug(28, 5) ("aclParseUserMaxIP: Max IP address s %d\n", (int) (*acldata)->max); return; err or: fatal("aclParseUserMaxIP: Malformed ACL %d\n"); } void aclDestroyUserMaxIP(v oid *data) { acl_user_ip_data **acldata = data; if (*acldata) cbdataFree(*acldat a); *acldata = NULL; } wordlist * aclDumpUserMaxIP(void *data) { acl_user_ip_dat a *acldata = data; wordlist *W = NULL; char buf[128]; if (acldata->flags.strict) wordlistAdd(&W, "-s"); snprintf(buf, sizeof(buf), "%lu", (unsigned long int) ac ldata->max); wordlistAdd(&W, buf); return W; } /* * aclMatchUserMaxIP - check fo r users logging in from multiple IP s

* 0 : No match * 1 : Match */ int aclMatchUserMaxIP(void *data, auth_user_reques t_t * auth_user_request, struct in_addr src_addr) { /* * the logic for flush the ip list when the limit is hit vs keep * it sorted in most recent access order a nd just drop the oldest * one off is currently undecided */ acl_user_ip_data *ac ldata = data; if (authenticateAuthUserRequestIPCount(auth_user_request) <= aclda ta->max) return 0; /* this is a match */ if (acldata->flags.strict) { /* * simpl y deny access - the user name is already associated with * the request */ /* rem ove _this_ ip, as it is the culprit for going over the limit */ authenticateAuth UserRequestRemoveIp(auth_user_request, src_addr); debug(28, 4) ("aclMatchUserMax IP: Denying access in strict mode\n"); } else { /* * non-strict - remove some/al l of the cached entries * ie to allow the user to move machines easily */ authen ticateAuthUserRequestClearIp(auth_user_request); debug(28, 4) ("aclMatchUserMaxI P: Denying access in non-strict mode - flushing the user ip cache\n"); }

return 1; } static void aclLookupProxyAuthStart(aclCheck_t * checklist) { auth_u ser_request_t *auth_user_request; /* make sure someone created auth_user_request for us */ assert(checklist->auth_user_request != NULL); auth_user_request = che cklist->auth_user_request; assert(authenticateValidateUser(auth_user_request)); authenticateStart(auth_user_request, aclLookupProxyAuthDone, checklist); } stati c int aclMatchInteger(intlist * data, int i) { intlist *first, *prev; first = da ta; prev = NULL; while (data) { if (data->i == i) { if (prev != NULL) { /* shift the element just found to the second position * in the list */ prev->next = dat a->next; data->next = first->next; first->next = data; } return 1; } prev = data ; data = data->next;

} return 0; } static int aclMatchIntegerRange(intrange * data, int i) { intrange *first, *prev; first = data; prev = NULL; while (data) { if (i < data->i) { (vo id) 0; } else if (i > data->j) { (void) 0; } else { /* matched */ if (prev != NU LL) { /* shift the element just found to the second position * in the list */ pr ev->next = data->next; data->next = first->next; first->next = data; } return 1; } prev = data; data = data->next; } return 0; } static int aclMatchTime(acl_tim e_data * data, time_t when) {

static time_t last_when = 0; static struct tm tm; time_t t; assert(data != NULL) ; if (when != last_when) { last_when = when; xmemcpy(&tm, localtime(&when), size of(struct tm)); } t = (time_t) (tm.tm_hour * 60 + tm.tm_min); debug(28, 3) ("acl MatchTime: checking %d in %d-%d, weekbits=%x\n", (int) t, (int) data->start, (in t) data->stop, data->weekbits); while (data) { if (t >= data->start && t <= data ->stop && (data->weekbits & (1 << tm.tm_wday))) return 1; data = data->next; } r eturn 0; } #if SQUID_SNMP static int aclMatchWordList(wordlist * w, const char * word) { debug(28, 3) ("aclMatchWordList: looking for %s \n", word); while (w != NULL) { debug(28, 3) ("aclMatchWordList: checking %s \n", w->key); if (!strcmp (w->key, word)) return 1; w = w->next; } return 0; } #endif

int aclAuthenticated(aclCheck_t * checklist) { request_t *r = checklist->request ; http_hdr_type headertype; if (NULL == r) { return -1; } else if (!r->flags.acc elerated) { /* Proxy authorization on proxy requests */ headertype = HDR_PROXY_A UTHORIZATION; } else if (r->flags.internal) { /* WWW authorization on accelerate d internal requests */ headertype = HDR_AUTHORIZATION; } else { #if AUTH_ON_ACCE LERATION /* WWW authorization on accelerated requests */ headertype = HDR_AUTHOR IZATION; #else debug(28, 1) ("aclAuthenticated: authentication not applicable on accelerated requests.\n"); return -1; #endif } /* get authed here */ /* Note: t his fills in checklist->auth_user_request when applicable (auth incomplete) */ s witch (authenticateTryToAuthenticateAndSetAuthUser(&checklist->auth_user_request , headertype, checklist->request, checklist->conn, checklist->src_addr)) { case AUTH_ACL_CANNOT_AUTHENTICATE: debug(28, 4) ("aclMatchAcl: returning 0 user authe nticated but not authorised.\n"); return 0; case AUTH_AUTHENTICATED: if (checkli st->auth_user_request) { authenticateAuthUserRequestUnlock(checklist->auth_user_ request); checklist->auth_user_request = NULL; }

return 1; break; case AUTH_ACL_HELPER: debug(28, 4) ("aclMatchAcl: returning 0 s ending credentials to helper.\n"); checklist->state[ACL_PROXY_AUTH] = ACL_LOOKUP _NEEDED; return -1; case AUTH_ACL_CHALLENGE: debug(28, 4) ("aclMatchAcl: returni ng 0 sending authentication challenge.\n"); checklist->state[ACL_PROXY_AUTH] = A CL_PROXY_AUTH_NEEDED; return -1; default: fatal("unexpected authenticateAuthenti cate reply\n"); return -1; } } static int aclMatchAcl(acl * ae, aclCheck_t * che cklist) { request_t *r = checklist->request; const ipcache_addrs *ia = NULL; con st char *fqdn = NULL; char *esc_buf; const char *header; const char *browser; in t k, ti; if (!ae) return 0; switch (ae->type) { case ACL_BROWSER: case ACL_REFER ER_REGEX: case ACL_DST_ASN: case ACL_DST_DOMAIN: case ACL_DST_DOM_REGEX: case AC L_DST_IP:

case ACL_MAX_USER_IP: case ACL_METHOD: case ACL_PROTO: case ACL_PROXY_AUTH: case ACL_PROXY_AUTH_REGEX: case ACL_REP_MIME_TYPE: case ACL_REQ_MIME_TYPE: case ACL_ REP_HEADER: case ACL_REQ_HEADER: case ACL_URLPATH_REGEX: case ACL_URL_PORT: case ACL_URL_REGEX: case ACL_URLLOGIN: /* These ACL types require checklist->request */ if (NULL == r) { debug(28, 1) ("WARNING: %s ACL is used but there is no" " HTTP request -- access denied.\n", ae->name); return 0; } break; default: break ; } debug(28, 3) ("aclMatchAcl: checking %s \n", ae->cfgline); switch (ae->type ) { case ACL_SRC_IP: return aclMatchIp(&ae->data, checklist->src_addr); /* NOTRE ACHED */ case ACL_MY_IP: return aclMatchIp(&ae->data, checklist->my_addr); /* NO TREACHED */ case ACL_DST_IP: ia = ipcache_gethostbyname(r->host, IP_LOOKUP_IF_MI SS); if (ia) { for (k = 0; k < (int) ia->count; k++) {

if (aclMatchIp(&ae->data, ia->in_addrs[k])) return 1; } return 0; } else if (che cklist->state[ACL_DST_IP] == ACL_LOOKUP_NONE) { debug(28, 3) ("aclMatchAcl: Can t yet compare %s ACL for %s \n", ae->name, r->host); checklist->state[ACL_DST _IP] = ACL_LOOKUP_NEEDED; return 0; } else { return aclMatchIp(&ae->data, no_add r); } /* NOTREACHED */ case ACL_DST_DOMAIN: if ((ia = ipcacheCheckNumeric(r->hos t)) == NULL) return aclMatchDomainList(&ae->data, r->host); fqdn = fqdncache_get hostbyaddr(ia->in_addrs[0], FQDN_LOOKUP_IF_MISS); if (fqdn) return aclMatchDomai nList(&ae->data, fqdn); if (checklist->state[ACL_DST_DOMAIN] == ACL_LOOKUP_NONE) { debug(28, 3) ("aclMatchAcl: Can t yet compare %s ACL for %s \n", ae->name, inet_ntoa(ia->in_addrs[0])); checklist->state[ACL_DST_DOMAIN] = ACL_LOOKUP_NEED ED; return 0; } return aclMatchDomainList(&ae->data, "none"); /* NOTREACHED */ c ase ACL_SRC_DOMAIN: fqdn = fqdncache_gethostbyaddr(checklist->src_addr, FQDN_LOO KUP_IF_MISS); if (fqdn) { return aclMatchDomainList(&ae->data, fqdn); } else if (checklist->state[ACL_SRC_DOMAIN] == ACL_LOOKUP_NONE) { debug(28, 3) ("aclMatchA cl: Can t yet compare %s ACL for %s \n", ae->name, inet_ntoa(checklist->src_a ddr)); checklist->state[ACL_SRC_DOMAIN] = ACL_LOOKUP_NEEDED;

return 0; } return aclMatchDomainList(&ae->data, "none"); /* NOTREACHED */ case ACL_DST_DOM_REGEX: if ((ia = ipcacheCheckNumeric(r->host)) == NULL) return aclMa tchRegex(ae->data, r->host); fqdn = fqdncache_gethostbyaddr(ia->in_addrs[0], FQD N_LOOKUP_IF_MISS); if (fqdn) return aclMatchRegex(ae->data, fqdn); if (checklist ->state[ACL_DST_DOMAIN] == ACL_LOOKUP_NONE) { debug(28, 3) ("aclMatchAcl: Can t yet compare %s ACL for %s \n", ae->name, inet_ntoa(ia->in_addrs[0])); checkli st->state[ACL_DST_DOMAIN] = ACL_LOOKUP_NEEDED; return 0; } return aclMatchRegex( ae->data, "none"); /* NOTREACHED */ case ACL_SRC_DOM_REGEX: fqdn = fqdncache_get hostbyaddr(checklist->src_addr, FQDN_LOOKUP_IF_MISS); if (fqdn) { return aclMatc hRegex(ae->data, fqdn); } else if (checklist->state[ACL_SRC_DOMAIN] == ACL_LOOKU P_NONE) { debug(28, 3) ("aclMatchAcl: Can t yet compare %s ACL for %s \n", ae ->name, inet_ntoa(checklist->src_addr)); checklist->state[ACL_SRC_DOMAIN] = ACL_ LOOKUP_NEEDED; return 0; } return aclMatchRegex(ae->data, "none"); /* NOTREACHED */ case ACL_TIME: return aclMatchTime(ae->data, squid_curtime); /* NOTREACHED * / case ACL_URLPATH_REGEX: esc_buf = xstrdup(strBuf(r->urlpath));

rfc1738_unescape(esc_buf); k = aclMatchRegex(ae->data, esc_buf); safe_free(esc_b uf); return k; /* NOTREACHED */ case ACL_URL_REGEX: esc_buf = xstrdup(urlCanonic al(r)); rfc1738_unescape(esc_buf); k = aclMatchRegex(ae->data, esc_buf); safe_fr ee(esc_buf); return k; case ACL_URLLOGIN: esc_buf = xstrdup(r->login); rfc1738_u nescape(esc_buf); k = aclMatchRegex(ae->data, esc_buf); safe_free(esc_buf); retu rn k; /* NOTREACHED */ case ACL_MAXCONN: k = clientdbEstablished(checklist->src_ addr, 0); return ((k > ((intlist *) ae->data)->i) ? 1 : 0); /* NOTREACHED */ cas e ACL_URL_PORT: return aclMatchIntegerRange(ae->data, (int) r->port); /* NOTREAC HED */ case ACL_MY_PORT: return aclMatchIntegerRange(ae->data, (int) checklist-> my_port); /* NOTREACHED */ #if USE_IDENT case ACL_IDENT: if (checklist->rfc931[0 ]) { return aclMatchUser(ae->data, checklist->rfc931); } else { checklist->state [ACL_IDENT] = ACL_LOOKUP_NEEDED; return 0;

} /* NOTREACHED */ case ACL_IDENT_REGEX: if (checklist->rfc931[0]) { return aclM atchRegex(ae->data, checklist->rfc931); } else { checklist->state[ACL_IDENT] = A CL_LOOKUP_NEEDED; return 0; } /* NOTREACHED */ #endif case ACL_PROTO: return acl MatchInteger(ae->data, r->protocol); /* NOTREACHED */ case ACL_METHOD: return ac lMatchInteger(ae->data, r->method); /* NOTREACHED */ case ACL_BROWSER: browser = httpHeaderGetStr(&checklist->request->header, HDR_USER_AGENT); if (NULL == brow ser) return 0; return aclMatchRegex(ae->data, browser); /* NOTREACHED */ case AC L_REFERER_REGEX: header = httpHeaderGetStr(&checklist->request->header, HDR_REFE RER); if (NULL == header) return 0; return aclMatchRegex(ae->data, header); /* N OTREACHED */ case ACL_PROXY_AUTH: case ACL_PROXY_AUTH_REGEX: if ((ti = aclAuthen ticated(checklist)) != 1) return ti; ti = aclMatchProxyAuth(ae->data, r->auth_us er_request, checklist, ae->type);

return ti; /* NOTREACHED */ case ACL_MAX_USER_IP: if ((ti = aclAuthenticated(che cklist)) != 1) return ti; ti = aclMatchUserMaxIP(ae->data, r->auth_user_request, checklist->src_addr); return ti; /* NOTREACHED */ #if SQUID_SNMP case ACL_SNMP_ COMMUNITY: return aclMatchWordList(ae->data, checklist->snmp_community); /* NOTR EACHED */ #endif case ACL_SRC_ASN: return asnMatchIp(ae->data, checklist->src_ad dr); /* NOTREACHED */ case ACL_DST_ASN: ia = ipcache_gethostbyname(r->host, IP_L OOKUP_IF_MISS); if (ia) { for (k = 0; k < (int) ia->count; k++) { if (asnMatchIp (ae->data, ia->in_addrs[k])) return 1; } return 0; } else if (checklist->state[A CL_DST_ASN] == ACL_LOOKUP_NONE) { debug(28, 3) ("asnMatchAcl: Can t yet compare %s ACL for %s \n", ae->name, r->host); checklist->state[ACL_DST_ASN] = ACL_LO OKUP_NEEDED; } else { return asnMatchIp(ae->data, no_addr); } return 0; /* NOTRE ACHED */ #if USE_ARP_ACL

case ACL_SRC_ARP: return aclMatchArp(&ae->data, checklist->src_addr); /* NOTREAC HED */ #endif case ACL_REQ_MIME_TYPE: header = httpHeaderGetStr(&checklist->requ est->header, HDR_CONTENT_TYPE); if (NULL == header) header = ""; return aclMatch Regex(ae->data, header); /* NOTREACHED */ case ACL_REP_MIME_TYPE: if (!checklist ->reply) return 0; header = httpHeaderGetStr(&checklist->reply->header, HDR_CONT ENT_TYPE); if (NULL == header) header = ""; return aclMatchRegex(ae->data, heade r); /* NOTREACHED */ case ACL_REP_HEADER: if (!checklist->reply) return 0; retur n aclMatchHeader(ae->data, &checklist->reply->header); /* NOTREACHED */ case ACL _REQ_HEADER: return aclMatchHeader(ae->data, &checklist->request->header); /* NO TREACHED */ case ACL_EXTERNAL: return aclMatchExternal(ae->data, checklist); /* NOTREACHED */ case ACL_NONE: case ACL_ENUM_MAX: break; } debug(28, 0) ("aclMatch Acl: %s has bad type %d\n",

ae->name, ae->type); return 0; } int aclMatchAclList(const acl_list * list, aclC heck_t * checklist) { while (list) { int answer; checklist->current_acl = list-> acl; AclMatchedName = list->acl->name; debug(28, 3) ("aclMatchAclList: checking %s%s\n", list->op ? null_string : "!", list->acl->name); answer = aclMatchAcl(li st->acl, checklist); #if NOT_SURE_THIS_IS_GOOD /* This will make access denied i f an acl cannot be evaluated. * Normally Squid will just continue to the next ru le */ if (answer < 0) { debug(28, 3) ("aclMatchAclList: failure. returning -1\n" ); return -1; } #endif if (answer != list->op) { debug(28, 3) ("aclMatchAclList: no match, returning 0\n"); return 0; } list = list->next; } debug(28, 3) ("aclM atchAclList: returning 1\n"); return 1; } static void aclCheckCleanup(aclCheck_t * checklist)

{ /* Cleanup temporary stuff used by the ACL checking */ if (checklist->extacl_e ntry) { cbdataUnlock(checklist->extacl_entry); checklist->extacl_entry = NULL; } /* During reconfigure or if authentication is used in aclCheckFast without * fi rst being authenticated in http_access we can end up not finishing call * sequen ces into the auth code. In such case we must make sure to forget * the authentic ation state completely */ if (checklist->auth_user_request) { authenticateAuthUs erRequestUnlock(checklist->auth_user_request); checklist->auth_user_request = NU LL; if (checklist->request) { if (checklist->request->auth_user_request) { authe nticateAuthUserRequestUnlock(checklist->request>auth_user_request); checklist->r equest->auth_user_request = NULL; } } /* it might have been connection based */ if (checklist->conn) { if (checklist->conn->auth_user_request) { authenticateAut hUserRequestUnlock(checklist->conn->auth_user_request); checklist->conn->auth_us er_request = NULL; } assert(checklist->request); checklist->conn->auth_type = AU TH_BROKEN; } } checklist->current_acl = NULL; } int

aclCheckFast(const acl_access * A, aclCheck_t * checklist) { allow_t allow = ACC ESS_DENIED; int answer; debug(28, 5) ("aclCheckFast: list: %p\n", A); while (A) { allow = A->allow; answer = aclMatchAclList(A->acl_list, checklist); if (answer ) { if (answer < 0) return ACCESS_DENIED; aclCheckCleanup(checklist); return all ow == ACCESS_ALLOWED; } A = A->next; } debug(28, 5) ("aclCheckFast: no matches, returning: %d\n", allow == ACCESS_DENIED); aclCheckCleanup(checklist); return al low == ACCESS_DENIED; } static void aclCheck(aclCheck_t * checklist) { allow_t a llow = ACCESS_DENIED; const acl_access *A; int match; ipcache_addrs *ia; while ( (A = checklist->access_list) != NULL) { /* * If the _acl_access is no longer val id (i.e. its been * freed because of a reconfigure), then bail on this * access check. For now, return ACCESS_DENIED. */

if (!cbdataValid(A)) { cbdataUnlock(A); checklist->access_list = NULL; break; } debug(28, 3) ("aclCheck: checking %s \n", A->cfgline); allow = A->allow; match = aclMatchAclList(A->acl_list, checklist); if (match == -1) allow = ACCESS_DENIE D; if (checklist->state[ACL_DST_IP] == ACL_LOOKUP_NEEDED) { checklist->state[ACL _DST_IP] = ACL_LOOKUP_PENDING; ipcache_nbgethostbyname(checklist->request->host, aclLookupDstIPDone, checklist); return; } else if (checklist->state[ACL_DST_ASN ] == ACL_LOOKUP_NEEDED) { checklist->state[ACL_DST_ASN] = ACL_LOOKUP_PENDING; ip cache_nbgethostbyname(checklist->request->host, aclLookupDstIPforASNDone, checkl ist); return; } else if (checklist->state[ACL_SRC_DOMAIN] == ACL_LOOKUP_NEEDED) { checklist->state[ACL_SRC_DOMAIN] = ACL_LOOKUP_PENDING; fqdncache_nbgethostbyad dr(checklist->src_addr, aclLookupSrcFQDNDone, checklist); return; } else if (che cklist->state[ACL_DST_DOMAIN] == ACL_LOOKUP_NEEDED) { ia = ipcacheCheckNumeric(c hecklist->request->host); if (ia == NULL) { checklist->state[ACL_DST_DOMAIN] = A CL_LOOKUP_DONE; return; } checklist->dst_addr = ia->in_addrs[0]; checklist->stat e[ACL_DST_DOMAIN] = ACL_LOOKUP_PENDING; fqdncache_nbgethostbyaddr(checklist->dst _addr, aclLookupDstFQDNDone, checklist);

return; } else if (checklist->state[ACL_PROXY_AUTH] == ACL_LOOKUP_NEEDED) { debu g(28, 3) ("aclCheck: checking password via authenticator\n"); aclLookupProxyAuth Start(checklist); checklist->state[ACL_PROXY_AUTH] = ACL_LOOKUP_PENDING; return; } else if (checklist->state[ACL_PROXY_AUTH] == ACL_PROXY_AUTH_NEEDED) { /* Clie nt is required to resend the request with correct authentication * credentials. (This may be part of a stateful auth protocol. * The request is denied. */ debug (28, 6) ("aclCheck: requiring Proxy Auth header.\n"); allow = ACCESS_REQ_PROXY_A UTH; match = -1; } #if USE_IDENT else if (checklist->state[ACL_IDENT] == ACL_LOO KUP_NEEDED) { debug(28, 3) ("aclCheck: Doing ident lookup\n"); if (cbdataValid(c hecklist->conn)) { identStart(&checklist->conn->me, &checklist->conn->peer, aclL ookupIdentDone, checklist); checklist->state[ACL_IDENT] = ACL_LOOKUP_PENDING; re turn; } else { debug(28, 1) ("aclCheck: Can t start ident lookup. No client conn ection\n"); cbdataUnlock(checklist->conn); checklist->conn = NULL; allow = ACCES S_DENIED; match = -1; } } #endif else if (checklist->state[ACL_EXTERNAL] == ACL_ LOOKUP_NEEDED) {

acl *acl = checklist->current_acl; assert(acl->type == ACL_EXTERNAL); externalAc lLookup(checklist, acl->data, aclLookupExternalDone, checklist); return; } /* * We are done with this _acl_access entry. Either the request * is allowed, denied , requires authentication, or we move on to * the next entry. */ if (match) { de bug(28, 3) ("aclCheck: match found, returning %d\n", allow); cbdataUnlock(A); ch ecklist->access_list = NULL; aclCheckCallback(checklist, allow); return; } check list->access_list = A->next; /* * Lock the next _acl_access entry */ if (A->next ) cbdataLock(A->next); cbdataUnlock(A); } debug(28, 3) ("aclCheck: NO match foun d, returning %d\n", allow != ACCESS_DENIED ? ACCESS_DENIED : ACCESS_ALLOWED); ac lCheckCallback(checklist, allow != ACCESS_DENIED ? ACCESS_DENIED : ACCESS_ALLOWE D); } void aclChecklistFree(aclCheck_t * checklist) { if (checklist->request)

requestUnlink(checklist->request); checklist->request = NULL; if (checklist->con n) { cbdataUnlock(checklist->conn); checklist->conn = NULL; } if (checklist->acc ess_list) { cbdataUnlock(checklist->access_list); checklist->access_list = NULL; } if (checklist->callback_data) { cbdataUnlock(checklist->callback_data); check list->callback_data = NULL; } aclCheckCleanup(checklist); cbdataFree(checklist); } static void aclCheckCallback(aclCheck_t * checklist, allow_t answer) { debug( 28, 3) ("aclCheckCallback: answer=%d\n", answer); aclCheckCleanup(checklist); if (cbdataValid(checklist->callback_data)) checklist->callback(answer, checklist-> callback_data); cbdataUnlock(checklist->callback_data); checklist->callback = NU LL; checklist->callback_data = NULL; aclChecklistFree(checklist); } #if USE_IDEN T static void aclLookupIdentDone(const char *ident, void *data) {

aclCheck_t *checklist = data; if (ident) { xstrncpy(checklist->rfc931, ident, US ER_IDENT_SZ); #if DONT xstrncpy(checklist->request->authuser, ident, USER_IDENT_ SZ); #endif } else { xstrncpy(checklist->rfc931, dash_str, USER_IDENT_SZ); } /* * Cache the ident result in the connection, to avoid redoing ident lookup * over and over on persistent connections */ if (cbdataValid(checklist->conn) && !chec klist->conn->rfc931[0]) xstrncpy(checklist->conn->rfc931, checklist->rfc931, USE R_IDENT_SZ); aclCheck(checklist); } #endif static void aclLookupDstIPDone(const ipcache_addrs * ia, void *data) { aclCheck_t *checklist = data; checklist->state [ACL_DST_IP] = ACL_LOOKUP_DONE; aclCheck(checklist); } static void aclLookupDstI PforASNDone(const ipcache_addrs * ia, void *data) { aclCheck_t *checklist = data ; checklist->state[ACL_DST_ASN] = ACL_LOOKUP_DONE; aclCheck(checklist); }

static void aclLookupSrcFQDNDone(const char *fqdn, void *data) { aclCheck_t *che cklist = data; checklist->state[ACL_SRC_DOMAIN] = ACL_LOOKUP_DONE; aclCheck(chec klist); } static void aclLookupDstFQDNDone(const char *fqdn, void *data) { aclCh eck_t *checklist = data; checklist->state[ACL_DST_DOMAIN] = ACL_LOOKUP_DONE; acl Check(checklist); } static void aclLookupProxyAuthDone(void *data, char *result) { aclCheck_t *checklist = data; checklist->state[ACL_PROXY_AUTH] = ACL_LOOKUP_D ONE; if (result != NULL) fatal("AclLookupProxyAuthDone: Old code floating around somewhere.\nMake clean and if that doesn t work, report a bug to the squid deve lopers.\n"); if (!authenticateValidateUser(checklist->auth_user_request) || chec klist->conn == NULL) { /* credentials could not be checked either way * restart the whole process */ /* OR the connection was closed, there s no way to continue */ authenticateAuthUserRequestUnlock(checklist->auth_user_request); checklist-> auth_user_request = NULL; if (checklist->conn) { if (checklist->conn->auth_user_ request) { authenticateAuthUserRequestUnlock(checklist->conn->auth_user_request) ; checklist->conn->auth_user_request = NULL;

} checklist->conn->auth_type = AUTH_BROKEN; } } aclCheck(checklist); } static vo id aclLookupExternalDone(void *data, void *result) { aclCheck_t *checklist = dat a; checklist->state[ACL_EXTERNAL] = ACL_LOOKUP_DONE; checklist->extacl_entry = r esult; cbdataLock(checklist->extacl_entry); aclCheck(checklist); } aclCheck_t * aclChecklistCreate(const acl_access * A, request_t * request, const char *ident) { int i; aclCheck_t *checklist; checklist = cbdataAlloc(aclCheck_t); checklist>access_list = A; /* * aclCheck() makes sure checklist->access_list is a valid * pointer, so lock it. */ cbdataLock(A); if (request != NULL) { checklist->reques t = requestLink(request); checklist->src_addr = request->client_addr; checklist>my_addr = request->my_addr; checklist->my_port = request->my_port; }

for (i = 0; i < ACL_ENUM_MAX; i++) checklist->state[i] = ACL_LOOKUP_NONE; #if US E_IDENT if (ident) xstrncpy(checklist->rfc931, ident, USER_IDENT_SZ); #endif che cklist->auth_user_request = NULL; return checklist; } void aclNBCheck(aclCheck_t * checklist, PF * callback, void *callback_data) { checklist->callback = callba ck; checklist->callback_data = callback_data; cbdataLock(callback_data); aclChec k(checklist); } /*********************/ /* Destroy functions */ /*********************/ static v oid aclDestroyTimeList(acl_time_data * data) { acl_time_data *next = NULL; for ( ; data; data = next) { next = data->next;

memFree(data, MEM_ACL_TIME_DATA); } } void aclDestroyRegexList(relist * data) { relist *next = NULL; for (; data; data = next) { next = data->next; regfree(&dat a->regex); safe_free(data->pattern); memFree(data, MEM_RELIST); } } static void aclFreeIpData(void *p) { memFree(p, MEM_ACL_IP_DATA); } static void aclFreeUserD ata(void *data) { acl_user_data *d = data; if (d->names) splay_destroy(d->names, xfree); memFree(d, MEM_ACL_USER_DATA); } void aclDestroyAcls(acl ** head) {

acl *a = NULL; acl *next = NULL; for (a = *head; a; a = next) { next = a->next; debug(28, 3) ("aclDestroyAcls: %s \n", a->cfgline); switch (a->type) { case ACL _SRC_IP: case ACL_DST_IP: case ACL_MY_IP: splay_destroy(a->data, aclFreeIpData); break; #if USE_ARP_ACL case ACL_SRC_ARP: #endif case ACL_DST_DOMAIN: case ACL_S RC_DOMAIN: splay_destroy(a->data, xfree); break; #if SQUID_SNMP case ACL_SNMP_CO MMUNITY: wordlistDestroy((wordlist **) & a->data); break; #endif #if USE_IDENT c ase ACL_IDENT: aclFreeUserData(a->data); break; #endif case ACL_PROXY_AUTH: aclF reeUserData(a->data); break; case ACL_TIME: aclDestroyTimeList(a->data); break; #if USE_IDENT

case ACL_IDENT_REGEX: #endif case ACL_PROXY_AUTH_REGEX: case ACL_URL_REGEX: case ACL_URLLOGIN: case ACL_URLPATH_REGEX: case ACL_BROWSER: case ACL_REFERER_REGEX: case ACL_SRC_DOM_REGEX: case ACL_DST_DOM_REGEX: case ACL_REP_MIME_TYPE: case AC L_REQ_MIME_TYPE: aclDestroyRegexList(a->data); break; case ACL_REP_HEADER: case ACL_REQ_HEADER: aclDestroyHeader(a->data); break; case ACL_PROTO: case ACL_METHO D: case ACL_SRC_ASN: case ACL_DST_ASN: #if SRC_RTT_NOT_YET_FINISHED case ACL_NET DB_SRC_RTT: #endif case ACL_MAXCONN: intlistDestroy((intlist **) & a->data); bre ak; case ACL_MAX_USER_IP: aclDestroyUserMaxIP(&a->data); break; case ACL_URL_POR T: case ACL_MY_PORT: aclDestroyIntRange(a->data); break;

case ACL_EXTERNAL: aclDestroyExternal(&a->data); break; case ACL_NONE: case ACL_ ENUM_MAX: debug(28, 1) ("aclDestroyAcls: no case for ACL type %d\n", a->type); b reak; } safe_free(a->cfgline); memFree(a, MEM_ACL); } *head = NULL; } void aclDe stroyAclList(acl_list ** head) { acl_list *l; for (l = *head; l; l = *head) { *h ead = l->next; memFree(l, MEM_ACL_LIST); } } void aclDestroyAccessList(acl_acces s ** list) { acl_access *l = NULL; acl_access *next = NULL; for (l = *list; l; l = next) { debug(28, 3) ("aclDestroyAccessList: %s \n", l->cfgline); next = l-> next; aclDestroyAclList(&l->acl_list); safe_free(l->cfgline); cbdataFree(l);

} *list = NULL; } /* maex@space.net (06.09.1996) * destroy an _acl_deny_info_lis t */ void aclDestroyDenyInfoList(acl_deny_info_list ** list) { acl_deny_info_list *a = NULL; acl_deny_info_list *a_next = NULL; acl_name_list *l = NULL; acl_name_lis t *l_next = NULL; for (a = *list; a; a = a_next) { for (l = a->acl_list; l; l = l_next) { l_next = l->next; safe_free(l); } a_next = a->next; xfree(a->err_page_ name); memFree(a, MEM_ACL_DENY_INFO_LIST); } *list = NULL; } static void aclDest royIntRange(intrange * list) { intrange *w = NULL; intrange *n = NULL; for (w = list; w; w = n) { n = w->next; safe_free(w);

} } /* general compare functions, these are used for tree search algorithms * so they return <0, 0 or >0 */ /* compare two domains */ static int aclDomainCompar e(const void *a, const void *b) { const char *d1; const char *d2; int ret; d1 = b; d2 = a; ret = aclHostDomainCompare(d1, d2); if (ret != 0) { d1 = a; d2 = b; r et = aclHostDomainCompare(d1, d2); } if (ret == 0) { debug(28, 0) ("WARNING: %s is a subdomain of %s \n", d1, d2); debug(28, 0) ("WARNING: because of this % s is ignored to keep splay tree searching predictable\n", (char *) a); debug(28 , 0) ("WARNING: You should probably remove %s from the ACL named %s \n", d1, AclMatchedName); } return ret; } /* compare a host and a domain */ static int

aclHostDomainCompare(const void *a, const void *b) { const char *h = a; const ch ar *d = b; return matchDomainName(h, d); } /* * aclIpDataToStr - print/format an acl_ip_data structure for * debugging output. */ static void aclIpDataToStr(con st acl_ip_data * ip, char *buf, int len) { char b1[20]; char b2[20]; char b3[20] ; snprintf(b1, 20, "%s", inet_ntoa(ip->addr1)); if (ip->addr2.s_addr != any_addr .s_addr) snprintf(b2, 20, "-%s", inet_ntoa(ip->addr2)); else b2[0] = \0 ; if (i p->mask.s_addr != no_addr.s_addr) snprintf(b3, 20, "/%s", inet_ntoa(ip->mask)); else b3[0] = \0 ; snprintf(buf, len, "%s%s%s", b1, b2, b3); } /* * aclIpNetwork Compare2 - The guts of the comparison for IP ACLs. * The first argument (a) is a "host" address, i.e. the IP address * of a cache client. The second argument (b ) is a "network" address * that might have a subnet and/or range. We mask the ho st address * bits with the network subnet mask.

*/ static int aclIpNetworkCompare2(const acl_ip_data * p, const acl_ip_data * q) { struct in_addr A = p->addr1; const struct in_addr B = q->addr1; const struct in_addr C = q->addr2; int rc = 0; A.s_addr &= q->mask.s_addr; /* apply netmask * / if (C.s_addr == 0) { rc = 1; else if (ntohl(A.s_addr) < ntohl(B.s_addr)) rc = -1; else rc = 0; } else { rc = 1; else if (ntohl(A.s_addr) < ntohl(B.s_addr)) rc = -1; else rc = 0; } return rc; } /* * aclIpNetworkCompare - Compare two acl_ip _data entries. Strictly * used by the splay insertion routine. It emits a warnin g if it * detects a "collision" or overlap that would confuse the splay * sortin g algorithm. Much like aclDomainCompare. */ static int aclIpNetworkCompare(const void *a, const void *b) /* range address check */ if (ntohl(A.s_addr) > ntohl(C .s_addr)) /* single address check */ if (ntohl(A.s_addr) > ntohl(B.s_addr))

{ const acl_ip_data *n1; const acl_ip_data *n2; int ret; n1 = b; n2 = a; ret = a clIpNetworkCompare2(n1, n2); if (ret != 0) { n1 = a; n2 = b; ret = aclIpNetworkC ompare2(n1, n2); } if (ret == 0) { char buf_n1[60]; char buf_n2[60]; char buf_a[ 60]; aclIpDataToStr(n1, buf_n1, 60); aclIpDataToStr(n2, buf_n2, 60); aclIpDataTo Str((acl_ip_data *) a, buf_a, 60); debug(28, 0) ("WARNING: %s is a subnetwork of " " %s \n", buf_n1, buf_n2); debug(28, 0) ("WARNING: because of this %s is ignored " "to keep splay tree searching predictable\n", buf_a); debug(28, 0) ("W ARNING: You should probably remove %s " "from the ACL named %s \n", buf_n1, A clMatchedName); } return ret; } /* * aclIpAddrNetworkCompare - The comparison fu nction used for ACL * matching checks. The first argument (a) is a "host" addres s, * i.e. the IP address of a cache client. The second argument (b) * is an entr y in some address-based access control element. This * function is called via ac lMatchIp() and the splay library.

*/ static int aclIpAddrNetworkCompare(const void *a, const void *b) { return acl IpNetworkCompare2(a, b); } static void aclDumpUserListWalkee(void *node_data, vo id *outlist) { /* outlist is really a wordlist ** */ wordlistAdd(outlist, node_d ata); } static wordlist * aclDumpUserList(acl_user_data * data) { wordlist *wl = NULL; if (data->flags.case_insensitive) wordlistAdd(&wl, "-i"); /* damn this is VERY inefficient for long ACL lists... filling * a wordlist this way costs Sum( 1,N) iterations. For instance * a 1000-elements list will be filled in 499500 it erations. */ if (data->flags.required) wordlistAdd(&wl, "REQUIRED"); else if (da ta->names) splay_walk(data->names, aclDumpUserListWalkee, &wl); return wl; } sta tic void aclDumpIpListWalkee(void *node, void *state) { acl_ip_data *ip = node;

MemBuf mb; wordlist **W = state; memBufDefInit(&mb); memBufPrintf(&mb, "%s", ine t_ntoa(ip->addr1)); if (ip->addr2.s_addr != any_addr.s_addr) memBufPrintf(&mb, " -%s", inet_ntoa(ip->addr2)); if (ip->mask.s_addr != no_addr.s_addr) memBufPrintf (&mb, "/%s", inet_ntoa(ip->mask)); wordlistAdd(W, mb.buf); memBufClean(&mb); } s tatic wordlist * aclDumpIpList(void *data) { wordlist *w = NULL; splay_walk(data , aclDumpIpListWalkee, &w); return w; } static void aclDumpDomainListWalkee(void *node, void *state) { char *domain = node; wordlistAdd(state, domain); } static wordlist * aclDumpDomainList(void *data) { wordlist *w = NULL; splay_walk(data, aclDumpDomainListWalkee, &w); return w; }

static wordlist * aclDumpTimeSpecList(acl_time_data * t) { wordlist *W = NULL; c har buf[128]; while (t != NULL) { snprintf(buf, sizeof(buf), "%c%c%c%c%c%c%c %02 d:%02d-%02d:%02d", t->weekbits & ACL_SUNDAY ? S : - , t->weekbits & ACL_MONDA Y ? M : - , t->weekbits & ACL_TUESDAY ? T : - , t->weekbits & ACL_WEDNESDA Y ? W : - , t->weekbits & ACL_THURSDAY ? H : - , t->weekbits & ACL_FRIDAY ? F : - , t->weekbits & ACL_SATURDAY ? A : - , t->start / 60, t->start % 6 0, t->stop / 60, t->stop % 60); wordlistAdd(&W, buf); t = t->next; } return W; } static wordlist * aclDumpRegexList(relist * data) { wordlist *W = NULL; while ( data != NULL) { wordlistAdd(&W, data->pattern); data = data->next; } return W; } static wordlist * aclDumpIntlistList(intlist * data) {

wordlist *W = NULL; char buf[32]; while (data != NULL) { snprintf(buf, sizeof(bu f), "%d", data->i); wordlistAdd(&W, buf); data = data->next; } return W; } stati c wordlist * aclDumpIntRangeList(intrange * data) { wordlist *W = NULL; char buf [32]; while (data != NULL) { if (data->i == data->j) snprintf(buf, sizeof(buf), "%d", data->i); else snprintf(buf, sizeof(buf), "%d-%d", data->i, data->j); word listAdd(&W, buf); data = data->next; } return W; } static wordlist * aclDumpProt oList(intlist * data) { wordlist *W = NULL; while (data != NULL) { wordlistAdd(& W, ProtocolStr[data->i]); data = data->next; } return W;

} static wordlist * aclDumpMethodList(intlist * data) { wordlist *W = NULL; whil e (data != NULL) { wordlistAdd(&W, RequestMethodStr[data->i]); data = data->next ; } return W; } wordlist * aclDumpGeneric(const acl * a) { debug(28, 3) ("aclDum pGeneric: %s type %d\n", a->name, a->type); switch (a->type) { case ACL_SRC_IP: case ACL_DST_IP: case ACL_MY_IP: return aclDumpIpList(a->data); case ACL_SRC_DOM AIN: case ACL_DST_DOMAIN: return aclDumpDomainList(a->data); #if SQUID_SNMP case ACL_SNMP_COMMUNITY: return wordlistDup(a->data); #endif #if USE_IDENT case ACL_ IDENT: return aclDumpUserList(a->data); case ACL_IDENT_REGEX: return aclDumpRege xList(a->data); #endif

case ACL_PROXY_AUTH: return aclDumpUserList(a->data); case ACL_TIME: return aclD umpTimeSpecList(a->data); case ACL_PROXY_AUTH_REGEX: case ACL_URL_REGEX: case AC L_URLLOGIN: case ACL_URLPATH_REGEX: case ACL_BROWSER: case ACL_REFERER_REGEX: ca se ACL_SRC_DOM_REGEX: case ACL_DST_DOM_REGEX: case ACL_REQ_MIME_TYPE: case ACL_R EP_MIME_TYPE: return aclDumpRegexList(a->data); case ACL_REQ_HEADER: case ACL_RE P_HEADER: return aclDumpHeader(a->data); case ACL_SRC_ASN: case ACL_MAXCONN: cas e ACL_DST_ASN: return aclDumpIntlistList(a->data); case ACL_MAX_USER_IP: return aclDumpUserMaxIP(a->data); case ACL_URL_PORT: case ACL_MY_PORT: return aclDumpIn tRangeList(a->data); case ACL_PROTO: return aclDumpProtoList(a->data); case ACL_ METHOD: return aclDumpMethodList(a->data); #if USE_ARP_ACL case ACL_SRC_ARP: ret urn aclDumpArpList(a->data); #endif

case ACL_EXTERNAL: return aclDumpExternal(a->data); case ACL_NONE: case ACL_ENUM _MAX: break; } debug(28, 1) ("aclDumpGeneric: no case for ACL type %d\n", a->typ e); return NULL; } /* * This function traverses all ACL elements referenced * by an access list (presumably http_access ). If * it finds a PURGE method ACL, th en it returns TRUE, * otherwise FALSE. */ int aclPurgeMethodInUse(acl_access * a ) { acl_list *b; for (; a; a = a->next) { for (b = a->acl_list; b; b = b->next) { if (ACL_METHOD != b->acl->type) continue; if (aclMatchInteger(b->acl->data, ME THOD_PURGE)) return 1; } } return 0; } #if USE_ARP_ACL /* ==== BEGIN ARP ACL SUPPORT ================================== =========== */

/* * From: * To: * Date: dale@server.ctam.bitmcnit.bryansk.su (Dale) wessels@nla nr.net Thu, 04 Dec 1997 19:55:01 +0300 * ======================================= ============================= ======== * * Working on setting up a proper firewa ll for a network containing some * Win 95 computers at our Univ, I ve discovered that some smart students * avoid the restrictions easily just changing their IP addresses in Win 95 * Contol Panel... It has been getting boring, so I took Squ id-1.1.18 * sources and added a new acl type for hard-wired access control: * * acl <name> arp <Ethernet address> ... * * For example, * * acl students arp 00:0 0:21:55:ed:22 00:00:21:ff:55:38 * * NOTE: Linux code by David Luyer <luyer@ucs.u wa.edu.au>. * * */ #ifdef _SQUID_SOLARIS_ #include <sys/sockio.h> #else #include <sys/sysctl.h> #endif #ifdef _SQUID_LINUX_ #include <net/if_arp.h> #include <sy s/ioctl.h> Original (BSD-specific) code no longer works. Solaris code by R. Ganc arz <radekg@solaris.elektrownia-lagisza.com.pl> * Subject: Another Squid patch... :)

#else #include <net/if_dl.h> #include <net/route.h> #endif #include <net/if.h> # ifdef _SQUID_FREEBSD__ #include <net/if_arp.h> #endif #if HAVE_NETINET_IF_ETHER_ H #include <netinet/if_ether.h> #endif /* * Decode an ascii representation (asc) of an ethernet adress, and place * it in eth[6]. */ static int decode_eth(const char *asc, char *eth) { int a1 = 0, a2 = 0, a3 = 0, a4 = 0, a5 = 0, a6 = 0; if (sscanf(asc, "%x:%x:%x:%x:%x:%x", &a1, &a2, &a3, &a4, &a5, &a6) != 6) { debug(28 , 0) ("decode_eth: Invalid ethernet address %s \n", asc); return 0; } eth[0] = (u_char) a1; eth[1] = (u_char) a2; eth[2] = (u_char) a3; eth[3] = (u_char) a4; e th[4] = (u_char) a5; eth[5] = (u_char) a6; return 1; } static acl_arp_data * acl ParseArpData(const char *t) /* This is not valid address */

{ LOCAL_ARRAY(char, eth, 256); acl_arp_data *q = xcalloc(1, sizeof(acl_arp_data) ); debug(28, 5) ("aclParseArpData: %s\n", t); if (sscanf(t, "%[0-9a-fA-F:]", eth ) != 1) { debug(28, 0) ("aclParseArpData: Bad ethernet address: %s \n", t); saf e_free(q); return NULL; } if (!decode_eth(eth, q->eth)) { debug(28, 0) ("%s line %d: %s\n", cfg_filename, config_lineno, config_input_line); debug(28, 0) ("aclP arseArpData: Ignoring invalid ARP acl entry: can t parse %s \n", eth); safe_fre e(q); return NULL; } return q; } /*******************/ /* aclParseArpList */ /*******************/ static void ac lParseArpList(void *curlist) { char *t = NULL; splayNode **Top = curlist; acl_ar p_data *q = NULL; while ((t = strtokFile())) { if ((q = aclParseArpData(t)) == N ULL) continue; *Top = splay_insert(q, *Top, aclArpCompare); }

} /***************/ /* aclMatchArp */ /***************/ static int aclMatchArp(v oid *dataptr, struct in_addr c) { #if defined(_SQUID_LINUX_) struct arpreq arpRe q; struct sockaddr_in ipAddr; unsigned char ifbuffer[sizeof(struct ifreq) * 64]; struct ifconf ifc; struct ifreq *ifr; int offset; splayNode **Top = dataptr; /* * The linux kernel 2.2 maintains per interface ARP caches and * thus requires a n interface name when doing ARP queries. * * The older 2.0 kernels appear to use a unified ARP cache, * and require an empty interface name * * To support both, we attempt the lookup with a blank interface * name first. If that does not suc ceed, the try each interface * in turn */ /* * Set up structures for ARP lookup with blank interface name */ ipAddr.sin_family = AF_INET; ipAddr.sin_port = 0; i pAddr.sin_addr = c; memset(&arpReq, \0 , sizeof(arpReq)); xmemcpy(&arpReq.arp_p a, &ipAddr, sizeof(struct sockaddr_in));

/* Query ARP table */ if (ioctl(HttpSockets[0], SIOCGARP, &arpReq) != -1) { /* S kip non-ethernet interfaces */ if (arpReq.arp_ha.sa_family != ARPHRD_ETHER) { re turn 0; } debug(28, 4) ("Got address %02x:%02x:%02x:%02x:%02x:%02x\n", arpReq.ar p_ha.sa_data[0] & 0xff, arpReq.arp_ha.sa_data[1] & 0xff, arpReq.arp_ha.sa_data[2 ] & 0xff, arpReq.arp_ha.sa_data[3] & 0xff, arpReq.arp_ha.sa_data[4] & 0xff, arpR eq.arp_ha.sa_data[5] & 0xff); /* Do lookup */ *Top = splay_splay(&arpReq.arp_ha. sa_data, *Top, aclArpCompare); debug(28, 3) ("aclMatchArp: %s %s\n", inet_ntoa (c), splayLastResult ? "NOT found" : "found"); return (0 == splayLastResult); } /* lookup list of interface names */ ifc.ifc_len = sizeof(ifbuffer); ifc.ifc_buf = ifbuffer; if (ioctl(HttpSockets[0], SIOCGIFCONF, &ifc) < 0) { debug(28, 1) (" Attempt to retrieve interface list failed: %s\n", xstrerror()); return 0; } if ( ifc.ifc_len > sizeof(ifbuffer)) { debug(28, 1) ("Interface list too long - %d\n" , ifc.ifc_len); return 0; } /* Attempt ARP lookup on each interface */ offset = 0; while (offset < ifc.ifc_len) { ifr = (struct ifreq *) (ifbuffer + offset); of fset += sizeof(*ifr); /* Skip loopback and aliased interfaces */ if (0 == strncm p(ifr->ifr_name, "lo", 2))

continue; if (NULL != strchr(ifr->ifr_name, : )) continue; debug(28, 4) ("Looki ng up ARP address for %s on %s\n", inet_ntoa(c), ifr->ifr_name); /* Set up struc tures for ARP lookup */ ipAddr.sin_family = AF_INET; ipAddr.sin_port = 0; ipAddr .sin_addr = c; memset(&arpReq, \0 , sizeof(arpReq)); xmemcpy(&arpReq.arp_pa, &i pAddr, sizeof(struct sockaddr_in)); strncpy(arpReq.arp_dev, ifr->ifr_name, sizeo f(arpReq.arp_dev) - 1); arpReq.arp_dev[sizeof(arpReq.arp_dev) - 1] = \0 ; /* Qu ery ARP table */ if (-1 == ioctl(HttpSockets[0], SIOCGARP, &arpReq)) { /* * Quer y failed. Do not log failed lookups or "device * not supported" */ if (ENXIO == errno) (void) 0; else if (ENODEV == errno) (void) 0; else debug(28, 1) ("ARP que ry failed: %s: %s\n", ifr->ifr_name, xstrerror()); continue; } /* Skip non-ether net interfaces */ if (arpReq.arp_ha.sa_family != ARPHRD_ETHER) continue; debug(2 8, 4) ("Got address %02x:%02x:%02x:%02x:%02x:%02x on %s\n", arpReq.arp_ha.sa_dat a[0] & 0xff, arpReq.arp_ha.sa_data[1] & 0xff, arpReq.arp_ha.sa_data[2] & 0xff,

arpReq.arp_ha.sa_data[3] & 0xff, arpReq.arp_ha.sa_data[4] & 0xff, arpReq.arp_ha. sa_data[5] & 0xff, ifr->ifr_name); /* Do lookup */ *Top = splay_splay(&arpReq.ar p_ha.sa_data, *Top, aclArpCompare); /* Return if match, otherwise continue to ot her interfaces */ if (0 == splayLastResult) { debug(28, 3) ("aclMatchArp: %s fou nd on %s\n", inet_ntoa(c), ifr->ifr_name); return 1; } /* * Should we stop looki ng here? Can the same IP address * exist on multiple interfaces? */ } #elif defi ned(_SQUID_SOLARIS_) struct arpreq arpReq; struct sockaddr_in ipAddr; unsigned c har ifbuffer[sizeof(struct ifreq) * 64]; struct ifconf ifc; struct ifreq *ifr; i nt offset; splayNode **Top = dataptr; /* * Set up structures for ARP lookup with blank interface name */ ipAddr.sin_family = AF_INET; ipAddr.sin_port = 0; ipAdd r.sin_addr = c; memset(&arpReq, \0 , sizeof(arpReq)); xmemcpy(&arpReq.arp_pa, & ipAddr, sizeof(struct sockaddr_in)); /* Query ARP table */ if (ioctl(HttpSockets [0], SIOCGARP, &arpReq) != -1) { /*

* Solaris (at least 2.6/x86) does not use arp_ha.sa_family * it returns 00:00:00 :00:00:00 for non-ethernet media */ if (arpReq.arp_ha.sa_data[0] == 0 && arpReq. arp_ha.sa_data[1] == 0 && arpReq.arp_ha.sa_data[2] == 0 && arpReq.arp_ha.sa_data [3] == 0 && arpReq.arp_ha.sa_data[4] == 0 && arpReq.arp_ha.sa_data[5] == 0) retu rn 0; debug(28, 4) ("Got address %02x:%02x:%02x:%02x:%02x:%02x\n", arpReq.arp_ha .sa_data[0] & 0xff, arpReq.arp_ha.sa_data[1] & 0xff, arpReq.arp_ha.sa_data[2] & 0xff, arpReq.arp_ha.sa_data[3] & 0xff, arpReq.arp_ha.sa_data[4] & 0xff, arpReq.a rp_ha.sa_data[5] & 0xff); /* Do lookup */ *Top = splay_splay(&arpReq.arp_ha.sa_d ata, *Top, aclArpCompare); debug(28, 3) ("aclMatchArp: %s %s\n", inet_ntoa(c), splayLastResult ? "NOT found" : "found"); return (0 == splayLastResult); } #eli f defined(_SQUID_FREEBSD_) struct arpreq arpReq; struct sockaddr_in ipAddr; unsi gned char ifbuffer[sizeof(struct ifreq) * 64]; struct ifconf ifc; struct ifreq * ifr; int offset; splayNode **Top = dataptr; int mib[6]; size_t needed; char *lim , *buf, *next; struct rt_msghdr *rtm; struct sockaddr_inarp *sin; struct sockadd r_dl *sdl;

/* * Set up structures for ARP lookup with blank interface name */ ipAddr.sin_fa mily = AF_INET; ipAddr.sin_port = 0; ipAddr.sin_addr = c; memset(&arpReq, \0 , sizeof(arpReq)); xmemcpy(&arpReq.arp_pa, &ipAddr, sizeof(struct sockaddr_in)); / * Query ARP table */ mib[0] = CTL_NET; mib[1] = PF_ROUTE; mib[2] = 0; mib[3] = A F_INET; mib[4] = NET_RT_FLAGS; mib[5] = RTF_LLINFO; if (sysctl(mib, 6, NULL, &ne eded, NULL, 0) < 0) { debug(28, 0) ("Can t estimate ARP table size!\n"); return 0; } if ((buf = xmalloc(needed)) == NULL) { debug(28, 0) ("Can t allocate tempor ary ARP table!\n"); return 0; } if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) { debug(28, 0) ("Can t retrieve ARP table!\n"); xfree(buf); return 0; } lim = buf + needed; for (next = buf; next < lim; next += rtm->rtm_msglen) { rtm = (struct rt_msghdr *) next; sin = (struct sockaddr_inarp *) (rtm + 1); /*sdl = (struct s ockaddr_dl *) (sin + 1); */ #define ROUNDUP(a) \

((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) (char *) sdl = (char *) sin + ROUNDUP(sin->sin_len); if (c.s_addr == sin->sin_addr.s_addr) { i f (sdl->sdl_alen) { arpReq.arp_ha.sa_len = sizeof(struct sockaddr); arpReq.arp_h a.sa_family = AF_UNSPEC; memcpy(arpReq.arp_ha.sa_data, LLADDR(sdl), sdl->sdl_ale n); } } } xfree(buf); if (arpReq.arp_ha.sa_data[0] == 0 && arpReq.arp_ha.sa_data [1] == 0 && arpReq.arp_ha.sa_data[2] == 0 && arpReq.arp_ha.sa_data[3] == 0 && ar pReq.arp_ha.sa_data[4] == 0 && arpReq.arp_ha.sa_data[5] == 0) return 0; debug(28 , 4) ("Got address %02x:%02x:%02x:%02x:%02x:%02x\n", arpReq.arp_ha.sa_data[0] & 0xff, arpReq.arp_ha.sa_data[1] & 0xff, arpReq.arp_ha.sa_data[2] & 0xff, arpReq.a rp_ha.sa_data[3] & 0xff, arpReq.arp_ha.sa_data[4] & 0xff, arpReq.arp_ha.sa_data[ 5] & 0xff); /* Do lookup */ *Top = splay_splay(&arpReq.arp_ha.sa_data, *Top, acl ArpCompare); debug(28, 3) ("aclMatchArp: %s %s\n", inet_ntoa(c), splayLastResu lt ? "NOT found" : "found"); return (0 == splayLastResult); #else WRITE ME; #end if /* * Address was not found on any interface */ debug(28, 3) ("aclMatchArp: %s NOT found\n", inet_ntoa(c)); return 0; } static int

aclArpCompare(const void *a, const void *b) { #if defined(_SQUID_LINUX_) const u nsigned short *d1 = a; const unsigned short *d2 = b; if (d1[0] != d2[0]) return (d1[0] > d2[0]) ? 1 : -1; if (d1[1] != d2[1]) return (d1[1] > d2[1]) ? 1 : -1; i f (d1[2] != d2[2]) return (d1[2] > d2[2]) ? 1 : -1; #elif defined(_SQUID_SOLARIS _) const unsigned char *d1 = a; const unsigned char *d2 = b; if (d1[0] != d2[0]) return (d1[0] > d2[0]) ? 1 : -1; if (d1[1] != d2[1]) return (d1[1] > d2[1]) ? 1 : -1; if (d1[2] != d2[2]) return (d1[2] > d2[2]) ? 1 : -1; if (d1[3] != d2[3]) return (d1[3] > d2[3]) ? 1 : -1; if (d1[4] != d2[4]) return (d1[4] > d2[4]) ? 1 : -1; if (d1[5] != d2[5]) return (d1[5] > d2[5]) ? 1 : -1; #elif defined(_SQUID_ FREEBSD_) const unsigned char *d1 = a; const unsigned char *d2 = b; if (d1[0] != d2[0]) return (d1[0] > d2[0]) ? 1 : -1; if (d1[1] != d2[1]) return (d1[1] > d2[ 1]) ? 1 : -1; if (d1[2] != d2[2]) return (d1[2] > d2[2]) ? 1 : -1;

if (d1[3] != d2[3]) return (d1[3] > d2[3]) ? 1 : -1; if (d1[4] != d2[4]) return (d1[4] > d2[4]) ? 1 : -1; if (d1[5] != d2[5]) return (d1[5] > d2[5]) ? 1 : -1; # else WRITE ME; #endif return 0; } #if UNUSED_CODE /***************************** ***************************************** * This is from the pre-splay-tree code for BSD * I suspect the Linux approach will work on most O/S and be much * bett er - <luyer@ucs.uwa.edu.au> **************************************************** ******************* static int checkARP(u_long ip, char *eth) { int mib[6] = {CT L_NET, PF_ROUTE, 0, AF_INET, NET_RT_FLAGS, RTF_LLINFO}; size_t needed; char *buf , *next, *lim; struct rt_msghdr *rtm; struct sockaddr_inarp *sin; struct sockadd r_dl *sdl; if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) { debug(28, 0) ("Can t estimate ARP table size!\n"); return 0; } if ((buf = xmalloc(needed)) == NULL) { debug(28, 0) ("Can t allocate temporary ARP table!\n"); return 0;

} if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) { debug(28, 0) ("Can t retrieve ARP table!\n"); xfree(buf); return 0; } lim = buf + needed; for (next = buf; ne xt < lim; next += rtm->rtm_msglen) { rtm = (struct rt_msghdr *) next; sin = (str uct sockaddr_inarp *) (rtm + 1); sdl = (struct sockaddr_dl *) (sin + 1); if (sin ->sin_addr.s_addr == ip) { if (sdl->sdl_alen) if (!memcmp(LLADDR(sdl), eth, 6)) { xfree(buf); return 1; } break; } } xfree(buf); return 0; } ******************* ***************************************************/ #endif static void aclDumpA rpListWalkee(void *node, void *state) { acl_arp_data *arp = node; wordlist **W = state; static char buf[24]; while (*W != NULL) W = &(*W)->next; snprintf(buf, s izeof(buf), "%02x:%02x:%02x:%02x:%02x:%02x",

arp->eth[0], arp->eth[1], arp->eth[2], arp->eth[3], arp->eth[4], arp->eth[5]); w ordlistAdd(state, buf); } static wordlist * aclDumpArpList(void *data) { wordlis t *w = NULL; splay_walk(data, aclDumpArpListWalkee, &w); return w; } /* ==== END ARP ACL SUPPORT =============================================== */ #endif /* USE_ARP_ACL */

static squid_acl aclStrToType(const char *s) { if (!strcmp(s, "src")) return ACL _SRC_IP; if (!strcmp(s, "dst")) return ACL_DST_IP; if (!strcmp(s, "myip")) retur n ACL_MY_IP; if (!strcmp(s, "domain")) return ACL_DST_DOMAIN; if (!strcmp(s, "ds tdomain")) return ACL_DST_DOMAIN; if (!strcmp(s, "srcdomain")) return ACL_SRC_DO MAIN; if (!strcmp(s, "dstdom_regex")) return ACL_DST_DOM_REGEX; if (!strcmp(s, " srcdom_regex")) return ACL_SRC_DOM_REGEX; if (!strcmp(s, "time")) return ACL_TIM E; if (!strcmp(s, "pattern")) return ACL_URLPATH_REGEX; if (!strcmp(s, "urlpath_ regex")) return ACL_URLPATH_REGEX; if (!strcmp(s, "url_regex")) //Compara a stri ng que foi passada return ACL_URL_REGEX; // como parametro. if (!strcmp(s, "port ")) return ACL_URL_PORT; if (!strcmp(s, "myport")) return ACL_MY_PORT; if (!strc mp(s, "maxconn")) return ACL_MAXCONN; #if USE_IDENT if (!strcmp(s, "ident")) ret urn ACL_IDENT; if (!strcmp(s, "ident_regex")) return ACL_IDENT_REGEX; #endif if (!strncmp(s, "proto", 5)) return ACL_PROTO; if (!strcmp(s, "method")) return ACL _METHOD; if (!strcmp(s, "browser")) return ACL_BROWSER; if (!strcmp(s, "referer_ regex")) return ACL_REFERER_REGEX; if (!strcmp(s, "proxy_auth")) return ACL_PROX Y_AUTH; if (!strcmp(s, "proxy_auth_regex")) return ACL_PROXY_AUTH_REGEX; if (!st rcmp(s, "src_as")) return ACL_SRC_ASN; if (!strcmp(s, "dst_as")) return ACL_DST_ ASN; #if SQUID_SNMP if (!strcmp(s, "snmp_community")) return ACL_SNMP_COMMUNITY; #endif #if SRC_RTT_NOT_YET_FINISHED if (!strcmp(s, "src_rtt")) return ACL_NETDB _SRC_RTT; #endif #if USE_ARP_ACL

if (!strcmp(s, "arp")) return ACL_SRC_ARP; #endif if (!strcmp(s, "req_mime_type" )) return ACL_REQ_MIME_TYPE; if (!strcmp(s, "rep_mime_type")) return ACL_REP_MIM E_TYPE; if (!strcmp(s, "rep_header")) return ACL_REP_HEADER; if (!strcmp(s, "req _header")) return ACL_REQ_HEADER; if (!strcmp(s, "max_user_ip")) return ACL_MAX_ USER_IP; if (!strcmp(s, "external")) return ACL_EXTERNAL; if (!strcmp(s, "urllog in")) return ACL_URLLOGIN; return ACL_NONE; } const char * aclTypeToStr(squid_acl type) { if (type == ACL_SRC_IP) return "src" ; if (type == ACL_DST_IP) return "dst"; if (type == ACL_MY_IP) return "myip"; if (type == ACL_DST_DOMAIN) return "dstdomain"; if (type == ACL_SRC_DOMAIN) return "srcdomain"; if (type == ACL_DST_DOM_REGEX) return "dstdom_regex"; if (type == ACL_SRC_DOM_REGEX) return "srcdom_regex"; if (type == ACL_TIME) return "time"; i f (type == ACL_URLPATH_REGEX) return "urlpath_regex"; if (type == ACL_URL_REGEX) return "url_regex"; if (type == ACL_URL_PORT) return "port"; if (type == ACL_MY _PORT) return "myport"; if (type == ACL_MAXCONN) return "maxconn"; #if USE_IDENT if (type == ACL_IDENT) return "ident"; if (type == ACL_IDENT_REGEX) return "ide nt_regex"; #endif if (type == ACL_PROTO) return "proto"; if (type == ACL_METHOD) return "method"; if (type == ACL_BROWSER) return "browser"; if (type == ACL_REF ERER_REGEX)

return if (type return if (type "referer_regex"; == ACL_PROXY_AUTH) "proxy_auth"; == ACL_PROXY_AUTH_REGEX) return "proxy_auth_regex"; if (type == ACL_SRC_ASN) return "src_as"; if (type == ACL_DST_ASN) return "dst_as"; #if SQUID_SNMP if (type == ACL_SNMP_COMMUNITY) re turn "snmp_community"; #endif #if SRC_RTT_NOT_YET_FINISHED if (type == ACL_NETDB _SRC_RTT) return "src_rtt"; #endif #if USE_ARP_ACL if (type == ACL_SRC_ARP) retu rn "arp"; #endif if (type == ACL_REQ_MIME_TYPE) return "req_mime_type"; if (type == ACL_REP_MIME_TYPE) return "rep_mime_type"; if (type == ACL_REP_HEADER) retur n "rep_header"; if (type == ACL_REQ_HEADER) return "req_header"; if (type == ACL _MAX_USER_IP) return "max_user_ip"; if (type == ACL_EXTERNAL) return "external"; if (type == ACL_URLLOGIN) return "urllogin"; return "ERROR"; } void aclParseAcl Line(acl ** head) { /* we re already using strtok() to grok the line */ char *t = NULL; acl *A = NULL; LOCAL_ARRAY(char, aclname, ACL_NAME_SZ); squid_acl acltyp e; int new_acl = 0; /* snarf the ACL name */ if ((t = strtok(NULL, w_space)) == NULL) { debug(28, 0) ("%s line %d: %s\n", cfg_filename, config_lineno, config_in put_line); debug(28, 0) ("aclParseAclLine: missing ACL name.\n"); return; } xstr ncpy(aclname, t, ACL_NAME_SZ); /* snarf the ACL type */ if ((t = strtok(NULL, w_ space)) == NULL) { debug(28, 0) ("%s line %d: %s\n", cfg_filename, config_lineno , config_input_line); debug(28, 0) ("aclParseAclLine: missing ACL type.\n"); ret urn;

} if ((acltype = aclStrToType(t)) == ACL_NONE) { debug(28, 0) ("%s line %d: %s\n ", cfg_filename, config_lineno, config_input_line); debug(28, 0) ("aclParseAclLi ne: Invalid ACL type %s \n", t); return; } if ((A = aclFindByName(aclname)) == NULL) { debug(28, 3) ("aclParseAclLine: Creating ACL %s \n", aclname); A = memA llocate(MEM_ACL); xstrncpy(A->name, aclname, ACL_NAME_SZ); A->type = acltype; A>cfgline = xstrdup(config_input_line); new_acl = 1; } else { if (acltype != A->t ype) { debug(28, 0) ("aclParseAclLine: ACL %s already exists with different ty pe, skipping.\n", A->name); return; } debug(28, 3) ("aclParseAclLine: Appending to %s \n", aclname); new_acl = 0; } /* * Here we set AclMatchedName in case we need to use it in a * warning message in aclDomainCompare(). */ AclMatchedName = aclname; /* ugly */ switch (A->type) { case ACL_SRC_IP: case ACL_DST_IP: case A CL_MY_IP: aclParseIpList(&A->data); break; case ACL_SRC_DOMAIN: case ACL_DST_DOM AIN: aclParseDomainList(&A->data); break; case ACL_TIME: aclParseTimeSpec(&A->da ta); break; case ACL_URL_REGEX: case ACL_URLLOGIN: case ACL_URLPATH_REGEX: case ACL_BROWSER: case ACL_REFERER_REGEX: case ACL_SRC_DOM_REGEX: case ACL_DST_DOM_RE GEX: case ACL_REQ_MIME_TYPE: case ACL_REP_MIME_TYPE: aclParseRegexList(&A->data) ; break; case ACL_REP_HEADER: case ACL_REQ_HEADER: aclParseHeader(&A->data); bre ak; case ACL_SRC_ASN: case ACL_MAXCONN: case ACL_DST_ASN: aclParseIntlist(&A->da ta); break; case ACL_MAX_USER_IP: aclParseUserMaxIP(&A->data); break;

#if SRC_RTT_NOT_YET_FINISHED case ACL_NETDB_SRC_RTT: aclParseIntlist(&A->data); break; #endif case ACL_URL_PORT: case ACL_MY_PORT: aclParseIntRange(&A->data); b reak; #if USE_IDENT case ACL_IDENT: aclParseUserList(&A->data); break; case ACL_ IDENT_REGEX: aclParseRegexList(&A->data); break; #endif case ACL_PROTO: aclParse ProtoList(&A->data); break; case ACL_METHOD: aclParseMethodList(&A->data); break ; case ACL_PROXY_AUTH: if (authenticateSchemeCount() == 0) { debug(28, 0) ("aclP arseAclLine: IGNORING: Proxy Auth ACL %s \ because no authentication schemes w ere compiled.\n", A->cfgline); } else if (authenticateActiveSchemeCount() == 0) { debug(28, 0) ("aclParseAclLine: IGNORING: Proxy Auth ACL %s \ because no aut hentication schemes are fully configured.\n", A->cfgline); } else { aclParseUser List(&A->data); } break; case ACL_PROXY_AUTH_REGEX: if (authenticateSchemeCount( ) == 0) { debug(28, 0) ("aclParseAclLine: IGNORING: Proxy Auth ACL %s \ becaus e no authentication schemes were compiled.\n", A->cfgline); } else if (authentic ateActiveSchemeCount() == 0) { debug(28, 0) ("aclParseAclLine: IGNORING: Proxy A uth ACL %s \ because no authentication schemes are fully configured.\n", A->cf gline); } else { aclParseRegexList(&A->data); } break; #if SQUID_SNMP case ACL_S NMP_COMMUNITY: aclParseWordList(&A->data); break; #endif #if USE_ARP_ACL case AC L_SRC_ARP: aclParseArpList(&A->data); break; #endif case ACL_EXTERNAL: aclParseE xternal(&A->data); break; case ACL_NONE: case ACL_ENUM_MAX: fatal("Bad ACL type" ); break; } /*

} * Clear AclMatchedName from our temporary hack */ AclMatchedName = NULL; /* ugly */ if (!new_acl) return; if (A->data == NULL) { debug(28, 0) ("aclParseAclLine: IGNORING invalid ACL: %s\n", A->cfgline); memFree(A, MEM_ACL); return; } /* app end */ while (*head) head = &(*head)->next; *head = A; static int aclMatchAcl(acl * ae, aclCheck_t * checklist) { request_t *r = checkl ist->request; const ipcache_addrs *ia = NULL; const char *fqdn = NULL; char *esc _buf; const char *header; const char *browser; int k, ti; if (!ae) return 0; swi tch (ae->type) { case ACL_BROWSER: case ACL_REFERER_REGEX: case ACL_DST_ASN: cas e ACL_DST_DOMAIN: case ACL_DST_DOM_REGEX: case ACL_DST_IP: case ACL_MAX_USER_IP: case ACL_METHOD: case ACL_PROTO: case ACL_PROXY_AUTH: case ACL_PROXY_AUTH_REGEX : case ACL_REP_MIME_TYPE: case ACL_REQ_MIME_TYPE: case ACL_REP_HEADER: case ACL_ REQ_HEADER: case ACL_URLPATH_REGEX: case ACL_URL_PORT: case ACL_URL_REGEX: case ACL_URLLOGIN: /* These ACL types require checklist->request */ if (NULL == r) { debug(28, 1) ("WARNING: %s ACL is used but there is no" " HTTP request -- acce ss denied.\n", ae->name); return 0; } break; default: break; } debug(28, 3) ("ac lMatchAcl: checking %s \n", ae->cfgline); switch (ae->type) { case ACL_SRC_IP: return aclMatchIp(&ae->data, checklist->src_addr);

/* NOTREACHED */ case ACL_MY_IP: return aclMatchIp(&ae->data, checklist->my_addr ); /* NOTREACHED */ case ACL_DST_IP: ia = ipcache_gethostbyname(r->host, IP_LOOK UP_IF_MISS); if (ia) { for (k = 0; k < (int) ia->count; k++) { if (aclMatchIp(&a e->data, ia->in_addrs[k])) return 1; } return 0; } else if (checklist->state[ACL _DST_IP] == ACL_LOOKUP_NONE) { debug(28, 3) ("aclMatchAcl: Can t yet compare %s ACL for %s \n", ae->name, r->host); checklist->state[ACL_DST_IP] = ACL_LOOKUP _NEEDED; return 0; } else { return aclMatchIp(&ae->data, no_addr); } /* NOTREACH ED */ case ACL_DST_DOMAIN: if ((ia = ipcacheCheckNumeric(r->host)) == NULL) retu rn aclMatchDomainList(&ae->data, r->host); fqdn = fqdncache_gethostbyaddr(ia->in _addrs[0], FQDN_LOOKUP_IF_MISS); if (fqdn) return aclMatchDomainList(&ae->data, fqdn); if (checklist->state[ACL_DST_DOMAIN] == ACL_LOOKUP_NONE) { debug(28, 3) ( "aclMatchAcl: Can t yet compare %s ACL for %s \n", ae->name, inet_ntoa(ia->in _addrs[0])); checklist->state[ACL_DST_DOMAIN] = ACL_LOOKUP_NEEDED; return 0; } r eturn aclMatchDomainList(&ae->data, "none"); /* NOTREACHED */ case ACL_SRC_DOMAI N: fqdn = fqdncache_gethostbyaddr(checklist->src_addr, FQDN_LOOKUP_IF_MISS); if (fqdn) { return aclMatchDomainList(&ae->data, fqdn); } else if (checklist->state [ACL_SRC_DOMAIN] == ACL_LOOKUP_NONE) { debug(28, 3) ("aclMatchAcl: Can t yet com pare %s ACL for %s \n", ae->name, inet_ntoa(checklist->src_addr)); checklist>state[ACL_SRC_DOMAIN] = ACL_LOOKUP_NEEDED; return 0; } return aclMatchDomainLis t(&ae->data, "none"); /* NOTREACHED */ case ACL_DST_DOM_REGEX: if ((ia = ipcache CheckNumeric(r->host)) == NULL) return aclMatchRegex(ae->data, r->host); fqdn = fqdncache_gethostbyaddr(ia->in_addrs[0], FQDN_LOOKUP_IF_MISS); if (fqdn) return aclMatchRegex(ae->data, fqdn); if (checklist->state[ACL_DST_DOMAIN] == ACL_LOOKU P_NONE) { debug(28, 3) ("aclMatchAcl: Can t yet compare %s ACL for %s \n", ae ->name, inet_ntoa(ia->in_addrs[0])); checklist->state[ACL_DST_DOMAIN] = ACL_LOOK UP_NEEDED; return 0; } return aclMatchRegex(ae->data, "none"); /* NOTREACHED */ case ACL_SRC_DOM_REGEX: fqdn = fqdncache_gethostbyaddr(checklist->src_addr, FQDN _LOOKUP_IF_MISS); if (fqdn) {

return aclMatchRegex(ae->data, fqdn); } else if (checklist->state[ACL_SRC_DOMAIN ] == ACL_LOOKUP_NONE) { debug(28, 3) ("aclMatchAcl: Can t yet compare %s ACL f or %s \n", ae->name, inet_ntoa(checklist->src_addr)); checklist->state[ACL_SRC_ DOMAIN] = ACL_LOOKUP_NEEDED; return 0; } return aclMatchRegex(ae->data, "none"); /* NOTREACHED */ case ACL_TIME: return aclMatchTime(ae->data, squid_curtime); / * NOTREACHED */ case ACL_URLPATH_REGEX: esc_buf = xstrdup(strBuf(r->urlpath)); r fc1738_unescape(esc_buf); k = aclMatchRegex(ae->data, esc_buf); safe_free(esc_bu f); return k; /* NOTREACHED */ case ACL_URL_REGEX: esc_buf = xstrdup(urlCanonica l(r)); rfc1738_unescape(esc_buf); k = aclMatchRegex(ae->data, esc_buf); safe_fre e(esc_buf); return k; case ACL_URLLOGIN: esc_buf = xstrdup(r->login); rfc1738_un escape(esc_buf); k = aclMatchRegex(ae->data, esc_buf); safe_free(esc_buf); retur n k; /* NOTREACHED */ case ACL_MAXCONN: k = clientdbEstablished(checklist->src_a ddr, 0); return ((k > ((intlist *) ae->data)->i) ? 1 : 0); /* NOTREACHED */ case ACL_URL_PORT: return aclMatchIntegerRange(ae->data, (int) r->port); /* NOTREACH ED */ case ACL_MY_PORT: return aclMatchIntegerRange(ae->data, (int) checklist->m y_port); /* NOTREACHED */ #if USE_IDENT case ACL_IDENT: if (checklist->rfc931[0] ) { return aclMatchUser(ae->data, checklist->rfc931); } else { checklist->state[ ACL_IDENT] = ACL_LOOKUP_NEEDED; return 0; } /* NOTREACHED */ case ACL_IDENT_REGE X: if (checklist->rfc931[0]) { return aclMatchRegex(ae->data, checklist->rfc931) ; } else { checklist->state[ACL_IDENT] = ACL_LOOKUP_NEEDED; return 0; } /* NOTRE ACHED */ #endif case ACL_PROTO: return aclMatchInteger(ae->data, r->protocol); / * NOTREACHED */ case ACL_METHOD:

return aclMatchInteger(ae->data, r->method); /* NOTREACHED */ case ACL_BROWSER: browser = httpHeaderGetStr(&checklist->request->header, HDR_USER_AGENT); if (NUL L == browser) return 0; return aclMatchRegex(ae->data, browser); /* NOTREACHED * / case ACL_REFERER_REGEX: header = httpHeaderGetStr(&checklist->request->header, HDR_REFERER); if (NULL == header) return 0; return aclMatchRegex(ae->data, head er); /* NOTREACHED */ case ACL_PROXY_AUTH: case ACL_PROXY_AUTH_REGEX: if ((ti = aclAuthenticated(checklist)) != 1) return ti; ti = aclMatchProxyAuth(ae->data, r ->auth_user_request, checklist, ae->type); return ti; /* NOTREACHED */ case ACL_ MAX_USER_IP: if ((ti = aclAuthenticated(checklist)) != 1) return ti; ti = aclMat chUserMaxIP(ae->data, r->auth_user_request, checklist->src_addr); return ti; /* NOTREACHED */ #if SQUID_SNMP case ACL_SNMP_COMMUNITY: return aclMatchWordList(ae ->data, checklist->snmp_community); /* NOTREACHED */ #endif case ACL_SRC_ASN: re turn asnMatchIp(ae->data, checklist->src_addr); /* NOTREACHED */ case ACL_DST_AS N: ia = ipcache_gethostbyname(r->host, IP_LOOKUP_IF_MISS); if (ia) { for (k = 0; k < (int) ia->count; k++) { if (asnMatchIp(ae->data, ia->in_addrs[k])) return 1 ; } return 0; } else if (checklist->state[ACL_DST_ASN] == ACL_LOOKUP_NONE) { deb ug(28, 3) ("asnMatchAcl: Can t yet compare %s ACL for %s \n", ae->name, r->ho st); checklist->state[ACL_DST_ASN] = ACL_LOOKUP_NEEDED; } else { return asnMatch Ip(ae->data, no_addr); } return 0; /* NOTREACHED */ #if USE_ARP_ACL case ACL_SRC _ARP: return aclMatchArp(&ae->data, checklist->src_addr); /* NOTREACHED */ #endi f case ACL_REQ_MIME_TYPE: header = httpHeaderGetStr(&checklist->request->header, HDR_CONTENT_TYPE); if (NULL == header) header = "";

return aclMatchRegex(ae->data, header); /* NOTREACHED */ case ACL_REP_MIME_TYPE: if (!checklist->reply) return 0; header = httpHeaderGetStr(&checklist->reply->h eader, HDR_CONTENT_TYPE); if (NULL == header) header = ""; return aclMatchRegex( ae->data, header); /* NOTREACHED */ case ACL_REP_HEADER: if (!checklist->reply) return 0; return aclMatchHeader(ae->data, &checklist->reply->header); /* NOTREAC HED */ case ACL_REQ_HEADER: return aclMatchHeader(ae->data, &checklist->request>header); /* NOTREACHED */ case ACL_EXTERNAL: return aclMatchExternal(ae->data, checklist); /* NOTREACHED */ case ACL_NONE: case ACL_ENUM_MAX: break; } debug(28 , 0) ("aclMatchAcl: %s has bad type %d\n", ae->name, ae->type); return 0; } vo id aclDestroyAcls(acl ** head) { acl *a = NULL; acl *next = NULL; for (a = *head ; a; a = next) { next = a->next; debug(28, 3) ("aclDestroyAcls: %s \n", a->cfgl ine); switch (a->type) { case ACL_SRC_IP: case ACL_DST_IP: case ACL_MY_IP: splay _destroy(a->data, aclFreeIpData); break; #if USE_ARP_ACL case ACL_SRC_ARP: #endi f case ACL_DST_DOMAIN: case ACL_SRC_DOMAIN: splay_destroy(a->data, xfree); break ; #if SQUID_SNMP case ACL_SNMP_COMMUNITY: wordlistDestroy((wordlist **) & a->dat a); break; #endif #if USE_IDENT case ACL_IDENT: aclFreeUserData(a->data); break; #endif case ACL_PROXY_AUTH:

aclFreeUserData(a->data); break; case ACL_TIME: aclDestroyTimeList(a->data); bre ak; #if USE_IDENT case ACL_IDENT_REGEX: #endif case ACL_PROXY_AUTH_REGEX: case A CL_URL_REGEX: case ACL_URLLOGIN: case ACL_URLPATH_REGEX: case ACL_BROWSER: case ACL_REFERER_REGEX: case ACL_SRC_DOM_REGEX: case ACL_DST_DOM_REGEX: case ACL_REP_ MIME_TYPE: case ACL_REQ_MIME_TYPE: aclDestroyRegexList(a->data); break; case ACL _REP_HEADER: case ACL_REQ_HEADER: aclDestroyHeader(a->data); break; case ACL_PRO TO: case ACL_METHOD: case ACL_SRC_ASN: case ACL_DST_ASN: #if SRC_RTT_NOT_YET_FIN ISHED case ACL_NETDB_SRC_RTT: #endif case ACL_MAXCONN: intlistDestroy((intlist * *) & a->data); break; case ACL_MAX_USER_IP: aclDestroyUserMaxIP(&a->data); break ; case ACL_URL_PORT: case ACL_MY_PORT: aclDestroyIntRange(a->data); break; case ACL_EXTERNAL: aclDestroyExternal(&a->data); break; case ACL_NONE: case ACL_ENUM_ MAX: debug(28, 1) ("aclDestroyAcls: no case for ACL type %d\n", a->type); break; } safe_free(a->cfgline); memFree(a, MEM_ACL); } *head = NULL; } wordlist * aclD umpGeneric(const acl * a) { debug(28, 3) ("aclDumpGeneric: %s type %d\n", a->nam e, a->type); switch (a->type) { case ACL_SRC_IP: case ACL_DST_IP:

case ACL_MY_IP: return aclDumpIpList(a->data); case ACL_SRC_DOMAIN: case ACL_DST _DOMAIN: return aclDumpDomainList(a->data); #if SQUID_SNMP case ACL_SNMP_COMMUNI TY: return wordlistDup(a->data); #endif #if USE_IDENT case ACL_IDENT: return acl DumpUserList(a->data); case ACL_IDENT_REGEX: return aclDumpRegexList(a->data); # endif case ACL_PROXY_AUTH: return aclDumpUserList(a->data); case ACL_TIME: retur n aclDumpTimeSpecList(a->data); case ACL_PROXY_AUTH_REGEX: case ACL_URL_REGEX: c ase ACL_URLLOGIN: case ACL_URLPATH_REGEX: case ACL_BROWSER: case ACL_REFERER_REG EX: case ACL_SRC_DOM_REGEX: case ACL_DST_DOM_REGEX: case ACL_REQ_MIME_TYPE: case ACL_REP_MIME_TYPE: return aclDumpRegexList(a->data); case ACL_REQ_HEADER: case ACL_REP_HEADER: return aclDumpHeader(a->data); case ACL_SRC_ASN: case ACL_MAXCON N: case ACL_DST_ASN: return aclDumpIntlistList(a->data); case ACL_MAX_USER_IP: r eturn aclDumpUserMaxIP(a->data); case ACL_URL_PORT: case ACL_MY_PORT: return acl DumpIntRangeList(a->data); case ACL_PROTO: return aclDumpProtoList(a->data); cas e ACL_METHOD: return aclDumpMethodList(a->data); #if USE_ARP_ACL case ACL_SRC_AR P: return aclDumpArpList(a->data); #endif case ACL_EXTERNAL: return aclDumpExter nal(a->data); case ACL_NONE: case ACL_ENUM_MAX: break; } debug(28, 1) ("aclDumpG eneric: no case for ACL type %d\n", a->type); return NULL; } --------------x----------------------------x--------------------------x----------------

#include <iostream.h> #include <fstream.h> #include <conio.h> #include <stdio.h> int main (void) { FILE *in; char *matriz[] = {0}; int i = 0; clrscr(); if ((in = fopen("BL.TXT", "rt")) == NULL) { fprintf(stderr, "Cannot open input f ile.\n"); return 1; } while (!feof(in)) { fputc(fgets(in), matriz[i]); i++; } pr intf ("resultado= %c",matriz[1]); getch(); fclose(in); return 0; } ----------x-----------------------x-------------------------x----------------

#include <stdio.h> int main(void) { FILE *in, *out; if ((in = fopen("BL.TXT", "r t")) == NULL) { fprintf(stderr, "Cannot open input file.\n"); return 1; } if ((o ut = fopen("BL2.TXT", "wt")) == NULL) { fprintf(stderr, "Cannot open output file .\n"); return 1; } while (!feof(in)) fputc(fgetc(in), out); fclose(in); fclose(o ut); return 0; } ------------x----------------------x--------------------x-------------------------x-----------------#!/bin/bash read i echo $i >> /home/squid/ squid cat /home/squid/squid | awk -F "/" {print $3} >> /home/squid/squid2 perl /home/squid/www/cgi-bin/teste.pl #/usr/share/squid/erros/Portuguese/ERR_ACCESS_ DENIED #return i ---------x--------------x-----------------x-----------------x------

IFS=" " for url in `cat` ; do echo $url case $url in *jpg) echo "http://erro.htm l" ;; *) echo $url ;; esac done ------------x-------------------x--------------------x--------------------x----------------------#!/usr/bin/perl5.8.1 use DBI; open (teste, "teste.txt"); #Cone xao com o BD my $db = DBI->connect("dbi:Pg:dbname=bdblack","postgres","123456"); my $url = <teste>; @array = split(/[\s]/,$url); print "$_\n" foreach (@array); my $query = "SELECT * FROM sites WHERE url = @array[0] OR dominio = $url "; m y $res; $res = $db->do($query); if ($res == 1){ print ("\nSite Bloqueado\n"); } else{ print ("\nSite Livre\n"); } #Fecha a conexao $db -> disconnect(); close (t este); exit(); ---------x-------------------------x----------------------------x------------------------x-----------------#!/usr/bin/perl5.8.1 use DBI; open (teste, "teste.tx t"); #Conexao com o BD my $db = DBI->connect("dbi:Pg:dbname=bdblack","postgres", "123456"); my $url = <teste>; @array = split(/[\s]/,$url); my $query = "SELECT * FROM sites WHERE url = @array[0] OR dominio = $url "; my $res;

$res = $db->do($query); if ($res == 1){ print ("\nSite Bloqueado\n"); } else{ pr int ("\nSite Livre\n"); } #Fecha a conexao $db -> disconnect(); close (teste); e xit(); ----------------------x------------------------x----------------------------------x-------------------------#!/usr/bin/perl5.8.1 use DBI; #Conexao com o BD my $db = DBI->connect("dbi:Pg:dbname=bdblack","postgres","123456"); #Inserindo dado s para consulta print ("Site: "); chomp (my $url = <STDIN>); #Query para consult a no BD my $query = "SELECT * FROM sites WHERE url = $url OR dominio = $url " ; my $res; #Variavel para armazenar o retorno da consulta 1 ou 0 $res = $db->do( $query); #Executa consulta e armazena o resultado na var. res #Testa a condicao da variavel res if ($res == 1){ print ("\nSite Bloqueado\n"); } else{ print ("\n Site Livre\n"); } #Fecha a conexao $db -> disconnect(); exit(); ---------x------------------x------------------x-------------x---------############Copiando os dados para a tabela###################### copy squid from /home/squid/squid.txt delimiter as , ; ############################################################ #### #########Criando a tabela direto no banco bdblack################ psql -f t abelasites bdblack ############################################################# #### cat urls | awk -F "/" {print$1"/"$2","$2} ------x------------------x----------------------x---------------x--------create table sites (url varchar(300), dominio varchar (300)); -------x----------------x------------------x------------x-------

#!/usr/bin/perl5.8.1 use DBI; #Conexao com o BD my $db = DBI->connect("dbi:Pg:db name=bdblack","postgres","123456"); #Entrada de um valor para consulta print("Di gite um site: "); chomp ( my $url = <STDIN> ); #Query para consulta my $query = "SELECT * FROM sites WHERE url = $url "; #Executando consulta $db->do( $query ) ; #Preparando uma consulta my $sql = $db->prepare(q{ SELECT * FROM sites where u rl = "$url" }); $sql->execute(); #Imprimindo tabela my @array; while ( @array = $sql -> fetchrow_array() ){ write(); } format STDOUT = @<<<<<<<<<<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<< $array[0],$array[1] . #Fecha a conexao $db -> disconnect( ); exit(); -----------x---------------------x----------------------x---------------#!/usr/bin/perl5.8.1 use DBI; #Conexao com o BD my $db = DBI->connect("dbi:P g:dbname=bdblack","postgres","123456"); #Handle para consulta my $sql = $db -> p repare(q{SELECT * FROM sites}); #Executa consulta $sql -> execute(); #Entrada pa ra busca print("Digite um site para ser pesquisado: "); chomp( my $url_dom = <ST DIN> ); #Imprimir valores while (($url_dom) = $sql -> fetchrow_array()) { print $url_dom; } #Mostra a quantidade de linhas retornadas printf ("\nForam encontrad os %d resultados\n",$sql -> rows);

#Finaliza Query $sql -> finish(); #Fecha a conexao $db -> disconnect(); exit(); --------x-----------------x-----------------x--------------------x------#!/usr/b in/perl5.8.1 use DBI; #Conexao com o BD my $db = DBI->connect("dbi:Pg:dbname=bdb lack","postgres","123456"); #Inserindo dados para consulta print ("Site: "); cho mp (my $url = <STDIN>); #Query para consulta no BD my $query = "SELECT * FROM sq uid WHERE url = $url "; my $res; #Variavel para armazenar o retorno da consulta 1 ou 0 $res = $db->do($query); #Executa consulta e armazena o resultado na var. res #Testa a condicao da variavel res if ($res == 1){ print ("\nSite Bloqueado\ n"); } else{ print ("\nSite Livre\n"); } #Fecha a conexao $db -> disconnect(); e xit(); -----------x---------------x------------------x--------------x-----------postgresql-8.1.4.tar per-libwww-per-5.803-norch.tar alien_8.64.tar squid-2.5.st able13.tar perl-CGU-2.81.tar per-URi-1.31 perl-CPAn-1.61 perl-5.8.1 DBI-1.52.tar --------------x---------------x------------------x-----------------Ideias do gr upo 1 - Uso de banco de dados para acessar os dados mais rapidamente. 2 - Uso do programa diskd para as verses mais 2.4 at stable. 3 - Uso de parametros habilitad os na hora da compilao. 4 - Uso de outros proxy s como alternativa para a soluo do p roblema. 5 - Hardware especializado. 6 - Melhora no algoritmo de ordenao e de busc a. 7 - criao de uma tabela de indicao de hardware especifico para a quantidade de us uarios. 8 - cada requisio do browser considerada um GET

Referncias ANDRADE, de abril de 2006. BASTOS, Eri Ramos. Configurando um Squid Ninja. Jocie l. Instalando e configurando o Squid. <http://geocities.yahoo.com.br/cesarakg/installing-configuring-squid.html>, Aces so em 15 <http://www.linuxman.pro.br/squid/>.Acesso em 02 de maio de 2006. CAMPOS, August o C. Squid o Melhor Proxy. <http://squid.linuxit.com.br/download/squid/antigos/guiasquid-txt-1.2.txt>, Aces so em 25 de abril 04 de 2006. CIPRIANO, Luis Alberto Garcia. Configurando Oops. <http://zipper.paco.net/~igor/oops.eng/features.html>, Acesso em 04 de maro de 20 06. Deitel, Deitle; Mcphie, Nieto. Perl Como Programar. 3. ed. So Paulo. Bookman, 2005. Enciclopdia Bozolinux. Squid. <http://br.bozolinux.org/enciclopedia/index. php? title=Squid>.Acesso em 02 de maio de 2006. Ferreira, Ruben e. Linux - Guia do Ad ministrador do Sistema.1. ed. So Paulo. Novatec, 2003. JNIOR, Walter Flvio em Pimen ta. MPI. Hiperquicksort: Uma Anlise Prtica em 14 com de Implementao maro de 2006. MARTINS, maro de 2006. <http://www.comp.ufla.br/monografias/ano2002/Hiper quicksort_uma_analise_pratica_com_implementacao_em_MP.pdf>,Acesso Stfano. Guia Sobre Squid/Proxy Transparente. <http://squid.linuxit.com.br/download/squid/antigos/guiasquid-txt-1.2.txt>. Aces so em 11 de Oliveira, Alvaro Mendes de.Squid Plus com AD, redirector, controle de banda e re latrios.<http://www.vivaolinux.com.br/artigos/verArtigo.php?codigo=4716> .Acesso em

23 de setembro de 2006. Paes, Gustavo. Instalando e configurando os mdulos do ker nel 2.6 no Slackware. <http://www.slackware-rasil.com.br/web_site/artigos/artigo _completo.php?aid=60> Acesso em 15 de Agosto de 2006. RESENES, Jonas. Configuran do o Squid no Slackware. <http://www.vivaolinux.com.br/artigos/verArtigo.php?cod igo=1833&pagina=2#>. Acesso em 18 de fevereiro de 2006. REGULY,Alvaro.Instalando Squid. skin=print1>, Acesso em 15 abril de 2006. REIS, Cristiano Fernandes dos reis. Desenho de rede ideal de um servio Proxy. So Paulo. 2006. e configurando o .<http://www.sistemasabertos.com.br/twiki/bin/viewpub/Pub/ArtigoServidorProxy? SATO,Yutaka. Configurando Dansguardian. <http://www.dansguardian.org>, Acesso em 17 de Abril de 2006. SILVA, Hedwio Carvalho.Configurando o Dansguardian. http://www.dansguardian.org> , Acesso em 23 de Abril de 2006. Stones, Richard; Matthew, Neil. Professional Li nux Programando. 2. ed. So Paulo. Makron Books, 2002. THOENY,Peter. Monografia Pr oxy. <http://www.comp.ufla.br/monografias/ano2002/Hiperquicksort_uma_analise_pra tica_com _implementacao_em_MP.pdf>, Acesso em 02 de Maio de 2006. VESPERMAN, Jennifer. Instalando e Configurando o Squid. <http://br.geocities.com /cesarakg/installing-configuring-squid.html>. Acesso em 11 de Maro de 2006.

Wolfer, Thomas. Aumente a taxa de transferencia de dados de seus discos IDE com o hdparm. Linux Magazine. So Paulo: Setembro, ano 1, n 2, set 2004. pg. 36. ------------------------------////////////////----------------------------------------------------------Data: 14/03/2006 Hora:21:00:00 http://www.comp.ufla.br/monografias/ano2002/Hiperquicksort_uma_analise_pratica_c om_i mplementacao_em_MP.pdf http://pt.wikipedia.org/wiki/Lista_de_algoritmos#Alg oritmos_de_Classifica.C3.A7.C3.A3o http://www.unicamp.br/~hans/mc102/pascal/algo ritmo/_buscaBinaria.html ----------------------------//////////////////--------------------------------------------------------------------------------------// ////////////////-----------------------------------------------------------Data: 11/03/2006 Hora: 14:00:00 http://squid.linuxit.com.br/download/squid/antigos/guiasquid-txt-1.2.txt http:// www.sistemasabertos.com.br/twiki/bin/viewpub/Pub/ArtigoServidorProxy?skin=print1 http://geocities.yahoo.com.br/cesarakg/installing-configuring-squid.html ---------------------------//////////////////--------------------------------------------------------------------------------------//////////////////----------------------------------------------------------Data: 18/02/2006 Hora: 14:00:00 http://www.squid-cache.org/Doc/Prog-Guide/prog-guide-3.html http://www.linhadeco digo.com.br/livros.asp?id=575 http://www.ginux.ufla.br/documentacao/monografias. html http://www.vivaolinux.com.br/artigos/verArtigo.php?codigo=1833&pagina=2# ht tp://urlblacklist.com/ ----------------------------//////////////////----------------------------------------------------------------------------------------// //////////////-----------------------------------------------------------Data: 1 4/03/2006 Hora:21:00:00

http://pt.wikipedia.org/wiki/Lista_de_algoritmos#Algoritmos_de_Classifica.C3.A7. C3.A3o **http://www.unicamp.br/~hans/mc102/pascal/algoritmo/_buscaBinaria.html ---------------------------//////////////////--------------------------------------------------------------------------------------//////////////////----------------------------------------------------------Data: 11/03/2006 Hora: 14:00:00 **http://www.sistemasabertos.com.br/twiki/bin/viewpub/Pub/ArtigoServidorProxy? s kin=print1 ----------------------------//////////////////--------------------------------------------------------------------------------------//////////////////----------------------------------------------------------Data: 18/02/2006 Hora: 14:00:00 **http://www.squid-cache.org/Doc/Prog-Guide/prog-guide-3.html **http://www.ginux .ufla.br/documentacao/monografias.html **http://urlblacklist.com/ ---------------------------//////////////////----------------------------------------------------------Data: 16/04/2006 Hora: 14:50:00 ftp://www.delegate.org/pub/DeleGate/Manual.htm#DESCRIPTION **http://lists.debian .org/debian-l10n-portuguese/2001/10/msg00052.html ---------------------------/// /////////////////------------------------------------------------------------------------------------////////////////////---------------------------------------------------------Data: 02/05/2006 **http://zipper.paco.net/~igor/oops.eng/fea tures.html **http://www.dansguardian.org **http://www.delegate.org http://www.in f.ufes.br/~proinfo/aulas_via_chat/Setembro-01/turma2_0109.htm http://br.bozolinu x.org/enciclopedia/index.php?title=Squid http://www.linuxman.pro.br/squid/index. t2t Hora: 17:13:00 **http://www.inf.ufes.br/~proinfo/aulas_via_chat/Setembro-01/ turma2_0109.htm

http://www.slackwarenaveia.org/modules.php?name=Sections&op=printpage&artid=80 h ttp://www.linuxman.pro.br/squid/ http://zipper.paco.net/~igor/oops.eng/features. html http://www.dansguardian.org http://www.delegate.org -------------------------///////////////////////-------------------------------------------------------Lista de Siglas e Abreviaturas ACL (Access Control List ou Lista de Controle de Acesso): definida pela rea de cin cia da computao como uma lista que define quem tem permisso de acesso a certos serv ios. Isso para quem um servidor deve permitir ou negar determinada tarefa. normal mente uma lista de princpios com os tipos de acesso definido para cada usurio ou g rupo. ADSL (Asymmetric Digital Subscriber Line): um formato de DSL, uma tecnolog ia de comunicao de dados que permite uma transmisso de dados mais rpida atravs de lin has de telefone do que um modem convencional pode oferecer. Backbone: No context o de redes de computadores, o backbone (traduzindo para portugus, espinha dorsal) designa o esquema de ligaes centrais de um sistema mais amplo, tipicamente de ele vado dbito (velocidade, no portugus do Brasil) relativamente periferia. Backup: Re fere-se cpia de dados de um dispositivo para o outro com o objetivo de posteriorm ente os recuperar (os dados), caso haja algum problema. Browser: (tambm conhecido como web browser) um programa que habilita seus usurios a interagirem com docume ntos HTML hospedados em um servidor Web. Cache: um dispositivo de acesso rpido, i nterno a um sistema, que serve de intermedirio entre um operador de um processo e o dispositivo de armazenamento ao qual esse operador acede. A vantagem principa l na utilizao de uma cache consiste em evitar o acesso ao dispositivo de armazenam ento - que pode ser demorado - e que vale a pena armazenar as informaes procuradas em meio mais rpido. CGI (Common Gateway Interface): Consiste numa importante tec nologia que permite gerar pginas dinmicas permitindo a um navegador passar parmetro s para um programa alojado num servidor web. Dial-up: um tipo de acesso Internet no qual uma pessoa usa um modem e uma linha telefnica para se ligar a um n de uma rede de computadores do ISP. A partir desse momento, o ISP encarrega-se de faze r o routing para a Internet. DNS (Domain Name System - Sistema de Nomes de Domnio s): um sistema de gerenciamento de nomes hierrquico. Ethernet: uma tecnologia de interconexo para redes locais - Local Area Networks (LAN) baseada no envio de pac otes. Ela define cabeamento e sinais eltricos para a camada fsica, e formato de pa cotes e protocolos para a camada de controle de acesso ao meio (Media Access Con trol - MAC) do modelo OSI. A Ethernet foi padronizada pelo IEEE como 802.3. A pa rtir dos anos 90, ela vem sendo a tecnologia de LAN mais amplamente utilizada e tem tomado grande parte do espao de outros padres de rede como Token Ring, FDDI e ARCNET. Expresso Regular: Um padro a ser usado para procurar ou substituir palavra s ou grupos de palavras. um meio preciso de se fazer buscas de determinadas pores de texto. Firewall: o nome dado ao dispositivo de rede que tem por funo regular o trfego de rede entre redes distintas e impedir a transmisso de dados nocivos ou no autorizados de uma rede a outra. Dentro deste conceito incluem-se, geralmente, o s filtros de pacotes e Proxy de protocolos.

FTP (File Transfer Protocol - Protocolo de Transferncia de Arquivos): uma forma b astante rpida e verstil de transferir arquivos, sendo uma das mais usadas na inter net. Gateway: uma mquina intermediria geralmente destinada a interligar redes, sep arar domnios de coliso, ou mesmo traduzir protocolos. Exemplos de gateway podem se r os routers (ou roteadores) e firewalls, j que ambos servem de intermedirios entr e o utilizador e a rede. Um Proxy tambm pode ser interpretado como um gateway (em bora em outro nvel, aquele da camada em que opera), j que serve de intermedirio tam bm. Gopher: um protocolo de redes de computadores que foi desenhado para indexar repositrios de documentos na Internet. Host: qualquer mquina ou computador conecta do a uma rede. Os hosts variam de computadores pessoais a supercomputadores, den tre outros equipamentos, como roteadores. HTML (HyperText Markup Language - Ling uagem de Formatao de Hipertexto): Trata-se de uma linguagem de marcao utilizada para produzir pginas na Internet. De modo geral so documentos de texto escritos em cdig os que podem ser interpretados pelos browsers para exibir as pginas da World Wide Web. HTTP (HyperText Transfer Protocol - Protocolo de Transferncia de Hipertexto ): um protocolo da camada de "Aplicao" do modelo OSI, utilizado para transferncia d e dados na World Wide Web. Esse o protocolo da World Wide Web (www). O mesmo tra nsfere dados de hipermidia (imagens, sons e textos). Algumas de suas caracterstic as so: geralmente este protocolo, utiliza a porta 80 e usado para a comunicao de "s ites". ICP (Infra-estrutura de Chaves Pblicas): Uma Infra-Estrutura de Chaves Pbli cas um rgo ou inciativa pblica ou privada para a organizao de uma estrutura de emisso de chaves pblicas, baseando-se no princpio da terceira parte confivel, oferecendo u ma mediao de acreditao e confiana em transaes entre partes que utilizam certificados d gitais, bem como se responsabilizando pela emisso de tais certificados, assumindo -se ento como a parte confivel destas transaes. A infra-estrutura de chaves pblicas d o Brasil a Infra-Estrutura de Chaves Pblicas Brasileira, ou ICP-Brasil. ICQ: um p rograma de comunicao instantnea pela Internet que foi o mais popular durante anos. IMAP (Internet Message Access Protocol): um protocolo de gerenciamento de correi o eletrnico superior em recursos ao POP3 - protocolo que a maioria dos provedores oferece aos seus assinantes. A ltima verso o IMAP4. O mais interessante que as me nsagens ficam armazenadas no servidor e o internauta pode ter acesso a suas past as e mensagens em qualquer computador. IP (Internet Protocol - Protocolo de Inte rnet): um protocolo usado entre duas mquinas em rede para encaminhamento dos dado s. ISP (Internet Service Provider): Oferece principalmente servio de acesso inter net, agregando a ele outros servios relacionados, tais como "e-mail", "hospedagem de sites" ou blogs, entre outros. Kernel: entendido como o ncleo do Sistema Oper acional ou, numa traduo literal, cerne. Ele representa a camada mais baixa de inte rface com o Hardware, sendo responsvel por gerenciar os recursos do sistema compu tacional como um todo. no kernel que esto definidas funes para operao com perifricos mouse, discos, impressoras, interface serial/interface paralela), gerenciamento de memria, entre outros. Resumidamente, o kernel um conjunto de programas que for nece para os programas de usurio (aplicativos) uma interface para utilizar os rec ursos do sistema. Link: uma referncia num documento em hipertexto a outro documen to ou a outro recurso. Login: um conjunto de caracteres solicitado para os usurio s que por algum motivo necessitam acessar algum sistema computacional. Geralment e os sistemas computacionais solicitam um login e uma senha para a liberao do aces so. Logs: o termo utilizado para descrever o processo de registro de eventos rel evantes num sistema computacional. MIME (Multipurpose Internet Mail Extensions): uma norma da Internet para o formato das mensagens de correio eletrnico.

NAT (Network Address Translation): Tambm conhecido como masquerading uma tcnica qu e consiste em reescrever os endereos IP de origem de um pacote que passam sobre u m router ou firewall de maneira que um computador de uma rede interna tenha aces so ao exterior (rede pblica). NFS (Network File System): um modelo de sistema de arquivos, que tem como funo centralizar arquivos em um servidor, formando assim um diretrio virtual. NNTP (Network News Transfer Protocol): um protocolo da interne t para grupos de discusso da chamada usenet. OSI (Open Systems Interconnection): um conjunto de padres ISO relativo comunicao de dados. POP (Post Office Protocol (P OP3)): um protocolo utilizado no acesso remoto a uma caixa de correio eletrnico. RAID (Redundant Array of Independent Disks - Conjunto Redundante de Discos): um meio de se criar uma unidade virtual composta por vrios discos individuais, com a finalidade de duplicao (redundncia, recuperao de falhas) ou balanceamento (operaes I/ em paralelo). SCSI (Small Computer System Interface): A tecnologia SCSI foi cri ada para acelerar a taxa de transferncia de dados entre dispositivos de um comput ador, desde que tais perifricos sejam compatveis com o padro. SMTP (Simple Mail Tra nsfer Protocol): o padro de fato para envio de e-mail atravs da Internet. SSL (Sec ure Sockets Layer): um protocolo criptogrfico que provem comunicao segura na Interne t para coisas como e-mail, navegao por pginas, e outros tipos de transferncia de dad os. Tag: So estruturas de linguagem de marcao que consistem em breves instrues, tendo uma marca de incio e outra de fim. TCP (Transmission Control Protocol): um dos p rotocolos sob os quais assenta o ncleo da Internet nos dias de hoje. A versatilid ade e robustez deste protocolo tornou-o adequado para redes globais, j que este v erifica se os dados so enviados de forma correta, na seqncia apropriada e sem erros , pela rede. Telnet: um protocolo cliente-servidor de comunicaes usado para permit ir a comunicao entre computadores ligados numa rede, baseado em TCP. TTL (Time to Live): Significa o nmero de mquinas que os pacotes podem demorar numa rede de comp utadores antes de serem descartados (mx. 255). UDP: D s aplicaes acesso direto ao ser vio de entrega de datagramas, como o servio de entrega que o IP d. URL (Universal R esource Locator - Localizador Universal de Recursos): o endereo de um recurso, di sponvel em uma rede; seja a Internet, ou uma rede corporativa, uma intranet. WEB: uma rede de computadores na Internet que fornece informao em forma de hipertexto.