[Gelöst] Fritz!Box - Telefonbuch-Unterschiede

Theo Tintensich

Aktives Mitglied
Mitglied seit
10 Mrz 2008
Beiträge
2,186
Punkte für Reaktionen
96
Punkte
48
Hallo,

wenn ich bei meiner F!B das Telefonbuch per Weboberfläche herunter hole, bekomme ich eine andere Datei als wenn ich die Datei /var/flash/phonebook von der F!B verwendet.

Nicht nur werden dort auch die unter "internen Telefonnummern" stehenden Nummern aufgeführt, auch ist diese Datei keine "wohlformatierte" XML-Datei.
Es stehen unter anderem die beiden Zeiten
Code:
<uniqueid>xx</uniqueid>
<featureflags>xx</featureflags>
drin.
Und: die beiden als Telefonbuch geführten Abschnitte sind nicht sauber getrennt.
Die unter "interne Telefonnummern" geführten Daten werden zwischen den Tags
Code:
<phonebook owner="255"></phonebook>
an das 'echte' angefügt.


Mein IE schmiert beim öffnen ab, der Firefox mault die Fehler an.

Gibt es eine andere Methode per Script an das Telefonbuch zu kommen, außer die "vermurkste" Datei auszulesen bzw. sie die Daten mühselig über die Weboberfläche zu besorgen?

Irgendwie habe ich da (noch) nichts gefunden, um das z.B. per Cron-Job durchführen zu lassen.
Am liebsten wäre mir die "Weboberflächen"-Version.
Die muss ich, um sie von meinen anderen Scripten verarbeiten zu lassen, nicht weiter bearbeiten.
 
Zuletzt bearbeitet:
Abend

Ja, die gibt es.

Die Fritz!Box API

Code:
-rw-rw-r--    1 root     root          1767 Dec 18 21:11 CHANGELOG.txt
-rw-rw-r--    1 root     root          3311 Dec 18 21:11 README.txt
-rw-rw-r--    1 root     root         13509 Dec 18 21:34 fritzbox_api.class.php
-rw-rw-r--    1 root     root           859 Dec 18 21:11 fritzbox_diversity0on.php
-rw-rw-r--    1 root     root          2429 Dec 18 21:11 fritzbox_get_foncallslist.php
-rw-rw-r--    1 root     root          2314 Dec 18 21:11 fritzbox_get_foncallslist_xml.php
-rw-rw-r--    1 root     root          3429 Dec 18 21:11 fritzbox_guestlan_on_off.php
-rw-rw-r--    1 root     root          4499 Dec 18 21:11 fritzbox_guestwlan_on_off.php
-rw-rw-r--    1 root     root           733 Dec 18 21:46 fritzbox_ring_phone.php
-rw-rw-r--    1 root     root          3235 Dec 18 21:11 fritzbox_tam_on_off.php
-rw-rw-r--    1 root     root          1765 Dec 18 21:11 fritzbox_tam_swap.php
-rw-rw-r--    1 root     root          1907 Dec 19 20:01 fritzbox_user.conf.php
-rw-rw-r--    1 root     root          5892 Sep 29 11:46 fritzbox_wol.php
Dazu noch php-cgi von fritzmod.net...
Code:
root@deepbase # ../cgi-bin/php-cgi -f fritzbox_get_foncallslist.php
2015-01-07 21:06 Call list sucessfully downloadedroot@deepbase #
Und fertig ist die amrufsliste.csv, oups, Anrufsliste, nicht Telefonbuch. :mrgreen:
Frag doch mal im Fritz!Box API Thread nach, ob die auch das Telefonbuch holen kann.
 
Zuletzt bearbeitet:
Die 'aktuellste' Version der API, die ich gefunden habe, stammt aus dem Jahr 2013. (fritzbox_api_php_v0.5.0b7.zip), in der ist solches nicht zu finden.

