orx57 RSS

🔒
❌ À propos de FreshRSS
Il y a de nouveaux articles disponibles, cliquez pour rafraîchir la page.
À partir d’avant-hierLinuxFr.org : les journaux

[Tuto/HowTo] Sauvegarder la Base de données de phpBB sur ubuntu/debian/raspbian avec automysqlbackup

Par EauFroide

Ce tuto est la suite de [Tuto/HowTo] Sauvegarder les fichiers joints de phpBB3 sur le cloud via rsync et webdav/dafvs2
Le tuto d'origine se situe à l'adresse suivante : https://www.0rion.netlib.re/forum4/viewtopic.php?f=63&t=496#p1097

Introduction

  • automysqlbackup est un script libre, disponible dans les paquets Ubuntu et Debian/Raspbian, qui permet d'automatiser la sauvegarde de base de données. Une fois le paquet installé, par défaut il copiera les bases de données en suivant les cron suivants : @daily ("0 0 * * *"), @monthly ("0 0 1 * *"), @weekly ("0 0 * * 0"). Et grâce à l'option LATEST=yes vous disposerez aussi d'un dossier intitulé latest dans lequel sera situé le dernier backup en date.

Farm Link

Mise en place

Créez le dossier pour accueillir les sauvegardes de la (ou les) Base(s) De Données sur votre montage webdav/davfs2 créez dans le tuto précédent

sudo mkdir /media/montageDistant/phpBB_BDD/

Installez le logiciel

sudo apt-get update
sudo apt-get install automysqlbackup nano

Éditez le fichier de configuration
sudo nano /etc/default/automysqlbackup

Modifiez les valeurs suivantes (pour rechercher un élément tapez CTRL+W) :

  • BACKUPDIR="/var/lib/automysqlbackup" => remplacez /var/lib/automysqlbackup par le dossier où vous souhaitez ranger les backup de votre base de données (dans ce tuto /media/montageDistant/phpBB_BDD/)
  • LATEST=no => passez la valeur no à yes
  • SEPDIR=yes => Si vous souhaitez un dossier par base de données laissez yes, si vous préférez grouper les BDD dans un seul fichier pour chaque backup, entrez _no
  • PREBACKUP="/etc/mysql-backup-pre" => vous pouvez décommentez la commande (supprimer le #) et remplacez "/etc/mysql-backup-pre" par "/usr/sbin/service apache2 stop"
  • POSTBACKUP="/etc/mysql-backup-post" => vous pouvez décommentez la commande (supprimer le #) et remplacez "/etc/mysql-backup-pre" par "/usr/sbin/service apache2 start"
  • DBEXCLUDE="" => si vous souhaitez ne pas inclure des base de données, indiquez leur petit nom.

PS: lors du précédent tuto nous avons défini la sauvegarde des fichiers joints à minuit et trois minutes, les Base de données seront quant à elle sauvegardée chaque jours à minuit et une minute. Si deux minutes de décalage semble une éternité pour l'ubber geek que vous êtes alors en suivant le précédent tuto remplacez le cron "3 0 * * *" par @daily ;)

Lire les commentaires

Sortie de GHC 8.0.2 et une petite histoire de typage statique

Par Guillaum

Sommaire

GHC, le compilateur Haskell le plus utilisé, est sorti en version 8.0.2, vous pouvez consulter l'annonce de la sortie datée du 11 janvier 2017 ainsi que les notes de version

Il s'agit principalement d'une version de suivi qui corrige plus de deux cent bugs depuis la version 8.0 dont l'annonce de la sortie
avait été faite sur http://linuxfr.org. Donc à ce titre, il n'y a pas grand chose à raconter. Le futur, c'est GHC 8.2 qui devrait arriver aux environs d'avril si on en croit le planning. Celle-ci devrait apporter principalement des améliorations de performance de l'environnement d'exécution parallèle et du ramasse-miettes.

Comme ce journal frôle le journal bookmark et que je tient à mon karma, je vais vous présenter une fonctionnalité d'Haskell, que l'on retrouve dans de nombreux langages, j'ai nommé les ADT, où types de donnée algébriques

Il s'agit d'un croisement un peu douteux entre les struct, bien connus de nombreux langages de programmation, et les union, utilisés en C/C++ et qui sont une sorte d'enum. Le tout gonflé aux stéroïdes de la généricité, de la sécurité et du sucre syntaxique.

Remarque : ce journal a été rédigé dans l'espace de rédaction de dépêche, pour profiter de la collaboration pour corriger notamment de nombreuses coquilles. Merci aux participants, palm123, Anthony Jaguenaud et Lucas pour leur remarques bénéfiques.

ADT : un struct

Un ADT c'est un type. Commençons d'abord par la partie qui ressemble à des struct. Si je veux faire un point à 3 dimensions en Haskell, je ferai :

data Point = PointC Float Float Float deriving (Show)

Il s'agit de la déclaration du type Point. Ce type peut être construit grâce à un constructeur PointC qui prend 3 Float et renvoi un Point. Le type de ce constructeur est PointC :: Float -> Float -> Float -> Point, une fonction qui prend un Float, puis un autre Float, et encore un Float et renvoie un Point. Le nom du constructeur est libre, il aurait très bien pu être le même que le nom du type.

La clause deriving (Show) sert à générer automatiquement des fonctions pour l'affichage.

Un petit exemple de cas d'utilisation dans le shell interactif GHCI :

Prelude> PointC 1 2 3
PointC 1.0 2.0 3.0
Prelude> PointC 4 5 6
PointC 4.0 5.0 6.0

Le constructeur PointC peut aussi servir à déconstruire" les valeurs si il apparaît du coté gauche du signe = :

Prelude> PointC a b c = PointC 1 2 3
Prelude> a
1.0
Prelude> b
2.0
Prelude> c
3.0

Ceci est très pratique lors de la création de fonctions :

Prelude> getX (PointC x _ _) = x
Prelude> getY (PointC _ y _) = y
Prelude> getZ (PointC _ _ z) = z
Prelude> norm (PointC x y z) = sqrt (x * x + y * y + z * z)
Prelude> p = PointC 1 2 3
Prelude> getX p
1.0
Prelude> getY p
2.0
Prelude> getZ p
3.0
Prelude> norm p
3.7416575

Nous avons donc vu qu'un type en Haskell peut être vu comme un struct / objet dans d'autres langages, c'est à dire un agrégat de champs de type hétérogène. Si cela vous inquiète, on peut aussi donner des noms aux champs :

data Point = Point {x :: Float, y :: Float, z :: Float}

Mais ceci est une autre histoire.

ADT : un enum

Les "enum" dans de nombreux langages permettent de crée un type pouvant être représenté par plusieurs valeurs. L'exemple d'école :

data Couleur = Rouge | Vert | Bleu | Marron | Noir | Blanc deriving (Show)

Ici nous avons crée le type Couleur et nous lui avons associé 6 constructeurs différents. Observez bien le | entre les constructeurs, il représente l'alternative.

L'usage du nom "constructeur" ici est souvent troublante pour qui n'est pas habitué, dites vous simplement que Rouge est une fonction qui ne prend pas d'argument et renvoie une valeur de type Couleur, en ce sens, c'est un constructeur de Couleur.

On peut utiliser ces constructeurs pour créer des objets de type Couleur:

Prelude> Rouge
Rouge
Prelude> Bleu
Bleu

On peut aussi réaliser différentes opérations dessus grâce à de la déconstruction comme vu précédemment. Dans la fonction réaction qui suit, je liste les différents cas de couleur, le _ servant de joker. En Haskell, on peut définir des fonctions en listant les cas :

réaction Rouge = "Cool"
réaction Bleu = "Cool aussi, mais je préfère le rouge"
réaction Vert = "Bof Bof"
réaction Noir = "Moche"
-- cas générique
réaction _ = "Je n'aime pas les autres couleurs"

Et l'usage dans l'interpréteur nous donne :

Prelude> réaction Rouge
"Cool"
Prelude> réaction Blanc
"Je n'aime pas les autres couleurs"

Nous avons vu comment réaliser en Haskell l'équivalent des "enum" que l'on peut trouver dans d'autres langages.

ADT : enum avancés, ou union

Le C et le C++ proposent un mécanisme d'union, où un type peut contenir au choix plusieurs sous-types. Par exemple :

union Forme
{
     struct {
          float cote;
     } carre;

     struct {
          float coteA;
          float coteB;
     } rectangle;
};

Je ne reviendrai pas sur son usage en C, sachez seulement que le type Forme peut contenir soit un float cote, soit deux float coteA et coteB. L'usage des deux simultanément est indéfini et on ajoute souvent à la structure de donnée un marqueur pour informer l'utilisateur du type de la donnée réellement stockée.

En haskell, ce type peut être facilement représenté par un ADT combinant struct (ou type "produit") et enum (ou type "somme") :

data Forme = Carré Float | Rectangle Float Float deriving (Show)

Ici nous avons un type Forme qui contient deux constructeurs :
- Carré, qui associe un Float à une Forme
- Rectangle, qui associe deux Float à une Forme.

Contrairement aux langages qui supportent les enum où les unions, on remarque notamment que n'importe quel type complexe peut apparaître dans les différents cas de l'énumération.

Les outils décrit précédemment, de construction et de déconstruction par analyse de cas fonctionnent également. Ainsi on peut crée des Forme :

Prelude> Carré 10
Carré 10.0
Prelude> Rectangle 20 30
Rectangle 20.0 30.0

Et on peut faire des fonctions qui vont traiter notre type par analyse de cas :

surface (Carré c) = c * c
surface (Rectangle a b) = a * b

Ici la fonction surface déconstruit un Carré et renvoie sa surface. Si la déconstruction n'est pas possible (car c'est un Rectangle), alors la fonction passe au cas suivant). À l'usage :

