Informatique


Sharepoint Office365 sur Linux : automatiser l'authentification

Suite de l'aventure avec Sharepoint !

On a pu passer 2 étapes cruciales pour jouer avec Sharepoint Online :

Après quelques jours d'utilisation, il s'avère que les cookies d'authentification ne sont plus valables. C'est un gros problème car c'est pénible de les récupérer manuellement pour ensuite les injecter dans le fichier de configuration Davfs.

J'ai planché quelques heures sur une solution : réaliser le parcours de connexion d'un utilisateur qui passerait par un navigateur web.

Le projet est libre et voici comment l'installer et l'utiliser.

Note : il faut avoir NodeJS sur sa machine. J'ai développé le code en version 6.13.0.

Il faudra déclarer 3 variables d'environnement contenant le site Sharepoint, l'identifiant de connexion et le mot de passe :

Il ne reste plus qu'à lancer le script qui devrait vous retourner du JSON avec les 2 cookies dedans :

À vous de choisir la méthode pour alimenter la configuration de Davfs avec ces données !


Sharepoint Office365 sur Linux (Webdav/Davfs) avec des fichiers accentués

Suite de l'aventure avec Sharepoint !

Je me suis rendu compte que les répertoires et les fichiers nommés avec des accents ne sont pas montés par Davfs. Le problème vient bien sur de Microsoft qui n'est pas foutu d'implémenter un protocole en suivant les standards ! Le support technique est une vraie plaie et ne veut pas comprendre que le problème vient de chez eux…

En effet, les spécifications WebDAV indiquent que les caractères spéciaux (espace compris) doivent être encodés en %XXX. Par exemple, on doit retrouver %C3%A9 à la place de é. Or, Sharepoint ne remplace que les espaces (%20). Voici une partie de la réponse HTTP formée par Sharepoint pour un fichier nommé "éducation.pdf" :

<D:href>https://foo.sharepoint.com/sites/bar/Documents%20partages/éducation.pdf</D:href>

Alors que ça devrait être sous cette forme :

<D:href>https://foo.sharepoint.com/sites/bar/Documents%20partages/%C3%A9ducation.pdf</D:href>

Du coup, j'ai du travaillé sur un correctif et voici une POC qui corrige le problème. Elle consiste à faire passer les requêtes HTTP de DavFS à travers un proxy qui fera le boulot de Sharepoint : encoder les caractères en question !

Je travaille sur ma machine de dev dans ~/www/repo/sharepoint-webdav-proxy.

J'ai choisi le proxy mitmproxy car on peut modifier les requêtes et les réponses à la volé.

Les binaires de mitmproxy sont placés dans ./bin/. Si vous lancez une première fois bin/mitmproxy, des certificats SSL seront créés dans ~/.mitmproxy/.

Configuration de DavFS :

$ sudo cp ~simon/.mitmproxy/mitmproxy-ca-cert.pem /etc/davfs2/certs/

Dans /etc/davfs2/davfs2.conf, j'ai ajouté :

[/mnt/sharepoint/]
proxy 127.0.0.1:8118
trust_ca_cert /etc/davfs2/certs/mitmproxy-ca-cert.pem
use_proxy 1
[...]

Adapteur WebDAV :

Dans src/webdav-adapter.py :

Edit : la version colorée affiche mal certain caractères. Consulter la version texte.

Lancement du proxy :

./bin/mitmdump --mode regular --listen-host 127.0.0.1 --listen-port 8118 -s ./src/webdav-adapter.py

Une fois tout ça réalisé, mount.davfs va pouvoir monter les répertoires/fichiers accentués.


Monter un partage Sharepoint Office365 sur Linux (Webdav/Davfs)

Dans le cadre de mon travail, je développe une application web (nommée Tools) qui fait office de boite à outils pour le groupe Zenitude. L'idée de l'application est de fournir un ensemble d'outils pour faciliter le travail de mes collaborateurs.

Parmi la flopée de fonctionnalités, on trouve des interfaces qui affichent des données récupérées depuis des fichiers Excel. Elles sont analysées et mises en page par l'application (graphiques et tableaux).

Ces fichiers sont initialement déposés sur un espace collaboratif Sharepoint délivré par Office365. J'avais pour objectif de travailler avec les API de Microsoft mais c'est un véritable calvère. C'est mal documenté et le support technique de premier niveau est complètement naze. Du coup, je me suis résolu à faire des formulaires pour déposer les fichiers manuellement.

Pour éviter d'avoir des formulaires d'upload de fichier, je souhaite monter le partage Sharepoint sur le serveur afin d'accéder, en quasi temps réel, au contenu des fichiers qui m'intéressent. Microsoft fournit OneDrive qui est un outil de synchronisation pour monter le partage Sharepoint sur son ordinateur mais seul Microsoft Windows et IOS sont supportés. Il s'appuie sur le protocole WebDAV mais authentifie les utilisateurs avec le protocole OAuth2.

Sous Linux, davfs2 permet de faire des montages WebDAV dans son système de fichiers. La problématique d'authentification via OAuth2 est réelle car impossible de passer un couple login/mot de passe classique. Une solution existe et consiste à récupérer des cookies générés après l'authentification OAuth2 via un navigateur et indiquer à davfs2 de les injecter dans les requêtes HTTP WebDAV.

Pour des questions de sécurité, j'ai ajouté à l'organisation Office365 un compte utilisateur qui, par défaut, ne peut lire que les fichiers du partage. Lorsque que je me connecte à Office365 via un navigateur web en utilisant ce compte, 2 cookies sont créés : rtFa et FedAuth. Il faut conserver leur valeur respective car nous en auront besoin pour configurer le montage.

