0% encontró este documento útil (0 votos)
263 vistas90 páginas

Introducción A La Programación en Perl

Este documento presenta una introducción a la programación en Perl, CGI y JavaScript. Incluye secciones sobre conceptos básicos de Perl como variables, arreglos y estructuras de control, así como el uso de rutinas y referencias. También cubre CGI, incluyendo la generación dinámica de HTML y el manejo de formularios. Finalmente, introduce conceptos básicos de JavaScript como variables, funciones, estructuras de control y la validación de formularios. Cada sección contiene ejemplos de código y ejercicios propuestos para el lector.
Derechos de autor
© Attribution Non-Commercial (BY-NC)
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como DOCX, PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
263 vistas90 páginas

Introducción A La Programación en Perl

Este documento presenta una introducción a la programación en Perl, CGI y JavaScript. Incluye secciones sobre conceptos básicos de Perl como variables, arreglos y estructuras de control, así como el uso de rutinas y referencias. También cubre CGI, incluyendo la generación dinámica de HTML y el manejo de formularios. Finalmente, introduce conceptos básicos de JavaScript como variables, funciones, estructuras de control y la validación de formularios. Cada sección contiene ejemplos de código y ejercicios propuestos para el lector.
Derechos de autor
© Attribution Non-Commercial (BY-NC)
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como DOCX, PDF, TXT o lee en línea desde Scribd
Está en la página 1/ 90

Introduccin a la programacin en Perl, CGI y Javascript

Autor: Jos Vicente Nez Zuleta ( [email protected], [email protected] )

Tabla de contenido

Tabla de contenido 2

Indice de tablas 4 Indice de ilustraciones 6 Objetivos de este trabajo 9 Introduccin al Lenguaje Perl 10
Obtencin en instalacin de Perl 10

Perl bsico 11
Hola mundo 11 Uso de variables y asideros de archivo6 11
Ms sobre el uso de variables 12 Ms sobre el uso de asideros 13

Arreglos, Arreglos asociativos y lazos 13


Arreglos y lazos con for 13 Arreglos asociativos y lazos con foreach 14 Lazos con while y uso de split() 14

Estructuras de decisin 15 Uso de patrones en bsquedas y reemplazos, usando expresiones regulares 17 Ejercicio 1: Uso de estructuras de decisin, patrones y estructuras de repeticin 19
Solucin: 19

Uso de rutinas en Perl 19 Referencias en Perl 21 Ejercicio 2: Uso de rutinas y referencias 22


Solucin 23

Validacin de programas en Perl 25


Seguridad en Perl 25 Depuracin de programas en Perl 26
Perl en modo de advertencias (-w) 26 Perl en modo de depuracin (-d) 27 Corregir slo la sintaxis con -c 29

Ejercicio 3: Seguridad en Perl y depuracin de programas 29


Solucin 30

CGI (Common Gateway Interface) 31

Protocolos de comunicacin 31
Modelo OSI y TCP/IP 31 HTTP 32

Modelo cliente - servidor 33


El cliente 33 El servidor 33

CGI 34
Funcionamiento de CGI 34 Generacin dinmica de HTML 35

Ejercicio 4: Generacin dinmica de HTML 36


Solucin: 36

Mtodos de comunicacin 37
Mtodo GET 38 Mtodo POST 38 Variables de entorno adicionales 39 Codificacin de los datos 39

Ejercicio 5: Variables de entorno 39


Solucin 39

Formas en HTML 40
Elementos que contiene la etiqueta FORM 40

Uniendo todo: Manejo de los datos de una forma, seguridad 43 Ejercicio 6: Uso de formas y CGI 46
Solucin 47

Introduccin a Javascript 51
Objetos en Javascript 52
Mtodos de los objetos en Javascript. Programacin orientada a eventos. 53 Hola mundo en Javascript 54

Variables en Javascript 55 Funciones en Javascript 55 Estructuras de repeticin 56


Sintaxis y ejemplo de Do - while 56

Sintaxis y ejemplo de For 56 Sintaxis y ejemplo de For in 56 Sintaxis y ejemplo de while: 57

Estructuras de decisin 57 Cajas de alerta, confirmacin y preguntas 58 Expresiones regulares y arreglos 59


Arreglos 59 Expresiones regulares 60

Formas y validacin 61 Ejercicio 7: Validacin de Formas con Javascript 64


Solucin 64

Referencias bibliogrficas 67

Autor: Jos Vicente Nez Zuleta ([email protected]) 1

Tabla de contenido 2 Indice de tablas 4 Indice de ilustraciones 6 Objetivos de este trabajo 9 Introduccin al Lenguaje Perl 10
Obtencin en instalacin de Perl 10

Perl bsico 11
Hola mundo 11 Uso de variables y asideros de archivo6 11
Ms sobre el uso de variables 12 Ms sobre el uso de asideros 13

Arreglos, Arreglos asociativos y lazos 13


Arreglos y lazos con for 13 Arreglos asociativos y lazos con foreach 14 Lazos con while y uso de split() 14

Estructuras de decisin 15 Uso de patrones en bsquedas y reemplazos, usando expresiones regulares 17

Ejercicio 1: Uso de estructuras de decisin, patrones y estructuras de repeticin 19


Solucin: 19

Uso de rutinas en Perl 19 Referencias en Perl 21 Ejercicio 2: Uso de rutinas y referencias 22


Solucin 23

Validacin de programas en Perl 25


Seguridad en Perl 25 Depuracin de programas en Perl 26
Perl en modo de advertencias (-w) 26 Perl en modo de depuracin (-d) 27 Listando cdigo fuente y el contenido de las variables 27 Ejecutando el cdigo fuente 28 Puntos de quiebre, ejecucin continua del programa 28 Busqueda con patrones 29 Corregir slo la sintaxis con -c 29

Ejercicio 3: Seguridad en Perl y depuracin de programas 29


Solucin 30

CGI (Common Gateway Interface) 31


Protocolos de comunicacin 31
Modelo OSI y TCP/IP 31 HTTP 32

Modelo cliente - servidor 33


El cliente 33 El servidor 33

CGI 34
Funcionamiento de CGI 34 Generacin dinmica de HTML 35

Ejercicio 4: Generacin dinmica de HTML 36


Solucin: 36

Mtodos de comunicacin 37

Mtodo GET 38 Mtodo POST 38 Variables de entorno adicionales 39 Codificacin de los datos 39

Ejercicio 5: Variables de entorno 39


Solucin 39

Formas en HTML 40
Elementos que contiene la etiqueta FORM 40 Input: Recolecta informacin acerca del usuario 40 Option: Ocurre dentro del elemento select, el cual le permite al usuario escoger entre varias alternativas, y es usado para representar cada opcin de select. 41 Select: Le permite al usuario escoger entre mltiples alternativas 41 Textarea: Recolecta mltiples lneas de texto por el usuario. Al usuario se le presenta un panel cuadrado en el cual puede escribir. Se usa en pares. 41

Uniendo todo: Manejo de los datos de una forma, seguridad 43 Ejercicio 6: Uso de formas y CGI 46
Solucin 47

Introduccin a Javascript 51
Objetos en Javascript 52
Mtodos de los objetos en Javascript. Programacin orientada a eventos. 53 Hola mundo en Javascript 54

Variables en Javascript 55 Funciones en Javascript 55 Estructuras de repeticin 56


Sintaxis y ejemplo de Do - while 56 Sintaxis y ejemplo de For 56 Sintaxis y ejemplo de For in 56 Sintaxis y ejemplo de while: 57

Estructuras de decisin 57 Cajas de alerta, confirmacin y preguntas 58 Expresiones regulares y arreglos 59


Arreglos 59

Expresiones regulares 60

Formas y validacin 61 Ejercicio 7: Validacin de Formas con Javascript 64


Solucin 64

Referencias bibliogrficas 67
Indice de ilustraciones

Autor: Jos Vicente Nez Zuleta ([email protected]) 1

Tabla de contenido 2 Indice de tablas 4 Indice de ilustraciones 6 Objetivos de este trabajo 9 Introduccin al Lenguaje Perl 10
Obtencin en instalacin de Perl 10

Perl bsico 11
Hola mundo 11 Uso de variables y asideros de archivo6 11
Ms sobre el uso de variables 12 Ms sobre el uso de asideros 13

Arreglos, Arreglos asociativos y lazos 13


Arreglos y lazos con for 13 Arreglos asociativos y lazos con foreach 14 Lazos con while y uso de split() 14

Estructuras de decisin 15 Uso de patrones en bsquedas y reemplazos, usando expresiones regulares 17 Ejercicio 1: Uso de estructuras de decisin, patrones y estructuras de repeticin 19
Solucin: 19

Uso de rutinas en Perl 19 Referencias en Perl 21 Ejercicio 2: Uso de rutinas y referencias 22


Solucin 23

Validacin de programas en Perl 25


Seguridad en Perl 25 Depuracin de programas en Perl 26
Perl en modo de advertencias (-w) 26 Perl en modo de depuracin (-d) 27 Listando cdigo fuente y el contenido de las variables 27

Ejecutando el cdigo fuente 28 Puntos de quiebre, ejecucin continua del programa 28 Busqueda con patrones 29 Corregir slo la sintaxis con -c 29

Ejercicio 3: Seguridad en Perl y depuracin de programas 29


Solucin 30

CGI (Common Gateway Interface) 31


Protocolos de comunicacin 31
Modelo OSI y TCP/IP 31 HTTP 32

Modelo cliente - servidor 33


El cliente 33 El servidor 33

CGI 34
Funcionamiento de CGI 34 Generacin dinmica de HTML 35

Ejercicio 4: Generacin dinmica de HTML 36


Solucin: 36

Mtodos de comunicacin 37
Mtodo GET 38 Mtodo POST 38 Variables de entorno adicionales 39 Codificacin de los datos 39

Ejercicio 5: Variables de entorno 39


Solucin 39

Formas en HTML 40
Elementos que contiene la etiqueta FORM 40 Input: Recolecta informacin acerca del usuario 40 Option: Ocurre dentro del elemento select, el cual le permite al usuario escoger entre varias alternativas, y es usado para representar cada opcin de select. 41 Select: Le permite al usuario escoger entre mltiples alternativas 41

Textarea: Recolecta mltiples lneas de texto por el usuario. Al usuario se le presenta un panel cuadrado en el cual puede escribir. Se usa en pares. 41

Uniendo todo: Manejo de los datos de una forma, seguridad 43 Ejercicio 6: Uso de formas y CGI 46
Solucin 47

Introduccin a Javascript 51
Objetos en Javascript 52
Mtodos de los objetos en Javascript. Programacin orientada a eventos. 53 Hola mundo en Javascript 54

Variables en Javascript 55 Funciones en Javascript 55 Estructuras de repeticin 56


Sintaxis y ejemplo de Do - while 56 Sintaxis y ejemplo de For 56 Sintaxis y ejemplo de For in 56 Sintaxis y ejemplo de while: 57

Estructuras de decisin 57 Cajas de alerta, confirmacin y preguntas 58 Expresiones regulares y arreglos 59


Arreglos 59 Expresiones regulares 60

Formas y validacin 61 Ejercicio 7: Validacin de Formas con Javascript 64


Solucin 64

Referencias bibliogrficas 67
Objetivos de este trabajo
Est trabajo terico / prctico persigue los siguientes objetivos:

y Obtencin de destrezas bsicas en la programacin y depuracin de programas en Perl. y Comprensin de que es y como funciona CGI, as como la elaboracin y depuracin de programas sencillos. y Introducir a la programacin con Javascript y la validacin de formas en aplicaciones cliente servidor.

Introducir a la programacin de scripts seguros (con y sin CGI).

Durante todo este trabajo se presenta cdigo fuente como ejemplo para explicar los conceptos tericos. Al final de cada seccin se proponen ejercicios para que sean realizados por el lector.

La plataforma utilizada para la elaboracin de los ejercicios fue Linux Slackware 3.4, por lo que algunos comandos podran variar de plataforma en plataforma. El servidor Web utilizado para correr los ejemplos fue Apache versin 1.3.0. Los programas hechos en Javascript fueron probados conNetscape Communicator 4.05. La versin de Perl Utilizada fue 5.04, la versin de Javascript fue 1.2.

Algunos conceptos fueron omitidos o tratados de manera breve por razones de espacio. Nada puede reemplazar la prctica y la investigacin, por lo que se remite al lector interesado a la bibliografa al final de este documento.

Se supone que el lector tiene conocimientos bsicos de programacin en algn lenguaje estructurado, que tiene conocimientos bsicos sobre Unix y HTML y que sabe utilizar un browser para navegar por internet.

S encuentra fallas o desea hacer algn comentario adicional puede escribir a:

[email protected]

Jos Vicente Nez Zuleta.

Introduccin al Lenguaje Perl


Perl es un lenguaje que permite la manipulacin de archivos de texto y procesos. Perl provee una manera concisa y fcil para hacer las cosas las cuales pueden ms difciles en C o en Shell. Esas fueron las ideas que motivaron a su autor (Larry Wall)[11].

En el principio, Perl fue pensado como un leguaje de reduccin de datos, Un lenguaje que permitiera navegar con facilidad y de manera arbitraria por archivos de texto de manera eficiente; Sin embargo Perl ha evolucionado tanto que hoy en da se le considera como una herramienta de programacin en Internet y Administracin de sistemas y redes Unix.

Las siguientes son algunas de las razones por las cuales Perl es popular:

y Reduce el ciclo de programacin. No tiene que compilar su aplicacin, Perl es interpretado y por ello sus programas pueden ser corridos en muchas plataformas sin necesidad de ser recompilado. y Es portable, ya que hay un interpretador de Perl para cada variedad de Unix y Windows, por lo que los cambios que debe hacer a su aplicacin son mnimos o nulos. y Puede hacer mejor muchas cosas que seran ms difciles en otros lenguajes como C o Shell, como la manipulacin de archivos de texto. y La sintaxis de otros lenguajes como Shell, Sed, AWK o C es muy similar a la de Perl. Inclusive cuenta con herramientas para traducir cdigo de Sed y AWK a Perl de manera automtica. y Es extensible. En Internet puede conseguir una enorme cantidad de mdulos los cuales pueden ser incluidos en sus programas sin ninguna dificultad. Si lo desea, puede desarrollar sus propias extenciones. y No cuesta nada. Perl esta protegido por una licencia artstica, la cual permite su libre distribucin. y Es confiable y robusto. Programas como dnswalk, Majordomo y otros estn hechos en Perl.
1

Sin embargo, pueden haber cosas del lenguaje que no le gusten como:

y Cualquiera puede ver el cdigo fuente de su aplicacin porque el cdigo es interpretado y no compilado. y Por ser interpretado y no compilado su velocidad puede ser inferior a la versin en C en algunos casos.

Teniendo esto en cuenta, usted puede decidir si Perl se adapta o no a sus necesidades.

Obtencin en instalacin de Perl


Puede conseguir la ltima versin de Perl en su pgina Web [8]:
2

http://www.perl.com

Bsicamente, lo que debe hacer para instalar Perl es lo siguiente: y Descomprimalo con gunzip xxx.tar.gz y Desempaquetelo en un directorio con tar -xvf xxx.tar.gz y Ejecute el script configure (por ejemplo configure -Dcc=gcc) y Escoja el sistema operativo sobre el cual correr Perl y De aqu en adelante responder muchas preguntas, de acuerdo a su sistema operativo (Crear las dependencias del programa con make depend, entre otros) y Luego corra los tests (el instalador le dir como) y finalmente ejecute el comando make install.
3

Perl bsico
Hola mundo
A continuacin se muestra el programa "hola mundo", escrito en Perl:
4

1. #!/usr/bin/perl 2. print("Hola mundo cruel\n");

Guarde este pequeo fragmento de cdigo como hola_mundo.pl, cambie su permisologa a ejecucin slo por el usuario, y crralo:

$host> chmod u+x hola.pl $host> hola.pl Hola mundo

La lnea 1 contiene lo que se conoce como una "galleta mgica" y le indica al programa en donde se encuentra el interpretador de Perl. La segunda lnea le dice a Perl que imprima un mensaje por pantalla (Ntese el enorme parecido con la orden printf de C). Fjese que cada comando en Perl termina en punto y coma ";".

Otra forma de correr ese script es eliminando la primera lnea y dicindole a Perl que corra el script directamente:

$host> perl hola.pl Hola mundo $host>

La lnea de comandos de Perl es muy extensa, por lo que mencionaremos slo lo nece sario .
5

Uso de variables y asideros de archivo

El programa anterior es bastante limitado, por lo que extenderemos su utilidad con el uso de variables:

1. 2. 3. 4.

#!/usr/bin/perl print("Por favor introduzca su nombre \n"); $nombre=<STDIN>; print("Hola $nombre, ese es un nombre bonito \n");

En la lnea 3 hace una asignacin a la variable $nombre de lo que se "capture" por el asidero de archivos estndar STDIN (Standard Input). Luego mostramos el contenido de esa variable en la lnea 4.STDIN, STDOUT y STDERR son llamados asideros y vienen por omisin en cualquier sistema operativo, por lo que Perl provee acceso directo a ellos. STDIN, STDOUT y STDERR son entrada, salida y error estndar respectivamente. Note como al declarar a la variable $nombre no se le especifico ningn tipo.

Corramos el programa para ver que hace:

$host> hola.pl Escriba por favor su nombre Jose Vicente Hola Jose Vicente , ese es un nombre bonito

