Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 13/04/2014, à 11:02

Zakhar

Faire un md5 sur la Freebox V6 (Revolution)

La Freebox V6 disposent d'API qui permettent de faire un md5.

Chose étrange, cet API n'est pas exposé dans l'interface "Freebox OS".

Pourtant, pouvoir vérifier qu'un fichier a bien été copié sur la Freebox en récupérant un md5 est très intéressant, surtout quand on est à distance. En effet, en local on peut toujours relire le fichier copié et comparer/faire le md5, mais à distance, avec l'upload ADSL limité, cela s'avère bien vite limitant pour des gros fichiers.

J'ai donc construit un script qui vous permet de faire un md5 de fichiers sur la Freebox.

Le voici :

#! /bin/sh
#           DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
#                    Version 2, December 2004

# Copyright (C) 2014 Zakhar @ ubuntu.fr

# Everyone is permitted to copy and distribute verbatim or modified
# copies of this license document, and changing it is allowed as long
# as the name is changed.

#            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
#   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

#  0. You just DO WHAT THE FUCK YOU WANT TO.

# This program is free software. It comes without any warranty, to
#      the extent permitted by applicable law. You can redistribute it
#      and/or modify it under the terms of the Do What The Fuck You Want
#      To Public License, Version 2, as published by Sam Hocevar. See
#      http://www.wtfpl.net/ for more details.
#===========================================================
#
# Fonction :
# ----------
# Réalise un md5 du/des fichier(s) passé(s) en paramètre.
# Ce script fonctionne uniquement avec une Freebox V6 (Révolution).
#
# Important :
# -----------
# Vous devez avoir autorisé votre application et inscrite dans les
# variables ci-dessous app_id/app_token
#
# Usage :
# -------
#  fb5sum Fichier [...Fichiers]
#
# Version : 1.0
# -------
#
# Tested : Ubuntu Precise, Synology DSM4.2 (+coreutils)
# ------
#
# Date : 2014-04-13
# -----
#
# Author : Zakhar
# ------
#
# History : 
# -------
#
# TODO:
# Il faudrait automatiser l'autorisation de l'appli... mais comme c'est l'affaire d'une seule commande :
# curl http://mafreebox.freebox.fr/api/v1/login/authorize -d '{"app_id":"fbxmd5","app_name":"Freebox MD5","app_version":"1.0","device_name":"Terminal"}'
#
# TODO
# On pourrait aussi afficher le temps restant et la vitesse de traitement, comme c'est affiché dans le panneau des tâches.

freebox="http://mafreebox.freebox.fr"  #IP de la freebox
app_id="fbxmd5"                        #Valeur indiquée lors de l'autorisation en local
app_token="Mettez votre app_token ici" #Valeur retournée par la freebox lors de l'autorisation en local
session_token=''
id=0
cleaning=0
status=0


##################        Usage          ##################
  if [ -z "${1}" ]; then
    echo "Usage   : fb5sum Fichier [...Fichiers]"
    echo "Fichier : chemin complet du fichier ex. /Disque dur/Téléchargement/fichier.txt"
    exit 1
  fi


################## Nettoyage à la sortie ##################
cleanup()
{
  cleaning=1
  if [ -n "${session_token}" ]; then
    [ ${id} -ne 0 ] && deleteTask 

    ###################       Logout        ###################
    out="$(curl -i -s "${freebox}/api/v${version}/login/logout" -H "X-Fbx-App-Auth: ${session_token}" -d '')"
    session_token=''
    successIsTrue "${out}" 'Erreur au logout !'

  fi
  exit $status
}

trap cleanup HUP INT QUIT ABRT TERM EXIT

################## Test HTTP 200         ##################
## @param 1: output de curl
## @param 2: chaine à afficher en cas d'erreur

http200()
{
  if ! printf '%s' "${1}" | head -n1 | grep -q 'HTTP/1.1 200 OK'; then
    echo
    echo "${2}"
    echo "${1}"
    status=1
    [ ${cleaning} -eq 0 ] && exit 1
  fi
}