On va installer le driver davfs2 pour réaliser le montage :

# aptitude install davfs2

Je décide que le point de montage sera dans /mnt/sharepoint. Dans /etc/davfs2/davfs2.conf, on indique à davfs2 d'ajouter les cookies. Il faut bien évidement remplacer XXXXXX et YYYYYY par ce que vous avez récupéré :

[/mnt/sharepoint/]
ask_auth 0
add_header Cookie rtFa=XXXXXX;FedAuth=YYYYYY

Il reste maintenant à faire le montage :

# mount.davfs -o ro "https://foo.sharepoint.com/bar/Documents partages" /mnt/sharepoint

Si tout se passe bien, vous devrier avoir le montage fonctionnel. Ça ne sera pas détaillé ici mais vous pouvez maintenant affiner la configuration, faire du cache sur les fichiers, gérer les permissions plus finement, passer par /etc/fstab pour automatiser le montage, etc.


Monitordisplay : gérer ses dispositions d'écrans

Je branche très souvent des écrans externes à mon laptop et je suis un peu lassé de bidouiller xrandr. En effet, ses instructions sont simples mais assez longues et pénibles à écrire.

Ainsi, j'ai décidé de me faire un outil pour pouvoir configurer des modes d'affichage, pouvoir ajouter plusieurs dispositions et les activer rapidement.

Comme à mon habitude, c'est un outil en ligne de commande. J'ai décidé d'utiliser PHP pour une question de pratique pour moi.

Installation de monitordisplay

Il faut installer l'interpréteur PHP (5 ou 7) :

Maintenant que PHP est installé, il faut récupérer le projet :

Configuration

monitordisplay va essayer de charger 3 fichiers. Chaque fichier peut surcharger la configuration du précédent. Voici la liste :

  • /etc/monitordisplay/config.ini
  • $HOME/.config/monitordisplay/config.ini
  • $HOME/.monitordisplay

Je suis le seul utilisateur du laptop donc je vais juste créer le dernier.

Le fichier de configuration copié contient 2 écrans :

laptop et hdmi sont les identifiants "humains" sur lesquels je vais m'appuyer pour réaliser les dispositions. Le paramètre name contient l'identifiant technique passé à xrand. resolutionX et resolutionY indiquent la résolution de l'écran.

Il est possible de configurer plusieurs fois le même écran. Il suffit de modifier l'identifiant humain. Vous pouvez ainsi prévoir plusieurs résolutions.

Maintenant, il reste à renseigner des modes d'affichage. En voici trois exemples :

Tout comme un écran, le mode d'affichage porte un identifiant. Il possède également une liste de dispositions (config[]) et un indicateur (optionnel) d'écran principal (primary). L'ordre des identifiants définie la position, de gauche à droite, des écrans.

Utilisation

Pour activer un mode d'affichage (exemple : work), il suffit de lancer cette ligne de commande :

Le mode work contient deux dispositions. Pour passer à la seconde disposition, il suffit de lancer :

-t permet donc de passer successivement d'une disposition à une autre.

Quand monitordisplay charge un mode ou change de disposition, par défaut, il désactive les écrans non pris en charge. Si vous souhaitez outre-passer ce comportement, il suffit de passer l'argument -s. C'est assez pratique quand vous souhaitez initialiser une résolution sur un écran sans désactiver les autres.

Le code source est disponible sur gitnet et c'est open bar ;)


Let's Encrypt - Comment se faciliter la vie ?

Mon serveur web est composé d'un frontend nginx et d'un backend apache. L'ensemble de mes certificats (à l'exception du wildcard deblan.org) est géré par Let's Encrypt. Mon problème jusqu'à aujourd'hui était que lors de la création ou le renouvellement d'un certificat, mon service nginx devait être coupé pour réaliser l'authentification nécessaire à la validation faite par Let's Encrypt.

Le service nginx, tel que je l'ai configuré, possède un fichier de configuration unique qui écoute sur le port 80. Ce fichier permet :

  • d'indiquer mon backend apache
  • de gérer les problématiques de cache des assets (images, css, javascripts, etc.)

Vous pouvez remarquer l'include à la ligne 20. Voici le contenu du snippet :

Il identifie un répertoire unique où seront générés les fichiers d'authentification de Let's Encrypt. Il aura fallu créer ce répertoire au préalable (sudo mkdir -p /var/www/letsencrypt/).

Reste à présent 2 scripts :

  • celui qui permet de générer un certificat
  • celui qui permet de renouveler les certificats qui vont expirer

Pour la génération d'un certificat, j'ai souhaité une ligne de commande simple : le-get-certificate monsite.com www.monsite.com foo.monsite.com. Voici son contenu :

Edit : la commande cerbot renew fait le travail tout seul. L'intérêt de mon script pourrait d'ajouter rapidement des domaines à certifier en augmentant le CSR automatiquement.

Edit 2 : certbot renew --webroot -w /var/www/letsencrypt --agree-tos est sans doute la meilleurs manière de renouveler les certificats. J'ai rencontré quelques problèmes avec le script proposé ci-dessous.

Concernant le renouvellement, le script suivant s'appuie sur un fichier de configuration que vous devrez alimenter à chaque création de certificat. Il doit être créé à cet emplacement : /etc/letsencrypt/domains.conf. Voici à quoi il ressemble chez moi et j'ai ajouté la ligne nécessaire pour l'exemple de la commande de création :

Voici à présent le script que devra être exécuté périodiquement pour le renouvellement :

J'espère que cela pourra vous être utile et si vous avez des remarques, n'hésitez pas à m'en faire part :)