Prelude> surface (Carré 10)
100.0
Prelude> surface (Rectangle 5 3)
15.0

Plusieurs remarques :

  • Le compilateur nous protège et ce de plusieurs manières :

    • Si j'avais oublié de gérer les cas Rectangle, le compilateur m'aurait prévenu.
    • Contrairement aux unions en C/C++, on ne peut pas confondre un Rectangle et un Carre, c'est de nombreuses heures de recherche d'erreurs qui disparaissent soudainement.
  • La syntaxe et l'usage sont succincts, c'est agréable à mon goût. La même chose est possible dans de nombreux langages, par exemple en C++, grâce à l'utilisation de "variant" mais l'usage est lourd. Comparez le programme entier en Haskell à la version C++ :

data Forme = Carré Float | Rectangle Float Float

surface (Carré c) = c * c
surface (Rectangle a b) = a * b

main = do
   let carré = Carré 10
       rectangle = Rectangle 5 3

   print (surface carré)
   print (surface rectangle)

La version C++ équivalente suivante utilise boost::variant, en c++17 nous utiliserons std::variant :

#include <iostream>
#include <boost/variant.hpp>

struct Carre
{
    float c;
};

struct Rectangle
{
    float a;
    float b;
};

using Forme = boost::variant<Carre, Rectangle>;

class surface
{
public:
    float operator()(const Carre &carre) const
    {
        return carre.c * carre.c;
    }

    float operator()(const Rectangle &rectangle) const
    {
        return rectangle.a * rectangle.b;
    }
};

int main()
{
    Forme carre = Carre{10};

    Forme rectangle = Rectangle{5, 3};

    // affiche 100
    std::cout << boost::apply_visitor(surface(), carre) << std::endl;
    // affiche 15
    std::cout << boost::apply_visitor(surface(), rectangle) << std::endl;
}

Ce code passe par la définition du type en trois étapes : définition des sous types Carre et Rectangle et définition du type Forme comme un variant, un choix, entre les deux précédents types.

La classe surface est ici un visiteur qui propose une surcharge de l'opérateur float operator(const T &t) pour chaque sous type T que peut contenir notre variant.

La fonction boost::apply_visitor est chargée d'appeler la bonne surcharge de l’opérateur operator() de surface en fonction du contenu du variant passé en second paramètre.

ADT : exemple plus poussé

Alors pourquoi je vous raconte tout cela. En premier lieu, j'aime bien. En second lieu, je me dis que cela peut vous intéresser à Haskell ou au moins vous sensibiliser à l'existence de ce type d'outil et peut-être que vous les utiliserez dans vos projets futurs. Par exemple, dans mon travail quotidien, je fais du C++, mais Haskell m'a beaucoup influencé et j'utilise tous les jours des boost::variant. Mon opinion là-dessus c'est que même si la syntaxe en C++ est verbeuse à souhait, cela sauve de certaines situations. Au final je pense que le code est plus robuste.

Pour finir, je vais vous donner un exemple d'un problème que je rencontre souvent dans des API et qui serait, à mon sens, mieux traité avec des ADT. C'est le cas traditionnel des valeurs sentinelles. Je fais un peu concurrence au journal de cette semaine sur la prévention de bug en Ocaml grâce à un typage plus strict. Là où ce journal s'intéressait à la définition d'un type synonyme mais incompatible, je m'intéresse à la définition d'un type totalement diffèrent permettant de représenter un contexte différent et ainsi de supprimer les cas impossibles et de rendre plus robustes les cas possibles.

Introduction

Pour appuyer mon propos, intéressons-nous à une libraire C++ que j'utilise tous les jours, OpenEXR, qui permet, entre autre, de lire et d'écrire des images au format EXR très utilisé dans l'industrie de l'image. La page github d'OpenEXR.

Cette librairie propose entre autre la lecture et l'écriture de fichiers via plusieurs threads, ce qui est une fonctionnalité très pratique quand l'écriture de plusieurs Go d'images en séquentiel est le facteur limitant sur des machines à 24 coeurs.

Le point de l'API qui nous intéresse est le suivant, les fonctions setGlobalThreadCount et globalThreadCount :

void    setGlobalThreadCount (int count);
int globalThreadCount();

Alors, si on lit la documentation, on peut voir que count dans setGlobalThreadCount sert à définir le nombre de thread utilisés globalement pour réaliser les écritures.

En cherchant un peu, on tombe sur ce commentaire :

  • The functions in this file query and control the total number of worker threads, which will be created globally for the whole library. Regardless of how many input or output files are opened simultaneously, the library will use at most this number of worker threads to perform all work. The default number of global worker threads is zero (i.e. single-threaded operation; everything happens in the thread that calls the library).

Traduction à l'arrache :

La fonction setGlobalThreadCount controle le nombre total de threads […] la bibliothèque utilisera au maximum ce nombre de threads. Le nombre par défaut est zéro, ce qui signifie que les opérations ne seront pas parallélisées.