Leider gibt es für die von Nutzern bereitgestellten Scripten keine zentrale Ablage vorhanden, so dass man sich durch zur Zeit 14 Forenseiten kämpfen müsste.
Im Schnelldurchlauf habe ich solches nicht gefunden.
 
Wahrscheinlich ist das Exportieren als LUA Funktion implementiert.
Beim Onlinetelefonbuch weiss ich wie es geht.
 
Der "reguläre" Export eines Telefonbuchs läuft - wie so vieles - über das firmwarecfg-Binary. Das erwartet ein HTTP-Post mit entsprechenden Formularfeldern, u.a. einer Session-ID.

Mit ein wenig Phantasie läßt sich das vielleicht auch direkt auf der Box als Kommando aufrufen (wenn man die CGI-Umgebung entsprechend emuliert) oder man sieht sich einfach mal in der Datei "/etc/default.$CONFIG_PRODUKT/$OEM/phonebook.lua" an, wie die TR-064-Ausgabe für das Telefonbuch zusammengebaut wird und erstellt sich anhand dieses Beispiels seine eigene Version.

Ansonsten gibt es noch die o.a. Möglichkeit, die Telefonbücher über TR-064 abzufragen, aber auch das ist eher nichts für einen cron-Job in der Box selbst. Von außen geht das aber durchaus ganz gut, diverse Beispiele für die TR-064-Benutzung gibt es im Forum (meist im Zusammenhang mit "Neu verbinden" oder der Abfrage der Line-Parameter). Ob das Telefonbuch über TR-064 auch ohne Anmeldung gelesen werden kann, weiß ich nicht, aber die TR-064-Schnittstelle könnte sich auch mit einer einfachen Basic-Authentifizierung zufrieden geben, was den Challenge-Response-Mechanismus von AVM dann nicht erforderlich macht ... dann sollte man natürlich dort nur verschlüsselt zugreifen (Port 49443, Protokoll HTTPS).

Wenn dann ein halbwegs vernünftiges XML-File dabei herauskommt und das auf Anhieb nicht so paßt wie erwartet, gibt es da ja mit XSLT eine sehr einfache Möglichkeit der Umwandlung in das gewünschte Ergebnis.

EDIT: URL für Description via TR-064: http://fritz.box:49000/phonebook.xml
 
Zuletzt bearbeitet:
Ich habe mal so'n bisschen mir die Daten angesehen, die die Seite mit dem Telefonbuch für "Sichern" anzeigt.
Da steht u.a.:
Code:
<form method="POST" action="../cgi-bin/firmwarecfg" enctype="multipart/form-data" id="export_form" name="uiPostExportForm" onsubmit="return false">
<input type="hidden" id="sid_export" name="sid" value="xxxxxxxxxxxx" disabled>
<input type="hidden" id="select_fonbook_id" name="PhonebookId" value="0" disabled>
<input type="hidden" id="select_fonbook_name" name="PhonebookExportName" value="Telefonbuch" disabled>
<input type="hidden" id="select_fonbook_export" name="PhonebookExport" value="" disabled>
</form>

Wenn ich mir ein Script zusammenbastle, das den für FW-Version 5.50ff Teil auf http://www.wehavemorefun.de/fritzbox/IP-Pakete_mitschneiden verwendet, bekomme ich ein Shellscript mit folgenden Inhalt:
Code:
#!/bin/sh
IP="fritz.box"
Passwd="xxxxx"

# Challenge abholen
Challenge=`wget -O - "http://$IP/login_sid.lua" 2>/dev/null | sed 's/.*<Challenge>\(.*\)<\/Challenge>.*/\1/'`

# login aufbauen und hashen
CPSTR="$Challenge-$Passwd"
MD5=`echo -n $CPSTR | iconv -f ISO8859-1 -t UTF-16LE | md5sum -b | awk '{print substr($0,1,32)}'`
RESPONSE="$Challenge-$MD5"
POSTDATA="?username=&response=$RESPONSE"

# login senden und SID herausfischen
SID=`wget -O - --post-data="$POSTDATA" "http://$IP/login_sid.lua" 2>/dev/null | sed 's/.*<SID>\(.*\)<\/SID>.*/\1/'`


