nXMLRPCd
Este documento describe nxmlrpcd basado en kxmlrpcd (KDE XmlRpc Daemon) El demonio permite a un cliente implementado en cualquier lenguaje (python, perl,java, etc) sobre cualquier plataforma (unix, windows, macos, etc) acceder a los clientes DCOP del KDE. Los programas que hacen uso de DCOPno necesitan modificaciones en su codigo para poder hacer uso de este sistema, y los clientes solo tienen que hacer llamadas Xml-Rpc a estos procedimientos de la manera habitual. La mayoria de las aplicaciones de KDE son clientes del dcopserver (hacen uso de DCOP para comunicarse entre ellas), esto significa que la mayoría de las aplicaciones KDE pueden ser manipuladas con scripts de manera remota desde cualquier lenguaje y plataforma.
Descripción técnica
Xml-Rpc es un standard de llamada a procedimiento remoto (RPC) haciendo uso de XML y HTTP. Su objetivo es la comodidad y simplicidad, para que su implementación sea lo mas simple posible. Para lograr eso se hace uso de XML como método de llamada a procedimiento remoto, siendo las llamadas a funciones y las respuestas encapsuladas en XML's. Se hace uso del protocolo HTTP como metodo de transferencia para las llamadas.
La ventaja de esta arquitectura es que cualquier lenguaje decente (incluso scripts) tiene capacidad de utilizarlo de manera sencilla mediante parsers XML y clientes HTTP. Esto hace que programas que hagan uso de Xml pueda hacer uso de la arquitectura de manera relativamente sencilla. Existen clientes y servidores para un monton de lenguajes tanto compilados como interpretados.
Echale un vistazo a http://www.xmlrpc.com para mas información sobre especificaciones e implementaciones.
El problema
Xml-Rpc tenía pinta de ser una manera genial de hacer llamadas remotas a aplicaciones KDE. El trabajo original de Kurt trataba de hacer que las aplicaciones KDE tuviesen un sevidor embebido de XML-RPC, aunque esto tomaría su tiempo para que las aplicaciones hiciesen uso de esta arquitectura. Cuando se diseño DCOP, parecia obvio que los programadores no querrian hacer implementaciones para DCOP o Xml-Rpc a la vez.
La Solución
La biblioteca DCOP tiene una gran ventaja sobre Xml-Rpc, y es que esta enlazada con todas y cada una de las aplicaciones KDE. Esto significa que todas las aplicaciones que hacen uso de DCOP tienen funcionalidad remota de una manera muy muy simple. Kurt decidió hacer uso de todas las capacidades de la arquitectura y crear una pasarela XmlRpc a Dcop. Esto implica que todas las llamadas a procedimiento remoto Xml-Rpc son traducidas a DCOP y viceversa.
KDE XmlRpc Daemon
El resultado es kxmlrpcd. Kxmlrpcd es un servidor web que corre en unpuerto tcp (configurable) que recibe llamadas XmlRpc, a su vezes un cliente DCOP. La arquitectura típica es la siguiente:

El cliente DCOP esta registrado con un nombre (por ejemplotestDCOP)y el nombre de su objeto es test.
El cliente XmlRpc hace una llamada a procedimiento al demonio sobre la URL 'http://localhost:port/testDCOP' en concreto al nombre de metodo 'test.function' y dos strings como parámetros. El demonio (nkxmlrpcd) acepta las peticiones y las traduce a peticiones DCOP, convirtiendo los strings de XmlRpc en tipos QStrings de Qt (en este caso QStrings), serializando estos mediante un QDataStream. El demonio llama entonces al cliente DCOP y espera hasta que la respuesta llegue por parte del cliente, una vez que ha llegado, la empaqueta como XmlRpc y la envia como respuesta al cliente XmlRpc.
De este modo el cliente XmlRpc no sabe en ningún momento que está interactuando con un cliente DCOP. Cree que el servidor nkxmlrpcd es el que responde a todas las peticiones. Por otro lado el cliente DCOP cree que se esta comunicando unicamente con otro cliente DCOP llamado kxmlrpcd.
Autenticación
Al principio, el demonio corría sobre un puerto prefijado (6242) y aceptaba todas las peticiones. Esto tiene dos problemas potenciales. El que se trabaje en un puerto único impide que dos personas puedan lanzar su demonio en la misma máquina, lo cual es inaceptable para ordenadores multiusuario.
El problema mas serio es el de la autenticación. Principalmente por que no hay, esto implica que cualquiera desde cualquier máquina tiene acceso a todos los objetos DCOP como si se tratase del propietario de la sesión. Esto es un Fallo de seguridad Enorme.
La manera en la que el demonio lo soluciona, es guardando un numero de puerto aleatorio y un token de autenticación separados por una coma en un fichero que se guarda en $HOME/.kxmlrpcd. El token sigue siendo una cadena de 16 bytes (char) elejida de manera aleatioria con caracteres ASCII. El token debe ser incluido en cada llamada a procedimiento remoto como primer parametro de tipo string. Si no existe este primer parametro, o no coincide el token, la llamada a procedimiento remoto es rechazada.
El puerto elegido no es realmente aleatorio. El rango de puertos comienza en el 18300 y va hasta el 19300. De esta manera se permitea los administradores de red que configuren sus firewalls para mejor control, en caso de ser necesario.
Este metodo tiene como ventaja colocar la autenticación fuera de los dominios del kxmlrpcd, de tal manera que es responsabilidad del cliente conseguir el token como primer paso para realizar llamadas a procedimientos. De este modo el cliente debe conseguir el token de alguna manera, lo cual ya implica algun otro tipo de autenticación mas fuerte, ya sea por que se registró previamente, por que monto una unidad de almacenamiento compartida, etc.
En cualquier caso siguen existiendo al menos dos métodos de romper todos los niveles de seguridad. El mas facil es colocar un analizador de protocolos o sniffer en la red para leer el token que pasa por ella. La única manera de solucionar esto es encapsular la comunicacion en ssh, ssl o ipsec, es decir cifrar los enlaces. Nota de Kurt.(ninguno de los enlaces que he realizado, ha sido encriptado, lo cual es un tema que da un poco de miedo, cuando se trabaja en un proyecto internacional)
El segundo metodo es utilizar fuerza bruta. De cualquier modo hay 7916posibles combinaciones, lo cual hace muy tedioso a los que quieran drealizar este tipo de ataques
nKxmlrpcd
KxmlRpcd se dejo de utilizar en el proyecto KDE debido a que la autenticación y seguridad de este sistema no eran todo lo buenas que debrian ser. El Problema es que al ir encapsulado el trafico en HTTP, y tener que cumplir el standard se hace un poco inseguro utilizar XmlRpc para llamada a modulos del escritorio KDE. De esta manera el token resulta completamente inefectivo ya que con un simple sniffer se puede capturar el token de estas comunicaciones.
Por otro lado la obtencion del token no ha quedado especificada y se deja comoopcion a la persona que implementa los clientes xmlrpc, que aparte de la comunicacion por xmlrpcd tienen que hacer uso de algun otor mecanismo para poderconseguir el token.
Las modificaciones que he realizado tienen la siguiente intención:
Por un lado, ya que la autenticación en mis comunicaciones las hago a otro nivel, me parecia correcto hacer que el token de autenticación no fuese generado de manera aleatoria (haciendo menos complejos mis clientes xmlrpc). De esta manera se puede colocar el token de autenticación que se quiere utilizar en el fichero $KDEHOME/share/config/kxmlrpcd en la sección general donde también existe la posiblidad de poner el puerto por defecto.
[General]
Port=18300
AuthToken=0123456789ABCDEF
Tambien es posible especificar el token y puerto en el momento en el que se lanzael kxmlrpcd. De esta manera con lanzar el programa como:
nkxmlrpcd --port 19000 --token FEDCBA9876543210
tendremos lanzada la pasarela en el puerto 19000 con el token FDECBA9876543210.
Esto no hace que las comunicaciones sean mas seguras, solo hace que sean mas simples. Para hacer que las comunicaciones sean seguras, hasta ahora nos hemos valido del uso de sistemas de cifrado fuerte como IPSec o SSH. Para realizar esto, encapsulamos todo el trafico con el resto de los sistemas que nos queremos comunicar, y lo ciframos. Por otro lado colocamos un firewall que actua denegando los puertos de nkxmlrpcd. De esta manera, toda comunicación con los puertos de nkxmlrpcd no solo debe ser autenticada, sino que es cifrada, haciendo que los ataques de sniffing, hombre en el medio, o similares sean muy dificiles de relizar.
Facilidad de uso
Quiza te preguntes ¿es realmente tan sencillo de utilizar?. La respuesta es si. Echale un vistazo a los scripts que hay en 'test' realizados en bash y python como ejemplo de lo sencillo que es. Es muy facil utilizar incluso shell scripting como metodo de acceso remoto a aplicaciones KDE!!!.
Instalación
Puede instalar el paquete directamente desde los fuentes, compilando el programa, o en caso de que utilice Debian como distribución, instalar el paquete deb.
Instalar y compilar el código
- Descargar el paquete
- Descomprimir el paquete
- Compilar
- Para instalar la biblioteca, ejecutar como superusuario
Para descargar nkxmlrpcd pulsa aquí
tar xzf nkxmlrpcd.tar.gz
make
make install
Instalar paquete deb
- Descargar el paquete
- Para instalar la biblioteca, ejecutar como superusuario
dpkg -i nkxmlrpcd_0.1-0_i386.deb
Limitaciones de la Arquitectura
Esta arquitectura es genial en el sentido de que tanto cliente como servidor no necesitan recodificar nada para hacer uso de ella. En Cualquier caso esto implica limitaciones de uso.
No es posible hacer uso de tipos QT, Los únicos tipos que son útiles por tener asignación directa entre QT y XmlRpc son:
| Xml-Rpc | QT/C++ |
| int | int |
| boolean | bool |
| string | QString (unicode) |
| double | double |
| dateTime | QDateTime |
| base64 | QByteArray |
| struct | QMap (tipos limitados) |
| array | QValueList (tipos limitados) |
Por ejemplo tipos como QPixmap, QList, etc, no estan permitidos. Los struct y array estan muy restringidos. Como se describe en las especificaciones de XmlRpc las estrurcturas y los arrays, pueden tener un número no definido de diferentes tipos, incluyendo estructuras recursivas y arrays recursivos. Desafortunadamente no hay ninguna manera sencilla de mapear estas estructuras en tipos de C++, ya que C++ es fuertemente tipado y no tiene manera de crear tipos dinámicos al vuelo.
Solo es posible hacer uso de una estructura y array si las siguientes dos condiciones se cumplen:
- La estructura o array solo contiene un tipo
- La estructura o array no pueden contener otras estructuras o arrays.Solo pueden contener tipos simples.
NkxmlRpcd y libbslxml
La mayoría de las aplicaciones que hemos desarrollado hacen uso intensivo de XML como lenguaje de modelado de datos. Por otro lado, XmlRpc es un modo bastante elegante de comunicar aplicaciones remotas, quiza un tanto inseguro, pero existen capas mas altas que funcionan perfectamente para encriptar y autenticar... por esto me parecio una pena que el proyecto kxmlrpc fuese desestimado como proyecto KDE.
Retomé principalmente el proyecto para hacer que una aplicación que necesitaba comunicacion mediante DCOP con otras aplicaciones del escritorio, hiciese uso de las mismas funciones DCOP para comunicarse con otros clientes DCOP en otras máquinas. El resultado fue la necesidad de eliminar el token de autenticación (parcialmente) y realizar la autenticación con IpSec.
El mejor resultado que obtuve fue el de reutilización de código... Crear funciones que se pueden exportar via DCOP y luego utilizarlas desde otros clientes remotos mediante XmlRpc, realmente hace que te olvides de las comunicaciones, y ahorres una gran cantidad de tiempo en el diseño de tus aplicaciones.
Hacer uso de XML de manera intensiva para gestión de datos me permite ademas comunicar entre distintas aplicaciones DCOP y por tanto XmlRpc cantidades de datos, que luego se pueden validar mediante DTDs o esquemas, de manera que todos los problemas que hay con las estructuras y arrays no resultan tales. Para poder hacer esto acabo encapsulando un XML como string dentro de un XmlRpc, las bibliotecas libqutexr y libbslxml hacen que todo esto sea muy facil y que la creación de programas distribuidos sea muy sencilla.
Lo único que se echa en falta en todo este esquema es un poco de seguridad en ese nivel. Es necesario encriptar y autenticar las comunicaciones en otros niveles. Hasta la fecha hemos hecho uso de ssh y IpSec como medio de autenticación y cifrado, añadiendo firewalls que no permiten entrar en los puertos kxmlrpc. Quiza otros sitemas de Rpc sean mas eficientes, pero en cuanto a Mantenimiento del software y reutilización de los objetos DCOPObjects que utilizo habitualmente es la mejor manera de permitir acceso a procedimientos remotos sobre estos objetos.
Existen otros textos mas técnicos que explican esta arquitectura de desarrollo de una manera mas extensa.Creo que es una lástima que el codigo de kurt haya desaparecido del proyecto KDE por falta de gente que lo utilice...
Por nuestra parte... Kurt, tu código no esta muerto ;).
Fallos o faltas de funcionalidad
- Hay una laguna de memoria en kxmlrpcserver, pero no puedo encontrarla UPDATE: Encontrada! estaba en QDomDocument
- La funcion 'shutdown()' no hace lo que debe correctamente
- Cada peticion realiza una conexion por separado, estaria bien hacer usode un keepalive en caso de ser posible.
- Fallo al enviar parametros con longitud superior a 1kb... se esta preparando correccion