On tombe aussi sur des discussion github intéressantes, dont je ne trouve plus le lien, désolé, traitant du moyen de fournir à setGlobalThreadCount une valeur qui correspond au nombre de thread système optimal (sans avoir à trouver celui-ci, on peut imaginer qu'il puisse changer à la volée en fonction de la charge de la machine, où dans un environnement virtualisé, en fonction des besoins), et les débats tournaient autour du fait de mettre -1 comme nombre de thread pour ce cas de figure. Ce n'est pas implémenté à ma connaissance dans openEXR, mais supposons que cela le soit.

Donc en gros, voici le comportement que nous pouvons imaginer pour setGlobalThreadCount(n) :

  • Si n > 0, alors c'est le nombre de thread utilisé globalement
  • Si n = 0, alors il n'y aura pas de multi threading
  • Si n = -1, alors on utilise le nombre de thread machine
  • Si n = -12, autre cas particulier que nous pourrions imaginer.

Le problème

Premier problème, en tant qu'utilisateur, je n'avais pas conscience de l'existence des cas 0, -1 et -12 sans lire le code source et la documentation d'OpenEXR.

Second problème, on va se planter, LARGEMENT, en beauté. Qui ? Les développeurs d'OpenEXR sans doute, et moi en utilisant leur API. Comment je le sais ? Parce que je me suis planté.

Où pouvons-nous nous planter ? Partout où le nombre global de thread est utilisé. Si le cas particulier 0, -1 et -12 n'est pas géré explicitement, et bien c'est un bug. Cela peut faire des choses marrantes, comme par exemple créer 0 thread de travail, et répartir le travail entre eux, ce qui donne un blocage de l'application.

Troisième problème, le futur. Même si c'est bien géré actuellement, que se passe-t-il demain lorsque quelqu'un va écrire une nouvelle fonction basée sur cette valeur sans connaître l'existence des cas particuliers qui existent ? Et bien cela va marcher, jusqu'à ce que quelqu'un utilise un cas particulier non traité, et là, pan. Ou si quelqu'un ajoute un nouveau cas particulier et ne le gère pas à tous les endroits nécessaires ?

On peut aussi se planter en passant une mauvaise constante par erreur. Imaginons qu'il existe dans le même espace de nom, une constante nommée "NoThreading", mais utilisée par une autre librairie, et ayant pour valeur magique un entier. Si celui-ci est négatif, c'est le drame, le comportement du programme est largement indéfini, au mieux c'est une erreur à l'exécution, au pire ?. Si celui-ci est positif, il faut espérer qu'il ne soit pas trop gros, car je n'aimerais pas créer 100000 threads sur ma machine de production, l'OS ne tiendrait pas.

Ce type de bug potentiel est la raison qui fait que la montée de version sur un gros projet logiciel est difficile du fait de la peur des régressions. Et même le meilleur système de test unitaire ne peut rien garantir à ce sujet.

Je passe aussi sur le problème de documentation et de lecture de code avec l'utilisation de constantes magiques en paramètre de fonction. setGlobalThreadCount(-123) n'est pas très informatif. Alors oui, cela se règle avec des définitions de constante, mais on peut encore se tromper, en définissant la constante à une mauvaise valeur, et rien ne force le développeur à utiliser la constante magique.

Ce problème est présent de partout, dans toutes les bibliothèques que nous utilisons, dans tous les langages que nous utilisons. Ceux-ci proposent des valeurs sentinelles. Python avec la méthode find des chaînes de caractères, qui renvoie -1 si la chaîne n'est pas trouvés (Il y a la version avec exception, c'est moins pire). C++ avec la fonction std::find qui retourne un itérateur vide en cas d'échec et rien qui ne vous force à tester cela.

La solution

La solution passe par la définition d'un type représentant le problème plus finement. Dans le cas d'OpenEXR, et si celui-ci était écrit en Haskell, nous pourrions avoir un type :

-- Word est en entier non signé
data PolitiqueThread = NombreFixé Word | NombreMaximumHardware | PasDeThreading | CasParticulier

Ainsi on pourrait appeller la fonction setGlobalThreadCount de différentes façon :

setGlobalThreadCount (NombreFixé 8)

setGlobalThreadCount NombreMaximumHardware

setGlobalThreadCount PasDeThreading

setGlobalThreadCount CasParticulier

Nous réglons en premier lieu le problème de documentation lors de l'appel. En tant qu'utilisateur, je suis forcé de voir que ce n'est pas juste un entier, et d'au moins voir la documentation avec la liste des cas, qui est automatiquement à jour. Le code est lisible et il est explicite que cette valeur n'est pas anodine.

Nous réglons aussi le problème lors de l'usage. On ne peut plus utiliser les valeurs -1 et -12 et 0 par erreur en considérant qu'il s'agit d'un nombre de thread et non pas d'un cas particulier, car le langage nous force à déconstruire et à gérer les différents cas de déconstruction. Observez comment 0, -1 et -12 n'apparaissent pas :

threadCount <- getGlobalThreadCount
case threadCount of
   NombreFixé n -> "nombre fixé à " ++ show n
   NombreMaximumHardware -> "Fait chauffer la ferme de calcul"
   PasDeThreading -> "Plutôt tranquille"
   CasParticulier -> "Celui-ci je ne l'aime pas"

Nous réglons aussi le problème de l'évolution future et de l'ajout de nouveau cas particulier, puisque le compilateur vas râler aux endroits où tous les cas ne sont pas gérés.

Le problème de passer une valeur qui n'a pas de sens par défaut n'existe plus non plus. Le type PolitiqueThread est incompatible avec un autre type. La seul erreur possible reste de passer un nombre qui n'a pas de sens à NombreFixé. Soit un nombre négatif, soit un nombre trop grand qui ferait exploser le système.

Je n'ai pas de solution parfaite à ce dernier problème. On peut en premier lieu cacher le constructeur NombreFixé et le remplacer par une fonction type :

nombreFixé n
 | n > 0 && n < maximumThread = NombreFixé (fromIntegral n)
 | otherwise = erreurRuntime ("n est trop bizarre: " ++ show n)

-- fromIntegral sert à convertir n qui est un entier signé vers un `Word`.

Cette solution limite la casse. Il y en d'autres. On pourrait par exemple utiliser de l'analyse statique de code en imposant des contraintes sur nombreFixé. Liquid Haskell sait faire cela, mais dans un contexte limité.

Conclusion

En profitant de la sortie de GHC 8.0.2, j'ai essayé de vous sensibiliser un peu plus au problème des valeurs sentinelles. À mon sens, ce problème est grave car il en découle du code peu lisible, peu "naturellement" documenté, peu robuste à l'évolution et peu robuste à l'utilisation normale par un développeur qui ne connaît pas par cœur les détails de l'API qu'il utilise. Une solution est l'emploi d'ADT, ceux-ci sont disponibles dans de nombreux langages, comme Haskell, Caml, Rust, Scala, Swift, … Et peuvent plus ou moins facilement être remplacés par des structures équivalentes à la simplicité près, comme avec les variant en C++.

Ce que je vous ai montré n'est qu'une partie de ce qui est possible avec les ADTs, et un lecteur motivé pourra commencer sa lecture sur la section de wikipedia consacrée aux ADT généralisés

Lire les commentaires

Le logiciel libre vu dans un contexte élargi

Par ǝpɐןƃu∀ nǝıɥʇʇɐW-ǝɹɹǝıԀ