wget --post-data="sid=$SID&PhonebookId=0&PhonebookExportName=Telefonbuch" http://$IP/cgi-bin/firmwarecfg -O telefonbuch.xml
Das kommt, beim Aufruf bis zur letzten 'wget'-Zeile, ab der das Script auf eine passende Antwort von der F!B wartet.

Sind die "--post-data" richtig?
Oder muss da noch ein "&PhonebookExport=" mit ran?

---
Der Cronjob soll von einem anderen Rechner (Linux) aus erfolgen, nicht auf der F!B.
 
Zuletzt bearbeitet:
Oder muss da noch ein "&PhonebookExport=" mit ran?
Vermutlich ja ... firmwarecfg macht so ziemlich jeden Im- und Export und nach meiner Interpretation ist das die "Operation", die auszuführen ist und erst daraus ergibt sich die Notwendigkeit der anderen Formularfelder.

Ich bin aber etwas skeptisch (nicht selbst getestet allerdings), ob sich der firmwarecfg mit einem "normalen" POST-Request (application/x-www-form-urlencoded) zufrieden gibt oder ob er auf "multipart/form-data" besteht. Wenn es also auch mit "PhonebookExport" in der URL-Form nicht klappen will, könntest Du noch die Alternative testen.
 
timmt, die drei Werte sollten auch rein, aber leider...
mit
Code:
wget --post-data="sid=$SID&PhonebookId=0&PhonebookExportName=Telefonbuch&PhonebookExport=" http://$IP/cgi-bin/firmwarecfg \
enctype="multipart/form-data" \
id="export_form" \
name="uiPostExportForm" \
onsubmit="return false" \
-O telefonbuch.xml

bekomme ich nur:
Code:
 wget '--post-data=sid=xxxx&PhonebookId=0&PhonebookExportName=Telefonbuch&PhonebookExport=' http://fritz.box/cgi-bin/firmwarecfg enctype=multipart/form-data id=export_form name=uiPostExportForm 'onsubmit=return false' -O telefonbuch.xml
--2015-01-08 18:29:47--  http://fritz.box/cgi-bin/firmwarecfg
Auflösen des Hostnamen »fritz.box (fritz.box)«... 192.168.179.1
Verbindungsaufbau zu fritz.box (fritz.box)|192.168.179.1|:80... verbunden.
HTTP-Anforderung gesendet, warte auf Antwort... ^C

Da fällt mir auf:
Code:
--post-data=sid=xxxx&
geht das?
"--post-data=sid=...."

Wer kennt sich da aus?
 
Ist dir bewusst, daß du dich mit der IP 192.168.179.x im Gastnetz der FritzBox befindest?
Vermutlich werden dadurch die Zugriffe auf Box-interne Daten erfolgreich verhindert!
Der Standard-Zugriff sollte doch über die IP 192.168.178.1 erfolgen.

Joe
 
Zuletzt bearbeitet:
Ich habe für meine Box eine andere IP, und die hie nur eingetragen, um meine nicht zu nennen ;-)

Der der Zugriff funktioniert, was man daran sieht, dass z.B. das Challange-Response-Verfahren zur Ermittlung der SID erfolgreich durchgelaufen wird.
 
