Estudio sobre el uso del goto en GitHub

Siga la flecha Parece que GitHub es una fuente inagotable de aprendizaje. Traemos hoy [PDF] An empirical study of goto in C code from GitHub repositories. En este caso estudian la utilización de esta conocida estructura de control que permite romper el flujo de cualquier programa cuando se cumplen determinadas condiciones (o dejan de cumplirse).

En general es una estructura de control que está mal vista desde el punto de vista del desarrollo estructurado de programas. Podemos recordar aquí el famoso [PDF] Edgar Dijkstra: Go To Statement Considered Harmful, de Edsger Dijkstra, uno de los padres de la programación estructurada. Sin embargo, es cierto que en algunos casos la estructura del programa puede mejorar mucho si se utiliza con ‘sabiduría’.

El artículo habla del uso del ‘goto’ por parte de los programadores (si lo utilizan y para qué) y su aparición en la correción de fallos después de lanzar una versión.

Se usa. A nivel de fichero:

Considerable use of goto at the file level: We find that 246,657 out of the 2,150,387 files (or 11.47%) examined in our study have at least one goto statement.

A nivel de proyectos:

We find that 3,093 out of the 11,627 projects (or 26.60%) have at least one file with a goto statement. We also find that more than half the projects have about 20% of the files that have at least one goto statement.

Se utiliza, fundamentalmente, para código de sistema y de red, pero también para otras cuestiones. Mirando en las funciones parece que el uso principal es para gestión de errores, limpieza (liberación de memoria, etc.). Otra característica interesante es que la mayoría de los saltos son hacia adelante y raramente se hacen hacia atrás.

We find that, in general, the use of goto is actually well disciplined. Most uses of goto statements are reasonably structured, filling the void of miss- ing higher-level constructs found in other languages. There are of course usages that are unstructured as Dijkstra feared, but they are overall in

Después de publicar una versión la tendencia era a que se mantengan más o menos el mismo número de ‘gotos’ en el código, por lo que los proyectos no parecen considerarlos como algo perjudicial y desaconsejable.

If we assume bugs in the post-release phase of a project as a measure of harm, then the small number of goto statements being removed/modified in bug fixes implies that goto statements were not consid- ered harmful enough to be removed/modified in the post-release phase of the project in most cases.

Interesante.

Seguridad de la gestión de acceso mediante SSH

Cerrado El National Institute of Standards and Technology publica informes de lo más variado y de vez en cuando le dedica atención a la seguridad informática.

Traemos hoy aquí el informe [PDF] Security of Interactive and Automated Access Management Using Secure Shell (SSH) que habla del protocolo SSH desde el punto de vista de gestión en las organizaciones.

This publication assists organizations in understanding the basics of SSH interactive and automated access management in an enterprise, focusing on the management of SSH user keys.

Los primeros capítulos pueden ser interesantes para alguien que todavía no se haya preocupado de estos temas (a veces los informes sobre temas más complejos nos sirven para entender mejor las cuestiones básicas porque las tratan en los capítulos introductorios). Los siguientes, tendrán interés si queremos ir más allá en los temas de gestión de la seguridad.

Calidad del software y lenguajes de programación

Verificación de programas En [PDF] A Large Scale Study of Programming Languages and Code Quality in Github nos muestran una investigación realizada examinando el código de los repositorios de GitHub: analizan para diversos tipos de lenguajes la cantidad de fallos, basándose en los ‘commits’ que contienen etiquetas relacionadas con errores (‘error’, ‘bug’, ‘fix’ , ‘issue’, ‘mistake’, ‘incorrect’, ‘fault’, ‘defect’ and ‘flaw’).

El resumen sería (de manera muy básica) que los lenguajes fuertemente tipados son algo mejores que los débilmente tipados. También que los lenguajes funcionales son algo mejores que los demás.

… we report that language design does have a significant, but modest effect on software quality. Most notably, it does appear that strong typing is modestly better than weak typing, and among functional languages, static typing is also somewhat bet- ter than dynamic typing. We also find that functional languages are somewhat better than procedural languages.

En todo caso, el efecto no es muy grande.

Puede que también tengan interés en leer los comentarios del hilo de Hacker News sobre el trabajo A Large Scale Study of Programming Languages and Code Quality in GitHub.

También me gusta destacar el valor que tiene un sitio como GitHub (internet, para el caso) para poder realizar este tipo de estudios que serían bastante difíciles de realizar con el código disponible en ‘casa’ de cada uno que lo tenga.