################## Test JSON success     ##################
## @param 1: output de curl
## @param 2: chaine à afficher en cas d'erreur

successIsTrue()
{
  http200 "${1}" "${2}"
  if ! printf '%s' "${1}" | grep -q '"success":true'; then
    echo
    echo "${2}"
    echo "${1}"
    status=1
    [ ${cleaning} -eq 0 ] && exit 1
  fi
}


################## Test chaine non vide  ##################
## @param 1: chaine à tester
## @param 2: chaine à afficher en cas d'erreur
## @param 3: output de curl

notEmpty()
{
  if [ -z "${1}" ]; then
    echo
    echo "${2}"
    echo "${3}"
    status=1
    [ ${cleaning} -eq 0 ] && exit 1
  fi
}


################### Suppression de la tâche ###############

deleteTask()
{
  out="$(curl -i -s -X DELETE "${freebox}/api/v${version}/fs/tasks/${id}" -H "X-Fbx-App-Auth: ${session_token}")"
  id=0
  successIsTrue "${out}" "Erreur suppression de la tâche."
}



###########################################################
################## Début de la connexion ##################
###########################################################


################## Lecture de la version ##################

  printf "Connexion ... 1/3"
  out="$(curl -i -s "${freebox}/api_version")"
  http200 "${out}" "Erreur HTTP."

  version="$(printf "%s" "${out}" | sed  '/api_version/ !d;s/.*api_version":"//;s/\([0-9]*\)\..*/\1/')"
  notEmpty "${version}" "Impossible de lire la version." "${out}"



################## Obtention du challenge #################
  printf "\b\b\b2/3"
  out="$(curl -i -s "${freebox}/api/v${version}/login")"
  successIsTrue "${out}" "Erreur, impossible d'initier un login."

  challenge="$(printf "%s" "${out}" | sed '/"success"/ !d;s|.*"challenge":"||;s|",.*||;s|\\/|/|g')"
  notEmpty "${challenge}" "Impossible d'obtenir le challenge." "${out}"


#### Création du password = hash($challenge,$app_token) ######
  password="$(printf '%s' "${challenge}" | openssl dgst -sha1 -hmac $app_token | sed 's/(stdin)= //')"


################## Ouverture de la session ################
  printf "\b\b\b3/3"
  out="$(curl -i -s "${freebox}/api/v${version}/login/session/" -d "{\"app_id\":\"${app_id}\",\"password\":\"${password}\"}")"
  successIsTrue "${out}" "Erreur, impossible d'ouvrir la session."

  session_token="$(printf '%s' "${out}" | sed '/"success"/ !d;s|.*"session_token":"||;s|",.*||;s|\\/|/|g')"
  notEmpty "${session_token}" 'Impossible de lire le token de session.' "${out}"

  printf "\b\b\bOK \n"


###########################################################
################### fin de la connexion ###################
###########################################################


