sexta-feira, outubro 26, 2007

Brincando com Squid Autenticando no MySQL (Linux)

Olá povo!

Mais uma vez aqui para mais uma aventurazinha =P

Na faculdade surgiu um trabalho de final de ano que agruparia várias matérias num único projeto, chamado Projeto Integrador, o qual consistia em fazer um autenticador (helper) para o Squid em C para autenticar no MySQL.
Me baseando num outro projeto[1] que já existia. Como era pra faculdade eu dei uma melhorada na sintaxe e deixei ele verboso pois o professor de C queria um log bem bonito (rs).

How it works:

1. Instalando o Squid, MySQL, GCC e libs.
2. Source do Helper.
3. Compilando o Helper.
4. Estrutura do banco Squid.
5. Configurando o Squid.
6. Inserindo e testando usuários.
7. Considerações.
8. Links



1. Instalando o SQUID.

Na faculdade os professores pediram para usar o Debian (apesar de gostar mais do FreeBSD), os caras mandam (rs). Depois do linux instalado na máquina e também


# apt-get install squid
# apt-get install mysql-server
# apt-get install libmysqlclient15-dev
# apt-get install libmysqlclient15off
# apt-get install gcc


2. Source do Helper



#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <mysql/mysql.h>

#define HOST "localhost"
#define USER "root"
#define PASS "root"
#define DB "squid"

#define TAB "usuarios"
#define USER_TAB "login"
#define PASS_TAB "senha"
#define ACT_TAB "status"

main() {
char query[255], *senha, *user;;
MYSQL_RES *resp;
MYSQL conexao;
FILE *log;
char buffer[255];
int res;

if((log=fopen("/var/log/mysql_auth.log","a")) == NULL ) {
(void)printf("ERR\n");
}
/* joga a saida pro standart out pro squid ler */
if( (setvbuf(stdout, NULL, _IOLBF, 0)) != 0 ) {
return;
}

mysql_init(&conexao);

while(1) {
if((log=fopen("/var/log/mysql_auth.log","a")) == NULL ) {
(void)printf("ERR\n");
}
if(mysql_real_connect(&conexao, HOST,USER,PASS,DB,0,NULL,0)) {
if((fgets(buffer, 255, stdin)) == NULL ) {
break;
}
/* encontra a quebra de linha e aponta a senha */
if((senha = strchr(buffer, '\n')) != NULL ) {
*senha = '\0';
}

if((senha = strchr(buffer, ' ')) == NULL ) {
(void) printf("ERR\n");
fprintf(log,"Senha vazia\n");
}
*senha++='\0';

sprintf(query, "SELECT " USER_TAB " FROM " TAB " WHERE " USER_TAB "='%s' AND " PASS_TAB "=PASSWORD('%s') AND " ACT_TAB "='1'",buffer, senha);

fprintf(log,"Conectado ao banco\n");
if((res = mysql_query(&conexao, query)) == 0) {
fprintf(log,"Select Efetuado com Sucesso:\n %s\n", query);
resp = mysql_store_result(&conexao);
fprintf(log,"resposta da consulta: %i\n", resp);
} else {
(void) printf("ERR\n");
fprintf(log,"Erro %d: %s\n", mysql_errno(&conexao),mysql_error(&conexao));
continue;
}

if(resp -> row_count != 0) { // verifica se o objeto row_count dentro de resp eh diferente de zero pra responder
(void) printf("OK\n");
fprintf(log,"Usuário %s login: OK\n",buffer);
mysql_free_result(resp);
mysql_close(&conexao);
} else {
(void) printf("ERR\n");
fprintf(log,"Usuário %s login : Denied\n", buffer);
}
fclose(log);
exit(0);

} else {
(void) printf("ERR\n");
fprintf(log,"Erro %d: %s\n", mysql_errno(&conexao),mysql_error(&conexao));
}
}
}



Porém como o blogspot não respeita identação ¬¬ está tudo fora do lugar. Caso queiram baixem o fonte em http://neo.bs2.com.br/integrador/autenticador.c

3. Compilando o helper

É muito simples:

# gcc -l mysqlclient autenticador.c -o autenticador

mova-o para uma pasta onde o squid tem acesso ex.: /etc/squid/

4. Estrutura do banco MySQL para o Squid:



CREATE DATABASE IF NOT EXISTS squid;
USE squid;
DROP TABLE IF EXISTS `usuarios`;
CREATE TABLE `usuarios` (
`login` varchar(40) NOT NULL,
`senha` varchar(255) NOT NULL,
`status` int(11) NOT NULL default '1',
UNIQUE KEY `login` (`login`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;


Salve-o como banco.sql.
Insira-o no banco com o comando:


# mysql -uroot -proot -e"source banco.sql"


5. Configurando o Squid.

Tomando como padrão que a sua rede seja 192.168.0.0, será necessário colocar as seguintes linhas no squid.conf



auth_param basic program "/etc/squid/autenticador"
auth_param basic realm "Proxy - Digite usuário/senha"
auth_param basic children 5
auth_param basic casesensitive off

acl senha proxy_auth REQUIRED
acl rede src 192.168.0.0./24

http_access allow rede senha


6. Inserindo e testando usuários.

Vamos inserir um usuário teste:


# mysql -uroot -proot squid
> INSERT INTO usuarios VALUES ('teste',PASSWORD('teste'),1);
> QUIT


Crie o arquivo de LOG e dê permissão para que o squid grave nele


# touch /var/log/mysql_auth.log
# chmod 777 /var/log/mysql_auth.log



Inicialize o SQUID:


# /etc/init.d/squid start


Configure seu navegador com o IP e porta do proxy e faça o teste.
No banco se você quiser apenas desativar um usuário sem deletá-lo basta trocar o valor no campo status para 0 (zero).

Facilitei a sua vida? esse software está sobre a Licensa BeerWare... ou seja me paga uma cerveja =]

7. Considerações

Como é um trabalho para a faculdade achei interessante documentar, apesar de não ter tido tempo de escrever este artigo antes de entregar (pois, poderia usá-lo no trabalho), foi bacana desenvolver isso.

Espero que ajude outras pessoas também, que precisem de uma solução como esta onde precisa-se buscar os usuários do squid no banco MySQL.

8. Links
[1] http://www.devet.org/squid/proxy_auth/

Read more!