Freebox Server (Ultra V9/ Pop V8/ Delta V7 / Revolution V6 / Mini 4K)

  • Status Nouveau
  • Percent Complete
    0%
  • Task Type Anomalie
  • Category Freebox OS → API
  • Assigned To No-one
  • Operating System Freebox Server V6 (Révolution)
  • Severity High
  • Priority Very Low
  • Reported Version 4.7.3
  • Due in Version Undecided
  • Due Date Undecided
  • Votes
  • Private
Attached to Project: Freebox Server (Ultra V9/ Pop V8/ Delta V7 / Revolution V6 / Mini 4K)
Opened by vialusant - 07/02/2023
Last edited by vialusant - 07/02/2023

FS#37679 - API V10 retourne invalid_token après génération du hmac

Bonjour,

Je tente depuis plusieurs jours de taper via API ma freebox server revolution (A jour du dernier firmware)

J’ai donc bien suivis la DOC, et je suis en python 3.8

1 - Générer mon application, puis la confirmer sur le front en physique, j’ai le “status”:”granted” 2 - Je récupère le challenge
3 - Tentative d’ouverture de session via le password généré depuis le app_token et le challenge

J’obtiens en retour (tout est anonymisé) :

{'uid': '732edfg65fgaze', 'success': False, 'msg': "Erreur d'authentification de l'application", 'result': {'password_salt': 'M/iYdsf6a9dhyuiods9qsxtfpc+r1KFB', 'challenge': 'KRgdfez6r5sHHRTEuygfvVTGK'}, 'error_code': 'invalid_token'}

Je ne comprend pas ou la raison du soucis, si quelqu’un peut m’éclairer si je me suis trompé ou si c’est un bug

import datetime
import hashlib
import hmac
import json
import pickle
import time
import requests
import urllib3
import sys
import base64

def make_digest(message, key):
    
    key = bytes(key, 'UTF-8')
    message = bytes(message, 'UTF-8')
    
    digester = hmac.new(key, message, hashlib.sha1)
    #signature1 = digester.hexdigest()
    signature1 = digester.digest()
    #print(signature1)
    
    #signature2 = base64.urlsafe_b64encode(bytes(signature1, 'UTF-8'))
    signature2 = base64.urlsafe_b64encode(signature1)    
    #print(signature2)
    
    return str(signature2, 'UTF-8')

appid = "applicationidcustom"
appname ="AppnameCustom"
devicename ="Dlocalcustom"
appversion = "1"
apptoken = "dfgmonapptokengenererlorsdelauthOw0Udhyq/"

#Etape 2 : Obtenir le challenge value avant de sauthentifier
url = "http://mafreebox.freebox.fr/api/v10/login/"
headers = {"Content-Type": "application/json; charset=utf-8"}
response = requests.get(url, headers=headers)
ReturnResponse = response.json()
if ReturnResponse["success"] == False:
	sys.exit(0)

#Etape 3 : Recuperation du token de session
CurrentChallenge = ReturnResponse["result"]["challenge"]
CurrentPassword = make_digest(CurrentChallenge, apptoken)
url = "http://mafreebox.freebox.fr/api/v10/login/session/"
data = {"app_id": appname, "password": CurrentPassword}
headers = {"Content-Type": "application/json; charset=utf-8"}
response = requests.post(url, headers=headers, json=data)
ReturnResponse = response.json()
print(ReturnResponse)
#{'uid': '732edfg65fgaze', 'success': False, 'msg': "Erreur d'authentification de l'application", 'result': {'password_salt': 'M/iYdsf6a9dhyuiods9qsxtfpc+r1KFB', 'challenge': 'KRgdfez6r5sHHRTEuygfvVTGK'}, 'error_code': 'invalid_token'}

Personne n'a de syntaxe fonctionelle à me fournir afin que je puisse tester ?
Je tourne en rond depuis 5 jours

Toujours d'actualité, j'ai refais une session debug, toujours un "invalid_token"

Bonjour

Je ne connais pas python mais vous saurez probablement lire du shell (bash 4+)

Voici ce que j'utilise en bash ( et qui fonctionne avec toutes les versions d'openssl):

login_fbx () {
    local APP_ID="$1"
    local APP_TOKEN="$2"
    local answer=

    answer=$(call_freebox_api 'login') || return 1
    local challenge=$(get_json_value_for_key "$answer" "result.challenge")
    [[ "$(openssl version |cut -d' ' -f2)" != "1.1.1n" ]] && \
    local password=$(echo -n "$challenge" | openssl dgst -sha1 -hmac "$APP_TOKEN" | sed  's/^SHA1(stdin)= //') || \
    local password=$(echo -n "$challenge" | openssl dgst -sha1 -hmac "$APP_TOKEN" | sed  's/^(stdin)= //')
    answer=$(call_freebox_api '/login/session/' "{\"app_id\":\"${APP_ID}\", \"password\":\"${password}\" }") || return 1
    _SESSION_TOKEN=$(get_json_value_for_key "$answer" "result.session_token")
}


Quelques explications pour comprendre le code ci dessus :

La fonction call_freebox_api fait un simple GET ou POST sur l'API :

# simple API call using curl automatic GET or POST detection (simple POST)  
call_freebox_api () {
    local api_url="$1"
    local data="${2-}"
    local options=("")
    local url="$FREEBOX_URL"$( echo "/$_API_BASE_URL/v$_API_VERSION/$api_url" | sed 's@//@/@g')
    [[ -n "$_SESSION_TOKEN" ]] && options+=(-H "X-Fbx-App-Auth: $_SESSION_TOKEN")
    [[ -n "$data" ]] && options+=(-d "$data")
    mk_bundle_cert_file fbx-cacert                # create CACERT BUNDLE FILE
    [[ -n "$FREEBOX_CACERT" ]] && [[ -f "$FREEBOX_CACERT" ]] \
            && options+=(--cacert "$FREEBOX_CACERT") \
            || options+=("-k")
    answer=$(curl -s "$url" "${options[@]}")
    #_check_success "$answer" || return 1
    _check_success "${answer}" || ctrlc
    echo "${answer}"
    del_bundle_cert_file fbx-cacert               # remove CACERT BUNDLE FILE
}


la fonction get_json_value_for_key (que je ne détaille pas car utilise plusieurs centaines de lignes de code ce qui est trop pour poster ici) fait en gros l'équivalent de :

jq -r 

# ex: 
get_json_value_for_key "$answer" "result.challenge"

# est équivalent à : 
echo ${answer} | jq -r .result.challenge

Et la fonction login_fbx détaillée plus haut se connecte à l'API et renvoit un token ($_SESSION_TOKEN) que j epasse ensuite en temps que header dans la requete:

X-Fbx-App-Auth: $_SESSION_TOKEN

Pour debug, pourriez vous ajouter des 'echo' de chaque variable à chaque ligne executée ? (genre pour simuler un debugger 'pas à pas')
Quand on sais ce que l'on cherche à construire (vous pouvez le générer avec mon code), ça permet de debug efficacement

Si vous devez faire des tests plus poussés en comparent avec mon code, vous serez certainement interressé par le dépot github
https://github.com/nbanb/fbx-delta-nba_bash_api.sh

Sinon je crois qu'il existe plein de projets en python ou pas mal de personnes ont déjà répondu à votre problématique avec des fonctions qui permettent de se login sur la box avec l'API (perso je ne suis pas dev, je ne connais pas python)

Cordialement
nbanba

Loading...

Available keyboard shortcuts

Tasklist

Task Details

Task Editing