Hay algo mal!, El programa est capturando el retorno de carro introducido despus de obtener el nombre. Eso lo podemos solucionar con la rutina chop(), la cual elimina el ltimo carcter de una variable:

1. 2. 3. 4. 5.

#!/usr/bin/perl print("Escriba por favor su nombre \n"); $nombre=<STDIN>; chop($nombre); # Eliminamos el retorno de carro print("Hola $nombre, ese es un nombre bonito \n");

Vea como en la lnea 4 introducimos un comentario, utilizando el carcter #.

Corra el programa de nuevo y note el cambio.

En Perl: y y y No se utilizan tipos de datos en la declaracin de variables Las variables pueden declararse a cualquier altura del cdigo Los asideros permiten acceder a recursos del sistema como la salida y entrada por omisin.

Ms sobre el uso de variables En Perl no hace falta declarar el tipo de una variable como en C o Pascal; Otra diferencia es que Perl internamente utiliza slo dos tipos de variables: Cadena de caracteres o nmeros reales. Veamos por ejemplo, como el siguiente programa es correcto.

#!/usr/bin/perl # Colocamos una cadena de caracteres $variable="Hola, contengo una cadena"; print("El contenido de \$variable es :\t $variable\n"); # Colocamos ahora un numero real $variable=3.141616; print("El contenido de \$variable es :\t $variable\n"); # Colocamos ahora un entero $variable=55; print("El contenido de \$variable es :\t $variable\n");

Veamos su salida por pantalla:

leon[80] $host> variables.pl El contenido de $variable es : Hola, contengo una cadena El contenido de $variable es : 3.141616 El contenido de $variable es : 55

Hemos introducido dos trucos nuevos: el uso del carcter " delante de otro (Le dice a Perl que no \" interprete el carcter, sino que lo proteja y "\t" (Deje una tabulacin).

Veamos otras formas de asignacin de variables:

$respuesta=666; # Un nmero entero $pi=3.141516; # Un nmero real $cantidad=55e2; # Notacin cientifica $mascota='Godzila'; #Una cadena $aviso="$mascota, cuando el tamao cuenta \n"; # Interpolacin de variables $Directorio='ls'; # Guarda el resultado de la ejecucin de un comando

Note que Perl distingue el uso de maysculas y minsculas en la declaracin de variables.

Ms sobre el uso de aside ros La importancia real de los asideros est en que nos permiten redirigir la entrada y la salida de informacin en nuestro programa. Veamos brevemente las operaciones posibles con los asideros:

open(ASIDERO,"nombre del archivo"); # Abre el archivo para l ectura open(ASIDERO,">nombre del archivo"); # Abre el archivo para lectura, escritura open(ASIDERO,">>nombre del archivo"); # Le agrega al archivo open(ASIDERO,"| comando de salida"); # Enva salida a un filtro open(ASIDERO,"nombre del archivo |"); # Recog la salida de un filtro e

En el siguiente ejemplo, los asideros se utilizarn para acceder a las facilidades del sistema:

1. 2. 3. 4. 5. 6. 7. 8.

#!/usr/bin/perl # Veamos el contenido del archivo /etc/hosts # para ello se utiliza cat y eliminamos todos los # comentarios open(ARCHIVO,"cat /etc/hosts|grep -v '#' |"); print <ARCHIVO>,"\n"; # cerramos el archivo (No hace falta, perl lo hace solo) close(ARCHIVO);

Fjese como en la lnea 5 abrimos un asidero, utilizando un filtro compuesto por cat y grep para luego mostrar el resultado imprimiendo el contenido del asidero. Ms adelante se explicar porque este programa es inseguro.

Arreglos, Arreglos asociativos y lazos

Perl cuenta con ciertas estructuras de repeticin, las cuales le permiten procesar cierto grupo de instrucciones de manera repetitiva.

Arreglos y lazos con for Un arreglo no es ms que un conjunto de elementos almacenados en direcciones contiguas de memoria. Veamos como funcionan con el siguiente ejemplo:

1. 2. 3. 4. 5. 6. 7. 8.

#!/usr/bin/perl @usuarios=('jose','luis','pepe'); #Nombres de los usuarios @peso_kg=(70.5,90,65.4); #Peso $num=@usuarios; print("Usuarios a ser procesados: $num \n"); for($i=0;$i<=$#usuarios;$i++) { print("Nombre:\t$usuarios[$i],\tPeso:\t$peso_kg[$i]\n"); }