Wer kennt sich da aus?
Ich offenbar doch nicht ... :-(

Ich weiß nicht, was Du da für ein 'wget' hast, meines (GNU 1.16) kennt gar keine von den Optionen, mit denen Du die Übermittlung in der alternativen Foirm versuchst und erwartet eigentlich auch alle Optionen (also auch -O) vor der URL.

Ansonsten kenne ich ehrlich gesagt auch kein wget mit "multipart/form-data"-Support (das muß nichts heißen) und - woran es bei mir beim Senden von solchen Formularen per wget (Option post-file bzw. body-file) auch noch zu scheitern pflegte - wget unterstützt von Haus aus kein HTTP 1.1 und firmwarecfg regiert in einigen Situationen (vielleicht auch nur beim Upload, das will ich jetzt nicht testen) mit "100 Continue", womit wget nichts anzufangen weiß.

Also würde ich zuerst mal ein ordentliches Kommando zusammenbauen (multipart/form-data war ja nur ein Hinweis und keine definitive Aussage, daß url-encoded nicht geht), mir die SID einfach anzeigen lassen (solange die IP sich nicht ändert, bleibt die SID ja für mehrere Versuche gültig) und dann einfach mal "von Hand" mit "verbose"-Ausgabe und allen Debug-Möglichkeiten, die man sonst noch so hat - z.B. ein paralleles tcpdump - ein ordentliches wget auf die Beine stellen. Blöd ist an dieser Stelle durchaus, daß firmwarecfg nach meinen Tests auf falsche Requests nicht immer mit einer passenden Fehlermeldung reagiert ... aber ob von Deinem Kommando am Ende ein Request so gesendet wird, wie es beim Aufruf im Browser auch der Fall ist, sollte man schon feststellen können.

Wenn am Ende alle Stränge reißen, habe ich ein bash-Script, mit dem man eine Datei mit einem "multipart/form-data"-Request zusammenbauen kann (wenn man kein "höhere" Sprache wie perl verwenden kann oder will) und dann wird diese Datei einfach per 'nc' an die Box gesendet. Ich habe jedenfalls nur wenige Probleme, die FRITZ!Box-Konfiguration per Shell-Script zu exportieren und - nach erfolgreicher Änderung - auch wieder zu importieren. Der Export (das sollte für das Telefonbuch und die Konfigurationsdaten identisch laufen) könnte wahrscheinlich sogar über eine "url-encoded form" funktionieren. Also hänge das mit multipart nicht am Anfang zu hoch, ich hatte explizit geschrieben, daß es eine weitere "Falle" sein könnte.

Im Moment scheiterst Du - nach meiner Annahme - an einem falschen Aufbau des wget-Aufrufs.
 
Ich habe für meine Box eine andere IP, und die hie nur eingetragen, um meine nicht zu nennen...
Diese Aussage ist absoluter Nonsens, da private IP-Adressen (dazu gehört auch 192.168.xxx.xxx) nicht für/aus öffentlichen IP-Netzen erreichbar sein dürfen.
Alle Provider unterdrücken deshalb konsequent das Routing privater IP-Adressen.
Solange du also die tatsächliche öffentliche IP-Adresse deines Gateways (der FritzBox) nicht veröffentlichst, wird auch kein Hacker Zugriff auf dein privates Netzwerk bekommen.

Joe
 
Abend

Hm, als Nonsens würde ich das nicht bezeichnen.
Wir leben im Zeitalter von wirklich perfiden Arten von Angriffen.
Dafür braucht es nur eine Webseite oder EMail, die die bekannten Adressen antestet.
Stichwort: XSS
Das Wissen darüber sollte schon zu einer gesunden Paranoia führen.
Der einfachste Schutz dagegen ist surfen/mailen über den Gastzugang.
 
Warum ist es Nonsens, wenn ich von der LAN-Seite meines Netzes die Daten abfragen will?

Da ist die IP-Adresse sowas von vollkommen egal, so lange die Fritzbox eindeutig darüber identifiziert wird.

Ob ich für mein Netz 10.0.0.0/8 oder 192.168.1.0/24 oder 192.168.179.0/24 nehmen.
Vollkommen egal.
Eindeutig muss es sein.
 
Mein System ist ein
Code:
Linux server 3.2.0-4-amd64 #1 SMP Debian 3.2.63-2+deb7u2 x86_64 GNU/Linux
mit
Code:
GNU Wget 1.13.4

Da es bei den Befehlen keinen Fehler gibt, nehme ich an, dass es sie gibt ;-)
 