###########################################################
################## Calcul des MD5        ##################
###########################################################

  for f in "$@"; do

    ################## Soumission de la tâche #################
    out="$(curl -i -s "${freebox}/api/v${version}/fs/hash/" -H "X-Fbx-App-Auth: ${session_token}" -d "{\"src\":\"$(printf '%s' "${f}" | base64 -w0)\",\"hash_type\":\"md5\"}")"
    successIsTrue "${out}" 'Soumission de la tâche impossible.'

    id="$(printf '%s' "${out}" | sed '/"success"/ !d;s|.*"id":||;s|,.*||')"
    notEmpty "${id}" "Impossible de lire l'ID de la tâche." "${out}"

    while :; do

      ########### Récupération de l'avancement ###############
      out="$(curl -i -s "${freebox}/api/v${version}/fs/tasks/${id}" -H "X-Fbx-App-Auth: ${session_token}")"
      successIsTrue "${out}" "Lecture de l'avancement de la tâche impossible."

      progress="$(printf '%s' "${out}" | sed '/"success"/ !d;s|.*"progress":||;s|}.*||')"
      notEmpty "${progress}" 'Impossible de lire la progression de la tâche.' "${out}"
      printf "\b\b\b%2u%%" $progress

      state="$(printf '%s' "${out}" | sed '/"success"/ !d;s|.*"state":"||;s|",.*||')"
      notEmpty "${state}" "Impossible de lire l'état de la tâche." "${out}"

      case "${state}" in
        'queued')  printf "\rEn attente."
                   ;;
        'running') printf "\rEn cours : %2u%% " ${progress}
                   ;;
        'paused')  printf "\rEn pause : %2u%% " ${progress}
                   ;;
        'done')    printf "\rTerminé  : 100%%"
                   break
                   ;;
        'failed')  printf "\rEchoué.        "
                   break
                   ;;
        *)         printf "\rEtat inconnu : %s" "${state}"
                   break
      esac

      sleep 2
    done

    if [ "${state}" = 'done' ]; then
      ################## Lecture du résultat (md5) ###############
      out="$(curl -i -s "${freebox}/api/v${version}/fs/tasks/${id}/hash" -H "X-Fbx-App-Auth: ${session_token}")"
      successIsTrue "${out}" "Erreur lecture du hash."

      hash="$(printf '%s' "${out}" | sed '/"success"/ !d;s|.*"result":"||;s|".*||')"
      printf "\r%s  %s\n" "${hash}" "${f}"

    else
      ################## Lecture de la cause d'erreur ############
      error="$(printf '%s' "${out}" | sed '/"success"/ !d;s|.*"error":"||;s|",.*||')"
      printf  "\rEchec: %s  %s\n" "${error}" "${f}"

    fi

    deleteTask
  done

L'usage est simple, une fois que vous avez récupéré le source et que vous l'avez rendu exécutable, vous lancez avec :

./fbxmd5.sh 'Disque dur/Téléchargement/mon_Fichier.iso'

IMPORTANT: au préalable, vous devez autoriser l'application et obtenir un 'token'.
Pour cela, exécutez la ligne de commande indiquée en commentaire dans les TODO, autorisez l'application, récupérez le token affiché et mettez le dans la variable app_token.
Au niveau des autorisations, vous pouvez restreindre l'application à l'accès aux fichiers seulement, cela suffit.