En las lneas 1 y dos se muestra como se puede inicializar a un arreglo (Denotado con el smbolo @). Obtenemos la cantidad de elementos que tiene almacenados con la instruccin que se muestra en la lnea 3 y luego mostramos elemento por elemento en un lazo de repeticin (utilizando un bluclefor) el cual se mueve desde el primer elemento (con ndice 0) hasta el ltimo ($#usuarios), incrementando el contador de uno en uno.

Arreglos asociativos y lazos con foreach Este programa pudo ser implementado de otra forma. Perl cuenta con una estructura llamadaarreglo asociativo o hash, la cual asocia una clave con un valor:

1. #!/usr/bin/perl 2. # Guardamos el nombre y peso de la persona en un solo sitio 3. %usuarios=( 4. 'jose', 70.5, 5. 'luis', 90, 6. 'pepe', 65.4, 7. ); 8. # Averiguamos cuantos elementos tiene el hash 9. $num=0; 10. # Repetimos el lazo por cada una de las claves del 11. # hash, incrementando el contador 12. foreach $aux (keys(%usuarios)) { 13. $num++; 14. } 15. print("Usuarios a ser procesados: $num \n"); 16. foreach $aux (keys(%usuarios)) { 17. print("Nombre:\t$aux,\tPeso:\t$usuarios{$aux}\n"); 18. }

Fjese como la iniciacin de un hash (lneas 3 a la 7) implica llenar dos valores: uno de ellos es la clave (en este caso el nombre) y el otro su valor asociado (el peso). Note tambin la forma de acceder a los valores del hash: Si no conocemos las claves, entonces las obtenemos por medio de la funcin keys(), luego vemos el contenido asociado usando $hash{$clave}.

El comando foreach obtiene todas las claves del hash usuarios con ayuda de keys() y hace un recorrido (una por una) guardndolas en $aux.
7

Lazos con while y uso de split() Los lazos con for y foreach son tiles, pero tienen limitaciones cuando se trata de utilizar una condicin lgica complicada en la estructura de repeticin. Es all donde el uso de lazos con while se hace obligatorio. Ilustraremos esto con un programa que lee el contenido de una base de datos:

150.185.128.1 merlin SunOS 150.185.128.15 gandalf Solaris 150.185.128.2 arha SunOS 150.185.128.128 randu Linux 150.185.128.12 melchor SunOS 150.185.128.80 medussa Solaris 150.185.128.123 sorceles Linux 150.185.131.1 zeus Windows

Veamos el cdigo que permite ver sus valores por pantalla:

1. 2. 3. 4. 5. 6. 7. 8. 9.

#!/usr/bin/perl print("Cargando la base de datos..."); open(ARCHIVO,"maquinas.txt") || die "no pude abrir el archivo $! \n"; print("listo!\n"); while(<ARCHIVO>) { chop($_); # Eliminamos el retorno de carro ($ip,$nombre,$so)=split(' ',$_); print("Nombre :$nombre <$ip,$so>\n"); }

En la lnea 2 se utiliza el operador lgico || ("or", ms adelante se explicar con ms detalle) para validar la si se ha podido abrir el archivo; Si falla la apertura del archivo, la funcin die() muestra un mensaje por pantalla y aborta la ejecucin del script; Este es el uso ms comn de die().

En la lnea 5 el programa entra en el lazo condicional de un bucle while. Este continuar repitindose indefinidamente mientras la condicin encerrada entre parntesis sea verdadera (En este caso, que no haya fin de archivo). Si la condicin no se cumple, se sale del bucle, o nunca se entra. En este caso cada ciclo del bucle avanza el apuntador al archivo que al principio estaba en la primera lnea a la siguiente, hasta que se llegue al fin del archivo. Como se abri el archivo para lectura, cada lnea es "leda del archivo" y es referenciada por <ARCHIVO>.

En la lnea 6 se utiliza una variable especial llamada "$_". Significa "la variable actual", y en este caso se refiere a la lnea que esta siendo leda en el bucle. Se necesita quitar el carcter de retorno de carro al final de la lnea, por lo que se utiliza a la rutina chop().

En la lnea 7 se divide a la variable $_ en tres partes para ser almacenados en$ip, $nombre y $sorespectivamente, con ayuda de la rutina split(). Split utiliza como separador de campos un espacio en blanco (hablamos de un separador de campos ya que cada palabra en la lnea esta separada por un espacio).

En la lnea 8 se muestra el contenido de la base de datos con la funcin print().

Estructuras de decisin
Las estructuras de decisin tienen la siguiente forma en Perl:

If (condicin) { Cdigo; } elsif (condicin) { ms cdigo; } else { an ms cdigo; }

Supongamos que en el ejemplo anterior, se modifica a la base de datos para indique si la mquina es un servidor o no, el programa debe mostrar el nuevo campo por pantalla. Se cometio un error intencional en el archivo, colocando el tipo de medussa en minsculas. Este tipo de error de entrada de datos es muy comn, y se solucionar ms adelante:

150.185.128.1 merlin SunOS Servidor 150.185.128.15 gandalf Solaris Cliente 150.185.128.2 arha SunOS Servidor 150.185.128.128 randu Linux Cliente 150.185.128.12 melchor SunOS Cliente 150.185.128.80 medussa Solaris cliente 150.185.128.123 sorceles Linux Servidor 150.185.131.1 zeus Windows Cliente

El siguiente cdigo muestra el uso de las estructuras de decisin: 1. #!/usr/bin/perl 2. print("Cargando la base de datos..."); 3. open(ARCHIVO,"maquinas2.txt") || die "no pude abrir el archivo $! \n"; 4. print("listo!\n"); 5. while(<ARCHIVO>) { 6. chop($_); # Eliminamos el retorno de carro 7. ($ip,$nombre,$so,$tipo)=split(' ',$_); 8. if ($tipo eq "Servidor") { 9. print("Servidor->\t"); 10. } elsif ($tipo eq "Cliente") { 11. print("Cliente->\t"); 12. } else { 13. print("Desconocido->\t"); 14. } 15. print("Nombre :$nombre <$ip,$so>\n"); 16. }

En la lnea 8 se valida que la variable $tipo sea igual a "Servidor", utilizando el comparador de cadenas; Si no se cumple entonces comparamos para ver si es un "Cliente". Si no es ninguno de los dos tipos le asignamos "Desconocido":

leon[246] Si maestro while2.pl Cargando la base de datos...listo! Servidor-> Nombre :merlin <150.185.128.1,SunOS> Cliente-> Nombre :gandalf <150.185.128.15,Solaris> Servidor-> Nombre :arha <150.185.128.2,SunOS> Cliente-> Nombre :randu <150.185.128.128,Linux> Cliente-> Nombre :melchor <150.185.128.12,SunOS> Desconocido-> Nombre :medussa <150.185.128.80,Solaris> Servidor-> Nombre :sorceles <150.185.128.123,Linux> Cliente-> Nombre :zeus <150.185.131.1,Windows>

La comparacin de cadenas presenta el inconveniente de que la comparacin es absoluta, es decir la cadena buscada tiene que coincidir de manera exacta con la cadena candidata, sino falla la.

Las condiciones lgicas de los if - else pueden ser tan complejas como se desee, y pueden est r a anidadas si se quiere. Suponga por ejemplo que ninguna de las mquinas con Windows es servidora, entonces podra hacerce la siguiente modificacin al programa en la lnea 8, utilizando una comparacin compuesta unida por una condicin "y":

if (($tipo eq "Servidor") && ($so ne "Windows")) {

Se muestra a continuacin un pequeo resumen de las posibles comparaciones lgicas que pueden hacerce bajo Perl:

Operador lgico Significado $a && $b $a || $b ! $a And (Y) Or (O)

Resultado Verdadero si a y b son verdaderos $a si $a es verdadero, de lo contrario $b

Not (Negacin) Verdadero si $a es falso y


Tabla 1: Operadores lgicos posibles bajo Perl

Y estas son las comparaciones entre variables que se pueden hacer:

Prueba numrica Prueba de cadena Significado == != > >= < <= <=> Eq En Gt Ge Lt Le Cmp y Es igual a diferente Ms grande que Mayor o igual Menor que Menor o igual No es igual, con signo

Tabla 2: Comparaciones lgicas posibles

Uso de patrones en bsquedas y reemplazos, usando expresiones regulares


Una de las caractersticas ms atractivas de Perl es que permite identificar o cambiar porciones de texto de manera flexible, utilizando lo que se conocen como patrones. La sintaxis de un patrn es:

Patrn de bsqueda $variable =~ /patrn/ $variable patrn/ =~ s/patrn

Resultado Retorna verdadero si patrn est dentro de $variable viejo/nuevo Sustituye el patrn viejo por el patrn nuevo

$variable =~ tr/a-z/A-Z/

Convierte de minsculas a maysculas el contenido de

$variable. y
Tabla 3: Patrones de bsqueda y reemplazo ms comunes

El programa que se mostr en el paso anterior tena el inconveniente de que realizaba comparaciones absolutas; Para un usuario seria ms cmodo poder escribir en maysculas o minsculas en el archivo de datos y que el progerama se ocupara de corregir la apariencia del contenido; Tambin sera comodo poder utilizar uno o ms espacios o tabuladores para separar la informacin de cada mquina:

150.185.128.1 merlin SunOS Servidor 150.185.128.15 gandalf Solaris Cliente 150.185.128.2 arha SunOS SERVIDOR 150.185.128.128 randu Linux cLiENte 150.185.128.12 melchor SunOS Cliente 150.185.128.80 medussa Solaris cliente 150.185.128.123 sorceles Linux Servidor 150.185.131.1 zeus Windows CliENTE

El siguiente cdigo permite hacer eso utilizando caracteres especiales y expresiones regulares:

1. #!/usr/bin/perl 2. print("Cargando la base de datos..."); 3. open(ARCHIVO,"maquinas3.txt") || die "no pude abrir el archivo $! \n"; 4. print("listo!\n"); 5. while(<ARCHIVO>) { 6. chop($_); # Eliminamos el retorno de carro 7. ($ip,$nombre,$so,$tipo)=split('\s+',$_); 8. $tipo =~ tr/a-z/A-Z/; #Convertimos el tipo a mayusculas 9. $aux=$so; # Guardamos el viejo valor de $so 10. $so =~ tr/a-z/A-Z/; #Convertimos $so a mayusculas 11. if (($tipo eq "SERVIDOR") && ($so ne "WINDOWS")) { 12. print("Servidor->\t"); 13. } elsif ($tipo eq "CLIENTE") { 14. print("Cliente->\t"); 15. } else { 16. print("Desconocido->\t"); 17. } 18. $so=$aux; 19. print("Nombre :$nombre <$ip,$so>\n"); 20. }

En la lnea 7 se sutituye el espacio en blanco (que es poco flexible), por la expresin \s+. Para entender lo que significa, se descompondr la expresin:

Proteja el carcter "s" ponindole un \ adelante

y y

El carcter s significa un carcter de espacio (espacio en blanco, tabulacin). + significa uno o ms

La conversin de minsculas a maysculas se hace en las lneas 8 y 10. En las lneas 11 y 13 se hace una comparacin con los valores, pero en maysculas, lo cual facilita la programacin.

La siguiente tabla contiene caracteres para expresiones regulares:

Carcter especial Significado . [a-z0-9] [^a-z-0-9] \d \D \w \W \s \S Encuentra cualquier carcter, excepto una nueva lnea Encuentra cualquier carcter del conjunto Encuentra cualquier carcter que no este en el conjunto Encuentra cualquier dgito Encuentra cualquier cosa que no sea un dgito Encuentra cualquier carcter alfanumrico Encuentra cualquier carcter no alfanumrico Encuentra un carcter de espacio (espacio, tabulacin, nueva lnea) Encuentra un carcter que no sea de espacio (espacio, tabulacin, nueva lnea) Encuentra una nueva lnea Encuentra un retorno Encuentra a fi o a fo o a fu en una cadena de caracteres Encuentra uno o cero x Encuentra cero o ms x Encuentra una o ms x Encuentra dentro de un bloque de palabra Encuentra fuera de un bloque de palabra Encuentra al principio de la lnea Encuentra al final de la lnea y
Tabla 4: Algunas expresiones regulares

\n \r fi|fa|fo x? x* x+ \b \B ^ $

Ejercicio 1: Uso de estructuras de decisin, patrones y estructuras de repeticin

Haga un programa que muestre el siguiente men por pantalla:

Bienvenido al la votacin del mundial, Francia 98!:

Por favor, escriba el nombre del pas por el cual desea votar:

1. 2. 3. 4. 5.

Brasil Colombia Alemania Argentina Salir: escriba "gol" o "salir"

Para salir debe escribir "gol" o "salir". Si el especificada, el programa vuelve a mostrar el men.

usuario

escribe

una

opcin

que

no

est

Al terminar el programa, debe mostrar la cantidad de votos obtenidos por cada Pas.

Solucin: 1. 2. 3. 4. 5. 6. 7. 8.
#!/usr/bin/perl -w $respuesta=""; %votacion=( brasil=>0, colombia=>0, alemania=>0, argentina=>0, );

1. while (($respuesta ne "gol") && ($respuesta ne "salir")) { 2. if ($respuesta eq "brasil") { 3. $votacion{'brasil'}++; 4. } elsif ($respuesta eq "colombia") { 5. $votacion{'colombia'}++; 6. } elsif ($respuesta eq "alemania") { 7. $votacion{'alemania'}++; 8. } elsif ($respuesta eq "argentina") { 9. $votacion{'argentina'}++; 10. } 11. print("Bienvenido al la votacin del mundia Francia 98!:\n"); l, 12. print("Por favor, escriba el nombre del pas por el cual desea votar: \n"); 13. printf("1) Brasil\n2) Colombia\n3) Alemania\n4) Argentina\n5) Salir: escriba \"gol\" o
\"salir\"\n"); 14. $respuesta=<STDIN>; 15. chop($respuesta); 16. $respuesta =~ tr/A-Z/a-z/; 17. } 18. print("Resultados de la votacion por pais \n"); 19. foreach $pais (sort keys(%votacion)) { 20. print("$pais: $votacion{$pais}\n"); 21. }

Uso de rutinas en Perl


El uso de rutinas se hace indispensable en cualquier lenguaje de programacin. Permiten mantener el tamao del cdigo dentro de lmites aceptables, a la vez que facilitan la programacin.

Una rutina se define de la siguiente manera:

sub mirutina ([parmetro]) { [return(algo)]; }

Parmetro es opcional y se usa para obligar al usuario de la rutina a utilizarla con la cantidad de parmetros adecuados. Si desea especificar los parmetros, escriba $ para una variable tipo escalar,@ para un arreglo, % para un hash y & para una referencia a una rutina. Una rutina puede retornar o no algun valor.
9

Todos los parmetros que se pasan a una subrutina vienen contenidos en la variable especial@_. Si desea acceder a algn elemento en especial de ese arreglo puede hacerlo con$_[ndice], donde indice va desde 0 hasta el nmero de parmetros que tenga el arreglo.

Si desea que los cambios efectuados en una variable permanezcan an despus de finalizada la rutina, deber utilizar un parmetro por referencia (similar a los punteros en C); Para ello colquele un \delante al tipo de parmetro (Esto es obligatorio cuando se pasa ms de un arreglo como parmetro a una funcin). En Perl todas las variables que no son de tipo hash o arreglo (es decir, de tipo escalar) son pasadas por referencia.

Adems de especificar el formato de un parmetro, estos pueden ser declarados como locales a la funcin utilizando la palabra reservada my o local (La diferencia entre ambas es que my no permite que una subrutina llamada dentro de una rutina modifique una variable, mientras que local s).

La sintaxis para invocar una rutina es la siguiente:

&mirutina;

El siguiente programa convierte la primera letra de una cadena a mayusculas y el resto a minusculas :
10

1. #!/usr/bin/perl

1. 2. 3. 4. 5.

# Esta rutina convierte el contenido de la cadena de minsculas # a maysculas sub mayusculas($) { $_[0] =~ tr/a-z/A-Z/; # Modificamos el contenido del primer arg. }

1. 2. 3. 4.

# Adivine lo que hace esta rutina : -) sub minusculas($) { $_[0] =~ tr/A-Z/a-z/; }

1. # Esta rutina solo pone en mayscula el primer carcter 2. sub oracion($) { 3. # Si el primer carcter es una letra 4. if ($_[0] =~ /^[a-z]|^[A-Z]/ ) { 5. #Extraigo el primer carcter de la cadena 6. local($primer)=substr($_[0],0,1); 7. #Extraigo el resto de la cadena 8. local($resto)=substr($_[0],1,length($_[0])); 9. #Convierto el resto de la cadena a minusculas 10. #y la primera letra a mayusculas 11. &minusculas($resto); 12. &mayusculas($primer); 13. #Uno las dos subcadenas 14. $_[0]=$primer.$resto; 15. }

16.
17. $palabra="hola"; 18. print("Antes: $palabra\n"); 19. &oracion($palabra); 20. print("Despus: $palabra\n"); 21. $palabra="1hola"; 22. print("Antes: $palabra\n"); 23. &oracion($palabra); 24. print("Despus: $palabra\n"); 25. $palabra="hOlA"; 26. print("Antes: $palabra\n"); 27. &oracion($palabra); 28. print("Despus: $palabra\n"); 29. $palabra="HolA"; 30. print("Antes: $palabra\n"); 31. &oracion($palabra); 32. print("Despus: $palabra\n");

Fjese como se declar el tipo de parmetro que va a recibir cada una de las funciones en las lneas 4, 8, y 12 como un escalar. Como Perl siempre pasa los parmetros por referencia, podemos estar confiados que cualquier cambio que hagamos permanecer an despus determinar la ejecucin de la rutina.

Las conversiones de maysculas a minsculas (y viceversa) se hacen contr() en la lnea 5 (y 9); La deteccin de s el primer carcter de la palabra es una letra se hacecon ayuda de unaexpresin regular compuesto, en la lnea 14, la cual significa: "encuentre al principio de la lnea una letra que sea minscula o al principio de la lnea una letra que sea mayscula".

Finalmente se concatenan los resultados en la variable original con el operador de interpolacin de Per l (".").

La siguiente es una salida de ejemplo:

leon[121] $host> rutinas.pl Antes: hola Despues: Hola Antes: 1hola Despus: 1hola Antes: hOlA Despus: Hola Antes: HolA Despus: Hola

Referencias en Perl
Una referencia es un apuntador a algo; El concepto de referencias en Perl es muy similar al concepto de apuntador en C o Pascal. Cuando se dice algo, nos referimos a un escalar, un arreglo, un hash o incluso una subrutina.

La siguiente tabla muestra como usar una referencia en Perl:

Tipo Escalar

Asignacin

Ejemplo de uso

$apuntador=\$variable; print $$apuntador,"\n";

Arreglo

$apuntador=\@arreglo; Print $$apuntador[5],"\n"; foreach (@$apuntador)

Arreglo asociativo $apuntador=\%hash;

Print $$apuntador[$clave},"\n"; foreach $clave (keys %$apuntador)

Tabla 5: uso de las referencias en Perl

Si desea utilizar ms de un arreglo o hash como parmetro de una funcin, entonces debe pasarlos por referencia. Esto se debe a que Perl concatena todos los argumentos que le son pasados en una sola variable (@_). Para evitar que esto pase, usted debe: y y Pasar una referencia en el argumento de una funcin Utilizar el apuntador dentro de la funcin, con la sintaxis indicada en la tabla anterior.

El siguiente programa toma un arreglo y un hash e imprime su contenido por pantalla:

1. #!/usr/bin/perl

1. sub refer (\@\%) { 2. my($arreglo,$hash)=@_; 3. print("imprimendo el arreglo\n"); 4. $i=0; 5. foreach (@$arreglo) { 6. print("$i : $$arreglo[$i]\n"); 7. $i++; 8. } 9. print("imprimendo el hash\n"); 10. foreach $i (keys %$hash) { 11. print("$i : $$hash{$i}\n"); 12. } 13. }

1. 2. 3. 4. 5. 6. 7. 8. 9.

@a=(1,2,3,4,5,6); %b=( 1=>'Uno', 2=>'Dos', 3=>'Tres', 4=>'Cuatro', 5=>'Cinco', 6=>'Seis', );

1. &refer(\@a, \%b);

Los parmetros de la funcin esperan una referencia, por lo que le colocamos el operador\ en la lnea 24.

Note como se pueden declarar los elementos de un hash, en las lnea 17 a la 22, utilizando el operador=> (En vez de ",". Esto ayuda a clarificar el programa).

Ejercicio 2: Uso de rutinas y referencias

Suponga que le han encomendado la tarea de verificar la conectividad de un grupo de mquinas en su laboratorio lo ms rpido posible. Use para ello el programa que muestra el contenido de la base de datos y modifquelo para que este le haga un ping a cada una de las mquinas que se encuentran en el laboratorio; El programa debe interpretar la respuesta del programa ping y basndose en eso muestra un mensaje por pantalla.

Tambin se desea que el archivo de entrada pueda tener comentarios (En una lnea individual, marcados con #), lneas en blanco y que al ser invocado de la siguiente manera produzca los siguientes resultados:

Verifica_red.pl, dice solamente si la mquina con direccin ip xx.yy.zz.ww est viva. Verifica_red.pl -i, dice si la mquina con la direccin ip xx.yy.zz.ww est viva y si es o no un servidor y su sistema operativo. Para procesar la lnea de comandos utilice el arreglo especial @ARGV, en el cual se guarda la lnea de comandos cuando se ejecuta un programa.

Se recomienda que utilice subrutinas para que el cdigo sea ms legible y fcil de mantener.

Solucin El formato del archivo propuesto es el siguiente:

# Maquinas de mi dominio 192.168.1.1 leon Linux Servidor 192.168.1.2 tigre Linux/Windows95 Cliente 192.168.1.3 pantera Linux/Windows95 Cliente 192.168.1.4 puma Linux/Windows95 Cliente

# Maquinas externas a mi red, pero de inters 150.185.128.1 merlin SunOS Servidor 150.185.128.15 gandalf Solaris Cliente 150.185.128.2 arha SunOS SERVIDOR 150.185.128.128 randu Linux cLiENte 150.185.128.12 melchor SunOS Cliente 150.185.128.80 medussa Solaris cliente 150.185.128.123 sorceles Linux Servidor 150.185.131.1 zeus Windows CliENTE

El siguiente es el cdigo fuente que realiza el trabajo:

#!/usr/bin/perl

# Este script verifica el funcionamiento de # un grupo de maquinas funcionando en una red # usando la herramienta ping # # Hecho por Jos Vicente Nuez Zuleta ([email protected])

# ****************************************************] # Configuracin del script # $pingdir="/bin"; #Directorio donde va ping $maqdir="./datos.txt"; #Ubicacin y nombre del archivo de datos $band="-c 1";

# ****************************************************] # Fin de la configuracin del script

# Rutina que carga el contenido del archivo a memoria sub cargar_red(\%\%\%) { my($ip,$so,$ti)=@_; #Las variables vienen en @_ # Leemos los datos y los guardamos en un hash open(DATOS,$maqdir) || die "No puedo cargar los datos de la red $! \n"; my($aux,$aux2,$aux3,$aux4); #Variable auxiliar #Comenzamos la lectura de los datos my $c=0; while(<DATOS>) { #Validamos que no sea un comentario o lnea vaca chop($_); if (($_ !~ /^\#/) && ($_ ne "")) {

$c++; #Otra maquina leida ($aux,$aux2,$aux3,$aux4)=split('\s+',$_); $$ip{$aux2}=$aux; $$so{$aux2}=$aux3; $$ti{$aux2}=$aux4; } } return($c); } #Fin Cargar

# Devuelve el tipo de maquina, dado el nombre #sub tipo($\%) { # my($nom,$tip)=@_; # return($$tip{$nom}); #} # Devuelve el so de maquina, dado el nombre #sub tipo($\%) { # my($nom,$so)=@_; # return($$so{$nom}); #} # Devuelve el ip de maquina, dado el nombre #sub tipo($\%) { # my($nom,$ip)=@_; # return($$ip{$nom}); #}

# Verificamos la lista de argumentos if ($#ARGV <= 0) { # Verificamos los argumentos del programa if (($ARGV[0] ne "-i") && ($#ARGV == 0)) { die "Error: Argumento incorrecto <$ARGV[0]> \a\n"; }

# Para poder pasar cada uno de los arreglos asociativos # debemos hacerlo por referencia. $cont=&cargar_red(\%dirip,\%sistop,\%tipo); # Comenzamos a verificar las maquinas foreach $maquina (keys %dirip) { $res=`$pingdir/ping $band $dirip{$maquina}`; print("$maquina <$dirip{$maquina}"); if ($#ARGV == 0) { print(",$sistop{$maquina},$tipo{$maquina}>, ") } else { print(">, "); } print("Estado..."); if ($res =~ /0 packets/) { print("X\n"); } else { print("V\n"); } } } else { die "Error: cantidad errnea de argumentos $! \n\a"; }

Validacin de programas en Perl


Seguridad en Perl
Por razones de espacio slo se cubrirn algunos aspectos sobre Perl y seguridad. El primero de ellos es la versin de Perl; Las versiones anteriores a la 5.0.4 tienen un bug de seguridad (buffer overflow) el cual permite que un usuario cualquiera se convierta en root bajo algunas plataformas (Puede conseguir el script en www.rootshell.com).

Se mostrarn a continuacin algunos errores comnes y su solucin:

y Recuerda el programa que trabajaba con asideros? El no e specificar la ruta absoluta cuando ejecuta un comando externo puede comprometer su seguridad. La lnea que llama al programa externo dice:

open(ARCHIVO,"cat /etc/jose|grep -v '#' |");

El programador supone que invoca al programa /bin/cat, confiando en que este slo abre el archivo/etc/hosts. Pero qu ocurre si un atacante cambia la variable de entorno$PATH y la reemplaza para que busque primero un script llamado cat, como el que se muestra a continuacin:

#!/usr/bin/perl open(ARCHIVO,"/etc/passwd"); while(<ARCHIVO>) { print("$_"); }

Se muestra a continuacin la forma de explotar el error, escrito en Perl:

1. #!/usr/bin/perl 2. # Obtenemos el valor de la variable de ambiente PATH 3. $var=$ENV{PATH}; 4. # Veamos lo que contiene la variable 5. print("Contenido de \$PATH: $var\n"); 6. # Lo que hace el atacante es mover a "." de primero, para poder 7. # cambiar al legitimo cat por otro 8. $var="\.:$var"; 9. $ENV{PATH}=$var; 10. print("Contenido de \$PATH: $ENV{PATH}\n"); 11. #Ahora ejecutamos al script con problemas 12. system("asidero.pl");

La clave de este script est en la lnea 8, en donde se cambia el orden de bsqueda.

Este error se puede solucionar fcilmente de dos maneras:

y Coloque la ruta completa del comando ping. De esta manera, cualquier cambio en la ruta de bsqueda quedar sin efecto. y Antes de correr el script, coloque valores conocidos a la variable de ambiente $PATH (Esto puede ser un poco tedioso a veces), justo lo necesario para correr el script. y El siguiente es el script "seguro": y
#!/usr/bin/perl # Rutas "seguras" de mis programas $catdir="/bin"; $grepdir="/usr/bin"; # Ahora se define una ruta segura, la cual sera valida solo # mientras se ejecuta el programa $ENV{PATH}="/bin:/usr/bin";

# Veamos el contenido del archivo /etc/hosts # para ello se utiliza cat y eliminamos to dos los # comentarios open(ARCHIVO,"$catdir/cat /etc/hosts|$grepdir/grep -v '#' |"); print <ARCHIVO>,"\n"; # cerramos el archivo (No hace falta, perl lo hace solo) close(ARCHIVO);

Otra forma de violentar un programa es abusando de los parmetros que recibe:

#!/usr/bin/perl system("/bin/ls $ARGV[0]");

El programa muestra el contenido del directorio actual; de hecho puede recibir parmetros de ls como -l:

leon[56] $host> seg2.pl -l

Pero podemos abusar de l:

leon[58] $host> seg2.pl -l;cat /etc/passwd

Para remediarlo, fije la cantidad de parmetros con los que puede correr el programa de la siguiente manera:

system('/bin/ls','-l');

Si quiere seguir utilizando lnea de comandos, entonces debe los datos que puede recibir el script.

Depuracin de programas en Perl


Perl en modo de advertencias ( -w) El primer paso es decirle a Perl que corra el programa con mensajes de advertencia:

#!/usr/bin/perl -w

Validemos el programa verifica_red.pl para ver como funciona est caracterstica:

leon[53] $host> ./verifica_red.pl Name "main::cont" used only once: possible typo at ./verifica_red.pl line 65. Use of uninitialized value at ./verifica_red.pl line 60.

La advertencia de la lnea 65 nos indica que no estamos haciendo nada con esta variabl slo la e, llenamos con la cantidad de mquinas ledas pero no hacemos ms nada. Si se agrega en la lnea 66 estas instrucciones:

print("Leidas $cont maquinas\n");

Se elimina la advertencia.

Perl se queja en la lnea 60 sobre utilizar un valor no inicializado. Esto ocurre s ARGV[0] no existe (cuando se invoca al programa sin argumentos; pruebe invocndolo con la opcin -i). Solucione este problema anidando las expresiones if en la lnea 60:

# Verificamos los argumentos del programa if ($#ARGV == 0) { if ($ARGV[0] ne "-i") { die "Error: Argumento incorrecto <$ARGV[0]> \a\n"; } }

Perl en modo de depuracin ( -d) Si cambia la bandera -w por la bandera -d arrancar Perl en modo de depuracin. Si bien hay depuradores ms amigables en C, C++ o Pascal, esta herramienta se volver indispensable cuando haga programas ms grandes. Una vez realizado el cambio, arranque el script para ver como funciona:
11

$host> verifica_redd.pl

Loading DB routines from perl5db.pl version 1 Emacs support available.

Enter h or `h h' for help.

main::(verifica_redd.pl:12): $pingdir="/bin"; #Directorio donde va pin g DB<1>

Para salir del depurador escriba "q".

Listando cdigo fuente y el contenido de las variables

El comando "l" (list) sirve para mostrar 10 lneas de cdigo a la vez:

leon[72] $host> verifica_redd.pl

Loading DB routines from perl5db.pl version 1 Emacs support available.

Enter h or `h h' for help.

main::(verifica_redd.pl:12): $pingdir="/bin"; #Directorio donde va pin g DB<1> l 12==> $pingdir="/bin"; #Directorio donde va ping 13: $maqdir="./datos.txt"; #Ubicacion y nombre del archivo de datos 14: $band="-c 1"; 15 16 # ************************************ ****************] 17 # Fin de la configuracion del script 18 19 # Rutina que carga el contenido del archivo a memoria 20 sub cargar_red(\%\%\%) { 21: my($ip,$so,$ti)=@_; #Las variables vienen en @_

Puede mirar el cdigo de una lnea en especial con slo indicar su nmero:
DB<2> l 5 5 # usando la herramienta ping

Puede listar un rango de lneas:

DB<3> l 5-15

5 # usando la herramienta ping 6 # 7 # Hecho por Jose Vicente Nunez Zuleta ([email protected]) 8 9 # ****************************************************] 10 # Configuracion del script 11 # 12==> $pingdir="/bin"; #Directorio donde va ping 13: $maqdir="./datos.txt"; #Ubicacion y nombre del archivo de datos 14: $band="-c 1"; 15

La lnea que est en negritas muestra en donde est nuestro apuntador de instruccin.

El comando p (print) le permite saber el valor de una variable:

DB<11> p $maqdir ./datos.txt DB<12>

Puede hacer esto mismo utilizando el comando "X":

DB<12> X maqdir $maqdir = './datos.txt' DB<13>

Ejecutando el cdigo fuente


Puede correr el programa paso a paso con el comando "s" (step):

DB<4> s main::(verifica_redd.pl:13): $maqdir="./datos.txt"; #Ubicacin y nombre del archivo de datos

DB<4>

El comando "n" se comporta de manera similar, excepto que no entra dentro del cdigo de una rutina cuando esta es llamada.

Puntos de quiebre, ejecucin continua del programa


Se define un punto de quiebre con el comando "b". la ejecucin del programa se detendr en el momento en que el apuntador de instruccin llegue a la lnea o condicin indicada por el punto de quiebre. Por ejemplo, coloquemos un punto de quiebre en la lnea en la lnea 58 y corramos el programa:

DB<26> b 58 DB<27> c main::(verifica_redd.pl:58): if ($#ARGV <= 0) { DB<27>

Puede decirle al depurador que se detenga en una funcin en particular. Por ejemplo, detenga la ejecucin en la rutina cargar_red:

DB<27> b cargar_red DB<28> c main::cargar_red(verifica_redd.pl:21): 21: my($ip,$so,$ti)=@_; #Las variables vienen en @_ DB<28>

Para ver todos los puntos de quiebra definidos, escriba "L". Si lo que desea es eliminarlos todos, escriba "D"; Si escribe "d numero de lnea" elimina un punto de quiebra en particular:

DB<28> L verifica_redd.pl: 21: my($ip,$so,$ti)=@_; #Las variables vienen en @_ break if (1) 58: if ($#ARGV <= 0) { break if (1) DB<28> d 58

DB<29> L verifica_redd.pl: 21: my($ip,$so,$ti)=@_; #Las variables vienen en @_ break if (1) DB<29>

Busqueda con patrones


El depurador le permite buscar por patrones (utilizando inclusive expresiones regulares) con ayuda del operador / (bsqueda hacia delante) y ? (bsqueda hacia atrs). Buque, por ejemplo, donde encuentra la palabra "ip":

DB<29> /ip 33: $$ip{$aux2}=$aux; DB<30>

Busque ahora una lnea en donde haya un comentario, utilizando una expresin regular:

DB<30> /^\#/ 41: # Devuelve el tipo de maquina, dado el nombre DB<31>

Corregir slo la sintaxis con -c Si ejecuta perl -c programa, perl le indicar si la sintaxis est bien o no:
leon[67] $host> perl -c hola.pl hola.pl syntax OK

Ejercicio 3: Seguridad en Perl y depuracin de programas


Investigue que hace, depure y corrija el siguiente programa:

1. 2. 3. 4. 5.

#!/usr/bin/perl # Este programa tiene varios errores # dejados de manera intencional $inutil=9993.345; @palabras=(

6. 'hola', 7. 'casa', 8. 'mundo', 9. 'prueba', 10. ); 11. sub mayu(@) { 12. my(@arr)=@_; 13. for ($i=0;$i <$#arr;$i++) { 14. $arr[$i] =~ tr/a-z/A-Z/; 15. } 16. } 17. print("@palabras\n"); 18. &mayu(@palabras); 19. print("@palabras\n"); 20. $fecha=`date`; 21. print("Terminado a $fecha");

Solucin
#!/usr/bin/perl

# Este programa tiene varios errores # dejados de manera intencional @palabras=( 'hola', 'casa', 'mundo', 'prueba', ); sub mayu(\@) { my($arr)=@_; $lim=scalar(@$arr); for ($i=0;$i < $lim;$i++) { $$arr[$i] =~ tr/a-z/A-Z/; } } print("@palabras\n"); &mayu(\@palabras); print("@palabras\n"); $fecha=`/bin/date`; print("Terminado a $fecha");

CGI (Common Gateway Interface)


CGI [1][3] es el "pegamento" que permite realizar transacciones bancarias por Internet o hacer bsquedas en sitios como www.yahoo.com. CGI provee un canal consistente, independiente del lenguaje de programacin, para el acceso remoto a bases de datos o aplicaciones.

Antes de dar una definicin formal sobre lo que es CGI, veamos algunos conceptos claves.

Protocolos de comunicacin
Modelo OSI y TCP/IP Para poder conectar dos aplicaciones que estn separadas fsicamente entre s, se utiliza un lenguaje y reglas de comunicacin comn a ambas, llamado protocolo de comunicacin. Existe una abstraccin llamada el modelo OSI, la cual permite a aplicaciones remotas comunicarse de manera confiable, a la vez de que su funcionamiento se mantiene independientemente del medio fsico por el cual entran en contacto.

El modelo OSI est compuesto de siete capas, cada una de las cuales es recorrida de arriba abajo, las cuales permiten la comunicacin entre una aplicacin y otra:
12

Ilustracin 1: Modelo OSI

Esto es lo que hace cada capa:

1. Capa de aplicacin. Esta capa trata con los detalles especficos de la aplicacin. El protocolo HTTP (El cual es el protocolo sobre el cual opera el WWW) est contenido aqu. Est capa es la responsable de darle al usuario las herramientas y medios para usar el programa. 2. Capa de presentacin. La capa de presentacin trata con la representacin de los datos que los componentes de la capa de aplicacin usan o refieren en sus comunicaciones. Por ejemplo, es en esta capa que un browser decide como presentar una imagen. 3. Capa de sesin. La capa de sesin provee mecanismos para organizar y sincronizar intercambios de datos con las capas superiores. Esto se debe a las diferencias en como una arquitectura almacena la informacin respecto a la otra. 4. Capa de transporte. Le asegura a las capas superiores que los datos sern transmitidos de manera confiable y con el menor costo posible. TCP (Uno de los protocolos sobre los cuales trabaja Internet) se encuentra aqu. 5. Capa de red. Se encarga de considerar el enrutamiento de la informacin. IP (Uno de los protocolos sobre los cuales trabaja Internet) se encuentra aqu. 6. Capa de enlace. Provee una transferencia punto a punto. Tambin detecta errores provenientes de la capa fsica. 7. Capa fsica. Se encarga de los medios electrnicos y mecnicos que comienzan, mantienen y detienen las conexiones fsicas entre dos entidades de enlace.

Como se dijo con anterioridad, el protocolo HTTP es el corazn del World Wide Web. HTTP surgi debido a las deficiencias de otros protocolos como FTP en el manejo de informacin de hipertexto. Al igual que FTP, HTTP corre en las capas superiores del modelo OSI.

HTTP A continuacin se explican brevemente algunas de las caractersticas del protocolo HTTP:

y Utiliza un esquema de direccionamiento completo: Cuando se ensambla un enlace en HTML, estos tienen la forma general de http://nombre-de-la-maquina:numero de puerto/ruta/archivo.html . Note que el nombre de la mquina conforma con las reglas de codificacin de IP (aaa.bbb.ccc.ddd) o el esquema utilizado por DNS. y Es extensible y est abierto a la representacin de tipos de datos: Cuando un cliente establece una conexin, se enva una cabecera que conforma con las especificaciones de correo electrnico estndares para Internet (RFC822) . Normalmente, desde el punto de vista de la programacin de "puentes", muchos clientes esperan ms que un simple archivo de texto o HTML. Cuando el servidor transmite informacin de vuelta al cliente, incluye una cabecera con extensiones MIME (Multipurpouse Internet Mail Extensin, Extensin Internet de correo electrnico de multipropsito), para decirle al cliente que tipo de datos sigue a la cabecera. El servidor no necesita tener la capacidad de interpretar el tipo de dato pedido, eso es la responsabilidad del cliente. y No tiene estado: Sin estado significa que una vez que el cliente y el servidor han terminado sus dilogos, la conexin es terminada. Esto tiene consecuencias importantes y muestra una diferencia con respecto a otros protocolos como FTP. Sin estado tambin significa que no hay "memoria" entre las conexiones entre clientes. Esto significa que el servidor ve cada conexin de un cliente como una conexin nueva, an si este vuelve a pedir el mismo documento. y Es rpido. y Existen implementaciones portables, y es un estndar abierto: No pertenece a un solo fabricante, corre en muchas plataformas y permite nuevas adiciones como protocolos de cifrado de datos como SHTTP o Secure Socket Layers.
13 14

Modelo cliente - servidor


Como muchas otras aplicaciones de red, el World Wide Web se ajusta al modelo cliente - servidor. l termino cliente / servidor ha sido utilizado ampliamente durante muchos aos para describir una gran variedad de sistemas.

La comunicacin entre el cliente y el servidor ocurre sobre la red, la cual en el caso del WWW es Internet. El cliente y el servidor pueden estar corriendo en diferentes sistemas operativos, sobre diferentes arquitecturas, haciendo nuestro modelo independiente de la plataforma.
15

El cliente En nuestro caso, el cliente es un browser como Netscape Communicator o Lynx. El browser lo que hace es pedirle un documento a un servidor (utilizando un localizador uniforme de recursos, URL o Uniform Resource Locators), para luego procesarlo (transformarlo para ser presentado por pantalla).

El servidor El servidor se encarga de manejar archivos, responde a las peticiones del cliente y enva las respuestas a las preguntas realizadas. El servidor tambin provee un enlace a aplicaciones que no son clientes http, por medio de CGI.
16

La siguiente ilustracin muestra como es la interaccin entre un par de clientes y un servidor: y


Ilustracin 2: Comunicacin entre un cliente y un servidor

Si usted puesto primer Ahora datos al

ha hecho una pgina html y la ha en un servidor, ha estado utilizando el tipo de interaccin cliente - servidor. fjese en el segundo tipo, el servidor no necesita saber como interpretar los que devuelve programa, el slo los pasa cliente.

CGI
CGI medio para es que (Common Gateway Interface) [10] es el que tiene un servidor que habla HTTP comunicarse con un programa. La idea cada cliente y programa servidor (independientemente del sistema operativo) se adhieran a los mismos mecanismos para el flujo de datos entre el cliente, el servidor y el programa que hace el puente.

Cuando se habla de un cliente de un puente, se dice que puede ser un programa que acta como intermediario entre el servidor HTTP y otro programa que puede ser ejecutado por medio de lnea de comandos (Por ejemplo una base de datos relacional).

Cuandos e habla de una interfaz, se dice que es un mecanismo estndar que le permite a los programadores trabajar dentro de un entorno productivo sin tener que reinventar la rueda.

Funcionamiento de CGI Una transaccin con CGI efecuta los siguientes pasos:

1. El cliente enva una peticin conformando con el formato estndar de un URL a el servidor (se incluye el tipo de servicio, ubicacin del servicio). Adems se enva un encabezado con datos provistos por el cliente 2. El servidor procesa la peticin de llegada y decide que hacer luego, dependiendo del tipo de servicio solicitado. Si es un archivo html lo devuelve pero si es un programa CGI entonces: y El encabezado con datos es recibido por el cliente, si existe. Estos datos son pasados al programa como variables de entorno ($ENV{} en Perl). y Los parmetros de ejecucin del programa, si existen, son tomados por el programa. Estos datos pueden ser pasados por medio de variables de entorno($ENV{QUERY_STRING}) o por Entrada estndar (<STDIN>). La forma en como el cliente enva los datos la decide el programador al hacer la interfaz. 1. El programa CGI devuelve una respuesta, como un documento HTML, al servidor. El programa CGI siempre debe devolver alguna respuesta. Los datos deben estar precedidos por un encabezado que conforme con las convenciones MIME, el tipo de dato devuelto es indicad o en la cebecera. 2. La salida es devuelta al cliente por el servidor y se corta la comunicacin.

Generacin dinmica de HTML Se supone que para esta parte que el administrador del sistema le ha dado permiso para ejecutar programas basados en CGI en el servidor. Para la parte prctica, se guardarn los programas en el directorio /cgi-bin del servidor.

Asegrese que el directorio public_html y sus subdirectorios tienen permisologa de lectura y ejecucin para todo el mundo. Todos los script que haga debern tener permiso de ejecucin para todo el mundo:

$host> chmod a+xr cgi-bin/

A continuacin se muestra el cdigo bsico para generar un documento dinmico con CGI, utilizando Perl [2]:

1. #!/usr/bin/perl 2. print "Content-type: text/html \n\n"; 3. print("<!-- Esta pagina fue generada de manera dinamica -->\n"); 4. print("<html>\n"); 5. print("<head>\n"); 6. print("<title>\"Hola mundo\"</title>\n"); 7. print("</head>\n"); 8. print("<body>\n"); 9. print "<h1>Hola mundo. Este es mi primer CGI en Perl </h1> \n"; 10. print("</body>\n"); 11. print("</html>\n");

La lnea 2 es muy importante, ya que all se define el tipo de datos que va a recibir el browser (text/html) con el siguiente formato:

Content-type tipo/subtipo <retorno de carro> retorno de carro>

Los dos retornos de carro son muy importantes, sin ellos el programa no trabajar. La siguiente tabla muestra algunas de los tipos de cabecera ms usadas:

Tipo

17

Significado Documento en html Documento de texto Audio en formato wav Pelculas en formato mpeg Imgenes en formato JPG

text/html text/plain audio/wav video/mpeg image/jpg

Tabla 6: Tipos MIME comunes

Se mostrar a continuacin la salida esperada del programa: y


Ilustracin 3: Salida de ejemplo de hola.cgi

Ejercicio HTML

4:

Generacin

dinmica

de

Convierta el programa "verifica_red.pl" a CGI para que este muestre su salida por pantalla por medio de una tabla. Para simplificar las cosas elimine la parte que procesa la lnea de comandos.

Utilice colores para resaltar los resultados. El programa debe mostrar todos los datos que estn en nuestra base de datos a medida que verifique cada mquina.

Solucin: 1. #!/usr/bin/perl

1. 2. 3. 4. 5. 6.

# # # # # #

Este script verifica el funcionamiento de un grupo de maquinas funcionando en una red usando la herramienta ping. Esta version utiliza CGI Hecho por Jose Vicente Nunez Zuleta ([email protected])

1. # ****************************************************] 2. # Configuracion del script

3. 4. 5. 6.

# $pingdir="/bin"; #Directorio donde va ping $maqdir="./datos.txt"; #Ubicacion y nombre del archivo de datos $band="-c 1";

1. # ****************************************************] 2. # Fin de la configuracion del script

1. 2. 3. 4. 5.

# Rutina que carga el contenido del archivo a memoria sub cargar_red(\%\%\%) { my($ip,$so,$ti)=@_; #Las variables vienen en @_ # Leemos los datos y los guardamos en un hash open(DATOS,$maqdir) || die "<P>No puedo cargar $!</body></html>\n"; 6. my($aux,$aux2,$aux3,$aux4); #Variable aux iliar 7. #Comenzamos la lectura de los datos 8. my $c=0; 9. while(<DATOS>) { 10. #Validamos que no sea un comentario o linea vacia 11. chop($_); 12. if (($_ !~ /^\#/) && ($_ ne "")) { 13. $c++; #Otra maquina leida 14. ($aux,$aux2,$aux3,$aux4)=split('\s+',$_); 15. $$ip{$aux2}=$aux; 16. $$so{$aux2}=$aux3; 17. $$ti{$aux2}=$aux4; 18. } 19. } 20. return($c); 21. } #Fin Cargar

los

datos

de

la

red

1. print("Content-type: text/html \n\n"); #Encabezado del mensaje 2. print("<!-- Documento generado de manera dinamica -->\n"); 3. print("<html><head><title>Verifica Red: 1.0</title></head> \n"); 4. print("<body bgcolor=#000000 text=yellow> \n"); 5. $cont=&cargar_red(\%dirip,\%sistop,\%tipo); 6. print("<font size=5 face=\"Arial,Helvetica,Verdana\">Leidas $cont maquinas</font>\n"); 7. # Comenzamos a verificar las maquinas 8. print("<table border\=0>\n"); 9. print("<tr bgcolor=blue>\n"); 10. print("<th>Nombre<th>IP<th>Sistema operativo<th>Tipo<th>Estado \n"); 11. foreach $maquina (keys %dirip) { 12. $res=`$pingdir/ping $band $dirip{$maquina}`; 13. print("<tr>\n"); 14. print("<td>$maquina\n"); 15. print("<td>$dirip{$maquina}\n"); 16. print("<td>$sistop{$maquina}\n"); 17. print("<td>$tipo{$maquina}\n"); 18. if ($res =~ /0 packets/) { 19. print("<td bgcolor=red>\&nbsp\n"); 20. } else { 21. print("<td bgcolor=green>\&nbsp\n"); 22. } 23. } 24. print("</table>"); 25. print("</body></html>");

Para probar el script, cambie su permisologa con chmod a+x verifica_red.pl y coloque una instruccin similar a esta en su browser:

http://www.servidor.dominio/cgi-bin/verifica_red.cgi

Mtodos de comunicacin
Como se mencion con anterioridad, un cliente puede pasar informacin al servidor utilizando dos mtodos:

y y

Variables de entorno Entrada estndar

A continuacin se explicar brevemente cada uno de ellos:

Mtodo GET El mtodo GET trabaja con variables de entorno, colocando los datos en dos variables llamadas "QUERY_STRING" y "PATH_INFO". El contenido de estas variables es codificado por el servidor y es responsabilidad del programador decodificarlas de nuevo.

Sin embargo, esas no son las nicas variables que pasa el cliente al servidor. Las restantes variables envan informacin que puede ser utilizada de manera til, como la validacin del tipo de browser que utiliza un usuario. Ellas no dependen de la aplicacin particular que maneja el cliente.

El siguiente cdigo muestra el contenido de la cadena QUERY_STRING cuando es enviada por el usuario:

#!/usr/bin/perl print ("Content type: text/plain\n\n"); print ("El contenido de la variable QUERY_STRING es: $ENV{QUERY_STRING}\n");

Corriendo el script como http://www.servidor.dominio /cgi-bin/get.cgi?Esta es una prueba , produce la siguiente salida:

El contenido de la variable QUERY_STRING es: Esta

Note como se pierde el resto de la cadena. Esto significa que debemos codificar nuestro mensaje para que pueda llegar completo, algo de lo que se encargan las formas en html de las cuales hablaremos ms adelante. El contenido de la cadena QUERY_STRING viene justo despus del signo de interrogacin.

La gente de NCSA, los autores del browser Mosaic, no recomiendan el uso de GET ya que si el cliente enva una cadena muy larga, esta puede derribar al Shell que recibe la variable de ambiente (esto se conoce como "quedarse sin espacio de entorno").

Para evitar estas limitaciones, se usa entonces el mtodo POST.

Mtodo POST El mtodo POST no tiene las limitaciones del mtodo GET ya que utiliza a STDIN para obtener los datos. Los datos tambin son codificados all, de manera que es responsabilidad del programador decodificar los datos.

El siguiente cdigo muestra como trabaja el mtodo POST en Perl:

#!/usr/bin/perl # read trata de leer CONTEN_LENGTH bytes de datos en $_ desde STDIN $entrada=read(STDIN,$_,$ENV{CONTENT_LENGTH}); print ("Content type: text/plain\n\n"); print ("El usuarios escribio lo siguiente: $entrada \n");

La captura de datos se hace desde STDIN, con ayuda de la funcin read(). Para utilizar este mtodo, debemos utilizar una forma de html.

Variables de entorno adicionales El siguiente programa muestra el contenido de las variables de presentes al momento de ejecutar nuestra aplicacin:

#!/usr/bin/perl print("Content-type: text/html\n\n"); print("<html><head><title>Variables de entorno</title></head> \n"); print("<body>\n"); print("<ul>\n"); foreach $variable (keys %ENV) {

print("<li>$variable = $ENV{$variabl e}\n"); } print("</ul></body></html>\n");

La siguiente es una salida de ejemplo al correr este programa con lynx servidor.dominio/cgibin/variables.cgi:

Variables de entorno (p1 of 2)


* SERVER_SOFTWARE = Apache/1.3.0 (Unix) * GATEWAY_INTERFACE = CGI/1.1 * DOCUMENT_ROOT = /usr/local/etc/httpd/htdocs * REMOTE_ADDR = 150.185.146.42 * SERVER_PROTOCOL = HTTP/1.0 * REQUEST_METHOD = GET * REMOTE_HOST = berlioz.ing.ula.ve * QUERY_STRING = * HTTP_USER_AGENT = Lynx 2.5 libwww -FM/2.14 * PATH = /usr/local/sbin:/usr/local/bin:/sbin:/usr/sbin:/bin:/usr/bin:/usr/ X11/bin:/usr/andrew/bin:/usr/openwin/bin:/usr/games:.:/usr/lib/teT eX/bin * HTTP_ACCEPT = audio/x-pn-realaudio, application/postscript, application/x-csh, application/x-perl, x-conference/x-cooltalk, audio/x-pn-realaudio, */*, application/x-wais-source, application/html, text/plain, text/html, www/mime * REMOTE_PORT = 2918 * HTTP_ACCEPT_LANGUAGE = en * SCRIPT_NAME = /cgi-bin/variables.cgi * SERVER_NAME = www.felinos.ve * REQUEST_URI = /cgi-bin/variables.cgi * SERVER_PORT = 80 * HTTP_HOST = leon.felinos.ve * SERVER_ADMIN = [email protected]

Codificacin de los datos El servidor codifica los datos de la siguiente manera: y y y Los espacios son cambiados al signo + Ciertos caracteres de teclados son convertidos a su equivalente hexadecimal. Los campos entre las formas son concatenados a &

Ejercicio 5: Variables de entorno


Haga un pequeo programa en Perl que le diga al usuario remoto que browser est utilizando. Utilice para ello el contenido de la variable HTTP_USER_AGENT.

Solucin
#!/usr/bin/perl print("Content-type: text/html\n\n"); print("<HTML><HEAD><TITLE>Tu browser es</TITLE></HEAD><BODY> \n"); if ($ENV{HTTP_USER_AGENT} =~ /Mozilla/) { print("<P>Estas utilizando Nestcape \n"); } elsif ($ENV{HTTP_USER_AGENT} =~ /Lynx/) { print("<P>Estas utilizando Lynx"); } else { print("<P>No puedo determinar tu browser \n"); } print("</BODY></HTML>");

Formas en HTML
Para esta parte suponemos que el lector est familiarizado con el lenguaje bsico de HTML. Si el lector est interesado puede consultar [1], en la seccin de bibliografa al final de este trabajo.

FORM es usado en un documento HTML como cualquier etiqueta. Su estructura bsica es:

<FORM Action = "URL" [Enctype] Method = "POST|GET"> Contenidos de la forma </FORM>

Aqu el elemento Action = URL corresponde al script o programa CGI que procesar la informacin enviada por el cliente. Method identifica la forma en que los contenidos de la forma son enviados por el programa que pregunta. El elemento Enctype identifica el mtodo utilizado para codificar los pares de valor / datos (sino se especifica, el browser usa application/x-www-form-urlencoded ).
18

Una etiqueta FORM no puede ser anidada, pero puede haber tantas como sea en un documento.

Elementos que contiene la etiqueta FORM Los siguientes son los elementos que integran la etiqueta FORM [10]:

Input: Recolecta informacin acerca del usuario


Atributos de Input y Align: se usa slo con un tipo de imagen. Los posibles valores son top, middle y bottom. y Checked: Provoca que el estado inicial de un botn o caja de seleccin sea marcado. y Maxlength: Coloca el tamao mximo de caracteres que un usuario puede entrar en un campo de texto. El valor por omisin es ilimitado. y Name: Especifica el nombre simblico usado en la transferencia de salida de la forma. y Size: Especfica el ancho el campo mostrado al usuario. y Src: Define el archivo fuente para la imagen cuando el atributo Type es colocado en image. y Text: Es un rea de entrada de datos de una sola lnea. Si el usuario presiona entrar entonces los datos son enviados al script correspondiente. y Type: Define que tipo de entrada es posible. Sus valores son: y Checkbox: Usado para recolectar datos que puedan tener mltiples valores a la vez. y Hidden: Especifica valores configurados por la forma, sin ayuda del usuario. y Image: Enva la forma una vez que el usuario presiona la imagen, con las respectivas coordenadas x/y ms el nombre del objeto. y Password: El usuario entra texto aqu, pero este no se ve por pantalla. y Radio: Recolecta informacin donde uno y solo un valor puede ser seleccionado. y Reset: Reinicia la forma a sus valores por omisin. El atributo value muestra la cadena de caracteres que el usuario ver por pantalla. y Submit: Enva los valores de la forma. El atributo value muestra la cadena de caracteres que el usuario ver por pantalla. y Text: Es usada para una sola lnea de texto. Utiliza los atributos value y Maxlength. Value define el valor mostrado por el campo o el valor del campo cuando es seleccionado.

Option: Ocurre dentro del elemento select, el cual le permite al usuario escoger entre varias alternativas, y es usado para representar cada opcin de select.
Atributos de option: y Selected: indica s la opcin esta seleccionada

y Value: Si esta presente, este es el valor retornado por select, si no, el valor retornado es especificado por option.

Select: Le permite al usuario escoger entre mltiples altern ativas


Atributos de select: y Multiple: Por omisin, el usuario solo puede seleccionar un tem a la vez. El uso de este atributo permite seleccionar ms de un atributo. y Name: El nombre lgico que ser enviado y est asociado al escoger select. y Size: Especifica la cantidad de tems visibles. Si no se especifica, la seleccin se comportar como un men "pull-down".

Textarea: Recolecta mltiples lneas de texto por el usuario. Al usuario se le presenta un panel cuadrado en el cual puede escribir. Se usa en pa res.
Atributos de textarea: y Cols: El nmero de columnas que sern mostradas (el usuario puede usar la barra de desplazamiento para moverse a lo largo de ms columnas si es necesario). y Rows: Nmero de filas que sern mostradas. y Name: Nombre lgico asociado al texto retornado.

El siguiente ejemplo muestra una par de formas que recogen datos. Estos son procesados por un script en CGI el cual sabe interpretar los datos provenientes del mtodo POST y el mtodo GET:

1. <!-- Ejemplo de una forma que trabaja con lo dos metodos --> s 2. <!-- Hecho por Jos Vicente Nuez Zuleta ([email protected]) --> 3. <html> 4. <head> 5. <title>Envio de datos con GET y POST</title> 6. </head> 7. <body bgcolor=#ffffff> 8. <P><strong>Envio de datos con GET</strong> 9. <form action="http://www.felinos.ve/cgi-bin/res.cgi method=get"> 10. <input type=hidden name="evaluacion" value="depende del usuario"> 11. Escriba su nombre: <input type=text name="nombre" size=20><br> 12. Sexo: 13. <input type=radio name=sexo value=M>Masculino 14. <input type=radio name=sexo value=F>Femenino 15. <P>Diga cual de las partes del curso le han gustado mas: 16. <input type=checkbox name=perl-basico>Perl b&aacute;sico 17. <input type=checkbox name=perl-dep>Depuraci&oacute;n en Perl 18. <input type=checkbox name=cgi checked>Perl y CGI 19. <P>Escriba un comentario secreto para el instructor:<input type=password name=secreto
size=5 maxlength=5><br> 20. <P>Otorgue una calificacion del 1 al 10 a este curso: 21. <SELECT name=calific> 22. <OPTION>9

23. <OPTION>8 24. <OPTION>7 25. <OPTION>6 26. <OPTION>5 27. <OPTION>4 28. <OPTION>3 29. <OPTION>2 30. <OPTION value="ups">1 31. <OPTION selected>10 32. </SELECT> 33. <P>Finalmente, sea expresivo y escriba lo que quiera: 34. <P><textarea cols=20 name=expresion rows=3></textarea> 35. <P><input type=submit value="Enviar con GET"> 36. <P><input type=reset value="Volver a empezar"> 37. </form> 38. <P><strong>Envio de datos con POST</strong> 39. <form action="http://www.servidor.dominio/cgi -bin/res.cgi method=post"> 40. <input type=hidden name="evaluacion" value="depende del usuario"> 41. Escriba su nombre: <input type=text name="nombre" size=20><br> 42. Sexo: 43. <input type=radio name=sexo value=M>Masculino 44. <input type=radio name=sexo value=F>Femenino 45. <P>Diga cual de las partes del curso le han gustado mas: 46. <input type=checkbox name=perl-basico>Perl b&aacute;sico 47. <input type=checkbox name=perl-dep>Depuraci&oacute;n en Perl 48. <input type=checkbox name=cgi checked>Perl y CGI 49. <P>Escriba un comentario secreto para el instructor:<input type=password name=secreto
size=5 maxlength=5><br> 50. <P>Otorgue una calificacion del 1 al 10 a este curso: 51. <SELECT name=calific> 52. <OPTION>9 53. <OPTION>8 54. <OPTION>7 55. <OPTION>6 56. <OPTION>5 57. <OPTION>4 58. <OPTION>3 59. <OPTION>2 60. <OPTION value="ups">1 61. <OPTION selected>10 62. </SELECT> 63. <P>Finalmente, sea expresivo y escriba lo que quiera: 64. <P><textarea cols=20 name=expresion rows=3>< /textarea> 65. <P><input type=submit value="Enviar con POST"> 66. <P><input type=reset value="Volver a empezar"> 67. </form>

68. 69. 70.

</body> </html> <!-- Fin del documento -->

La similar

apariencia documento a la siguiente: y

del sera

Ilustracin 4: Salida de ejemplo para un par de formas

Uniendo todo: datos de una

Manejo de los forma,

seguridad
Cuando haga programas en CGI preprese para el peor escenario posible al recibir los datos de una forma. No slo el usuario puede equivocarse escribiendo los datos, sino que un atac ante malicioso puede tratar de violentar su sistema.

En la parte de seguridad en Perl, se vi como agregando ms informacin a la lnea de comandos de un programa poda violar la seguridad del sistema. Esto puede evitarse convirtiendo todos los caracteres que no pertenezcan a un grupo conocido en el carcter"_": A continuacin se muestra el cdigo de un programa potencialmente inseguro:
19

1. #!/usr/bin/perl

1. $result=`/bin/ping $ARGV[0] -c 1`; 2. print("La maquina esta $result");

La lnea 2 es potencialmente insegura ya que en vez de suministrar solamente una direccin o nombre de mquina, un atacante puede hacer algo como esto:

leon[91] $host> ping_inseguro.pl localhost;/bin/cat /etc/passwd

El siguiente ejemplo explota esa vulnerabilidad en el programa test-env, que viene con los servidoresNCSA y otros, al utilizar los llamados "metacaracteres", los cuales son caracteres especiales interpretados por el Shell, para obtener informacin no autorizada de una mquina (En este caso el contenido del directorio /cgi-bin):

berlioz[56] $host> lynx http://www.victima.com/cgi-bin/test-cgi?/usr/local/etc/httpd/cgi-bin/*

Con el siguiente resultado:

CGI/1.0 test script report:

argc is 1. argv is /usr/local/etc/httpd/cgi -bin/\*.

PATH = /usr/local/bin:/usr/bin:/bin:. SERVER_SOFTWARE = Apache/1.2b10 PHP/FI -2.0b11 SERVER_NAME = www.victima.com GATEWAY_INTERFACE = CGI/1.1 SERVER_PROTOCOL = HTTP/1.0 SERVER_PORT = 80 REQUEST_METHOD = GET HTTP_ACCEPT = audio/x-pn-realaudio, application/postscript, application/x -csh, application/x-perl, x-conference/x-cooltalk, audio/x-pn-realaudio, */*, applica tion/x-wais-source, application/html, text/plain, text/html, www/mime PATH_INFO = PATH_TRANSLATED = SCRIPT_NAME = /cgi-bin/test-cgi QUERY_STRING = /usr/local/etc/httpd/cgi -bin/analog /usr/local/etc/httpd/cgi -bin /archie /usr/local/etc/httpd/cgi-bin/calendar /usr/local/etc/httpd/cgi -bin/came

A continuacin se muestra el cdigo que permite recolectar los datos de la forma que hicimos anteriormente, con las consideraciones de seguridad aplicadas:

1. #!/usr/bin/perl 2. # 3. # Hecho por Jose Vicente Nunez Zuleta ([email protected]) 4. # 5. # La siguiente rutina determina el tipo de metodo empleado 6. # en el envio de los datos 7. sub metodo_forma { 8. my($metodo)=$ENV{'REQUEST_METHOD'}; 9. my($entrada); 10. #Validamos primero el tipo de codificacion 11. if (($ENV{'CONTENT_TYPE'} !~ /^application \/x-www-form-urlencoded/i)
($ENV{'CONTENT_TYPE'} ne '')) { 12. print("Content-type: text/html\r\n\r\n"); 13. print("<html><head><title>Error en CGI</title></head> \n"); 14. print("<body bgcolor=#FFFFFF>\n"); 15. print("<H1>Error: Codificacion desconocida \n</H1>"); 16. print("<H2>Soporta: application\/x-www-form-urlencoded\n</H2>"); 17. print("</body></html>\n"); 18. exit; 19. } 20. $metodo =~ tr/A-Z/a-z/; #Convierta la respuesta a minusculas 21. #El metodo es get y QUERY_STRING no esta vacia 22. if (($metodo eq "get") && ($ENV{QUERY_STRING} ne '')) { 23. return($ENV{QUERY_STRING}); 24. #El metodo es POST y tiene longitud > 0 25. } elsif (($metodo eq "post") && ($ENV{'CONTENT_LENGTH'} > 0)) { 26. read(STDIN,$entrada,$ENV{'CONTENT_LENGTH'});

&&

27. return($entrada); 28. } else { #Metodo desconocido o valor nulo 29. print("Content-type: text/html\r\n\r\n"); 30. print("<html><head><title>Error en CGI</title></head> \n"); 31. print("<body bgcolor=#FFFFFF>\n"); 32. print("<H1>Error: Metodo desconocido o valor nulo \n</H1>"); 33. print("<H2>Soporta: Method=GET\|POST\n</H2>"); 34. print("</body></html>\n"); 35. exit; 36. } 37. } #Fin metodo_forma()

# La siguiente rutina decodifica la entrada y la g uarda en # un arreglo asociativo sub decodificar_forma($) { my($BUENOS_CARACTERES)='-a-zA-Z0-9_.@ '; #Caracteres validos en los datos my($entrada)=@_; my(%pares,$clave,$valor); $entrada =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("c",hex($1))/ge; #Convierto alfanumerico los caracteres en hexadecimal 8. @pares=split('&',$entrada); #Separo cada par y lo guardo en un arreglo 9. foreach $par (@pares) { # proceso cada par en pares 10. ($clave,$valor)=split(/=/,$par); #Guarde clave,valor usando la busqueda anterior 11. $valor =~ s/\+/ /g; #Cambie + por espacio en toda la cadena 12. # Seguridad en caracteres,segun aviso del Cern en 13. # http://geek-girl.com/bugtraq/1997_4/0232.html 14. $clave =~ s/[^$BUENOS_CARACTERES]/_/go; 15. $valor =~ s/[^$BUENOS_CARACTERES]/_/go; 16. #Finalmente construya el arreglo asociativo 17. $pares{$clave}=$valor; 18. } 19. return(%pares); 20. } # Fin Decodificar_forma()

1. 2. 3. 4. 5. 6. 7.

1. # Comienzo del programa principal 2. $entrada=&metodo_forma(); 3. %datos=&decodificar_forma($entrada); 4. $| = 1; #Vaciamos el buffer de escritura lo mas rapido posible 5. print("Content-type: text/html\r\n\r\n"); 6. print("<html>\n"); 7. print("<head><title>Datos enviados por el usuario</title></head> \n"); 8. print("<body bgcolor=\#ffffff>\n"); 9. print("<pre>\n"); 10. print("El contenido de la forma es:\n"); 11. foreach $clave (keys(%datos)) { 12. print("$clave = $datos{$clave}\n"); 13. } 14. print("Variables de entorno\n"); 15. foreach $clave (keys(%ENV)) { 16. print("$clave = $ENV{$clave}\n"); 17. } 18. print("</pre>\n"); 19. print("</body>\n"); 20. print("</html>");

En la lnea 7 encontramos a la rutina metodo_forma, la cual se encarga bsicamente de:

y Verificar que los datos estn codificados con application\/x-www-form-urlencoded. Este valor viene vacio cuando se usa el mtodo GET. y Averiguar si los datos fueron enviados con GET o POST y que tengan una longitud mayor que cero.

Una vez conocida la forma en como fueron enviados los datos, estos son guardados en una variable, listos para ser decodificados. De esto se encarga la rutina decodificar_forma,a cual hace lo siguiente: y En la lnea 44 se convierten los elementos que estn en hexadecimal en la variable capturada con metodo_forma a su equivalente alfanumrico. Para ello se utiliza una expresin regular con reemplazo y a la funcin unpack(). y En la lnea 45 se separa a los pares clave / valor y los guarda en un arreglo. Luego se procesa el arreglo, lnea 46, y por cada par: y Se separan en clave y valor (lnea 47); y A cada clave y valor les son sustituidos los signos + por espacios en blanco (lnea 48). y Se eliminan los caracteres de cada clave y valor si no estn en una lista de caracteres conocidos (lneas 51 y 52). y Se crea un arreglo asociativo con cada par y valor (lnea 54). y Al finalizar de procesar los pares se devuelve el arreglo asociativo (lnea 56).
20 21

El cdigo anterior produce una salida similar a esta:


El contenido de la forma es: perl-basico = on nombre = sfsdfsfsf cgi = on calific = 2 secreto = sdfsf expresion = ddsdfsfsdf evaluacion = depende del usuario sexo = F Variables de entorno SERVER_SOFTWARE = Apache/1.3.0 (Unix) GATEWAY_INTERFACE = CGI/1.1 DOCUMENT_ROOT = /usr/local/etc/httpd/htdocs REMOTE_ADDR = 192.168.1.3 SERVER_PROTOCOL = HTTP/1.0 REQUEST_METHOD = POST REMOTE_HOST = pantera.felinos.ve

HTTP_REFERER = http://www.servidor.dominio/~jose/forma.html?evaluacion=depende+del+usuario&nombre=&cgi=on&secret o=&calific=10&expresion=%09%09%09 QUERY_STRING = HTTP_USER_AGENT = Mozilla/4.01 [en] (Win95; I)

Note que slo una de las formas puede hacer el envo, ya sea con GET o POST.

Ejercicio 6: Uso de formas y CGI


Modifique a verifica_red.cgi para que permita hacer un ping a un grupo de mquinas de manera dinmica,es decir, basandose en la base de datos que se utiliz en el ejemplo. El programa debe mostrar todas las mquinas, pero debe permitir hacer un ping a algunas o todas las mquinas (Utilice cajas de seleccin para ese fin). El programa tambin debe permitir hacer ping a una direccin arbitraria, usando una caja de texto. Si lo desea, valide la sintaxis de la direccin IP suministrada al programa ping. Si le parece muy complicado, entonces haga una forma con un nmero fijo de mquinas y enve los datos al script que hace la verificacin.

Sugerencia para el enfoque dinmico: Utilice dos programas, uno que lea la base datos y permita hacer la seleccin por pantalla con HTML dinmico y otro que haga el ping y devuelva los resultados al usuario.

Solucin Se muestra primero el cdigo que lee la base de datos y muestra la forma por pantalla: 1. #!/usr/bin/perl

1. 2. 3. 4.

# Este Script carga la base de datos y la muestra por pantalla # permitiendo luego llamar a verifica_red.cgi # # Hecho por Jose Vicente Nunez Zuleta ([email protected])

1. 2. 3. 4. 5. 6. 7.

# ****************************************************] # Configuracion del script # $maqdir="./datos.txt"; #Ubicacion y nombre del archivo de datos $password="jose98"; #Password no encriptado, viaja por la red como texto # ****************************************************] # Fin de la configuracion del script

1. 2. 3. 4.

# Rutina que carga el contenido del archivo a memoria sub cargar_red(\%\%\%) { my($ip,$so,$ti)=@_; #Las variables vienen en @_ # Leemos los datos y los guardamos en un hash

5. open(DATOS,$maqdir) || die "<html><head><title>Error en CGI</title></head><body><P>Error: No puedo cargar los datos de la red $!</body></html> n"; \ 6. my($aux,$aux2,$aux3,$aux4); #Variable auxiliar 7. #Comenzamos la lectura de los datos 8. my $c=0; 9. while(<DATOS>) { 10. #Validamos que no sea un comentario o linea vacia 11. chop($_); 12. if (($_ !~ /^\#/) && ($_ ne "")) { 13. $c++; #Otra maquina leida 14. ($aux,$aux2,$aux3,$aux4)=split('\s+',$_); 15. $$ip{$aux2}=$aux; 16. $$so{$aux2}=$aux3; 17. $$ti{$aux2}=$aux4; 18. } 19. } 20. return($c); 21. } #Fin Cargar

1. $| = 1; #Vaciamos el buffer de escritura lo mas rapido posible 2. print("Content-type: text/html \n\n"); #Encabezado del mensaje 3. print("<!-- Documento generado de manera dinamica -->\n"); 4. print("<html><head><title>Verifica Red: 1.0</title></head> \n"); 5. print("<body bgcolor=#000000 text=yellow vlink=red alink=yellow link=yellow> \n"); 6. $cont=&cargar_red(\%dirip,\%sistop,\%tipo); 7. print("<font size=5 face=\"Arial,Helvetica,Verdana\">Leidas $cont maquinas</font>\n"); 8. # Presentamos el menu para probar las maquinas 9. print("<H1>Verificar <em>una m&aacute\;quina</em> arbitraria</H1>\n"); 10. print("<form action=\"http://www.felinos.ve/cgi-bin/verifica_red.cgi\"
method=post>\n"); 11. print("<P>Introduzca la direcci&oacute\;n IP o nombre que quiere verificar: <input type=text name=individual size=20 maxlength=20>\n"); 12. print("<H1>Verificar <em>grupo</em> de m&aacute \;quinas </H1>\n"); 13. print("<table border\=0>\n"); 14. print("<tr bgcolor=blue>\n"); 15. print("<th>Nombre<th>IP<th>Sistema operativo<th>Tipo<th>&#191Verificar? \n"); 16. foreach $maquina (sort keys %dirip) { 17. print("<tr>\n"); 18. print("<td>$maquina\n"); 19. print("<td>$dirip{$maquina}\n"); 20. print("<td>$sistop{$maquina}\n"); 21. print("<td>$tipo{$maquina}\n"); 22. print("<td align=center><input type=checkbox checked name=$maquina $dirip{$maquina}>\n"); 23. } 24. print("</table>"); 25. print("<P>\n"); 26. print("<BR><P><input type=submit value=Verificar> <input type=reset value= \"Volver a empezar\">\n"); 27. print("</form>\n"); 28. print("Sugerencias:<a href=\"mailto:jose\@ing.ula.ve\">jose\@ing.ula.ve\"</a>\n"); 29. print("</body></html>");

El cdigo de la lnea 56 es importante, ya que all se almacena el nombre de la mquina y su direccin ip como un solo valor para enviarlo al programa que hace la verificacin de la red. Dejamos queverifica_red.cgi programa se encargue de revisar la sintaxis de las direcciones ip ya que eso lo hace ms resistente a ataques.

Finalmente se muestra el cdigo del programa que verifica la red:

1. #!/usr/bin/perl 2. # este programa recibe los datos enviados por carga_red.cgi 3. # y verifica un grupo de maquinas 4. # Hecho por Jose Vicente Nunez Zuleta ([email protected]) 5. # 6. # VARIABLES 7. $pingdir="/bin"; 8. $banderas="-c 1"; 9. # 10. # 11. # La siguiente rutina determina el tipo de metodo empleado 12. # en el envio de los datos 13. sub metodo_forma { 14. my($metodo)=$ENV{'REQUEST_METHOD'}; 15. my($entrada); 16. #Validamos primero el tipo de codificacion 17. if (($ENV{'CONTENT_TYPE'} !~ /^application \/x-www-form-urlencoded/i)
($ENV{'CONTENT_TYPE'} ne '')) { 18. print("Content-type: text/html\r\n\r\n"); 19. print("<html><head><title>Error en CGI</title></head> \n"); 20. print("<body bgcolor=#FFFFFF>\n"); 21. print("<H1>Error: Codificacion desconocida \n</H1>"); 22. print("<H2>Soporta: application\/x-www-form-urlencoded\n</H2>"); 23. print("</body></html>\n"); 24. exit; 25. } 26. $metodo =~ tr/A-Z/a-z/; #Convierta la respuesta a minusculas 27. #El metodo es get y QUERY_STRING no esta vacia 28. if (($metodo eq "get") && ($ENV{QUERY_STRING} ne '')) { 29. return($ENV{QUERY_STRING}); 30. #El metodo es POST y tiene longitud > 0 31. } elsif (($metodo eq "post") && ($ENV{'CONTENT_LENGTH'} > 0)) { 32. read(STDIN,$entrada,$ENV{'CONTENT_LENGTH'}); 33. return($entrada); 34. } else { #Metodo desconocido o valor nulo 35. print("Content-type: text/html\r\n\r\n"); 36. print("<html><head><title>Error en CGI</title></head> \n"); 37. print("<body bgcolor=#FFFFFF>\n"); 38. print("<H1>Error: Metodo desconocido o valor nulo\n</H1>"); 39. print("<H2>Soporta: Method=GET\|POST\n</H2>"); 40. print("</body></html>\n"); 41. exit; 42. } 43. } #Fin metodo_forma()

&&

# La siguiente rutina decodifica la entrada y la guarda en # un arreglo asociativo sub decodificar_forma($) { my($BUENOS_CARACTERES)='-a-zA-Z0-9_.@ '; #Caracteres validos en los datos my($entrada)=@_; my(%pares,$clave,$valor); $entrada =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("c",hex($1))/ge; #Convierto alfanumerico los caracteres en hexadecimal 8. @pares=split('&',$entrada); #Separo cad par y lo guardo en un arreglo a 9. foreach $par (@pares) { # proceso cada par en pares 10. ($clave,$valor)=split(/=/,$par); #Guarde clave,valor usando la busqueda anterior 11. $valor =~ s/\+/ /g; #Cambie + por espacio en toda la cadena 12. # Seguridad en caracteres,segun aviso del Cern en 13. # http://geek-girl.com/bugtraq/1997_4/0232.html 14. $clave =~ s/[^$BUENOS_CARACTERES]/_/go; 15. $valor =~ s/[^$BUENOS_CARACTERES]/_/go;

1. 2. 3. 4. 5. 6. 7.

16. #Finalmente construya el arreglo asociativo 17. $pares{$clave}=$valor; 18. } 19. return(%pares); 20. } # Fin Decodificar_forma() 21. # La siguiente rutina valida que el formato de la direccion IP sea 22. # www.xxx.yyy.zzz. Retorna una cadena vacia si la direccion 23. # contiene errores. Esta rutina no permite el uso de 127.0.0.1 24. sub valida_ip($) { 25. my($aux)=$_[0]; 26. my($result)=$_[0]; 27. #Validamos que solo hayan 4 octetos 28. $aux =~ s/[^\.]//g; #Dejo solo el caracter '.' 29. if (length($aux) != 3) { 30. return(''); 31. } 32. my(@octetos); 33. ($octetos[0],$octetos[1],$octetos[2],$octetos[3])=split(' \.',$result); 34. my($octeto); 35. #Validamos la sintaxis correcta de cada octeto 36. foreach $octeto (@octetos) { 37. if ( ($octeto =~ /\D|\W+/) || ($octeto <= 0) || ($octeto >= 255) ) { 38. return(''); 39. } 40. } 41. return($aux); 42. } #Fin valida_ip() 43. # Comienzo del programa principal 44. $entrada=&metodo_forma(); 45. %datos=&decodificar_forma($entrada); 46. $| = 1; #Vaciamos el buffer de escritura lo mas rapido posible 47. print("Content-type: text/html\r\n\r\n"); 48. print("<html>\n"); 49. print("<head><title>Resultados de Verifica Red 1.0</title></head> \n"); 50. print("<body bgcolor=#000000 text=yellow vlink=red alink=yellow link=yellow> \n"); 51. print("<font face=\"arial,helvetica,verdana\" size=5>Resultados de
inspecci&oacute;n:</font>\n"); 52. print("<table border=0>\n"); 53. print("<tr bgcolor=blue>\n"); 54. print("<th>Nombre<th>IP<th>Estado\n"); 55. #Validamos la direccion IP de la caja de texto 56. if (&valida_ip($datos{'individual'}) ne '') { 57. $maquinas{'No tiene nombre'}=$datos{'individual'}; 58. } 59. #Validamos ahora la direccion de las demas maquinas 60. foreach $clave (keys %datos) { 61. if ($datos{$clave} =~ /on/) { 62. $datos{$clave} =~ s/on//ig; #Elimino a "= on" 63. ($maquina,$ip)=split('-',$clave); #Separo el par maquina-ip 64. if (&valida_ip($ip) ne '') { 65. $maquinas{$maquina}=$ip; 66. } 67. } 68. } 69. #Imprimimos los resultados 70. foreach $clave (keys %maquinas) { 71. print("<tr><td>$clave<td>$maquinas{$clave}"); 72. $res=`$pingdir/ping $banderas $maquinas{$clave}`; 73. if ($res =~ /\b0% packet/) { 74. print("<td bgcolor=green>\&nbsp\n"); 75. } else { 76. print("<td bgcolor=red>\&nbsp\n"); 77. } 78. } 79. print("</table>\n");

la

80. print("<P><a atras</a>\n"); 81. print("</body>\n"); 82. print("</html>");

href=\"http://www.servidor.dominio/cgi -bin/cargar_red.cgi\">Volver

Se utilizan la misma rutina para validar el formato de los datos que vienen por la red ms la rutinavalida_ip en la lnea 67, la cual verifica solamente el formato de la direccin ip. Note que el programa ignora la prueba de la mquina si alguna de las conversiones falla.

En el siguiente punto se mostrar como se puede hacer parte de este procesamiento de datos en el cliente, utilizando el lenguaje Javascript.

Introduccin a Javascript
Hasta este punto se ha mostrado solamente aplicaciones que corren en el servidor, utilizando CGI. Posiblemente se haya dado cuenta que este enfoque tiene varias deficiencias:

y El cliente queda inactivo una fraccin de tiempo, esperando respuesta del servidor. Si el trabajo que hace el programa toma mucho tiempo en ejecutarse, se pierde el inters en utilizar al Web como herramienta. y No se aprovecha el poder de procesamiento del cliente, todo el trabajo lo hace el servidor lo cual se traduce en una distribucin desigual de trabajo. y Hay que esperar a que los datos lleguen al servidor para que sean validados. Se considera un desperdicio de ancho de banda el enviar datos errneos por la red al servidor.

La idea entonces es darle algo de poder de procesamiento al cliente, de manera que este realice algo de ese procesamiento, aligerando la carga del servidor y mejorando los tiempos de respuesta. Eso significa que el cliente pueda examinar los datos y le notifique al usuario acerca de cualquier error obvio.

Esto acerca an ms a los clientes HTML a la filosofa de cliente / servidor, a la vez que hace ms interactivo el contenido del Web.

La primera idea de darle ms poder a los clientes se vio plasmada con la versin 2 de Netscape Navigator, al utilizar un lenguaje llamado Javascript. Para ese entonces, el lanzamiento de Javascript coincidi con el del lenguaje Java por parte de Sun Microsystems.
22

Aunque Java y Javascript tienen algunas similitudes sus propsitos principales los hacen muy distintos. La siguiente tabla muestra algunas de esas diferencias:

Java Compilado Orientado a objetos. Soporta herencia.

Javascript Interpretado Basado en objetos. No soporta herencia.

Applets como entidad separada entidad de Cdigo insertado dentro de HTML HTML

Tipos de datos definidos como entero, real

Tipos de datos no declarativos, como en Perl

Tabla 7: Diferencias bsicas entre Java y Javascript

Javascript no es el nico lenguaje que trabaja de esta manera. Microsoft diseo un lenguaje basado en Visual Basic, llamado VBScript. Sin embargo, una de sus principales desventajas con respecto a Javascript es que est atado a correr dentro de Ambientes Windows mientras que Javascript es multi plataforma. Otra ventaja de Javascript sobre VBScript es que Javascript est a punto de convertirse en un estndar internacional.

En los siguientes puntos se explicarn algunas caractersticas de Javascript con algunos ejemplos, sin embargo se recomienda al lector interesado que consulte la bibliografa recomendada [4][6] para profundizar sus conocimientos.

Objetos en Javascript
Javascript est basado en objetos, pero no est orientado a objetos. Se pueden tratar con los objetos que ya estn creados o se pueden crear nuevos objetos, pero no se pueden crear nuevas clases ni hacer herencia.

Algunos de esos objetos estn relacionados con el browser mientras que otros estn relacionados con objetos genricos, como una cadena.

Cada uno de los objetos que conforman el lenguaje Javascript forma una jerarqua similar a la siguiente:
23

Ilustracin 5: Jerarqua de objetos en Javascript

La siguiente tabla muestra algunos objetos en Javascript:

Objeto Anchor Button Checkbox Date

Significado / Etiqueta en HTML <a></a> <input type="button"> <input type="checkbox"> Objeto genrico para el tratamiento de fechas

Document La pgina que muestra el browser Form Frame Hidden History <form></form> <frame></frame> <input type="hidden"> Contiene informacin acerca del URL visitado por el usuario. Es similar al objeto anchor (Ancla) Informacin acerca del URL actual Un objeto genrico que trata con funciones matemticas Informacin acerca del navegador usado <input type ="password"> <input type="radio"> <input type="reset"> <select></select> Objeto genrico para el manejo de cadenas <input type=submit> <input type="text"> <textarea></textarea> Informacin acerca de la ventana actual y
Tabla 8: Listado de algunos objetos en Javascript

Link Location Math Navigator Password Radio reset Select String Submit Text Textarea Window

A continuacin se mostrar como puede trabajar con esos objetos, utilizando sus mtodos, y como puede incorporar Javascript en sus documentos HTML.

Mtodos de los objetos en Javascript. Programacin orientada a eventos. La programacin orientada a eventos es distinta a la programacin tradicional, en el sentido de que un objeto dentro del browser, como un botn en una forma o la misma ventana del browser, tiene asociado ciertas propiedades (valores asociados con los objetos) y un mtodo (acciones asociadas al objeto) las cuales pueden cambiar por la interaccin que hay entre el usuario y la pgina. Al producirse un cambio en el estado de un mtodo, por ejemplo al presionar un botn en una forma, entonces se ejecuta el cdigo asociado a ese mtodo.

En un programa tradicional, este tiene un cuerpo o rutina principal y una serie de funciones que son llamadas de acuerdo a la ejecucin del programa. En la programacin orientada a eventos slo se llama la rutina asociada a un evento, no existe algo as como una rutina central.

Por ejemplo, el objeto <input type=submit value=Enviar>, tiene como propiedades a value, el cual es el nombre que se mostrar en pantalla.

Para cada objeto estn definidos un nmero fijo de mtodos. Esos eventos son:

Evento Blur Change Click Focus Load

Significado Un objeto select, text, o textarea pierde el foco en una forma El valor de un campo en select, text o textarea cambia Se hace clic en un objeto en una forma Un campo recibe el foco de atencin, ya sea utilizando el ratn o tabulacin El browser termin de cargar un documento HTML. Si el documento contiene Frames entonces la carga del documento termina cuando todos los Frames estn cargados.

MouseOver Cuando el puntero del ratn pasa sobre un objeto Select Submit Unload Cuando el usuario selecciona parte o todo el texto de un campo de tipo text o textarea Cuando el usuario enva una forma El usuario deja el documento y
Tabla 9: Eventos posibles para los objetos en Javascript

Ms adelante se mostrar el uso de objetos segn sus mtodos.

Hola mundo en Javascript A continuacin se muestra el programa hola mundo en Javascript:

1. <html> 2. <head>

3. <title>Hola mundo en Javascript :-)</title> 4. </head> 5. <body> 6. <P>Esta es una demostraci&oacute;n de Javascript 7. <script language="JavaScript"> 8. <!-9. document.write("<P>&#161 Hola mundo cruel!") 10. //--> 11. </script> 12. </body> 13. </html>

En la lnea 7 se declara que el cdigo que viene a continuacin est hecho en Javascript. Para evitar problemas con browsers que no soportan a Javascript, ocultamos el cdigo de Javascript con el cdigo de comentarios en HTML (lneas 8 y 10. En la lnea 9 se utiliza el mtodo write del objeto documentpara mostrar un mensaje por pantalla. Note que este mensaje no aparecer en un browser que no tenga soporte para Javascript. En la lnea 11 cerramos la declaracin de cdigo de Javascript.

En Javascript se pueden utilizar la misma sintaxis para los comentarios que en C++, esto es: y y // Para comentarios cortos /* Comentarios que abarcan ms de una lnea */

Recuerde que Javascript trabaja con los mtodos de los objetos. El siguiente cdigo le indica al usuario la ltima vez que la pgina fue modificada:

1. 2. 3. 4. 5. 6. 7. 8. 9.

<html> <head> <title>Hola mundo en Javascript : -)</title> </head> <body> <P>Esta es una demostraci&oacute;n de Javascript <script language="JavaScript"> <!-document.write("<P>&#161 Hola mundo cruel!<BR>")

1. 2. 3. 4. 5.

document.write("Ultima modificaci&oacute;n: "+document.lastModified) //--> </script> </body> </html>

En la lnea 10 se utiliza otro truco: Se concatena la salida de un objeto con una cadena de caracteres (En Perl se hace con el operador punto, '.').

La salida por pantalla es la siguiente:

Esta es una demostracin de Javascript

Hola mundo cruel! Ultima modificacin: 06/07/98 01:47:47

Variables en Javascript
En Javascript no se necesita especificar el tipo de una variable cuando se declara. Todas las variables se declaran utilizando la palabra reservada var:

var suma = 0 var v, w = "hola"

Javascript soporta los siguientes tipos de datos implcitos:

24

y y y y

Nmeros, como -32 o 555.432 Una cadena de caracteres, como "Me gusta navegar en bote" Un valor lgico como true o false El valor especial null.

Funciones en Javascript
La sintaxis para declarar una funcin en Javascript es la siguiente:

function Nombre_funcion(argumento1,argumento2,...) { Cdigo de la funcin return(algo) }

Los argumentos son opcionales, as como la funcin puede no retornar nada.

La siguiente funcin calcula la multiplicacin de dos nmeros:

1. 2. 3. 4.

<html> <head> <title>Uso de funciones</title> </head>

5. <body> 6. <script language="JavaScript"> 7. <!-8. function multiplic(num1,num2) { 9. return(num1*num2); 10. } 11. var x=10 12. var y=10 13. var res=multiplic(x,y) 14. document.write("Multiplicamos "+x+"*"+y+"="+res) 15. //--> 16. </script> 17. </body> 18. </html>

Estructuras de repeticin
Las estructuras de repeticin que utiliza Javascript son muy similares a las de otros lenguajes como Perl o C. A continuacin se mostrar su sintaxis y un pequeo ejemplo de uso:

Sintaxis y ejemplo de Do - while


do sentencias while (condicin);

Por ejemplo:
var cont=0; do Cont++; while (cont <maximo);

Sintaxis y ejemplo de For


for ([expresin inicial;] [condicin;] [expresin de incremento]) { sentencias }

Por ejemplo:
for (var i = 0; i < 9; i++) { n += i

funcin(n)

Sintaxis y ejemplo de For in For in se utiliza para mostrar las propiedades de un objeto. Su sintaxis es:

for (variable in objeto) { sentencias }

La siguiente rutina muestra las propiedades de un objeto:

function propiedades(objeto, nombre) { var resulta = "" for (var i in objeto) { resulta += nombre + "." + i + " = " + objeto[i] + "<BR>" } resulta += "<HR>" return resulta }

Sintaxis y ejemplo de while:


while (condicin) { sentencias }

Por ejemplo:

While (i<=j) { document.write("Valor: "+i) }

Todas estas estructuras de repeticin pueden interrumpir su ejecucin por medio de la sentencia break:

for (var i=0; i<j; i++) { if (i == valor) { break; } }

Estructuras de decisin
La sintaxis de las sentencias if - else es la siguiente:

if (condicin) { cdigo} [else { cdigo}]

Las sentencia if - else trabaja con los siguientes operadores lgicos :


25

Operador lgico Significado a && b a || b And (Y) Or (O)

Resultado Verdadero si a y b son verdaderos $a s $a es verdadero, de lo contrario $b

!a

Not (Negacin) Verdadero s $a es falso y


Tabla 10: Operadores lgicos en Javascript

Como puede ver, su sintaxis es similar a la de Perl.

Los operadores de comparacin son ms sencillos que los de Perl, son iguales tanto para cadenas como para nmeros:

Prueba == != > >=

Significado Es igual a diferente Ms grande que Mayor o igual

< <=

Menor que Menor o igual y


Tabla 11: Operadores de comparacin en Javascript

Los siguientes operadores estn relacionados con los objetos en Javascript. No necesitan estar asociados directamente a una estructura de decisin para poder ser utiilizados:

Operador Significado new Permite crear una instancia de un objeto predefinido o elaborado por el usuario. Elimina la propiedad de un objeto o un elemento en un arreglo. Palabra especial utilizada para referirse al objeto actual. y
Tabla 12: Operadores especiales en Javascript

delete this

Cuando la cantidad de opciones a evaluar es grande, se puede utilizar la sentencia switch:

switch (expresin){ case etiqueta : sentencia; break; case etiqueta2 : sentencia; break; ... default : sentencia;

Cajas de alerta, confirmacin y preguntas


Javascript tiene algunas herramientas que pueden facilitar la entrada de datos, o la presentacin de informacin. Ellas son: y y y Mensajes de alerta (window.alert()) Mensaje de confirmacin (window.confirm()) Mensaje de pregunta (window.prompt())

A continuacin se presenta un ejemplo que utiliza estos tres mtodos del objeto ventana, ms el uso del objeto "button". La respuesta del usuario se obtiene utilizando el mtodo onclick en cada uno de los botones (ese mtodo se encarga de invocar a cada una de nuestras cajas de dialogo):

1. <html> 2. <head> 3. <title>Uso de funciones</title> 4. </head> 5. <body> 6. <script languaje=javascript> 7. <!-8. var respuesta 9. //--> 10. </script> 11. <FORM method="POST"> 12. <P><INPUT type="button" name="alerta" value="Boton de alerta" onclick="alert('Alerta
Roja')"></P> 13. <P><INPUT type="button" name="pregunta" value="Boton de pregunta" onclick="respuesta=prompt('Alerta Roja'); alert('Usted escribio : '+respuesta) "></P> 14. <P><INPUT type="button" name="confirmacion" value="Confirmaci&oacute;n" onclick="respuesta=confirm('&#191 Desea continuar?'); alert('Usted decidio : '+respuesta) "></P>

1. </FORM> 2. </body> 3. </html>

Declaramos el inicio y final de una forma en las lneas 11 y 15. En la lnea 12 tenemos una entrada de tipo botn, a la cual cuando se le hace clic invoca una caja de dialogo con un mensaje. En la lnea 13 se utiliza otro botn e invocamos ahora una caja de confirmacin la cual recoge nuestra respuesta, la cual es mostrada de inmediato por una caja de alerta.

En la lnea 14 se utiliza una caja de decisin, capturamos el resultado de la escogencia del usuario y lo mostramos por pantalla con ayuda de una caja de alerta.

Expresiones regulares y arreglos


Al igual que Perl, Javascript dispone de expresiones regulares para encontrar y sustituir caracteres en una variable. Tambin dispone del objeto arreglo, el cual se comporta de manera similar a los arreglos asociativos en Perl, ya que su ndice puede ser numrico o no.

Arreglos La forma de declarar un arreglo en Javascript es la siguiente:

var Arreglo = new Array()

El siguiente ejemplo muestra como imprimir el contenido de un par de arreglos:

1. <html> 2. <head>

3. <title>Arreglos en Javascript</title> 4. </head> 5. <body bgcolor=#ffffff> 6. <script> 7. <!-8. var arreglo = new Array(5) 9. arreglo[0]='Hola' 10. arreglo[1]='esta es' 11. arreglo[2]='una' 12. arreglo[3]='prueba' 13. arreglo[4]='simple' 14. var sexo = new Array(3) 15. sexo['jose']='m' 16. sexo['sylvia']='f' 17. sexo['raul']='m'

1. for(var i=0;i<5;i++) { 2. document.write(arreglo[i]+" ") 3. } 4. document.writeln("<P>") 5. document.writeln("Sexo de las siguientes personas:<br>") 6. document.writeln("Jose "+sexo['jose']+"<br>") 7. document.writeln("Sylvia "+sexo['sylvia']+"<br>") 8. document.writeln("Raul "+sexo['raul']+"<br>") 9. //--> 10. </script> 11. <h1>uso de arreglos</h1> 12. <form name="datos"> 13. </form> 14. </body> 15. </html>

Expresiones regulares Javascript tambin cuenta con expresiones regulares , muy tiles para el tratamiento de caracteres en variables.
26

Javascript utiliza los mismos caracteres especiales que Perl para construir una expresin regular:

Expresin regular Significado . [a-z0-9] [^a-z-0-9] \d \D \w Encuentra cualquier carcter, excepto una nueva lnea Encuentra cualquier carcter del conjunto Encuentra cualquier carcter que no este en el conjunto Encuentra cualquier dgito Encuentra cualquier cosa que no sea un dgito Encuentra cualquier carcter alfanumrico

\W \s \S

Encuentra cualquier carcter no alfanumrico Encuentra un carcter de espacio (espacio, tabulacin, nueva lnea) Encuentra un carcter que no sea de esp acio (espacio, tabulacin, nueva lnea) Encuentra una nueva lnea Encuentra un retorno Encuentra a fi o a fo o a fu en una cadena de caracteres Encuentra uno o cero x Encuentra cero o ms x Encuentra una o ms x Encuentra dentro de un bloque de palabra Encuentra fuera de un bloque de palabra Encuentra al principio de la lnea Encuentra una tabulacin vertical Encuentra al final de la lnea y
Tabla 13: caracteres especiales para expresiones regulares en Javascript

\n \r fi|fa|fo x? x* x+ \b \B ^ \v $

Tambin soporta el uso de los operadores g, bsqueda global, e i, sin importar mayusculas o minusculas.

La sintaxis es la siguiente:

result = /patrn/[g|i|gi]

El siguiente fragmento de cdigo verifica si el nombre de una persona no tiene nmeros o caracteres extraos al ser introducido por teclado. Slo se explicar el mtodo test, si el lector interesado desea saber que otras posibilidades existen en el uso de expresiones regulares, se recomienda que consulte[4]:

1. <html> 2. <head> 3. <title>Expresiones regulares en Javascript</title> 4. </head> 5. <body bgcolor=#ffffff> 6. <script> 7. <!-8. function vnombre() { 9. /* Busque uno o mas caracteres distintos a letras en 10. minusculas o mayusculas en toda la cadena */

11. validacion =/[0-9\W]/g 12. if (validacion.test(document.datos.nombre.value)) { 13. alert('El nombre contiene caracteres raros') 14. } else { 15. alert('El nombre esta bien') 16. } 17. } 18. //--> 19. </script> 20. <h1>Escriba el nombre del usuario</h1> 21. <form name="datos"> 22. <input type="text" size=15 maxlength=15 name=nombre> 23. <input type="button" name="Validacion" onclick="vnombre()" value="Validar el nombre
del usuario"> 24. <input type="button" value="Volver a empezar"> 25. </form> 26. </body> 27. </html> name="limpiar" onclick="document.datos.nombre.value=''"

Formas y validacin
Este es uno de los usos ms comunes para Javascript. La validacin del contenido de una forma se basa casi siempre en los siguientes eventos: y y onBlur onSubmit

Se busca entonces que los datos sean coherentes y estn completos antes de enviarlos por la red al servidor.

Para que pueda entender como trabaja la validacin examine el siguiente ejemplo. Suponga que le piden que almacene los siguientes datos sobre una persona: y y y y y Nombre Edad Estado Civil Sexo Sueldo

Estos datos tienen las siguientes restricciones: y y y y El nombre no puede ser un nmero La edad debe ser mayor que 15 aos y menor o igual que 95 La persona debe tener un nico estado civil, as como un nico sexo El sueldo puede ser un nmero real, mayor que cero y menor que 5000$

La siguiente es una implementacin de la solucin utilizando la etiqueta FORM y Javascript:

1. <html>

2. 3. 4. 5. 6. 7. 8. 9.

<head> <title>Datos personales</title> <script> <!-//Validacion del nombre function vnombre() { var cadena=document.datos.nombre.value if ((! isNaN(cadena)) && (cadena != '')) { //Validamos que el nombre no sea un numero y que tenga informacion 10. alert('El nombre no puede ser un numero') 11. document.datos.nombre.value='' //Borramos el error 12. document.datos.nombre.focus() //Colocamos el cursor en ese campo 13. } 14. } 15. // Validacion de la edad 16. function vedad() { 17. var cadena=document.datos.edad.value 18. var error=false 19. if (cadena != '') { 20. if (isNaN(cadena)) { 21. alert('La edad debe se un numero'); 22. error=true 23. } else if ((cadena <= 15) || (cadena > 99)) { 24. alert('La edad debe ir entre 16 y 99 anos'); 25. error=true 26. } 27. if (error == true) { 28. document.datos.edad.value='' 29. document.datos.edad.focus() 30. } 31. } 32. } 33. //Validacion del sueldo 34. function vsueldo() { 35. var cadena=document.datos.sueldo.value 36. var error=false 37. if (cadena != '') { 38. if (isNaN(cadena)) { 39. alert('Sueldo debe ser un numero'); 40. error=true 41. } else if ((cadena <= 0.0) || (cadena > 5000.0)) { 42. alert('Sueldo debe ser mayor que 0.0 y menor o igual que 5000 '); 43. error=true 44. } 45. if (error == true) { 46. document.datos.sueldo.value='' 47. document.datos.sueldo.focus() 48. } 49. } 50. } 51. // Validacion antes del envio con submit 52. function vtodo() { 53. var error=false 54. if ((document.datos.sexo.value == '') || (document.datos.estado.value == '') || (document.datos.edad.value == '') || ( document.datos.sueldo.value == '') ) { 55. error = true 56. } 57. if (error) { 58. alert('Datos incompletos en la forma, todos los campos son requeridos') 59. return false

1. } 2. }