Reforzar el acceso a nuestros sistemas

Traemos un par de lecturas sobre cómo podemos reforzar el acceso a nuestros sistemas, añadiendo seguridad de dos formas (que podrían combinarse entre sí, puesto que se ocupan de diferentes partes: acceso y autentificación a un sistema).

Candados

En primer lugar, en Using 2 factor authentication for SSH unas instrucciones sobre cómo utilizar el app Google Authenticator para establecer un sistema de dos factores para el servicio SSH.

La otra posibilidad es habilitar los servicios cuando los necesitemos, de forma que cuando no los vayamos a usar no estén disponibles. En este caso podríamos utiliar Latch. Tal y como cuentan en Fortificar GNU/Linux Ubuntu con Latch: Vídeo Tutorial se puede usar en cualquiera de los sistemas más comunes.

Publicar en Telegram las entradas de este sitio usando Python

Interactuando con el bot Siguiendo la línea de publicaciones anteriores, y tratando de alcanzar mayor difusión de las entradas de este sitio (y otro) decidimos probar el API de publicación de Telegram. Como siempre, es sencillo si encontramos las bibliotecas adecuadas y tenemos un poco de paciencia.

Pero primero tenemos que crear el bot. Siguiendo las instrucciones del BotFather. En este caso le pedimos el nuevo bot con:

/newbot

El botfather nos pide un nombre para nuestro bot, y un nombre de usuario (que deberá terminar en ‘bot’). Como respuesta nos envía el ‘token’ que nos servirá para identificarnos y poder interactuar con él. A partir de allí nuestra misión es mandarle cosas al bot.

Yo he elegido hacer un programita en Python, utilizando telepot. Las instrucciones están en telepot documentation El código que se muestra allí es muy sencillo.

import telepot
bot = telepot.Bot('***** AQUÍ VA EL TOKEN *****')

Y mandar un mensaje sería algo así como:

bot.sendMessage(999999999, 'Hola mundo')

En este caso ‘999999999’ es el identificador del bot, se puede utilizar el nombre asignado anteriormente.

En nuestro caso, como queremos que el bot avise automáticamente a sus seguidores cuando haya novedades utilizamos la fuente RSS del blog y algunos módulos de Python como feedparser.

Nos vamos a saltar esta parte porque ya la hemos contado en otro sitio y también la parte de obtener el título, el contenido y el enlace a la última entrada.

En este caso hay ciertos límites, no se pueden superar los 4096 caracteres en UTF8. Además, para que el texto tenga algo de gracia nos permiten algunas etiquetas de formato (que pueden ser HTML o Markdown). Como estamos leyendo la fuente RSS habremos leido HTML y la única prevención que hay que tener es utilizar sólo las etiquetas permitidas (negrita, cursiva, enlaces, código y texto pre-formateado). Para esto hice una chapucilla, consistente en eliminar todas las etiquetas que no le gustan al sistema:

Extraemos todas las etiquetas de nuestro texto:

tags = [tag.name for tag in soup.find_all()]

Y luego las recorremos:

for tag in tags:

Eliminando las que no son válidas:

   if tag not in validTags:

con unwrap. Previamente hemos tenido una consideración especial con las citas añadiéndoles delante y detrás unas comillas para que se refleje adecuadamente en el resultado final.

def cleanTags(soup):
    tags = [tag.name for tag in soup.find_all()]
    validTags = ['b', 'strong', 'i', 'em', 'a', 'code', 'pre']

    if soup.blockquote:
        soup.blockquote.insert_before('«')
        soup.blockquote.insert_after( '»')

    for tag in tags:
        if tag not in validTags:
            for theTag in soup.find_all(tag):
                theTag.unwrap()

Para enviar el mensaje necesitamos crear un canal FAQ channels y dar de alta como administrador al bot, para que pueda escribir en el canal:

bot.sendMessage('@'+channel, str(soup)[:4096], parse_mode='HTML')

El código está integrado en mi proyecto rssToSocial que no es un código para sentirse especialmente orgulloso. Pero permite hacer estas publicaciones sin tener que hacerlo a mano.

La explicación del código para publicar en otras redes sociales está en:

A partir de ahora (o dentro de un poco, que tengo que configurarlo) ya pueden recibir notificaciones siguiendo a mbpfernand0 en Telegram.

Primeros pasos con Omega2