Da es bei den Befehlen keinen Fehler gibt, nehme ich an, dass es sie gibt ;-)
Imho zu kurz gedacht, Du kannst das aber mit einem tcpdump leicht bestätigen oder auch das Gegenteil beweisen ...

Die nach der ersten URL stehenden Angaben werden nach meiner Interpretation von wget als weitere URLs angesehen und würden - sollte der erste Aufruf jemals enden - dann im weiteren Verlauf beim Versuch des Abrufs von Daten unter diesen URLs auch irgendwann mal zu Fehlern führen. Ich würde sogar soweit gehen, daß das mit "-O" angegebene XML-File nicht angelegt wird, in dem ja die Ausgaben dann irgendwie landen sollten. Das läßt sich ja für eine andere Seite mit einer Ausgabe von Daten (sei es dreist die Login-Seite) problemlos verifizieren, ob die Angabe von Optionen nach der ersten URL tatsächlich möglich ist. Wenn ja, müßte "-O" ja auch wirken. Dann darf da natürlich nach "-O" nicht der Name angegeben werden, unter dem ohnehin gespeichert würde (letzte Komponente des Pfades in der URL, also alles nach dem letzten Slash, selbst wenn da noch URL-Parameter enthalten sein sollten).

Wenn Deine Kommandozeile stimmen sollte, müßtest Du ja ein HTTP-POST mit passenden Parametern (multipart/form-data als Content-Disposition) an die Box beobachten können und nur deren Antwort ausbleiben. Das sollte der tcpdump eins-fix-drei enthüllen.

Und mal ganz nebenbei ... die Fähigkeiten so ziemlich jedes Linux-Kommandos lassen sich mit dem Aufruf "kommando --help" oder "kommando -h" ergründen ... wo siehst Du da bei GNU-wget-1.13 eine "enctype"-Option ? Sollte es eine solche tatsächlich geben, wäre das eine der wenigen Stellen, wo eine existierende Option in späteren Versionen wieder entfernt wurde (was aus Gründern der Abwärtskompatibilität - erst recht innerhalb einer Major-Nummer - eigentlich ein NoGo ist) oder Deine Debian-Distribution verwendet eine sehr eigenwillig angepaßte Version, die ihren Weg "upstream" einfach noch nicht gefunden hat oder verworfen wurde.
 
Ich hänge mal die Man-Pahe für das auf meinem System aktuellen wget hier mit an.
Da sind alle von mir aufgeführten Befehle/Parameter enthalten.
Anhang anzeigen Man_page_of_WGET.zip

Die XML-Datei wird, leer, angelegt
 
Ich hänge mal die Man-Pahe für das auf meinem System aktuellen wget hier mit an.
Da sind alle von mir aufgeführten Befehle/Parameter enthalten.
Tut mir leid ... anders als Du es offenbar kannst, kann ich keine Übereinstimmung zwischen dem in der man-Page beschriebenen Aufruf von 'wget' und Deinem Aufruf im ersten Code-Kasten in #8 feststellen.

Zwar ist die strikte Unterscheidung zwischen Optionen und URLs nicht so vorhanden, wie ich angenommen habe und wie es aus
Code:
wget [option]... [URL]...
für mich hervorgehen würde, aber im Text steht dann eben auch:
man-Page schrieb:
You may freely mix different option styles, or specify options after the command-line arguments.
das erklärt dann auch die Existenz der leeren Ausgabedatei.

Jedoch den Teil mit
Code:
enctype="multipart/form-data" \
id="export_form" \
name="uiPostExportForm" \
onsubmit="return false" \
beim Aufruf verstehe ich dann immer noch nicht, es sei denn, irgendwo in den Textpassagen ist auch noch erläutert, man solle HTML-Parameter (die in diesem Kontext gar keinen Sinn ergeben, wie z.B. die Definition der Event-Behandlung für das Formular mit "onsubmiit") in dieser Form angeben.