//--> </script> </head> <body bgcolor=#ffffff> <h1>Recolecci&oacute;n de datos personales</h1> <form name="datos" onSubmit="return vtodo()" action="http://www.servidor.dominio/cgi bin/res.cgi" method="post"> 7. <p>Escriba su nombre completo: <input type=text name=nombre size=20 maxlength=20 onBlur="vnombre()"> 8. <p>Escriba su edad: <input name=edad type=t ext size=2 maxlength=2 onBlur="vedad()"> 9. <P>Sexo:<input type=radio name=sexo value=m>M<input type=radio name=sexo value=f>F 10. <p>Indique su estado civil: 11. <p><input type=radio name=estado value=casado>Casado 12. <p><input type=radio name=estado value=soltero checked>Soltero 13. <p><input type=radio name=estado value=divorciado>Divorciado 14. <p><input type=radio name=estado value=viudo>Viudo 15. <p>Escriba su sueldo: <input name=sueldo type=text size=6 maxlength=6 onBlur="vsueldo()"> 16. <p> 17. <input type=submit value="Enviar datos" ><input type=reset value="Volver a empezar"> 18. </form>

1. 2. 3. 4. 5. 6.

1. </body> 2. </html>

Note como el cdigo en Perl que muestra los resultados por pantalla no realiza ningn tipo de validacin:

1. #!/usr/bin/perl 2. # este programa recibe los datos enviados por carga red 3. # y verifica un grupo de maquinas 4. # Hecho por Jose Vicente Nunez Zuleta ([email protected]) 5. # 6. # La siguiente rutina determina el tipo de metodo empleado 7. # en el envio de los datos 8. sub metodo_forma { 9. my($metodo)=$ENV{'REQUEST_METHOD'}; 10. my($entrada); 11. #Validamos primero el tipo de codificacion 12. if (($ENV{'CONTENT_TYPE'} !~ /^application \/x-www-form-urlencoded/i)
($ENV{'CONTENT_TYPE'} ne '')) { 13. print("Content-type: text/html\r\n\r\n"); 14. print("<html><head><title>Error en CGI</title></head> \n"); 15. print("<body bgcolor=#FFFFFF>\n"); 16. print("<H1>Error: Codificacion desconocida \n</H1>"); 17. print("<H2>Soporta: application\/x-www-form-urlencoded\n</H2>"); 18. print("</body></html>\n"); 19. exit; 20. } 21. $metodo =~ tr/A-Z/a-z/; #Convierta la respuesta a minusculas 22. #El metodo es get y QUERY_STRING no esta vacia 23. if (($metodo eq "get") && ($ENV{QUERY_STRING} ne '')) { 24. return($ENV{QUERY_STRING}); 25. #El metodo es POST y tiene longitud > 0 26. } elsif (($metodo eq "post") && ($ENV{'CONTENT_LENGTH'} > 0)) { 27. read(STDIN,$entrada,$ENV{'CONTENT_LENGTH'}); 28. return($entrada);

