9 sept 2007

/* Analizador lexico primitivo (basico)
Palabras reservadas: begin, end, do, while, if
Tipo de elementos/tokens: palabras reservadas, numeros enteros, identificadores, operadores aritmeticos(+,-), comentarios
Fecha: Agosto 2007

Coded by Yuan G. Ho
*/

#include <stdio.h>
#include <ctype.h>
#include <string.h>

void uso_programa();
int identif_token(char token[128], int);

int main(int argc, char **argv)
{
FILE *archivo;
char caracter;
char token[128];
int posicion=0;
int flag_com = 0; //bandera para comentarios

if(argc != 2) uso_programa();

archivo = fopen(argv[1], "r");

while ((caracter = fgetc(archivo)) != EOF)
{
if(caracter == '"' || flag_com == 1)
{
token[posicion++] = caracter;
if(flag_com == 0)
flag_com = 1;
else
if(flag_com == 1 && caracter == '"')
{
flag_com = 0;
token[posicion] = '0';
printf("%s ", token);
printf("ttttComentarion");
posicion = 0;
}

}
else
if(caracter != ' ' && caracter != 'n' && caracter != ';' && flag_com == 0)
{
token[posicion++] = caracter;
}
else {
if(posicion>0)
{
token[posicion] = '0';
printf("%s ", token);
switch(identif_token(token, posicion))
{
case 0: printf("ttttpalabra reservadan");
break;
case 1: printf("ttttIdentificadorn");
break;
case 2: printf("ttttOperador aritmeticon");
break;
case 3: printf("ttttNumeron");
break;
default: printf("ttttErrorn");
}
posicion = 0;
}
}
}

return 0;
}

void uso_programa()
{
puts("Uso: analizador archivo_fuente");
puts("Se debe ejecutar el programa pasando como parametro el nombre del archivo fuente que contiene el codigo a ser analizado");
}

int identif_token(char token[128], int longitud)
{

// -9 representa error
int trans_estado[8][7] = { {0,1,5,3,4,6,-1},
{-9, 1, 2, -9, -9, -9, -1},
{-9, 1, 2, -9, -9, -9, -1},
{-9, -9, 5, -9, -9, -9, -9},
{-9, -9, 5, -9, -9, -9, -9},
{-9, -9, 5, -9, -9, -9, -1},
{6, 6, 6, 6, 6, 7, -9},
{-9, -9, -9, -9, -9, -9, -1}
};

int estado = 0;
int ciclo;


for(ciclo = 0; ciclo < longitud; ciclo++)
{
if(estado == -9)
return -9;

if(isdigit(token[ciclo]))
estado = trans_estado[estado][2];
else if(isalpha(token[ciclo]))
estado = trans_estado[estado][1];
else if(isspace(token[ciclo]))
estado = trans_estado[estado][0];
else if(token[ciclo] == '+')
estado = trans_estado[estado][3];
else if(token[ciclo] == '-')
estado = trans_estado[estado][4];
else if(token[ciclo] == '"')
estado = trans_estado[estado][5];
else
estado = -9;
}

if(estado == 1)
if((strcmp(token, "begin") == 0) || (strcmp(token, "end") == 0) || (strcmp(token, "if") == 0) || (strcmp(token, "do") == 0) || (strcmp(token, "while") == 0))
return 0;
else
return 1;

if(estado == 5)
return 3;

if(estado == 3)
return 2;

if(estado == 4)
return 2;

if(estado == 2)
return 1;

if(estado == -9)
return -9;
}

Analizador Lexico - Lexer

Este es un analizador lexico sencillo que programe. Publicare la tabla de transicion de estados y el codigo del lexer, que es bastante primitivo.

Los pasos que segui para crear este lexer fueron:
  1. Definir mi lenguaje (palabras reservadas, comentarios, etc)
  2. Crear el automata finito (grafo)
  3. Crear las reglas
  4. Crear la tabla de transicion de estados
  5. Programar
Mi lenguaje lo defini de la siguiente manera:
  • Palabras reservadas: begin, end, do, if, while
  • Comentarios: cualquier cadena entre comillas dobles ("comentario")
  • Numeros: numeros enteros (2, -2, +5, etc)
  • Operadores aritmeticos: +, -
  • Identificadores: cualquier cadena que este compuesto por letras solas o letras y numeros, debe empezar con letra
Las reglas del automata se podran visualizar en la tabla de transicion de estados.

La tabla de transicion de estados a continuacion:


Y por ultimo, el codigo estara en el siguiente post, lo subire a google docs y luego lo publicare. No salio muy bien formateado =(

Cualquier sugerencia, correcion, comentario, lo que sea, enviarme un correo o escribirlo como comentario =D

1 sept 2007

Proteger tu linux desktop o workstation con iptables

Este es un mini-tutorial para proteger tu maquina de ataques. Utilizare iptables para ello, el kernel debe tener netfilter, ya sea como modulo, o formando parte del kernel, y tambien el modulo state de netfilter, para poder monitorear conexiones.

Son solo 2 reglas que deberas crear para tu firewall:
iptables -P INPUT DROP
iptables -A INPUT -m state --state ESTABLISHED -j ACCEPT


La primera cambia la politica de tu firewall, de ACCEPT a DROP. Netfilter tiene 3 cadenas o chains: INPUT, OUTPUT, FORWARD. INPUT filtra los paquetes entrantes, OUTPUT filtra los paquetes salientes, y FORWARD filtra los paquetes a los que le haces forward, duh!. En este caso, la politica de nuestro firewall es desechar cualquier paquete si no cumple con ninguna de las reglas.

La segunda regla le dice a nuestro firewall que acepte cualquier paquete que tenga un estado de Establecido. Esto se basa en el modulo state, que nos permite monitorear las conexiones, saber si un paquete pertenecen a alguna conexion en especifico. Esta segunda regla nos permite aceptar paquetes de cualquier conexion que iniciemos nosotros. Si la conexion lo inicia un host externo, el firewall desechara los paquetes.

Esto solo funcionara bien si no prestas ningun servicio en tu maquina, ejemplo: servidor correo, ftp, ssh, web, etc. Ya que nadie podra conectarse a los servicios, a menos que agregues un par de reglas a tu cadena INPUT.

Si por ejemplo quieres que alguien pueda accesar a tu servidor web, solo tienes que agregar otra regla:
iptables -A INPUT -p tcp --dport 80 -j ACCEPT

Por lo general los servidores web ofrecen servicios por el puerto 80 o 8080, tendras que hacer lo mismo para otros servicios.

Si deseas aprender mas de iptables o netfilter, mejor buscate un manual, tutorial o libro =P. Recuerda, la regla 2 es un ejemplo de Stateful firewall, un firewall basado en estados de conexion.