Ich mache aber auch kein Hehl daraus, daß ich kein Interesse habe, mir die wget-man-Page in aller Ausführlichkeit zu Gemüte zu führen. Wenn Du es richtig machst, wird es schon irgendwann funktionieren ... wenn ich recht habe, eben in dieser Form nicht. Mehr als meine Meinung - samt Begründung - dazu äußern kann ich ohnehin nicht, ob Du diese berücksichtigst, bleibt Deine eigene Entscheidung.
 
Moin

Wie wäre es denn mit einem SOAP Request?
soap.sh
Code:
#!/bin/sh

FRITZ_IP=192.168.178.1

NETCAT=$(which netcat)
[ -z "$NETCAT" ] && NETCAT=$(which nc)
[ -z "$NETCAT" ] && exit 1

( [ -n "$FRITZ_IP" ] && $NETCAT $FRITZ_IP 49000 ) || exit 1;

INTERFACE_NS="urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1"
WANIP_NS="urn:schemas-upnp-org:service:WANIPConnection:1"

if [ "$1" = "-ip" ]; then
        NS="$WANIP_NS"
        REQUEST="GetExternalIPAddress"
        SED='/^<NewExternalIP/ s,</\?NewExternalIPAddress>,,gp'
else
        NS="$INTERFACE_NS"
        REQUEST="GetAddonInfos"
        if [ "$1" = "-a" ]; then
                SED='s,<New,<, ; /^<[a-zA-Z]*[ >]/ s,^<\([^> ]*\) *>\([^<]*\)</.
*,\1\t\2,p'
        else
                SED='s/Send/OUT/ ; s/Receive/IN/ ; /^<NewByte/ s,^<NewByte\([^>]
*\)Rate>\([^<]*\)<.*,\1\t\2,gp'
        fi
fi

body="<?xml version=\"1.0\" encoding=\"utf-8\"?> \
<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" \
   s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\
        <s:Body><u:$REQUEST xmlns:u=$NS /></s:Body>\
</s:Envelope>"