Encore un journal Bookmark, mais totalement en rapport avec le libre cette fois :
Dans le cadre d'une série d'essais sur la notion de commun, un certain D. Temple propose ce joli texte (rien à voir avec l'illustration) ; narration diachronique du copyleft à travers l'histoire de monsieur Stallman, s'éclairant du contexte historique et philosophique. Pour ceux qui trouvent encore normal qu'autrui ai plus de pouvoir qu'eux mêmes sur leurs ordinateurs et leurs données (ce qui est le cas de la plupart d'entre nous, même utilisateurs exclusifs de logiciels libres), voici peut-être de quoi ouvrir un peu la réflexion sur un thème dépassant infiniment le seul domaine de l'informatique.
Plus qu'un simple rappel de l'histoire de la GPL, ce texte et l'essai dans lequel il s'inscrit montrent comment la notion de logiciel libre s'inscrit dans une réflexion plus globale qui engage l'avenir de l'humanité.

Désolé pour le côté lyrique et grandiloquent de cette présentation il fallait éviter le côté trop ouvertement je donne mon lien et --->[] ; pardon aussi aux collègues programmeurs que le texte assimile avec des dispositifs électromécaniques contrôlant laves-vaisselle et laves-linge :-).

Lire les commentaires

  • 20 janvier 2017 à 08:27

Google chiffrement de mail end to end

Par mouskouyouss

Bonjour à tous,

Il semblerait qu'il y ait quelques avancements concernant le chiffrement de bout en bout avec google mail.

Google vient de publier le projet keytransparency. Projet devant permettre de construire des clients (web)mail permettant le chiffrement de bout en bout pour monsieur et madame Michou.

Mais corrigez moi si j'ai mal compris.

Blog post à propos de key transparency
Application Chrome
Projet end-to-end

Vous en pensez quoi ?

Lire les commentaires

Faire un peu d'argent avec le logiciel Libre, l'après Wallabag...

Par matunixe

Bonjour'nal,

Alors que j'étais en pleine réflexion sur le devenir du projet Unixcorn et notamment son financement (dépendant actuellement à 98% de mon portefeuille) j'ai découvert l'article de blog de Nicolas Loeuillet, racontant le lancement de son entreprise wallabag.it : http://nicolas.loeuillet.org/billets/service-wallabag-it

Ça me titillais depuis bien longtemps, après avoir travaillé comme administrateur système dans une grande entreprise helvète, avoir repris les études en Bretagne, travailler à mon compte me faisais de l’œil et m'attirais grandement. Non pas grâce au statut, ou l'écosystème environnant (French-Tech-mes-fesses très peu pour moi) mais pour l'indépendance et la capacité de travailler d'un peu n'importe où sans contraintes.
J'ai donc contacté Nicolas et lui ai fait part de mon projet, le remerciant au passage pour son second article nous contant le début de son aventure, il sembla de suite enjoué et m'encouragea à me lancer. Voila ce qui fut fait en ce début de mois de janvier…

J'ai donc créé une micro-entreprise de vente de services, Whiskers Systems, axés pour l'instant autour de trois logiciels phares :

Je propose ensuite deux types d'offres, la première est l'hébergement de l'utilisateur sur notre propre infrastructure (sauf pour GitLab où il est possible de créer un compte gratuitement sur l'instance d'Unixcorn) et la seconde qui est l'installation, la configuration et la maintenance d'un serveur dédié avec la solution choisie.

J'ai donc créé un site internet, à base d'un "template" HTML simple (qui s’avérera être le même que celui de wallabag.it 🙈) et publié quelques offres avec la solution de payement française PayPlug. Celui-ci n'est pas encore terminé, les versions anglophones, néerlandaises et allemandes ne sont pas encore en ligne, pas encore de logo, etc.
Si vous avez des retours à faire ce sera avec plaisir, l'expérience étant toute nouvelle pour moi. 😀

Bonne visite !

Lire les commentaires

WhatsApp, sa porte discrète du fond et les backdoors de Signal

Par Apichat

Nous le savons tous WhatsApp n'a pas de backdoor, c'est d’ailleurs pour ça que son code source n'est pas public : ya rien à voir, tchatez.

Une très bonne explication est publiée sur le site de Reflet :

Il suffit à WhatsApp d’ajouter un nouvel appareil virtuel au compte de Bob, cet appareil recevra ainsi les messages qui lui sont destinés
De manière générale c’est le problèmes des systèmes où le lien entre personne physique et clef de chiffrement est établi et contrôlé par un acteur tiers, comme WhatsApp, ou en utilisant des mécanismes peu fiables, comme le contrôle du numéro de téléphone.
C’est également un problème par ex. chez Apple (iMessage) : Apple gère la liste des appareils liés à un compte et est donc en mesure d’ajouter un appareil « fantôme » au compte qui recevrai alors tous les messages qui lui sont destinés, et peut se faire passer pour ce compte.

Cependant, selon certains avis avisés de la Free Software Foundation Europe, il y aurait un certain nombre de backdoors présentes lors de l'utilisation du logiciel Signal (logiciel développé par Open Whisper Systems, entreprise qui a vendu à WhatsApp la mise en place de l'implémentation non-publique du protocole TextSecure-Axolotl-Signal_Protocol et qui nous assure qu'ils n'ont pas mis de backdoor dans le code-source non-publié de WhatsApp - logiciel qu'ils recommandent même si c'est leur concurrent).

Revenons-en à nos Systèmes Chuchotants (presque) Ouverts et parfois fermés et à ses portes d'accès inattendues. Ce que je trouve notable dans l'article de la FSFE :

Well beside the point about Signal being suggested by several widely known people: While Signal is indeed open-source, it is still not free software because it uses an external library that is not open. So every audit that works on the source code will fail to find security issues and backdoors in that externally included code – and this is where I want to start to look into Signal now.

[…]

Google Cloud Messaging and other METADATA
Well, you need to consider that Google knows a lot about everyone. The usual Android user will grant Google access to his contact database, list of installed apps, when which app is started, your current location, which text you write using the devices virtual keyboard (when using the “Gboard”) and even more.

[…]

So, when using Gboard, Google already knows the content of the messages shared, but not the recipient. And this is where the GCM data can be used. It shouldn’t be too hard to correlate the fact that one user is sending a message via Signal to another user receiving it.

[…]

With Gboard active, Google even knows the exact moment the message is sent (enter key is pressed). Of course there are millions of Signal users with different users likely sending messages in approximately the same time, but it’s no problem if you need multiple messages to be sure and there is another bunch of information further restricting the search space: both users likely have the phone number of the other one in their phone’s contact list and Google is usually well aware of the contents of your contact list.

[…]

Maps Integration
Critical about this is that the MapView view as used by Signal is just a wrapper that loads the actual MapView, by including code from the Google Play Services binary

[…]

The code is then executed in the Signal process, which includes access to the Signal history database and the crypto keys.

[…]

The Google Play Services binary can easily be updated in background through Google Play Store, even targeted to single users, and the updated code would become active inside Signal the moment you use it next time. Can it get worse? Yes. An apk update would be detectable to the user, but Google Play Services uses a dynamic module loading system (called Chimera and/or Dynamite) that seems to be capable of replacing the Maps implementation from a file not installed to the system, as long as it’s signed by Google.

[…]

But Signal is Forward secret, You can’t read old messages
The forward secrecy feature is only on the transport level. At both ends (in groupchats, all ends) the messages are available in plain text in form of a history. If you or the other(s) don’t wipe your chat history regularly, your history is still attackable. But this is how users want it, because it’s more user-friendly.

[…]

Et vous, qu'en pensez-vous ?

Lire les commentaires

Flash est en phase terminale!

