MarioDebian, mi devlog

Bitácora de un desarrollador newbie.

Mi primer paquete en Debian

python-netifaces es un pequeño módulo de python que permite obtener información de los interfaces de red.

Desde hace unas versiones es dependencia de TcosMonitor (encuentra interfaces del tipo eth0:1 cosa que con /sys/class/net no es posible)

Como hay que empezar por algo, entré en el IRC del grupo de empaquetadores de módulos python y me echaron una mano (bastante grande por cierto) para que el paquete estuviese lo mejor posible. Después de haber mandado un ITP, ayer ha sido subido a NEW, y acaba de ser etiquetado como pendiente.

La forma de usarlo es muy sencilla:

$ python
>>> import netifaces
>>> dir(netifaces)
['AF_APPLETALK', 'AF_ASH', 'AF_ATMPVC', 'AF_ATMSVC', 'AF_AX25', 'AF_BLUETOOTH', 'AF_BRIDGE', 'AF_DECnet', 'AF_ECONET', 'AF_FILE', 'AF_INET', 'AF_INET6', 'AF_IPX', 'AF_IRDA', 'AF_KEY', 'AF_LINK', 'AF_NETBEUI', 'AF_NETLINK', 'AF_NETROM', 'AF_PACKET', 'AF_PPPOX', 'AF_ROSE', 'AF_ROUTE', 'AF_SECURITY', 'AF_SNA', 'AF_UNIX', 'AF_UNSPEC', 'AF_WANPIPE', 'AF_X25', '__doc__', '__file__', '__name__', 'ifaddresses', 'interfaces']

>>> netifaces.interfaces()
['lo', 'eth0', 'br0', 'vbox0', 'vbox1', 'vbox2']

>>> for iface in netifaces.interfaces():
...   print "IFACE: ", iface, " ", netifaces.ifaddresses(iface)
...

IFACE:  lo   {17: [{'peer': '00:00:00:00:00:00', 'addr': '00:00:00:00:00:00'}], 2: [{'peer': '127.0.0.1', 'netmask': '255.0.0.0', 'addr': '127.0.0.1'}], 10: [{'netmask': 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff', 'addr': '::1'}]}
IFACE:  eth0   {17: [{'broadcast': 'ff:ff:ff:ff:ff:ff', 'addr': '00:1a:6b:6a:xx:xx'}], 10: [{'netmask': 'ffff:ffff:ffff:ffff::', 'addr': 'fe80::21a:6bff:fe6a:bec9%eth0'}]}
IFACE:  br0   {17: [{'broadcast': 'ff:ff:ff:ff:ff:ff', 'addr': '00:1a:6b:6a:xx:xx'}], 2: [{'broadcast': '192.168.0.255', 'netmask': '255.255.255.0', 'addr': '192.168.0.3'}], 10: [{'netmask': 'ffff:ffff:ffff:ffff::', 'addr': 'fe80::21a:6bff:fe6a:bec9%br0'}]}
IFACE:  vbox0   {17: [{'broadcast': 'ff:ff:ff:ff:ff:ff', 'addr': '00:ff:eb:8c:87:f0'}], 10: [{'netmask': 'ffff:ffff:ffff:ffff::', 'addr': 'fe80::2ff:ebff:fe8c:87f0%vbox0'}]}
IFACE:  vbox1   {17: [{'broadcast': 'ff:ff:ff:ff:ff:ff', 'addr': '00:ff:b0:e6:18:e8'}], 10: [{'netmask': 'ffff:ffff:ffff:ffff::', 'addr': 'fe80::2ff:b0ff:fee6:18e8%vbox1'}]}
IFACE:  vbox2   {17: [{'broadcast': 'ff:ff:ff:ff:ff:ff', 'addr': '00:ff:d4:4c:e8:67'}], 10: [{'netmask': 'ffff:ffff:ffff:ffff::', 'addr': 'fe80::2ff:d4ff:fe4c:e867%vbox2'}]}

Como vemos devuelve un diccionario con la información de cada interfaz, para sacar los datos IPV4 (lo más usual):

>>> netifaces.ifaddresses('br0')[netifaces.AF_INET]
[{'broadcast': '192.168.0.255', 'netmask': '255.255.255.0', 'addr': '192.168.0.3'}]

Quizás como última mejora le falta obtener la puerta de enlace (por ejemplo a través de /proc/net/route, mediante la tercera columna, hay que pasarlo a decimal y rotarlo), yo en tcosmonitor lo he ampliado mediante python.





pam-usb con soporte para TCOS

pam-usb es un módulo de autenticación PAM que, usando una memoria USB, permite hacer login (su, gksu, GDM, KDM, etc...) mediante la verificación del modelo, vendedor fabricante, número de serie y una pareja de claves aleatorias (llamadas PADS) una situada en la memoria USB y otra en la $HOME del usuario.

El módulo funciona muy bien salvo que sólo permite el acceso local en la máquina y he estado pensando que ya que en TCOS tenemos varias formas de llegar a los dispositivos de almacenamiento podemos usar pam-usb para autenticar en remoto.

Como primer acercamiento he estado revisando el código (bastante simple: pam +  dbus + hal) y como en TCOS no hay dbus ni hal en remoto he portado parte de él a llamadas XMLRPC y autenticación mediante la cookie de Xorg.

Funcionamiento

Cuando GDM (o el gestor que sea) recibe un usuario llama a PAM para ver si puede autenticarlo antes de pedirle la contraseña, pam-usb toma el control y comprueba que es una petición remota (la variable $DISPLAY tiene este aspecto: xx.xx.xx.xx:0) entonces dispara mi parte «pusb_remote_auth»

  1. hace una primera llamada XMLRPC para inyectar la cookie de las X como propiedad de la ventana root mediante xprop
  2. GDM sabe el usuario y antes de llegar a mi parte sabe si tiene un dispositivo (Vendedor Fabricante, modelo , número de serie, UUID de la partición) con el UUID hacemos una petición de montaje en el terminal: «mount /dev/disk/by-uuid/$UUID /mnt/$UUID»
  3. Leemos (si existe) el directorio .pamusb del dispositivo y devolvemos en base64 el contenido (clave aleatoria binaria) por XMLRPC que se comparará al PAD que tiene el usuario en su $HOME/.pamusb (en este punto pam-usb original hace la comparación de 2 archivos, yo sólo tengo uno y el base64 de otro por lo que tendré que crear un temporal o hacer la comparación de base64 del remoto y local)
  4. Una vez comparados actualizamos los PAD y mandamos al terminal el base64 del nuevo PAD para que lo guarde en el dispositivo y lo desmonte

Para que todo esto funcione, lógicamente, hay que haber dado de alta un usuario en la configuración /etc/pamusb.conf, para ello hay una herramienta: pamusb-conf (python+dbus+hal) que detecta el dispositivo USB y edita el XML para añadir la pareja dispositivo~usuario, esta herramienta sólo funciona en local y también habrá que hackearla o incluso hacer un frontend gráfico.

De momento no he subido nada al SVN pero supongo que a lo largo de esta semana ya habrá algo de código para ver y probar.

UPDATE: (21:05)

Ya he subido el código al SVN de TCOS [pam-usb-tcos], y de paso he mandado un mail al autor original a ver que le parece la escabechina que he hecho con su aplicación.