( $NETCAT $FRITZ_IP 49000 | sed -ne "$SED"  ) <<EOT
POST /upnp/control/WANCommonIFC1 HTTP/1.1
Content-Type: text/xml; charset="utf-8"
HOST: $FRITZ_IP:49000
Content-Length: ${#body}
SOAPACTION: "$NS#$REQUEST"

$body
EOT
#EOF
Ist nicht auf meinem Mist gewachsen, gibt es alles hier im Forum.
 
Zuletzt bearbeitet:
@koy:
Ginge natürlich auch, wäre dann das angesprochene TR-064-Interface ... wenn ich es richtig verstehe, paßt da das Format nicht. Ansonsten stünde der Pfad zur Service-Description irgendwo oben schon.

@Theo Tintensich:
Ich brauche das zwar nicht, habe es aber jetzt doch einmal ausprobiert. Meine Vermutung zu multipart war wohl doch richtig, auch bei mir reagiert firmwarecfg nicht auf "application/x-www-url-encoded".

Das folgende bash(!)-Script lädt das Telefonbuch problemlos, den Teil mit dem Login und dem Post-Aufruf mußt Du eben substituieren durch wget-Aufrufe, da das "fritzbox"-Script nicht zum Download zur Verfügung gestellt wird. Das Prinzip sollte trotzdem erkennbar sein.

Entscheidend sind die Aufrufe von "form=$($CALL_MPFD new)" bis "postdata=$($CALL_MPFD postfile $form)", wo aus den angegebenen Formularfeldern eine Datei gebaut wird, die einen multipart/form-data-Request enthält. Der Name der Datei steht anschließend in $postdata, diese kann als "--post-file"-Argument beim 'wget' verwendet werden. $CALL_MFPD ist am Anfang der Datei definiert, da bei mir die Script-Files alles 'nx' sind, brauche ich den expliziten Aufruf über "bash". Wenn man das multipart_form-Script ausführbar irgendwo ablegt, ist natürlich der Aufruf von "multipart_form new" usw. möglich, dann aber in der ersten Zeile von multipart_form auch den SheBang anpassen.
Code:
#! /bin/bash
cleanup()
{
    cleanup_file()
    {
        while [ $# -gt 0 ]; do
            [ ${#1} -lt 6 ] && return # /tmp/. is min valid length
            [ -d $1 -o -f $1 ] && rm -f $([ -d $1 ] && echo -n "-r") $1 2>/dev/null
            shift
        done
    }
    cleanup_file $configfile $envfile $phonebook $postdata $request
    exit $1
}
CALL_FB="/bin/bash ./fritzbox"
CALL_MPFD="/bin/bash ./multipart_form"
configfile=$(mktemp)
if [ -z "$1" ]; then
    echo "FRITZ_BOX=fritz.box\nFRITZ_USER=\nFRITZ_PASSWD=\n" >$configfile
else
    cat $1 >$configfile
    if [ $? -ne 0 ]; then
        echo "Configuration file '$1' is not usable." 1>&2
        exit $(cleanup 127)
    fi
fi
envfile=$(mktemp)
$CALL_FB login --config-file=$configfile --environment-file=$envfile
rc=$?
if [ $rc -ne 0 ]; then
    echo "Unable to login to your device." 1>&2
    exit $(cleanup $rc)
fi
phonebook=$(mktemp)
. $envfile
form=$($CALL_MPFD new)
$CALL_MPFD addfield $form sid $FRITZ_SID
$CALL_MPFD addfield $form PhonebookId 1
$CALL_MPFD addfield $form PhonebookExportName PB2
$CALL_MPFD addfield $form PhonebookExport
postdata=$($CALL_MPFD postfile $form)
echo "Reading phonebook file file ..." 1>&2
$CALL_FB post --config-file=$configfile --environment-file=$envfile /cgi-bin/firmwarecfg $postdata >phonebook.xml
rc=$?
if [ $rc -ne 0 ]; then
    $CALL_FB logout --config-file=$configfile --environment-file=$envfile
    echo "Error $rc reading box configuration file." 1>&2
    exit $(cleanup $rc)
fi
$CALL_MPFD cleanup $form
$CALL_FB logout --config-file=$configfile --environment-file=$envfile
cat phonebook.xml
exit $(cleanup 0)
Dieses Script wird als "multipart_form" zusätzlich benötigt (ist als Anhang auch noch mal vorhanden und läuft (vermutlich, lange nicht mehr getestet) sogar unter Busybox-ash, wenn es sein muß, wobei das wget der Box kein --post-file kennt und damit relativiert sich der Nutzen, aber es gibt (oder gab) ja auch noch 'nc'):
Code:
#! /bin/true
errmsg() { printf "%s\n" "$*" 1>&2; }
check_form()
{
	local form="$1" rc=0
	if [ -d $form ]; then
		if [ ! -f $form/content ]; then
			errmsg "The specified form directory '$form' does not contain a valid multipart form-data structure."
			rc=1
		else
			if [ ! -w $form/content ]; then
				errmsg "The specified form directory '$form' does not contain a valid multipart form-data structure."
				rc=1
			fi
		fi
	else
		errmsg "The specified form directory '$form' is invalid."
		rc=1
	fi
	return $rc
}
field_header()
{
	local type
	[ ${#2} -gt 0 ] && type="$(echo -e -n "\r\nContent-Type: $2")"
	echo -n "Content-Disposition: form-data; name=\"$1\"$type"
}
content_length()
{
	local form="$1" tab=$'\t' part name hdr boundary
	boundary="$(cat $form/boundary)"
	len=0
	while read line; do
		part="${line%%${tab}*}"
		name="${line#*${tab}}"
		type="${name#*${tab}}"
		[ ${#type} -gt 0 ] && name="${name%%${tab}*}"
		hdr="$(field_header "$name" "$type")"
		len=$(( len + 2 + 2 + ${#boundary} + 2 + ${#hdr} + 4 + $(wc -c <$form/$part) ))
	done <$form/content
	echo $(( len + 2 + 2 + ${#boundary} ))
}
post_data()
{
	local form="$1" tab=$'\t' field tf oifs="$IFS" fl
	tf=$(mktemp)
	boundary="$(cat $form/boundary)"
	cat $form/content |
	while read line; do
		field=""
		part="${line%%${tab}*}"
		name="${line#*${tab}}"
		type="${name#*${tab}}"
		[ ${#type} -gt 0 ] && name="${name%%${tab}*}"
		hdr="$(field_header "$name" "$type")"
		echo -n -e "$fl--$boundary\r\n$hdr\r\n\r\n" >>$tf
		fl="\r\n"
		cat $form/$part >>$tf
	done
	echo -n -e "\r\n--$boundary--" >>$tf
	echo -n -e "Content-Type: multipart/form-data; boundary=$boundary\r\n" >$form/formdata
	echo -n -e "Content-Length: $(wc -c <$tf)\r\n\r\n" >>$form/formdata
	cat $tf >>$form/formdata
	rm $tf 2>/dev/null
	echo -n -e "\r\n" >>$form/formdata
	echo "$form/formdata"	
}
op=$1
case $op in
	"new")
		if [ ${#2} -gt 0 ]; then
			errmsg "No parameters allowed for new form creation."
			rc=127
		else
			td=$(mktemp -d)
			touch $td/content
			echo -n -e "$(echo "$td$(date +%s)" | md5sum | sed -n -e "s/^\([0-9a-f]*\).*/\1/p")" >$td/boundary
			echo $td
			rc=0
		fi
		;;
	"cleanup")
		form="$2"
		if check_form $form; then
			rm -r $form 2>/dev/null
			rc=0
		else
			rc=127
		fi
		;;
	"addfield")
		form="$2"
		name="$3"
		value="$4"
		if check_form $form; then
			if [ ${#name} -eq 0 ]; then
				errmsg "Missing field name for 'addfield' operation."
				rc=127
			else
				part="$name$(date +%s)"
				echo -n -e "$value" >$form/$part
				echo -e "$part\t$name" >>$form/content
				rc=0
			fi
		else
			rc=127
		fi
		;;
	"addfile")
		form="$2"
		name="$3"
		file="$4"
		type="$5"
		if check_form $form; then
			if [ ${#name} -eq 0 ]; then
				errmsg "Missing field name for 'addfile' operation."
				rc=127
			else
				part="$name$(date +%s)"
				cat $file >$form/$part
				echo -e "$part\t$name\t$type" >>$form/content
				rc=0
			fi
		else
			rc=127
		fi
		;;
	"length")
		form="$2"
		if check_form $form; then
			content_length "$form"
			rc=0
		else
			rc=127
		fi
		;;
	"postdata")
		form="$2"
		if check_form $form; then
			cat $(post_data "$form")
			rc=0
		else
			rc=127
		fi
		;;
	"postfile")
		form="$2"
		if check_form $form; then
			post_data "$form"
			rc=0
		else
			rc=127
		fi
		;;
	*)
		errmsg "Unknown operation '$op'."
		rc=127
		;;
esac
exit $rc

EDIT:
Eines habe ich glatt noch vergessen ... offenbar ist firmwarecfg auch etwas "wählerisch", was die Reihenfolge der Formularfelder im Request angeht. Der Download funktioniert bei mir nur, wenn "PhonebookExport" das letzte Feld ist.
 
Zuletzt bearbeitet:
Holen Sie sich 3CX - völlig kostenlos!
Verbinden Sie Ihr Team und Ihre Kunden Telefonie Livechat Videokonferenzen

Gehostet oder selbst-verwaltet. Für bis zu 10 Nutzer dauerhaft kostenlos. Keine Kreditkartendetails erforderlich. Ohne Risiko testen.

3CX
Für diese E-Mail-Adresse besteht bereits ein 3CX-Konto. Sie werden zum Kundenportal weitergeleitet, wo Sie sich anmelden oder Ihr Passwort zurücksetzen können, falls Sie dieses vergessen haben.