Par Jehan

Un court journal qui fait suite à mon article sur Flash, sorti début novembre. Je disais alors — je me cite:

Il est à noter que GNU Gnash est un des projets listés comme prioritaires par la FSF et ce, depuis plusieurs années. Il serait probablement temps que cette liste de priorités soit donc revue à la lueur des dernières nouvelles et statistiques de ce format.

Bien que je tournai cela à l'époque comme un "conseil", il s'agissait bien entendu plutôt d'une sorte de prédiction puisqu'il n'y a pas de raison de penser que quiconque de la FSF me lise. ;-)
Je tombe aujourd'hui sur un news de la FSF, datée du 17 janvier 2017, indiquant une refonte complète de la liste des priorités. Ma première réaction est donc de vérifier si ma prédiction s'est accomplie et si donc je peux dès maintenant aller imprimer mes prospectus de marabout pour vendre mes services de futurologue.

Eh bien oui, alors que Gnash (la réimplémentation GNU de Flash) était la première listée (bon ils disent explicitement que l'ordre n'a pas d'importance, mais rusé comme je le suis, j'essaie d'appuyer mon point! Mon business plan de marabout en dépend!) dans les hautes priorités, il y a encore quelques jours à peine, la nouvelle liste ne contient tout simplement plus la moindre mention à Flash!

On dit quoi déjà pour les technologies libres et les standards ouverts? "D'abord ils vous ignorent, puis ils se moquent de vous, ensuite ils vous combattent, enfin vous gagnez." (souvent attribué à Gandhi, mais paraît que c'est une erreur)
Il paraît que c'est une stratégie gagnante de "l'activisme non-violent" (je découvre cela à l'instant en lisant WikiQuote). Mais il y a d'autres chemins par définition (notamment suivis par ceux qui ne suivent pas les chemins non-violents, donc). Celui suivi par les technologies propriétaires semble suivre le sens inverse que je tente d'articuler ainsi: "D'abord vous vous imposez (victoire ponctuelle), ensuite ils vous combattent, puis ils vous dénigrent, enfin ils vous ignorent avant que vous ne disparaissiez, oublié de tous." Nous sommes donc à l'avant-dernier stage: la technologie Flash est désormais ignorée par tout le monde. Ils sont quantités négligeables et tout le monde s'en fout.
Et c'est bien.

Voilà, vous pouvez maintenant commenter, ou bien même troller sur les autres priorités de la liste FSF si vous en avez envie! :-)

Lire les commentaires

2017 : l'année où Linux atteindra les 5% de parts de marché

Par NumOpen

Quelques prévisions sur http://www.techrepublic.com/article/open-source-predictions-for-2017/ :

  • Canonical abandonnera le marché de l'ordiphone et se concentrera sur les postes de travail et les serveurs.
  • ElementaryOS va devenir la deuxième distribution grand public sur le poste de travail, du fait de son ergonomie, juste derrière Linux Mint (je suis assez d'accord et j'ajoute qu'il faudra aussi surveiller Manjaro avec son système de mise à jour en continu bien pratique).
  • Microsoft va commencer à faire plus d'Open Source, y compris avec Windows.
  • Le marché des postes de travail sous Linux va passer la barre des 5%.
  • Android va continuer à écraser la concurrence et passer la barre des 90%.
  • Chrome OS et Android vont fusionner.
  • Linux va être de plus en plus ciblé par les attaques (et ça a déjà commencé) mais la communauté Linux va montrer sa réactivité.

Lire les commentaires

Remboursement de Windows 10 sur un PC portable Asus

Par ɹǝıʌıʃO

Howdy nal,

Je t’écris parce qu’après avoir trouvé le PC portable qui me convient, je me suis fait rembourser la licence de Windows 10 fournie avec lui. À l’époque je n’avais trouvé sur l’interweb que des retours d’expériences concernant des versions plus anciennes de Windows ; or, certaines choses ont changé, notamment la façon de préinstaller le système et sa clé de licence, et les procédures de l’époque ne s’appliquent donc plus telles quelles. Voici comment ça s’est passé.

Le 28 décembre 2016, je vais dans une grande enseigne d’électroménager commençant par D et finissant par Y pour y retirer un Asus E403SA-WX0067T. Comme nous sommes chez les geeks (et que c’est mon journal), je m’étends un peu sur les raisons de mon choix. Je voulais un portable bon marché, parce que je ne l’utiliserai pas de façon intensive. Je voulais un refroidissement passif et de la mémoire flash pour le stockage, parce que j’aime le silence. Je voulais au moins un port USB 3 type A et un type C, pour pouvoir brancher tout ce que je voulais, et une sortie pour écran ou projecteur. Le E403SA-WX0067T, en plus d’un charmant petit nom mélodieux, a tout cela (pour l’affichage externe c’est un port HDMI), plus un port USB 2, un lecteur de cartes SD, et une batterie qui donne environ 9 heures d’autonomie. Bien sûr, les caractéristiques ne sont pas à tomber par terre : processeur Pentium N3710 qui n’est pas un foudre de guerre, définition de 1366x768, mémoire flash eMMC (compter sur des performances du même ordre qu’un disque dur), mais ça me suffit. Et ce n’est pas cher : 399€, sachant que j’économise en plus 19,94€ (5% du prix) en allant le chercher en magasin. (Au passage, le PC est à nouveau disponible, mais à 449€). L’installation de Linux Mint 18.1 est franchement décevante : du premier coup, tout est tombé en marche. Pas de pilote à télécharger, de noyau à compiler, ni même un simple réglage à changer : rien, tout fonctionne impeccablement. La galère en installant Linux, c’était mieux à vent.

Me voilà donc pourvu d’un PC qui me va très bien et d’une licence de Windows 10 « famille » dont je n’ai pas l’utilité. Le 29 décembre, j’appelle donc le service après-vente Asus.

Première bonne nouvelle : visiblement, le SAV est au courant que ce remboursement est possible. La dame qui me répond n’est pas du tout surprise. Elle me demande ce que je compte installer à la place de Windows, je ne pense pas à lui demander pourquoi elle pose la question mais je suppose que c’est pour vérifier que je comprends ce que je demande. Elle me donne l’adresse électronique de la personne qui s’occupe des dossiers de ce genre, à qui j’envoie immédiatement un courriel. Le jour même, je reçois la liste des informations à envoyer : mes coordonnées, le numéro de série du PC, copie de la facture d’achat, copie de la carte de garantie, formulaire de remboursement sur lequel j’indique mon IBAN pour le virement. Je renvoie le tout le jour-même.

Deuxième courriel le lendemain pour m’envoyer le formulaire de demande de remboursement. C’est à cette étape que je certifie par écrit avoir effacé Windows sans avoir copié le système ni la licence. C’est également ce formulaire qui m’apprend le montant du remboursement : 50€, bonne nouvelle car sur la base de retours concernant Windows 8, je m’attendais plutôt à 40€. Je signe et renvoie tout ça dans la foulée.

Le 3 janvier, on m’informe que mon dossier est validé et transmis à la comptabilité. Le 20 janvier, je reçois un virement de 50€ de la part d’Asus \o/

Alors certes, la procédure pourrait être moins lourde. J’ai eu des papiers à remplir, imprimer, signer, numériser, envoyer, on m’a demandé plusieurs fois les mêmes informations… Bon. Mais le SAV Asus a immédiatement accepté ma demande, il n’a jamais été question d’immobiliser le PC ou de renvoyer quoi que ce soit (ni médias d’installation, ni certificat de licence…), et j’ai reçu mon remboursement moins de trois semaines après validation de mon dossier, délai qui me semble raisonnable (évidemment on peut toujours faire mieux…). Conclusion : je n’hésiterai pas, à l’avenir, à acheter un PC sous Windows chez eux.

Et franchement, 329,06€ pour ce PC, ce n’est vraiment pas cher :-)

Lire les commentaires

Création d'une revue scientifique libre et sceptique

Par astyan

Les scientifiques dépendent des journaux à revue par les pairs pour publier et partager leurs travaux. Ces journaux sont régulièrement critiqués pour plusieurs raisons telles que le prix pour lire ou soumettre une publication, le droit d'auteur souvent conservé par les maisons d'éditions, le fait que la revue par les pairs consiste en un échange privé entre les relecteurs et les auteurs ainsi que l'utilisation d'une métrique appelée facteur d'impact. Cette métrique encourage la publication dans des journaux avec un haut facteur d'impact qui sont ainsi devenus un oligopole.

En tant que libriste, sceptique et amateur de science j'ai commencé le développement d'un journal à revue par les pair sous forme de site web (sous licence libre) ayant pour but de s'attaquer aux problèmes listés précédemment. Je souhaite également augmenter la compréhension de la méthode scientifique et de la revue par les pairs par le public.
À moyen/long terme je souhaite travailler avec des scientifiques pour améliorer le journal afin de mettre en place des solutions bénéfiques pour les sciences (par exemple la publication de résultats négatifs, ou la publication de méthodologies avant de faire l’expérience).

Le code source est disponible sur github. J’accepte volontiers les critiques du code (je me doute qu'il est loin d'être parfait) et les contributions.
Pour en savoir plus vous pouvez en allant sur indiegogo (plateforme de financement participatif) où le projet est expliqué dans de plus amples détails.

NdM : Financement Indiegogo annulé. Voir ce commentaire plus bas.

Lire les commentaires

  • 23 janvier 2017 à 12:35

Le nouveau compilateur des Shaders DirectX sera Open Source

Par Nibel

Probablement dans un soucis de faire face à OpenGL/Vulkan et de rendre son offre plus attractive, Microsoft a annoncé le 23 janvier dernier rendre son nouveau compilateur de Shaders DirectX Open Source (basé sur Clang/LLVM).

Voici les sources sous licence MIT :
https://github.com/Microsoft/DirectXShaderCompiler

Lire les commentaires

À quoi sert un tableau de Karnaugh ?

Par finss

Cher journal,

Ce matin j'ai fait découvrir à mes élèves qu'une table de vérité pouvait être pliée et devenir un objet en 2 dimensions. Et si on utilise un binaire dit réfléchi (voire de Gray), il y a plein de propriétés qui en résultent.

Voir le regard d'un gamin qui comprend une chose et qui sait qu'il l'a comprise.

Être heureux.

Du coup je me suis posé la question bête et je te la transmets, tu penses quoi des tableaux de Karnaugh, cher journal ?

Nota-Bene : je sais que tu ne les utilises jamais

NdM : corrections orthographiques à la demande de l'auteur.

Lire les commentaires

  • 27 janvier 2017 à 22:35

adobe c'est bientôt mort ?

Par BAud

Sans vouloir revenir sur des sujets fâcheux comme flash mort sous Linux que Jehan a bien mis en avant mieux que moi dans son nourjal (phase terminale, parlant plus ou moins à certains d'entre nous, mais étant très claire)

Bin il y a la même pour le reste des projets qu'Adobe a légué la fondation Apache (AIR notamment, mais pas que) et une annonce sur slashdot concernant Director et Shockwave (la techno ayant donné l'extension en .swf : shockwave flash…)
https://tech.slashdot.org/story/17/01/27/1727202/adobe-is-killing-contribute-director-and-shockwave

Concernant, director, peu de monde l'a sans doute utilisé :

  • cela permettait de générer des présentations
  • je l'ai utilisé pour faire des CD ludo-éducatifs au siècle dernier, hormis quelques bugs, stait bien foutu

Concernant shockwave :

  • bin c'est un peu pour ça que youtube a aussi longtemps conservé des vidéos en flash, avant de passer en HTML5, ainsi que youpron et autres sites de grande audience souhaitant partager des vidéos sur le principe de l'interopérabilité que de la compatibilité (IE 4 est loin derrière nous, même microsoft a abandonné IE !)
  • beaucoup de jeux n'ont pas été portés, je croyais qu'il y avait un convertisseur ? (certains parlent de transpiler ?) corrigez-moi si je m'égare ? je crois que sur LinuxFr.org beaucoup de monde connaît de meilleures solutions

Hormis l'avenir d'Adobe (dont tout le monde se fout), comment voyez-vous le domaine de l'animation, surtout en HTML5 + SVG a priori (mais pas seulement). Je ne crois pas que le W3C ne participe à plus qu'à SVG en l'état, c'est pas forcément suffisant ?

Lire les commentaires

Stéganographie en Python avec Stegano

Par Cédric Bonhomme

Stegano est encore un module de stéganographie écrit en Python.

Ce journal a pour but de faire connaître un peu plus le projet mais surtout d'avoir des retours et tests.

Il est possible d'utiliser Stegano dans vos applications en tant que librairie ou en ligne de commande.
Différentes techniques sont utilisées. La classique technique LSB est implémentée.

Une variation de la technique LSB est également disponible. Il s'agit de décrire des ensembles afin de sélectionner les pixels qui seront utilisés pour cacher l'information. Voici un exemple:

Python 3.5.2 (default, Oct 20 2016, 10:10:10) 
[GCC 6.2.0 20161005] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from stegano import lsbset
>>> from stegano.lsbset import generators
>>> secret_message = "Hello World!"
>>> secret_image = lsbset.hide("./tests/sample-files/Lenna.png", secret_message, generators.eratosthenes())
>>> secret_image.save("./image.png")
>>> 
>>> message = lsbset.reveal("./image.png", generators.fibonacci())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/cedric/git/Stegano/stegano/lsbset/lsbset.py", line 115, in reveal
    for color in img_list[generated_number]:
IndexError: list index out of range
>>> 
>>> message = lsbset.reveal("./image.png", generators.eratosthenes())
>>> message
'Hello World!'

Cette technique limite la stéganalyse par parité (exemple).

Vous trouverez plus de détails dans la documentation.
Quelques générateurs d'ensemble sont disponibles. Vous pouvez évidemment en définir de nouveaux.

Pour l'usage en ligne de commande, vous trouverez des exemples ici. En plus du texte, vous pouvez également cacher des binaires dans une image.

J'accepte les contributions via GitHub si vous avez des générateurs intéressants (il est donc préférable d'utiliser des ensembles définis par des fonctions injectives). Pour les nouvelles fonctionnalités ou idées, il faut d'abord créer une issue avant de faire une pull request. Je n'accepte pas forcément tout, étant donné que j'ai encore quelques idées en têtes à tester.