Hace unos meses se anunció el proyecto de financiación de un nuevo ordenadorcito, el Omega2: $5 Linux Computer with Wi-Fi, Made for IoT. Tengo que decir que lo vi y no le presté atención, así que no participé en el proyecto. Mi hermano lo hizo y además encargó un par de cacharritos para darme uno.

Lo tengo en casa desde navidad pero hasta ahora no había tenido tiempo de escribir esta nota. En este caso lo probé y pude configurarlo con mucha rapidez. Desde el punto de vista de puesta en marcha el proyecto ha trabajado muy bien si nos olvidamos de un par de detalles que comentaremos luego: alimentamos la placa, esperamos a que arranque y crea un punto de acceso WiFi. La documentación es clara y se sigue bien. Desde cualquier otro ordenador podemos conectarnos a ese punto de acceso. Navegando desde esa red podremos conectarnos a la dirección del Omega y hacer la configuración inicial desde el navegador (o mediante ssh). Entre otras cosas le proporcionamos los datos de nuestra red WiFi y entonces se conecta. Personalmente me gusta más la configuración inicial del C.H.I.P. pero encuentro esta bastante cómoda y amigable (y mucho más que tener que buscar una pantalla a la que conectar el cacharrito, aunque sea la de la TV).

En cuanto a las pegas inciales dos, pero notables: la alimentación de la placa es a 3.3V (si compramos el ‘dock’ entonces podremos tener acceso a un puerto USB y alimentar el cacharrito desde allí, entre otras ventajas. Pero entonces hablamos de un ordenador de 20 dólares y no 5). La segunda pega es la separación de los pines: no es la estándar de una placa de prototipado así que no es posible pincharía allí y cablear, hay que poner los cables directamente a los pines (a lo mejor hay placas de prototipado con esa ditancia de pines, lo desconozco). La estoy alimentando gracias a que tenía una fuente de alimentación YwRobot.

Omega 2

Como decíamos arriba la documentación para ponerla en marcha y dar los primeros pasos está muy bien Onion Omega2 Documentation y ponerla en marcha es sencillo.

Una vez que conseguimos que arranque disponemos de un sistema funcionando que configuramos a nuestro gusto y podemos empezar a trabajar. Como punto positivo frente a otras placas nos ha parecido muy buena idea que genere su propia red y de manera simultánea pueda conectarse al router mediante interfaces virtuales. Así se pueden hacer proyectos (la documentación lo explica) para hacer un extensor de WiFi (llevar la WiFi a algún punto lejano, haciendo de repetidor), un punto de acceso, … Otro punto interesante es que utiliza LinuxWRT, con el inconveniente de tener que aprender a manejar otro gestor de paquetes, el opkg (aunque la documentación ayuda también en este aspecto).

Entramos por ssh:

El ssh en Omega 2

En cuanto al uso, tengo sentimientos enfrentados: es pequeñita, barata y sencilla de poner en marcha. Pero cuando empezamos a trabajar con el modelo básico, casi no podemos hacer nada (por falta de espacio): para empezar, hay que elegir entre tener Git o Python, porque no hay espacio libre suficiente para los dos. Podríamos aumentar el almacenamiento disponible (y hay instrucciones para ello) pero sería mejor teniendo un puerto USB para conectarlo.

Entre sus características

  • Procesador 580MHz MIPS CPU.
  • Memoria 64MB (el Omega 2+ tiene 128) y 16 Mb de almacenamiento (32 en el caso del Plus).
  • b/g/n Wi-Fi
  • Varios puertos para conectividad con diversos sistemas externos.

Tiene USB 2.0, pero sin el dock no tendremos el conector.

El tamaño es pequeñito, la mitad de lo que ocupa el C.H.I.P. aproximadamente y un poquito más que un NodeMCU.

Comparando tamaños: C.H.I.P., Omega2, NodeMCU, Arduino, Pine64, Raspberry Pi

Una cosa que me preocupaba de estos aparatitos son las prestaciones. Son bastante limitadas y he preparado una tabla para que se vea mejor. La comparación se hará con una Raspberry Pi (Model B), un C.H.I.P., una Pine 64 y también he hecho comparaciones con un PC de escritorio viejo (fecha alrededor de 2008), y mi portátil, que también tiene unos cuantos años (fecha alrededor de 2011):