Testé sur Ubuntu et sur Synology (DSM4.2, nécessite l'installation des coreutils)


"A computer is like air conditioning: it becomes useless when you open windows." (Linus Torvald)

Hors ligne

#2 Le 03/05/2017, à 21:29

Zakhar

Re : Faire un md5 sur la Freebox V6 (Revolution)

Depuis la V4 des APIs il y a un "bug bizarre" dans la soumission du hash.

Voir déclaration ici : https://dev.freebox.fr/bugs/task/21461

Le bug fait que 2 fois sur 3 la soumission de la tâche échoue. En réalité la soumission fonctionne si le base64 du path à contrôler se termine par '==', sinon elle échoue !..

Le fait de rajouter dans la requête de soumission le header Content-type: application/json, permet de faire fonctionner la soumission de tâche dans 100% des cas. L'ensemble des autres requêtes n'ont pas besoin de ce header.

Il faut donc remplacer, après le commentaire ################## Soumission de la tâche #################, la ligne qui suit par

par :

    ################## Soumission de la tâche #################
    out="$(curl -i -s "${freebox}/api/v${version}/fs/hash/" \
                   -H "Content-Type: application/json"      \
                   -H "X-Fbx-App-Auth: ${session_token}"    \
                   -d "{\"src\":\"$(printf '%s' "${f}" | base64 -w0)\",\"hash_type\":\"md5\"}" \
          )"

Le reste fonctionne inchangé


"A computer is like air conditioning: it becomes useless when you open windows." (Linus Torvald)

Hors ligne

#3 Le 04/05/2017, à 13:21

Zakhar

Re : Faire un md5 sur la Freebox V6 (Revolution)

# Version 1.1

  • Passage en https

  • Rajout des headers Content-type: application/json (quand nécessaire)

Fichier de certificats racine. Note: par rapport à la documentation, ce fichier contient en plus le certificat le Let's Encrypt pour le cas où vous auriez 'nommé' votre FreeboxOS.
Par défaut : freebox.pem dans le même répertoire que le script.

##
## CA Root Certificates for Freebox
##
## https://dev.freebox.fr/sdk/os/
##


Freebox ECC Root CA
====================
-----BEGIN CERTIFICATE-----
MIICWTCCAd+gAwIBAgIJAMaRcLnIgyukMAoGCCqGSM49BAMCMGExCzAJBgNVBAYT
AkZSMQ8wDQYDVQQIDAZGcmFuY2UxDjAMBgNVBAcMBVBhcmlzMRMwEQYDVQQKDApG
cmVlYm94IFNBMRwwGgYDVQQDDBNGcmVlYm94IEVDQyBSb290IENBMB4XDTE1MDkw
MTE4MDIwN1oXDTM1MDgyNzE4MDIwN1owYTELMAkGA1UEBhMCRlIxDzANBgNVBAgM
BkZyYW5jZTEOMAwGA1UEBwwFUGFyaXMxEzARBgNVBAoMCkZyZWVib3ggU0ExHDAa
BgNVBAMME0ZyZWVib3ggRUNDIFJvb3QgQ0EwdjAQBgcqhkjOPQIBBgUrgQQAIgNi
AASCjD6ZKn5ko6cU5Vxh8GA1KqRi6p2GQzndxHtuUmwY8RvBbhZ0GIL7bQ4f08ae
JOv0ycWjEW0fyOnAw6AYdsN6y1eNvH2DVfoXQyGoCSvXQNAUxla+sJuLGICRYiZz
mnijYzBhMB0GA1UdDgQWBBTIB3c2GlbV6EIh2ErEMJvFxMz/QTAfBgNVHSMEGDAW
gBTIB3c2GlbV6EIh2ErEMJvFxMz/QTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB
/wQEAwIBhjAKBggqhkjOPQQDAgNoADBlAjA8tzEMRVX8vrFuOGDhvZr7OSJjbBr8
gl2I70LeVNGEXZsAThUkqj5Rg9bV8xw3aSMCMQCDjB5CgsLH8EdZmiksdBRRKM2r
vxo6c0dSSNrr7dDN+m2/dRvgoIpGL2GauOGqDFY=
-----END CERTIFICATE-----

Freebox Root CA
===============
-----BEGIN CERTIFICATE-----
MIIFmjCCA4KgAwIBAgIJAKLyz15lYOrYMA0GCSqGSIb3DQEBCwUAMFoxCzAJBgNV
BAYTAkZSMQ8wDQYDVQQIDAZGcmFuY2UxDjAMBgNVBAcMBVBhcmlzMRAwDgYDVQQK
DAdGcmVlYm94MRgwFgYDVQQDDA9GcmVlYm94IFJvb3QgQ0EwHhcNMTUwNzMwMTUw
OTIwWhcNMzUwNzI1MTUwOTIwWjBaMQswCQYDVQQGEwJGUjEPMA0GA1UECAwGRnJh
bmNlMQ4wDAYDVQQHDAVQYXJpczEQMA4GA1UECgwHRnJlZWJveDEYMBYGA1UEAwwP
RnJlZWJveCBSb290IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA
xqYIvq8538SH6BJ99jDlOPoyDBrlwKEp879oYplicTC2/p0X66R/ft0en1uSQadC
sL/JTyfgyJAgI1Dq2Y5EYVT/7G6GBtVH6Bxa713mM+I/v0JlTGFalgMqamMuIRDQ
tdyvqEIs8DcfGB/1l2A8UhKOFbHQsMcigxOe9ZodMhtVNn0mUyG+9Zgu1e/YMhsS
iG4Kqap6TGtk80yruS1mMWVSgLOq9F5BGD4rlNlWLo0C3R10mFCpqvsFU+g4kYoA
dTxaIpi1pgng3CGLE0FXgwstJz8RBaZObYEslEYKDzmer5zrU1pVHiwkjsgwbnuy
WtM1Xry3Jxc7N/i1rxFmN/4l/Tcb1F7x4yVZmrzbQVptKSmyTEvPvpzqzdxVWuYi
qIFSe/njl8dX9v5hjbMo4CeLuXIRE4nSq2A7GBm4j9Zb6/l2WIBpnCKtwUVlroKw
NBgB6zHg5WI9nWGuy3ozpP4zyxqXhaTgrQcDDIG/SQS1GOXKGdkCcSa+VkJ0jTf5
od7PxBn9/TuN0yYdgQK3YDjD9F9+CLp8QZK1bnPdVGywPfL1iztngF9J6JohTyL/
VMvpWfS/X6R4Y3p8/eSio4BNuPvm9r0xp6IMpW92V8SYL0N6TQQxzZYgkLV7TbQI
Hw6v64yMbbF0YS9VjS0sFpZcFERVQiodRu7nYNC1jy8CAwEAAaNjMGEwHQYDVR0O
BBYEFD2erMkECujilR0BuER09FdsYIebMB8GA1UdIwQYMBaAFD2erMkECujilR0B
uER09FdsYIebMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMA0GCSqG
SIb3DQEBCwUAA4ICAQAZ2Nx8mWIWckNY8X2t/ymmCbcKxGw8Hn3BfTDcUWQ7GLRf
MGzTqxGSLBQ5tENaclbtTpNrqPv2k6LY0VjfrKoTSS8JfXkm6+FUtyXpsGK8MrLL
hZ/YdADTfbbWOjjD0VaPUoglvo2N4n7rOuRxVYIij11fL/wl3OUZ7GHLgL3qXSz0
+RGW+1oZo8HQ7pb6RwLfv42Gf+2gyNBckM7VVh9R19UkLCsHFqhFBbUmqwJgNA2/
3twgV6Y26qlyHXXODUfV3arLCwFoNB+IIrde1E/JoOry9oKvF8DZTo/Qm6o2KsdZ
dxs/YcIUsCvKX8WCKtH6la/kFCUcXIb8f1u+Y4pjj3PBmKI/1+Rs9GqB0kt1otyx
Q6bqxqBSgsrkuhCfRxwjbfBgmXjIZ/a4muY5uMI0gbl9zbMFEJHDojhH6TUB5qd0
JJlI61gldaT5Ci1aLbvVcJtdeGhElf7pOE9JrXINpP3NOJJaUSueAvxyj/WWoo0v
4KO7njox8F6jCHALNDLdTsX0FTGmUZ/s/QfJry3VNwyjCyWDy1ra4KWoqt6U7SzM
d5jENIZChM8TnDXJzqc+mu00cI3icn9bV9flYCXLTIsprB21wVSMh0XeBGylKxeB
S27oDfFq04XSox7JM9HdTt2hLK96x1T7FpFrBTnALzb7vHv9MhXqAT90fPR/8A==
-----END CERTIFICATE-----

Let'sEncryptAuthorityX3
=======================
-----BEGIN CERTIFICATE-----
MIIEkjCCA3qgAwIBAgIQCgFBQgAAAVOFc2oLheynCDANBgkqhkiG9w0BAQsFADA/
MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
DkRTVCBSb290IENBIFgzMB4XDTE2MDMxNzE2NDA0NloXDTIxMDMxNzE2NDA0Nlow
SjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUxldCdzIEVuY3J5cHQxIzAhBgNVBAMT
GkxldCdzIEVuY3J5cHQgQXV0aG9yaXR5IFgzMIIBIjANBgkqhkiG9w0BAQEFAAOC
AQ8AMIIBCgKCAQEAnNMM8FrlLke3cl03g7NoYzDq1zUmGSXhvb418XCSL7e4S0EF
q6meNQhY7LEqxGiHC6PjdeTm86dicbp5gWAf15Gan/PQeGdxyGkOlZHP/uaZ6WA8
SMx+yk13EiSdRxta67nsHjcAHJyse6cF6s5K671B5TaYucv9bTyWaN8jKkKQDIZ0
Z8h/pZq4UmEUEz9l6YKHy9v6Dlb2honzhT+Xhq+w3Brvaw2VFn3EK6BlspkENnWA
a6xK8xuQSXgvopZPKiAlKQTGdMDQMc2PMTiVFrqoM7hD8bEfwzB/onkxEz0tNvjj
/PIzark5McWvxI0NHWQWM6r6hCm21AvA2H3DkwIDAQABo4IBfTCCAXkwEgYDVR0T
AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwfwYIKwYBBQUHAQEEczBxMDIG
CCsGAQUFBzABhiZodHRwOi8vaXNyZy50cnVzdGlkLm9jc3AuaWRlbnRydXN0LmNv
bTA7BggrBgEFBQcwAoYvaHR0cDovL2FwcHMuaWRlbnRydXN0LmNvbS9yb290cy9k
c3Ryb290Y2F4My5wN2MwHwYDVR0jBBgwFoAUxKexpHsscfrb4UuQdf/EFWCFiRAw
VAYDVR0gBE0wSzAIBgZngQwBAgEwPwYLKwYBBAGC3xMBAQEwMDAuBggrBgEFBQcC
ARYiaHR0cDovL2Nwcy5yb290LXgxLmxldHNlbmNyeXB0Lm9yZzA8BgNVHR8ENTAz
MDGgL6AthitodHRwOi8vY3JsLmlkZW50cnVzdC5jb20vRFNUUk9PVENBWDNDUkwu
Y3JsMB0GA1UdDgQWBBSoSmpjBH3duubRObemRWXv86jsoTANBgkqhkiG9w0BAQsF
AAOCAQEA3TPXEfNjWDjdGBX7CVW+dla5cEilaUcne8IkCJLxWh9KEik3JHRRHGJo
uM2VcGfl96S8TihRzZvoroed6ti6WqEBmtzw3Wodatg+VyOeph4EYpr/1wXKtx8/
wApIvJSwtmVi4MFU5aMqrSDE6ea73Mj2tcMyo5jMd6jmeWUHK8so/joWUoHOUgwu
X4Po1QYz+3dszkDqMp4fklxBwXRsW10KXzPMTZ+sOPAveyxindmjkW8lGy+QsRlG
PfZ+G6Z6h7mjem0Y+iWlkYcV4PIWL1iwBi8saCbGS5jN2p8M+X+Q7UNKEkROb3N6
KOqkqm57TH2H3eDJAkSnh6/DNFu0Qg==
-----END CERTIFICATE-----

Le script:

#! /bin/sh
#           DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
#                    Version 2, December 2004

# Copyright (C) 2014 Zakhar @ ubuntu.fr

# Everyone is permitted to copy and distribute verbatim or modified
# copies of this license document, and changing it is allowed as long
# as the name is changed.

#            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
#   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

#  0. You just DO WHAT THE FUCK YOU WANT TO.

# This program is free software. It comes without any warranty, to
#      the extent permitted by applicable law. You can redistribute it
#      and/or modify it under the terms of the Do What The Fuck You Want
#      To Public License, Version 2, as published by Sam Hocevar. See
#      http://www.wtfpl.net/ for more details.
#===========================================================
#
# Fonction :
# ----------
# Réalise un md5 du/des fichier(s) passé(s) en paramètre.
# Ce script fonctionne uniquement avec une Freebox V6 (Révolution).
#
# Important :
# -----------
# Vous devez avoir autorisé votre application et inscrite dans les
# variables ci-dessous app_id/app_token
#
# Usage :
# -------
#  fb5sum Fichier [...Fichiers]
#
# Version : 1.1
# -------
#
# Tested : Ubuntu Precise/Xenial
# ------
#
# Date : 2017-05-04
# -----
#
# Author : Zakhar
# ------
#
# History : 
# -------
#
# 207-05-04 1.1 : Rajout du header Content-type: application/json dans la soumission du hash
#                           Passage en https
# TODO:
# Il faudrait automatiser l'autorisation de l'appli... mais comme c'est l'affaire d'une seule commande :
# curl http://mafreebox.freebox.fr/api/v1/login/authorize -d '{"app_id":"fbxmd5","app_name":"Freebox MD5","app_version":"1.0","device_name":"Terminal"}'
#

freebox="https://mafreebox.freebox.fr"  #IP de la freebox
app_id="fbxmd5"                        #Valeur indiquée lors de l'autorisation en local
app_token="Mettez votre app_token ici" #Valeur retournée par la freebox lors de l'autorisation en local
ca_pem="$(dirname ${0})/freebox.pem"
CURL="curl -i -s --cacert ${ca_pem}"
session_token=''
id=0
cleaning=0
status=0


##################        Usage          ##################
  if [ -z "${1}" ]; then
    echo "Usage   : fb5sum Fichier [...Fichiers]"
    echo "Fichier : chemin complet du fichier ex. '/Disque dur/Téléchargement/fichier.txt'"
    exit 1
  fi


################## Nettoyage à la sortie ##################
cleanup()
{
  cleaning=1
  if [ -n "${session_token}" ]; then
    [ ${id} -ne 0 ] && deleteTask 

    ###################       Logout        ###################
    out="$(curl -i -s "${freebox}/api/v${version}/login/logout" -H "X-Fbx-App-Auth: ${session_token}" -d '')"
    session_token=''
    successIsTrue "${out}" 'Erreur au logout !'

  fi
  exit $status
}

trap cleanup HUP INT QUIT ABRT TERM EXIT

################## Test HTTP 200         ##################
## @param 1: output de curl
## @param 2: chaine à afficher en cas d'erreur

http200()
{
  if ! printf '%s' "${1}" | head -n1 | grep -q 'HTTP/1.1 200 OK'; then
    echo
    echo "${2}"
    echo "${1}"
    status=1
    [ ${cleaning} -eq 0 ] && exit 1
  fi
}


################## Test JSON success     ##################
## @param 1: output de curl
## @param 2: chaine à afficher en cas d'erreur

successIsTrue()
{
  http200 "${1}" "${2}"
  if ! printf '%s' "${1}" | grep -q '"success":true'; then
    echo
    echo "${2}"
    echo "${1}"
    status=1
    [ ${cleaning} -eq 0 ] && exit 1
  fi
}


################## Test chaine non vide  ##################
## @param 1: chaine à tester
## @param 2: chaine à afficher en cas d'erreur
## @param 3: output de curl

notEmpty()
{
  if [ -z "${1}" ]; then
    echo
    echo "${2}"
    echo "${3}"
    status=1
    [ ${cleaning} -eq 0 ] && exit 1
  fi
}


################### Suppression de la tâche ###############

deleteTask()
{
  out="$(${CURL} -X DELETE "${freebox}/api/v${version}/fs/tasks/${id}" -H "X-Fbx-App-Auth: ${session_token}")"
  id=0
  successIsTrue "${out}" "Erreur suppression de la tâche."
}



###########################################################
################## Début de la connexion ##################
###########################################################


################## Lecture de la version ##################

  printf "Connexion ... 1/3"
  out="$(${CURL} "${freebox}/api_version")"
  http200 "${out}" "Erreur HTTP."

  version="$(printf "%s" "${out}" | sed  '/api_version/ !d;s/.*api_version":"//;s/\([0-9]*\)\..*/\1/')"
  notEmpty "${version}" "Impossible de lire la version." "${out}"



################## Obtention du challenge #################
  printf "\b\b\b2/3"
  out="$(${CURL} "${freebox}/api/v${version}/login")"
  successIsTrue "${out}" "Erreur, impossible d'initier un login."

  challenge="$(printf "%s" "${out}" | sed '/"success"/ !d;s|.*"challenge":"||;s|",.*||;s|\\/|/|g')"
  notEmpty "${challenge}" "Impossible d'obtenir le challenge." "${out}"


#### Création du password = hash($challenge,$app_token) ######
  password="$(printf '%s' "${challenge}" | openssl dgst -sha1 -hmac $app_token | sed 's/(stdin)= //')"


################## Ouverture de la session ################
  printf "\b\b\b3/3"
  out="$(${CURL} "${freebox}/api/v${version}/login/session/" \
                 -H "Content-Type: application/json"         \
                 -d "{\"app_id\":\"${app_id}\",\"password\":\"${password}\"}")"
  successIsTrue "${out}" "Erreur, impossible d'ouvrir la session."

  session_token="$(printf '%s' "${out}" | sed '/"success"/ !d;s|.*"session_token":"||;s|",.*||;s|\\/|/|g')"
  notEmpty "${session_token}" 'Impossible de lire le token de session.' "${out}"

  printf "\b\b\bOK \n"

###########################################################
################### fin de la connexion ###################
###########################################################


###########################################################
################## Calcul des MD5        ##################
###########################################################

  for f in "$@"; do

    ################## Soumission de la tâche #################
    out="$(${CURL} "${freebox}/api/v${version}/fs/hash/" \
                   -H "Content-Type: application/json"   \
                   -H "X-Fbx-App-Auth: ${session_token}" \
                   -d "{\"src\":\"$(printf '%s' "${f}" | base64 -w0)\",\"hash_type\":\"md5\"}" \
          )"
    successIsTrue "${out}" 'Soumission de la tâche impossible.'

    id="$(printf '%s' "${out}" | sed '/"success"/ !d;s|.*"id":||;s|,.*||')"
    notEmpty "${id}" "Impossible de lire l'ID de la tâche." "${out}"

    while :; do

      ########### Récupération de l'avancement ###############
      out="$(${CURL} "${freebox}/api/v${version}/fs/tasks/${id}" -H "X-Fbx-App-Auth: ${session_token}")"
      successIsTrue "${out}" "Lecture de l'avancement de la tâche impossible."

      progress="$(printf '%s' "${out}" | sed '/"success"/ !d;s|.*"progress":||;s|}.*||')"
      notEmpty "${progress}" 'Impossible de lire la progression de la tâche.' "${out}"

      state="$(printf '%s' "${out}" | sed '/"success"/ !d;s|.*"state":"||;s|",.*||')"
      notEmpty "${state}" "Impossible de lire l'état de la tâche." "${out}"

      case "${state}" in
        'queued')  printf "\rEn attente."
                   ;;
        'running') printf "\rEn cours : %2u%% " ${progress}
                   ;;
        'paused')  printf "\rEn pause : %2u%% " ${progress}
                   ;;
        'done')    printf "\rTerminé  : 100%%"
                   break
                   ;;
        'failed')  printf "\rEchoué.        "
                   break
                   ;;
        *)         printf "\rEtat inconnu : %s" "${state}"
                   break
      esac

      sleep 2
    done

    if [ "${state}" = 'done' ]; then
      ################## Lecture du résultat (md5) ###############
      out="$(${CURL} "${freebox}/api/v${version}/fs/tasks/${id}/hash" -H "X-Fbx-App-Auth: ${session_token}")"
      successIsTrue "${out}" "Erreur lecture du hash."

      hash="$(printf '%s' "${out}" | sed '/"success"/ !d;s|.*"result":"||;s|".*||')"
      printf "\r%s  %s\n" "${hash}" "${f}"

    else
      ################## Lecture de la cause d'erreur ############
      error="$(printf '%s' "${out}" | sed '/"success"/ !d;s|.*"error":"||;s|",.*||')"
      printf  "\rEchec: %s  %s\n" "${error}" "${f}"

    fi

    deleteTask
  done

"A computer is like air conditioning: it becomes useless when you open windows." (Linus Torvald)

Hors ligne