Actuellement Stegano fonctionne avec Python 2.7 et Python 3.5. Cependant, je n'assure pas que Python 2 sera encore longtemps supporté. Je ne pense pas que ce soit aujourd'hui un gros problème.

Lire les commentaires

Epeios Meta Mail User Agent : le protocole IMAP.

Par Claude SIMON

Suite des aventures concernant le développement d'un MUA, dont le début vous est rapporté ici.

Après POP3 (RFC 1939) et Mail Internet Format (RFC 5322), voici le tour d'IMAP (RFC 3501 et 5530) d'être implémenté (partiellement pour le moment), et notamment la structure générale des messages qui sont échangés entre client et serveur IMAP, ce qui facilitera la future implémentation des commandes manquantes.

La prise en compte d'IMAP n'ayant qu'un impact réduit sur l'application en elle-même (ajout de la possibilité de définir un agent IMAP, en plus de POP3), telle qu'elle était présentée dans le journal ci-dessus, je vais en profiter pour m'attarder sur l'utilitaire mmuaq[.exe], que vous trouverez dans processing/mmuaq/ (le lien menant au téléchargement de l’application est donné tout en bas).

Cet utilitaire me sert à mettre au point le code avant qu'il ne soit mis en œuvre dans l'application proprement dite, ainsi qu'à dépister les éventuels bugs, compte tenu qu'un utilitaire en ligne de commande est plus facile à débuguer qu'un daemon.