&&

29. } else { #Metodo desconocido o valor nulo 30. print("Content-type: text/html\r\n\r\n"); 31. print("<html><head><title>Error en CGI</title></head> \n"); 32. print("<body bgcolor=#FFFFFF>\n"); 33. print("<H1>Error: Metodo desconocido o valor nulo \n</H1>"); 34. print("<H2>Soporta: Method=GET\|POST\n</H2>"); 35. print("</body></html>\n"); 36. exit; 37. } 38. } #Fin metodo_forma()

# La siguiente rutina decodifica la entrada y la guarda en # un arreglo asociativo sub decodificar_forma($) { my($BUENOS_CARACTERES)='-a-zA-Z0-9_.@ '; #Caracteres validos en los datos my($entrada)=@_; my(%pares,$clave,$valor); $entrada =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("c",hex($1))/ge; #Convierto alfanumerico los caracteres en hexadecimal 8. @pares=split('&',$entrada); #Separo cada par y lo guardo en un arreglo 9. foreach $par (@pares) { # proceso cada par en pares 10. ($clave,$valor)=split(/=/,$par); #Guarde clave,valor usando la busqueda anterior 11. $valor =~ s/\+/ /g; #Cambie + por espacio en toda la cadena 12. # Seguridad en caracteres,segun aviso del Cern en 13. # http://geek-girl.com/bugtraq/1997_4/0232.html 14. $clave =~ s/[^$BUENOS_CARACTERES]/_/go; 15. $valor =~ s/[^$BUENOS_CARACTERES]/_/go; 16. #Finalmente construya el arreglo asociativo 17. $pares{$clave}=$valor; 18. } 19. return(%pares); 20. } # Fin Decodificar_forma()

1. 2. 3. 4. 5. 6. 7.

1. # Comienzo del programa principal 2. # Note como no se realiza validacion en este script, eso se 3. # lo confiamos al cliente (No es totalmente seguro) 4. $entrada=&metodo_forma(); 5. %datos=&decodificar_forma($entrada); 6. $| = 1; #Vaciamos el buffer de escritura lo mas rapido posible 7. print("Content-type: text/html\r\n\r\n"); 8. print("<html>\n"); 9. print("<head><title>Datos del usuario</title></head> \n"); 10. print("<body bgcolor=#ffffff\n"); 11. print("<h1>Datos del usuario</h1>\n"); 12. print("<ul>\n"); 13. foreach $clave (keys %datos) { 14. print("<li><strong>$clave :</strong> $datos{$clave} \n"); 15. } 16. print("<\ul>\n"); 17. print("</body>\n"); 18. print("</html>");

Ejercicio 7: Validacin de Formas con Javascript


Utilice expresiones regulares para validar el contenido del campo nombre del ejemplo anterior. Se desea que en el nombre no aparezcan nmeros ni caracteres de puntuacin.
27

Valide tambin al programa cargar_red.cgi. El programa no debe permitir el envio de datos si no se va a verificar a ninguna mquina:

Solucin Se muestra a continuacin el cdigo de cargar_red.cgi. Ntese como es necesario proteger ciertos caracteres para que estos puedan ser impresos desde Perl:

1. #!/usr/bin/perl

1. 2. 3. 4.

# Este Script carga la base de datos y la muestra por pantalla # permitiendo luego llamar a verifica_red.cgi # # Hecho por Jose Vicente Nunez Zuleta ([email protected])

1. 2. 3. 4. 5. 6.

# ****************************************************] # Configuracion del script # $maqdir="./datos.txt"; #Ubicacion y nombre del archivo de datos # ****************************************************] # Fin de la configuracion del script

# Rutina que carga el contenido del archivo a memoria sub cargar_red(\%\%\%) { my($ip,$so,$ti)=@_; #Las variables vienen en @_ # Leemos los datos y los guardamos en un hash open(DATOS,$maqdir) || die "<html><head><title>Error en CGI</title></head><body><P>Error: No puedo cargar los datos de la red $!</body></html> n"; \ 6. my($aux,$aux2,$aux3,$aux4); #Variable auxiliar 7. #Comenzamos la lectura de los datos 8. my $c=0; 9. while(<DATOS>) { 10. #Validamos que no sea un comentario o linea vacia 11. chop($_); 12. if (($_ !~ /^\#/) && ($_ ne "")) { 13. $c++; #Otra maquina leida 14. ($aux,$aux2,$aux3,$aux4)=split('\s+',$_); 15. $$ip{$aux2}=$aux; 16. $$so{$aux2}=$aux3; 17. $$ti{$aux2}=$aux4; 18. } 19. } 20. return($c); 21. } #Fin Cargar

1. 2. 3. 4. 5.

1. 2. 3. 4. 5. 6.

$| = 1; #Vaciamos el buffer de escritura lo mas rapido posible print("Content-type: text/html \n\n"); #Encabezado del mensaje print("<!-- Documento generado de manera dinamica -->\n"); print("<html><head><title>Verifica Red: 1.0</title>\n"); # Aqui colocamos el codigo de Javascript, escrito desde Perl print("<script languaje=\"Javascript 1.2\">\n");

7. print("function vmaquinas() \{\n"); 8. print("var vacio1=true\n"); 9. print("var vacio2=true\n"); 10. print("//Verificamos si hay una direccion en la caja de texto IP \n"); 11. print("\tif (document.datos.individual.value \!= '')\{\n"); 12. print("\t\tvacio1=false\n"); 13. print("\t\}\n"); 14. print("//Verificamos si el usuario selecciono alguna casilla \n"); 15. print("\tfor (var i=0;i<document.datos.elements.length;i++) \{\n"); 16. print("\t\tif (document.datos.elements[i].type == \"checkbox\") \{\n"); 17. print("\t\t\tif (document.datos.elements[i].checked) \{\n"); 18. print("\t\t\t\tvacio2=false\n"); 19. print("\t\t\t}\n"); 20. print("\t\t}\n"); 21. print("\t}\n"); 22. print("if ((vacio1 && vacio2)) \{\n"); 23. print("alert('Debe escoger una maquina para poder trabajar');return(false) \}\n"); 24. print("\}\n"); 25. print("//-->\n"); 26. print("</script>\n"); 27. print("</head>\n"); 28. print("<body bgcolor=#000000 text=yellow vli nk=red alink=yellow link=yellow>\n"); 29. $cont=&cargar_red(\%dirip,\%sistop,\%tipo); 30. print("<font size=5 face=\"Arial,Helvetica,Verdana\">Leidas $cont maquinas</font>\n"); 31. # Presentamos el menu para probar las maquinas 32. print("<H1>Verificar <em>una m&aacute\;quina</em> arbitraria</H1>\n"); 33. print("<form name=\"datos\" action=\"http://www.servidor.dominio/cgibin/verifica_red.cgi\" onSubmit=\" return vmaquinas()\" method=post>\n");

34. print("<P>Introduzca la direcci&oacute\;n IP que quiere verificar: <input type=text


name=individual size=20 maxlength=20><P> \n");

35. print("<table border\=0>\n"); 36. print("<tr bgcolor=blue>\n"); 37. print("<th>Nombre<th>IP<th>Sistema operativo<th>Tipo<th>&#191Verificar? \n"); 38. foreach $maquina (sort keys %dirip) { 39. print("<tr>\n"); 40. print("<td>$maquina\n"); 41. print("<td>$dirip{$maquina}\n"); 42. print("<td>$sistop{$maquina}\n"); 43. print("<td>$tipo{$maquina}\n"); 44. print("<td align=center><input type=checkbox checked name=$maquina $dirip{$maquina}>\n"); 45. } 46. print("</table>"); 47. print("<P>\n"); 48. print("<BR><P><input type=submit value=Verificar> <input type=reset value= \"Volver a empezar\">\n"); 49. print("</form>\n"); 50. print("Sugerencias: <a href=\"mailto:jose\@ing.ula.ve\">jose\@ing.ula.ve\"</a>\n"); 51. print("</body></html>");

Referencias bibliogrficas
Se recomienda que el lector interesado consulte la siguiente documentacin para que pueda profundizar los conocimientos acerca de los puntos expuestos en este trabajo.

1. December John, Ginsburg Mark. "HTML 3.2 & CGI Professional Reference Edition". Sams.net Publishing. 1996. 1321 p.

1. Kamran Husain, Breedlove F. Robert. "Perl 5 Unleashed" Sams.net Publishing. 1996. 798 p.

1. Mohseni Piroz. "Web Database Primer Plus, Conect your Database to the World Wide Web Using HTML, CGI, AND Java". Waite Group Press. 1996. 482 p.

1. Netscape Communications Corporation. "Javascript Guide 1.2". DevEdge On-line Documentation.http://developer.netscape.com/docs/manuals/communicator/jsguide 4/. 1997.

1. Netscape Communications Corporation. "Getting Started with the Javascript debugger" ". . DevEdge On-line Documentation.http://developer.netscape.com/docs/manuals/jsdebug/index.htm . 2. Netscape Communications Corporation On-line Documentation.http://developer.netscape.com/docs/manuals/ .

1. Perl Institute.

http://www.perl.org/ .

1. Perl Source. http://www.perl.com/.

1. Veer Vander Emily A. "Javascript Beginners".http://www.builder.com/Programming/Javascript/ .

for

1. World Wide Web Consortium. http://www.w3.org/ .

1. Wall Larry, Schwartz L. Randal. "Programming Perl". O'Reilly & Associates, Inc. 1992. 463 p.

1 Perl es rpido porque est hecho en C. De hecho, la diferencia de velocidad entre un script hecho en Perl y un programa en C no es muy grande. 2 En este trabajo utilizamos la versin 5.004 3 La instalacin de Perl es algo larga, as que busque una tasa de caf y rmese de paciencia 4 No recuerdo quien me lo dijo, pero el programa "Hola mundo" era el programa que haba sido portado a ms lenguajes que cualquier otro. 5 Escriba man perl si desea saber ms. 6 Se tradujo el trmino "filehandles" a asideros de archivo. 7 Si ha programado en Shell, este comando le debe resultar familiar. 8 Proteger en este caso significa que no lo interprete como un patrn de busqueda. 9 Sin embargo, nuestra rutina puede funcionar perfectamente sin pasarle ningn parmetro. 10 Esto se puede hacer ms fcilmente con las funciones lcfirst, ucfirst, uc y lc. 11 Se recomienda que escriba "man perldebug" para aprender acerca del depurador de Perl. 12 OSI es un modelo de referencia, no es una aplicacin en particular. Por ejemplo, TCP/IP se basa en este modelo de referencia. 13 La forma ms general es servicio://maquina/archivo.extensin 14 RFC viene de Request For Comments (Peticin de comentarios). 15 Aunque puede ser una Intranet sin ningn problema. 16 Una aplicacin CGI puede ser una base de datos, un programa de diagnstico, un simulador, etc. 17 Visite http://www.cis.ohio-state.edu/htbin/rfc/rfc1521.html , para obtener una descripcin completa de los tipos MIME. 18 Consulte ftp://ftp.merit.edu/documents/rfc/rfc1590.txt para ver los tipos de codificacin). 19 Se recomienda que consulte http://geek-girl.com/bugtraq/1997_4/0232.html . 20 En algunas de las expresiones regulares s/viejo/nuevo/ se utilizaron los modificadores g, e, i y o. El modificador hace una busqueda sin importar si es mayusculas o minusculas, g hace una busqueda en toda la variable, e evalua el resultado de la bsqueda y devuelve un valor, o se utiliza por eficiencia para aprovechar el hecho de que una expresin regular no cambia en una bsqueda. Escriba man perlfaq6 para mayor informacin. 21 unpack(TEMPLATE, EXPR) toma una cadena, EXPR, que representa una estructura y la expande en un valor de arreglo. En este ejemplo TEMPLATE es igual a c, que significa un valor de carcter con signo y $1 es el primer valor del ltimo carcter encontrado. 22 Javascript soporta muchos de los constructores de Java. 23 Esta imagen fue tomada de http://developer.netscape.com/docs/manuals/communicator/jsguide4/ (Gua de desarrollo de Javascript de Netscape Communications Corp). El crdito le corresponde a sus respectivos autores 24 Desde la versin 3.0 de Navigator, se puede utilizar el comando typeof para averiguar el tipo de una variable. 25 No se mencionaron en este trabajo los operadores de bits ni los operadores de asignacin para Perl o Javascript. Se espera qu e el lector consulte las referencias bibliogrficas respectivas. 26 Esta caracterstica esta presente en Javascript 1.2, no en las versiones anteriores 27 Sugerencia: Utilice la funcin implementada en el ejercicio de expresiones regulares.

También podría gustarte