Dispositivo microsegundos/iteración Nº de cores bogomips Procesador
Raspberry Pi 5.944 1 697,95 ARMv6-compatible processor rev 7 (v6l)
Omega 3 3.916 1 385,84 MIPS 24KEc V5.5
C.H.I.P. 1.125 1 1001,88 ARMv7 Processor rev 2 (v7l)
Pine 64 624 4 624 AArch64 Processor rev 4 (aarch64)
PC Escritorio 204 1 6800,56 Intel(R) Pentium(R) 4 CPU 3.40GHz
Portátil 69 2 5382,47 Intel(R) Core(TM) i7-2620M CPU @ 2.70GHz

La conclusión para mi fue que estos cacharritos pueden cumplir un papel en muchos momentos (y lo cumplen) pero no debemos olvidar las limitaciones en cuanto a potencia, que no permitirían (aún) pensar en ellos como sustitutos de un computador de sobremesa (salvo que tengamos requisitos muy austeros).

El sistema utilizado para medir las ‘prestaciones’ es muy básico, utilicé el código que proporcionaban en Performance Comparison - C++ / Java / Python / Ruby/ Jython / JRuby / Groovy.

En esta serie hemos publicado hasta ahora:

Sobre la Raspberry no hice un primeros pasos.

Divulgación de vulnerabilidades en la industria del automóvil

Un coche Los fabricantes de automóviles han permanecido muchos años de espaldas a la informatización. Ahora empiezan a utilizarlo como argumento de ventas (esencialmente a través de sistemas de comunicación y entretenimiento) pero en medio la informatización de la instrumentación de los coches ha sido más o menos inevitable. Y la aparicion de fallos también, claro (ver Coches y ataques). La reacción de los fabricantes era, hasta hace no mucho, atacar a los investigadores pensando que así evitarían que se divulgase su conocimiento.

Por eso traemos aquí GM embraces white-hat hackers with public vulnerability disclosure program donde se decía cómo el conocido fabricante había decidido no perseguir a los investigadores que informaran sobre fallos de seguridad, mediante un programa de divulgación responsable de vulnerabilidades:

“We very highly value third-party security research,” Massimilla said. He explained that under the program, those third parties can reveal vulnerabilities they find with the guarantee that GM will work with them and not take legal action—as long as they follow the fairly straightforward guidelines posted on the program’s portal.

Almacenamiento seguro de contraseñas

Sistemas de almacenamiento Primero, que quede clara una cosa: las contraseñas no se almacenan, se almacena una transformación unidireccional que permita comprobar que la persona que la utiliza la conoce, pero que impide (en la medida de lo posible) que el que nos pudiera robar los datos los utilice de manera directa.

En Storing Passwords in a Highly Parallelized World hablan de un tema al que se le está prestando mucha atención en los últimos años: no se trata sólo de almacenar las contraseñas de manera que sean ilegibles, sino que hay que tener en cuenta los ataques que pueden sufrir si alguien consigue acceder a la información y atacarla en condiciones favorables. En ese sentido, se favorecen métodos que añaden coste computacional (cuando se trata de una sola contraseña, con la clave correcta, es un coste asumible; si se trata de hacer pruebas empieza a ser interesante desde el punto de vista defensivo):

bcrypt is a password hash. The difference to cryptographic hashes like SHA-1 is that it adds a computational cost to password hashing. In other words: it’s intentionally slow. The reasoning is that if someone steals the hashes of the passwords of your customers, it’s going to be much more expensive to compute the passwords (which are probably also the passwords to their e-mail accounts) to those hashes.

Luego habla de una competición para generar nuevos métodos de hash criptográficos y del ganador, haciendo algunas pruebas de demostración en Python:

Argon2 is a secure, memory hard password hash. It comes in two variants but for password hashing only the side-channel hardened Argon2i is relevant. On 2015-11-05, an IETF draft has been submitted in order to make it an official Internet standard ASAP.

Números aleatorios seguros en Javascript

Aleatorio Otra nota sobre números aleatorios seguros. En este caso nos avisaban en V8 Javascript Fixes (Horrible!) Random Number Generator sobre un error en la forma de generar números aleatorios en Javascript que tiene el interés de proporcionar una explicación general bastante buena, como alguien encontró el fallo al encontrar una colisión en un identificador de sesión (tan sólo un mes después de empezar) y cómo los programadores eligieron la versión incorrecta de un método que no estaba mal.

En TIFU by using Math.random() cuentan los detalles sobre la historia en primera persona. Sin olvidar que estaban utilizando un generador de números aleatorios que no era criptográfico.

De paso, podemos probar el generador de nuestro navegador en este generador de imágenes aleatorias.