Notez qu'il ne s'agit pas du client en ligne de commande du MUA ; ce rôle est dévolu à l'utilitaire mmuaqcli[.exe], qui se trouve dans frontend/CLI/.

Les commandes disponibles dans mmuaq correspondent aux tâches de base nécessaires à le gestion d'un MUA. Concernant IMAP, il y a deux types de commandes, d'une part les commandes bas-niveau, chacune de ces commandes correspondant à une commande du protocole IMAP (avec lancement de quelques commandes accessoires, comme celle consistant à se logger, sans quoi peu de commandes IMAP pourront s'exécuter sans erreur), et des commandes de plus haut niveau, qui seront les commandes appelées par le backend de l'application, et qui nécessitent l'appel à plusieurs commandes IMAP de base.

Vu ce pourquoi cet utilitaire a été conçu, il a une option --verbose qui affiche le contenu de ce qui transite entre le client et le serveur. Ça permet de voir où cela coince lorsqu'il y a un problème. Les informations affichées avec --verbose, ainsi que celles affichées sans --verbose pour les commandes bas-niveau, subissent un (léger) formatage pour faciliter leur lecture.

Ainsi, voici ce qu'un SELECT (avec un LOGIN et un LOGOUT) peut donner lorsqu'on se connecte avec telnet sur un serveur IMAP (-> signale les commandes qui ont été saisies dans la console) :

$ telnet <host> imap
Trying <ip>...
Connected to <host>.
Escape character is '^]'.
* OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE STARTTLS AUTH=PLAIN] Dovecot ready.
-> 0 LOGIN <username> <password>
0 OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE SORT SORT=DISPLAY THREAD=REFERENCES THREAD=REFS THREAD=ORDEREDSUBJECT MULTIAPPEND URL-PARTIAL CATENATE UNSELECT CHILDREN NAMESPACE UIDPLUS LIST-EXTENDED I18NLEVEL=1 CONDSTORE QRESYNC ESEARCH ESORT SEARCHRES WITHIN CONTEXT=SEARCH LIST-STATUS SPECIAL-USE BINARY MOVE] Logged in
-> 1 SELECT inbox
* FLAGS (\Answered \Flagged \Deleted \Seen \Draft)
* OK [PERMANENTFLAGS (\Answered \Flagged \Deleted \Seen \Draft \*)] Flags permitted.
* 661 EXISTS
* 0 RECENT
* OK [UNSEEN 14] First unseen.
* OK [UIDVALIDITY 1409248764] UIDs valid
* OK [UIDNEXT 15448] Predicted next UID
1 OK [READ-WRITE] Select completed (0.000 secs).
-> 2 LOGOUT
* BYE Logging out
2 OK Logout completed.
Connection closed by foreign host.

Et la même chose avec mmuaq (-> signale les commandes envoyées par le logiciel) :

$ mmuaq --imap-select inbox --verbose
Capability: IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE STARTTLS AUTH=PLAIN
OK: Dovecot ready.
-> 0 LOGIN <username> <password>
Capability: IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE SORT SORT=DISPLAY THREAD=REFERENCES THREAD=REFS THREAD=ORDEREDSUBJECT MULTIAPPEND URL-PARTIAL CATENATE UNSELECT CHILDREN NAMESPACE UIDPLUS LIST-EXTENDED I18NLEVEL=1 CONDSTORE QRESYNC ESEARCH ESORT SEARCHRES WITHIN CONTEXT=SEARCH LIST-STATUS SPECIAL-USE BINARY MOVE
OK: Logged in
-> 1 SELECT inbox
Flags: (\Answered \Flagged \Deleted \Seen \Draft)
PermanentFlags: (\Answered \Flagged \Deleted \Seen \Draft *)
OK: Flags permitted.
Exists: 661
Recent: 0
Unseen: 14
OK: First unseen.
UIDValidity: 1409248764
OK: UIDs valid
UIDNext: 15448
OK: Predicted next UID
Read-Write
OK: Select completed (0.000 secs).
-> 2 LOGOUT
Bye: Logging out
OK: Logout completed.

Et la même commande sans --verbose, ce qui permet d'obtenir juste les informations retournées par la commande demandée :

$ mmuaq --imap-select inbox
Flags: (\Answered \Flagged \Deleted \Seen \Draft)
PermanentFlags: (\Answered \Flagged \Deleted \Seen \Draft \*)
Exists: 661
Recent: 0
Unseen: 14
UIDValidity: 1409248764
UIDNext: 15448
Read-Write

Un exemple avec une commande de plus haut niveau (-> signale les commandes envoyées par le logiciel, les réponses étant encadrés par <- et --) :

$ mmuaq --imap-RFC822-text inbox 1 --verbose
<- * OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE AUTH=PLAIN] Dovecot ready.
--
-> 0 LOGIN <username> <password>
<- 0 OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE SORT SORT=DISPLAY THREAD=REFERENCES THREAD=REFS THREAD=ORDEREDSUBJECT MULTIAPPEND URL-PARTIAL CATENATE UNSELECT CHILDREN NAMESPACE UIDPLUS LIST-EXTENDED I18NLEVEL=1 CONDSTORE QRESYNC ESEARCH ESORT SEARCHRES WITHIN CONTEXT=SEARCH LIST-STATUS SPECIAL-USE BINARY MOVE] Logged in
--
-> 1 LIST "" ""
<- * LIST (\Noselect) "/" ""
1 OK List completed.
--
-> 2 SELECT inbox
<- * FLAGS (\Answered \Flagged \Deleted \Seen \Draft)
* OK [PERMANENTFLAGS (\Answered \Flagged \Deleted \Seen \Draft \*)] Flags permitted.
* 3 EXISTS
* 0 RECENT
* OK [UNSEEN 3] First unseen.
* OK [UIDVALIDITY 1483863075] UIDs valid
* OK [UIDNEXT 4] Predicted next UID
2 OK [READ-WRITE] Select completed (0.000 secs).
--
-> 3 FETCH 1 RFC822.TEXT
<- * 1 FETCH (RFC822.TEXT {15}
Body mail 1.1
)
3 OK Fetch completed.
--
Body mail 1.1

-> 4 LOGOUT
<- * BYE Logging out
4 OK Logout completed.
--

Pour pouvoir utiliser les commandes relatives à IMAP, il faut créer une section IMAP dans la section Parameters du fichier de configuration de l'utilitaire (mmuaq.xcfg) avec le contenu suivant :

 <IMAP HostPort="HOST_PORT">
  <Username>USERNAME</Username>
  <Password>PASSWORD</Password>
 </IMAP>

avec, pour HOST_PORT, l'adresse et le port du serveur IMAP, sous la forme addresse:port, et pour USERNAMEet PASSWORD, respectivement le login et le mot de passe d'un compte IMAP du serveur indiqué. À noter que les connexions sécurisées ne sont pas encore prises en charge, mais certains serveurs IMAP acceptent des connexions non sécurisées de localhost, et permettent facilement de définir une liste d'IPs desquelles ils acceptent des connexions non sécurisée.

Si vous souhaitez pouvoir vous connecter à plusieurs comptes IMAP différents, sans avoir à modifier à chaque fois le fichier de configuration, vous pouvez définir, dans le fichier de configuration, un Setup pour chaque compte IMAP, et l'activer en passant son identifiant à l'option -s|--setup, comme indiqué dans la page d'aide de l'utilitaire (mmuaq[.exe] --help). Pour en savoir plus à propos des setups, vous pouvez consulter cette page.

Cet utilitaire permet aussi de lancer des commandes (celles préfixées par --pop3-) sur un serveur POP3, sous réserve de créer une section POP3 dans la section Parameters du fichier de configuration, avec le contenu suivant :

 <POP3 HostPort="HOST_PORT">
  <Username>USERNAME</Username>
  <Password>PASSWORD</Password>
 </POP3>

HOST_PORT, USERNAMEet PASSWORD ont la même signification que pour la section IMAP, et vous pouvez naturellement également utiliser les setups pour cette section.

Voici la liste des commandes acceptées par mmuaq :

$ mmuaq --help --#Language=fr
Utilitaire d'aide au développement de l'application 'MMUAq'.

mmuaq --help
    Affiche cette page.
mmuaq --version
    Affiche la version du programme.
mmuaq --license
    Affiche la licence du programme.
mmuaq --b64-encode [<entrée> [<sortie>]]
    Encodage 'Base64'.
mmuaq --b64-decode [<entrée> [<sortie>]]
    Decodage 'Base64'.
mmuaq --next-tag [<étiquette>]
    Retourne l'étiquette 'IMAP' suivante.
mmuaq --pop3-list [-s|--setup=<setup>] [--verbose] [<courrier>]
    Affiche des informations sur les courriers d'un serveur 'POP3'.
mmuaq --pop3-retrieve [-s|--setup=<setup>] [--verbose] <courrier>
    Récupère un courrier d'un serveur 'POP3'.
mmuaq --pop3-top [-s|--setup=<setup>] [--verbose] <courrier> <lignes>
    Affiche le début d'un courrier d'un serveur 'POP3'.
mmuaq --pop3-uidl [-s|--setup=<setup>] [--verbose] [<courrier>]
    Affiche l'identifiant unique des courriers d'un serveur 'POP3'.
mmuaq --imap-capability [-s|--setup=<setup>] [--verbose]
    Lance la commande 'CAPABILITY' du protocole 'IMAP'.
mmuaq --imap-list [-s|--setup=<setup>] [--verbose] <reference> <mailbox>
    Lance la commande 'LIST' du protocole 'IMAP'.
mmuaq --imap-lsub [-s|--setup=<setup>] [--verbose] <reference> <mailbox>
    Lance la commande 'LSUB' du protocole 'IMAP'.
mmuaq --imap-select [-s|--setup=<setup>] [--verbose] <mailbox>
    Lance la commande 'SELECT' du protocole 'IMAP'.
mmuaq --imap-fetch [-s|--setup=<setup>] [--verbose] [--uid] <mailbox> <sequence set> <items>
    Lance la commande 'FETCH' du protocole 'IMAP'.
mmuaq --imap-folders [-s|--setup=<setup>] [--verbose] [<dossier>]
    Affiche les sous-dossiers d'un dossier 'IMAP'.
mmuaq --imap-RFC822 [-s|--setup=<setup>] [--verbose] [--uid] <dossier> <courrier>
    Affiche le 'RFC822' d'un courrier d'un dossier 'IMAP'.
mmuaq --imap-RFC822-size [-s|--setup=<setup>] [--verbose] [--uid] <dossier> <courrier>
    Affiche le 'RFC822.SIZE' d'un courrier d'un dossier 'IMAP'.
mmuaq --imap-RFC822-header [-s|--setup=<setup>] [--verbose] [--uid] <dossier> <courrier>
    Affiche le 'RFC822.HEADER' d'un courrier d'un dossier 'IMAP'.
mmuaq --imap-RFC822-text [-s|--setup=<setup>] [--verbose] [--uid] <dossier> <courrier>
    Affiche le 'RFC822.TEXT' d'un courrier d'un dossier 'IMAP'.
mmuaq --imap-uid [-s|--setup=<setup>] [--verbose] <dossier> <courrier>
    Affiche l'UID' d'un courrier d'un dossier 'IMAP'.
mmuaq --imap-mail-amount [-s|--setup=<setup>] [--verbose] <dossier>
    Affiche le nombre de courriers d'un dossier 'IMAP'.
mmuaq --show-header [<entrée> [<sortie>]]
    Affiche l'entête d'un courrier.
mmuaq --get-field <champ> [<entrée> [<sortie>]]
    Affiche le contenu du champ d'un courrier.

--verbose ('Parameters/Verbose'='true'):
    Affiche les données échangées avec le serveur.
--uid ('Parameters/IMAP/UID'='true'):
    Lance le version 'UID' de la commande ('UID commande ...').
<setup> ('Parameters/@Setup'):
    Identifiant du 'setup' à utiliser.
<entrée> ('Parameters/Input'):
    Nom du fichier d'entrée (utilisation de l'entrée standard si absent).
<sortie> ('Parameters/Output'):
    Nom du fichier de sortie (utilisation de la sortie standard si absent).
<courrier> ('Parameters/MailID'):
    Identifiant de courrier (nombre, séquence, 'UID'... selon le contexte).
<lignes> ('Parameters/Lines'):
    Nombre de lignes.
<champ> ('Parameters/FieldName'):
    Nom du champ.
<étiquette> ('Parameters/Tag'):
    Étiquette 'IMAP'.
<reference> ('Parameters/IMAP/Reference'):
    'reference name' tel que défini pour le protocole 'IMAP'.
<mailbox> ('Parameters/IMAP/Mailbox'):
    'mailbox name' tel que défini pour le protocole 'IMAP'.
<sequence set> ('Parameters/IMAP/SequenceSet'):
    'sequence set' tel que défini pour le protocole 'IMAP'.
<items> ('Parameters/IMAP/Items'):
    'message data item names or macro' tel que défini pour le protocole 'IMAP'.
<dossier> ('Parameters/IMAP/Folder'):
    Dossier 'IMAP' ; dossier racine si absent.

Comme l'utilitaire est publié sous licence AGPL, les sources sont bien entendu consultables. Pour ceux que cela intéresse, voici en particulier ceux qui prennent en charge les différents protocoles :
- RFC 3522 (Internet Message Format) : muaimf.h muaimf.cpp,
- RFC 3501 et 5530 (IMAP) muaimabs.h muaimabs.cpp: muaima.h muaima.cpp,
- RFC 1939 (POP3) : muapo3.h muapo3.cpp,

et les sources de l'utilitaire proprement dit, qui met en œuvre ces différents sources : mmuaq.

Pour la documentation, les sources, les binaires… de l'application en général (qui inclut l'utilitaire détaillé dans ce journal), c'est par ici.

Lire les commentaires

❌