Fritz!Box API für PHP (inkl. Login-Sessions)

@fidodido: Eigentlich arbeitet PHP 5.4 ohne Probleme, ich selber benutze ein Windows-Build von 5.4.0. Zum debuggen kannst Du mal vor Zeile 230 in der fritzbox_api.class.php den Befehl ...

Hi Gregor,

vielen Dank für die debug- Tipps! Bin dadurch schnell drauf gekommen. Die Testausgaben haben überhaupt nichts ausgegeben:

"var_dump($this->doGetRequest(array('getpage' => $loginpage))); exit;" bringt: string(0) ""

"var_dump(simplexml_load_string($this->doGetRequest(array('getpage' => $loginpage)))); exit;" bringt: bool(false)

Ich habe mir dann gedacht dass die Box nicht gefunden wird und in die Config statt "fritz.box" mal die IP eingetragen. Dann ging es sofort.
Ein "ping fritz.box" auf der Konsole hat dann auch gezeigt, dass es falsch aufgelöst wird. Das ist ja nicht dramatisch - man muss es nur wissen.:p

Nochmals vielen Dank und viele Grüße!

Frank
 
Probleme mit Fritz!Box Api nach Firmware Update

@spackmat

Hi,

vielen Dank für Deine Antwort. Das Problem ist allerdings derart, dass der Login zwar funktioniert, die Einstellungen vom Gast-Wlan allerdings zurückgestellt sind. Konkret:
Ich stelle Verschlüsselung, Passwort und Logging ein. Mittels der Skripte aktiviere oder deaktiviere ich jetzt eigentlich nur noch das Gast-WLan. Seit dem Update ist es aber so, dass das Gast Wlan zwar aktiviert wird, die Einstellungen zur Verschlüsselung wieder auf "keine" stehen. :mad: Kann ich evtl. jedesmal das Passwort und die Verschlüsselung setzen?

Danke
 
Das Script liest die aktuellen Einstellungen aus und setzt sie wieder neu (muss leider so sein, man kann nicht einfach nur einzelne Felder neu setzen). Bei meiner 7390 mit Firitz!OS 6.03 klappt das nachwievor prima. Vielleicht ist das Formular bei Deiner Box ein anderes, dann muss man diesen Prozess leider entsprechend anpassen. Natürlich kann man das Script so modifizieren, dass es die Felder manuell auf irgendwelche Werte setzt, das Passwort kann man sowieso bereits als zweiten Parameter mitgeben.

Wenn Du Dir das Script mal anschaust, kannst Du sehen, wie die jeweils alten Werte ausgelesen und wie sie neu gesetzt werden. Das sind alles reguläre Ausdrücke, die die jeweiligen Inputs lesen und beim POST wieder setzen. Wenn Du Dir den Quellcode der Seite ansiehst, kannst Du sehen, welche Felder es gibt und die die heißen, dann musst Du die Regulären Ausdrücke entsprechend anpassen.

Ist lästig, aber AVM ändert da gerne mal was und macht das je Box unterschiedlich. Deswegen ist die API so abstrakt wie möglich und die Scripte selber konkretisieren das halbwegs verständlich für den jeweiligen Einsatzzweck.

Wenn Du eine Lösung hast, poste die mal hier, dann hilft das anderen weiter, die die gleiche Box haben wie Du.

Liebe Grüße,
spackmat
 
@spackmat
Hi, Danke für Deine Hinweise! Mit denen hab ich das Ding wieder zum Laufen bekommen. Tatsächlich gibt es nach dem Update mehr Optionen und einige Namensänderungen.

Das geänderte Script hab ich gestestet.
Anbei der geänderte Absatz im Script fritzbox_guestwlan_on_off.php für FRITZ!OS 06.04 für Fritzbox 6360 (cable) :
Code:
//.....

  // read guest_ssid setting 
  preg_match('@name="guest_ssid"[^>]+value="([^"]*)"[^>]*@', $output, $matches);
  $formfields['guest_ssid'] = isset($matches[1]) ? $matches[1] : 'defaultguestaccess';
  // read wpa_key setting
  preg_match('@name="wpa_key"[^>]+value="([^"]*)"[^>]*@', $output, $matches);
  $formfields['wpa_key'] = isset($matches[1]) ? $matches[1] : 'defaultwpakey';
  // read sec_mode setting
  preg_match('@name="sec_mode".*?<option value="(\d+)"[^>]+?selected.*?</select>@s', $output, $matches);
  $formfields['sec_mode'] = isset($matches[1]) ? $matches[1] : 'x';
  // read push_service setting
  preg_match('@name="push_service"[^>]+(checked)[^>]*@', $output, $matches);
  if ( isset($matches[1]) )
  {
    $formfields['push_service'] = 'on';
  }
  // read group_access setting
  preg_match('@name="group_access"[^>]+(checked)[^>]*@', $output, $matches);
  if ( isset($matches[1]) )
  {
    $formfields['group_access'] = 'on';
  }
  // read user_isolation setting
  preg_match('@name="user_isolation"[^>]+(checked)[^>]*@', $output, $matches);
  if ( isset($matches[1]) )
  {
    $formfields['user_isolation'] = 'on';
  }
 
  // set new given setting
  if ( $mode == true )
  {
    $formfields['activate_guest_access'] = 'on';
    if ( $wpa_key !== false )
    {
      $formfields['wpa_key'] = $wpa_key;
    }
  }


  //.....

Gruß
Domizilit
 
Zuletzt bearbeitet:
fritzbox_api an der 7330 SL mit OS 6.03 geht so leider nicht...

Hallo, hier mal meine kleinen Problemchen habe auch schon allerhand rumprobiert doch trotz euer exelenten Arbeit ohne Erfolg.
Ziel war es eigenltich nur meinem Router die CardDav Infos aus der Cloud zu übergeben.

@spackmat: Bei meinem 7330 SL und der Firmware 6.03 getestet, funktioniert das Script leider nicht

@fidodido:
1.)
fritzbox_api.class.php den Befehl
Code:
var_dump($this->doGetRequest(array('getpage' => $loginpage))); exit;
Code:
Ausgabe = bool(false)
2.)
Code:
var_dump(simplexml_load_string($this->doGetRequest(array('getpage' => $loginpage)))); exit;
Code:
Ausgabe = bool(false)
3.)
vielleicht SimpleXML deaktiviert? Nur so ein Tipp ins Blaue.
Wie das? und wie könnte sich das äussern und vorallem ändern lassen?

Ansonsten bekomme ich immer die Auskuft
Code:
 Response of initialization call /login_sid.lua in initSID was not xml-formatted.

Für Vorschläge wäre ich dankbar...
 
Wenn die Ausgabe von 1. schon false ist, kommt unter der in der Config angegebenen Adresse der Box gar keine Antwort zurück. Also würde ich da mal zuerst prüfen und die Adresse auf dem System mal direkt in einem Browser oder wenn es Linux ist mit wget im Terminal abrufen. Wenn da die Loginseite kommt, aber im Script nicht, würde ich als nächstes mal schauen, ob cURL installiert und aktiviert ist. Die API ruft Inhalte mit cURL ab und wenn da nichts rausfällt, stimmt da schon was nicht.
 
läuft schon etwas besser... aber noch kein File Upload

Wenn die Ausgabe von 1. schon false ist, kommt unter der in der Config angegebenen Adresse der Box gar keine Antwort zurück. [...] Die API ruft Inhalte mit cURL ab und wenn da nichts rausfällt, stimmt da schon was nicht.

'# wget fritz.box' ergab ->
Code:
wget fritz.box
--2014-03-03 16:00:23--  http://fritz.box/
Resolving fritz.box (fritz.box)... 127.0.0.1
Connecting to fritz.box (fritz.box)|127.0.0.1|:80... connected.
HTTP request sent, awaiting response... 200 OK
<- dem war nicht so ganz die korekte Adresse!

Nach dem ich der Linux Einheit beigebracht habe das fritz.box nicht 127.0.0.1 ist

kommt endlich ein Lebenszeichen:
Die Antwort kommt nun in etwa wie folgt.
Code:
.string(165) "<?xml version="1.0" encoding="utf-8"?><SessionInfo><SID>0000000000000000</SID><Challenge>xxXXxXxx</Challenge><BlockTime>0</BlockTime><Rights></Rights></SessionInfo>
und
Code:
(SimpleXMLElement)#2 (4) {
  ["SID"]=>
  string(16) "0000000000000000"
  ["Challenge"]=>
  string(8) "415f12a0"
  ["BlockTime"]=>
  string(1) "0"
  ["Rights"]=>
  object(SimpleXMLElement)#6 (0) {
  }
}
-> läuft also schon mal... bis dahin.
dann jedoch
Code:
Get all entries from CardDAV server(s)... Done.
Transform to FritzBox XML File... Done.
Upload to fritzbox at fritz.box...PHP Fatal error:  Call to undefined method fritzbox_api::doPostFile() in carddav2fb.php on line 284
Jetzt mag er die Post-Methode nicht mehr -.- gibt es noch eine andere Variante oder muss ich noch was nacharbeiten?

Nachtrag:

Die Script fritzbox_ring_phone / tam_on_off machen ihre arbeit, die fritzbox_api_class.php tut somit dann wohl doch ihren Job auch auf der FB 7330 SL.
- [...]get_foncallslist.php
- [...]get_foncallslist_xml.php quitieren mit failed to open stream: Invalid argument in [...]get_foncallslist[...] on line 52
 
Zuletzt bearbeitet:
doPostFile() gibt es in der aktuellen Version hier aus dem Forum gar nicht. Das hat jemand dankenswerterweise dazuprogrammiert. Schau doch mal nach, wo Du das CardDAV-Script her hast, da gibt es vielleicht einen Fork der API mit doPostFile().

Liebe Grüße,
spackmat
 
Hi,

ich sitze lustigerweise gerade an genau demselben Skript, wenn ich das richtig sehe.

Dieser, etwas ältere Fork hat tatsächlich eine extra Methode.

https://github.com/carlos22/fritzbox_api_php/blob/master/lib/fritzbox_api.class.php

Ich fände es auch super, wenn du das integrieren könntest :)


€dit: Ich habe die aktuelle Version der API von spackmat genommen und die doPostFile() Methode hineingemerged. Hier sind die beiden Methoden, die benötigt werden. Beide müssen in die Klasse "fritzbox_api" eingefügt werden:


PHP:
     /**
     * upload a file to the box (via POST) [all files are uploaded to the 'firmwarecfg' cgi-program]
     * the main cURL wrapper handles the command
     *
     * @access public
     * @param array $formfields an associative array with the POST fields to pass
     * @param array $filefileds an associative array with the file data (key: content) and type (key: type)
     * @return string the raw HTML code returned by the Fritz!Box
     */
    public function doPostFile($formfields = array(), $filefileds = array())
    {
        $ch = curl_init();

        // add the sid, if it is already set
        if ($this->sid != '0000000000000000') {
            // 'sid' MUST be the first POST variable!!! (otherwise it will not work!!)
            // therfore we use array_merge to ensuere the foreach outputs 'sid' fist
            $formfields = array_merge(array('sid' => $this->getSID()), $formfields);
            //$formfields['sid'] = $this->sid;
        }
        curl_setopt($ch, CURLOPT_URL, $this->config->getItem('fritzbox_url') . '/cgi-bin/firmwarecfg');
        curl_setopt($ch, CURLOPT_POST, 1);

        // remote config?
        if ($this->config->getItem('enable_remote_config')) {
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            // support for pre FRITZ!OS 5.50 remote config
            if (!$this->config->getItem('use_lua_login_method')) {
                curl_setopt($ch, CURLOPT_USERPWD, $this->config->getItem('remote_config_user') . ':' . $this->config->getItem('remote_config_password'));
            }
        }

        // enable for debugging:
        //curl_setopt($ch, CURLOPT_VERBOSE, TRUE);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

        // if filefileds not specified ('@/path/to/file.xml;type=text/xml' works fine)
        if (empty($filefileds)) {
            curl_setopt($ch, CURLOPT_POSTFIELDS, $formfields); // http_build_query
        } // post calculated raw data
        else {
            $header = $this->_create_custom_file_post_header($formfields, $filefileds);
            curl_setopt($ch, CURLOPT_HTTPHEADER, array(
                    'Content-Type: multipart/form-data; boundary=' . $header['delimiter'], 'Content-Length: ' . strlen($header['data']))
            );

            curl_setopt($ch, CURLOPT_POSTFIELDS, $header['data']);
        }

        $output = curl_exec($ch);

        // curl error
        if (curl_errno($ch)) {
            $this->error(curl_error($ch) . " (" . curl_errno($ch) . ")");
        }

        // finger out an error message, if given
        preg_match('@<p class="ErrorMsg">(.*?)</p>@is', $output, $matches);
        if (isset($matches[1])) {
            $this->error(str_replace('&nbsp;', ' ', $matches[1]));
        }

        curl_close($ch);
        return $output;
    }


    private function _create_custom_file_post_header($postFields, $fileFields)
    {
        // form field separator
        $delimiter = '-------------' . uniqid();

        /*
        // file upload fields: name => array(type=>'mime/type',content=>'raw data')
        $fileFields = array(
        'file1' => array(
        'type' => 'text/xml',
        'content' => '...your raw file content goes here...',
        'filename' = 'filename.xml'
        ),
        );
        // all other fields (not file upload): name => value
        $postFields = array(
        'otherformfield' => 'content of otherformfield is this text',
        );
        */

        $data = '';

        // populate normal fields first (simpler)
        foreach ($postFields as $name => $content) {
            $data .= "--" . $delimiter . "\r\n";
            $data .= 'Content-Disposition: form-data; name="' . urlencode($name) . '"';
            $data .= "\r\n\r\n";
            $data .= $content;
            $data .= "\r\n";
        }
        // populate file fields
        foreach ($fileFields as $name => $file) {
            $data .= "--" . $delimiter . "\r\n";
            // "filename" attribute is not essential; server-side scripts may use it
            $data .= 'Content-Disposition: form-data; name="' . urlencode($name) . '";' .
                ' filename="' . $file['filename'] . '"' . "\r\n";

            //$data .= 'Content-Transfer-Encoding: binary'."\r\n";
            // this is, again, informative only; good practice to include though
            $data .= 'Content-Type: ' . $file['type'] . "\r\n";
            // this endline must be here to indicate end of headers
            $data .= "\r\n";
            // the file itself (note: there's no encoding of any kind)
            $data .= $file['content'] . "\r\n";
        }
        // last delimiter
        $data .= "--" . $delimiter . "--\r\n";

        return array('delimiter' => $delimiter, 'data' => $data);
    }


Hiermit konnte ich dann auch mein Telefonbuch hochladen :)
 
Zuletzt bearbeitet:
Upload File (Phonebook / Telefonbuch) auf Fritzbox 7330 OS 6.03

https://github.com/carlos22/fritzbox_api_php/blob/master/lib/fritzbox_api.class.php

Ich fände es auch super, wenn du das integrieren könntest :)

PHP:
     /**
     * upload a file to the box (via POST) [all files are uploaded to the 'firmwarecfg' cgi-program]
     * the main cURL wrapper handles the command
     *
     * @access public
     * @param array $formfields an associative array with the POST fields to pass
     * @param array $filefileds an associative array with the file data (key: content) and type (key: type)
     * @return string the raw HTML code returned by the Fritz!Box
     */


Hiermit konnte ich dann auch mein Telefonbuch hochladen :)

Probehalber den von freak2k8 vorgeschlagenen Code eingefügt, ab Zeile 123 in die fritzbox_api.class.php aus dem carddav2fb Paket
Ergebnis:
Code:
Get all entries from CardDAV server(s)... Done.
Transform to FritzBox XML File... Done.
Upload to fritzbox at fritz.box...Done.
FritzBox: FRITZ!Box Telefonbuch wiederhergestellt
Und das Phonebook ist auch wirklich dort angekommen. Super Sache.

Nice work!

Läuft!
 
Zuletzt bearbeitet:
@Xandersoft: Vielleicht noch eine Anmerkung zu carddav2fb: Ich hatte noch Probleme sobald in den vCards Bilder aufgetaucht sind. Es gibt auch schon einen Fix, der allerdings nicht eingepflegt worden ist.

Du müsstest dann, in dem File vCard.php, nach Zeile 571 noch folgendes einfügen:

PHP:
         if ($Key=='photo'){
            if ($RawParams!=null){
                $RawParams = array_filter($RawParams,create_function('$k','return (substr(trim($k),0,3)=="enc" || substr(trim($k),0,4)=="type");'));
            }
         }

Dann sollte es wunderbar klappen, auch wenn Bilder auftauchen.

--
Sorry, das ist etwas Off-Topic, aber vielleicht hilft es ja
 
Zuletzt bearbeitet:
Gute Sache, habe aber momentan keinen Kopf das zu testen einzupflegen. Vielleicht bei Gelegenheit. So lange bitte den angegebenen Fork nehmen, wenn man das braucht.
 
Hallo zusammen,

im Endeffekt ist hier genau dass was ich suche. Nur liegen meine Daten als .vcf-Daten vor und nicht in einem Carddav.
Wie muss ich was verändern dass ich die .vcf Dateien in in Telefonbuch auf meiner FB7390 importieren kann?

Irgendwie habe ich gerade einen gordischen Knoten im Kopf und hoffe dass hier jmd ist der mir hilf ihn zu zerschlagen :D

Die .vcf Datei liegt auf meinem Raspberry Pi.

Könnte jmd mir bitte das Script für die folgenden drei Punkte posten?Und mir dann auch sagen wo ich was ändern muss damit der Upload klappt? (meine Fritzbox hat in meinem LAN einen anderen Namen da ich einen eigenen internen DNS Server laufen haben)

Transform to FritzBox XML File.
Upload to fritzbox at router.zuhause
FritzBox: FRITZ!Box Telefonbuch wiederhergestellt

Über eure Hilfe würde ich mich riesig freuen.

Viele Grüße
 
Zuletzt bearbeitet:
Hallo Zusammen,
mit php habe ich gar nichts am Hut, leider… Ich war dank dieser API aber in der Lage meine FritzBox 6360 ins FHEM zu integrieren und mit Buttons zu bauen die tam_on_off.php aufrufen - Das funktioniert wunderbar, vielen Dank schonmal dafür.
Ein weiteres Schmankerl wäre jetzt die AB Files abrufen zu können, diese würde ich gerne über meine Sonos Landschaft wiedergeben und nach wiedergabe löschen. Ich habe in der Hoffnung etwas zu finden mittlerweile den ganzen Thread durch - in Post 67 gab es etwas vielversprechendes, denn wenn ich alles richtig verstanden habe wollte der Author das gleiche realisieren wie ich. Leider ist dort aber nicht so schön wie in manch anderem Post ein php File als Anhang entstanden…
Was muss ich tun um ein File fritzbox_tam_get_message.php zu erhalten? Welches ich dann über FHEM weiter behandeln kann..?
 
Hello around!

Erstmal einen großen Dank in die Runde, die Fritz!Box API ist schon sehr praktisch.
Bisher habe ich die Funktion 'click2dial' in eine andere Anwendung eingebunden.

Leider habe ich nun ein doppeltes Problem. Meine Fritz!Box 7390 'hängt' regelmäßig, in sofern keine Datenverbindung mehr ins Internet erfolgt. (hier kein Thema)
Das lässt sich durch einen Neustart der Box erreichen, die weiterhin im LAN erreichbar ist.

Nun versuchte ich die FritzBox einfach Zeit gesteuert mit dieser API neuzustarten. Leider funktioniert das nicht. Auf der Box ist die aktuelle Firmware.
Hat vielleicht wer einen aktualisierten reboot script?

Greetz!

Ha! so gehts. Einfach jeden Schritt im Webinterface nachgearmt.

PHP:
<?php


date_default_timezone_set('Europe/Berlin'); // wtf

/**
 * Fritz!Box PHP tools CLI script to restart the small Fritz!
 *
 * Must be called via a command line, shows a help message if called without any or an invalid argument
 *
 * Check the config file fritzbox.conf.php!
 * 
 * @author   Gregor Nathanael Meyer <Gregor [at] der-meyer.de>
 * @license  http://creativecommons.org/licenses/by-sa/3.0/de/ Creative Commons cc-by-sa
 * @version  0.3 2013-01-02
 * @package  Fritz!Box PHP tools
 */

try
{
  // load the fritzbox_api class
  require_once('fritzbox_api.class.php');
  $fritz = new fritzbox_api();
  
  // init the output message
  $message = date('Y-m-d H:i') . ' ';

	echo $fritz->config->getItem('fritzbox_url') . "\n";

	
	// Neustart - 'Formular'
        
        $ch = curl_init(); 
        curl_setopt($ch, CURLOPT_URL, $fritz->config->getItem('fritzbox_url') . "/system/reboot.lua?sid=" . $fritz->getSID() . "&");
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);  //return the transfer as a string
	curl_setopt($ch, CURLOPT_REFERER, $fritz->config->getItem('fritzbox_url') . '/system/export.lua?sid=' . $fritz->getSID() .'&');
        $output = curl_exec($ch);
	curl_close($ch);
	//echo $output;
       
        

	// Neustart - Post

        $ch = curl_init(); 
        curl_setopt($ch, CURLOPT_URL, $fritz->config->getItem('fritzbox_url') . "/system/reboot.lua?sid=" . $fritz->getSID() . "&");
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);  //return the transfer as a string
	curl_setopt($ch, CURLOPT_POST, 1);
	curl_setopt($ch, CURLOPT_POSTFIELDS,"sid=" . $fritz->getSID() . "&reboot=");
	curl_setopt($ch, CURLOPT_REFERER, $fritz->config->getItem('fritzbox_url') . '/system/reboot.lua?sid=' . $fritz->getSID() .'&');
        $output = curl_exec($ch);
	curl_close($ch);
	//echo $output;



	// Neustart - Get - danach?

        $ch = curl_init(); 
        curl_setopt($ch, CURLOPT_URL, $fritz->config->getItem('fritzbox_url') . "/reboot.lua?sid=" . $fritz->getSID() . "");
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);  //return the transfer as a string
	curl_setopt($ch, CURLOPT_REFERER, $fritz->config->getItem('fritzbox_url') . '/reboot.lua?sid=' . $fritz->getSID() .'');
        $output = curl_exec($ch);
	curl_close($ch);
	echo $output;


	// Neustart -  Get - danach2?


        $ch = curl_init(); 
        curl_setopt($ch, CURLOPT_URL, $fritz->config->getItem('fritzbox_url') . "/reboot.lua?sid=" . $fritz->getSID() . "&ajax=1&xhr=1&t1395061372634=nocache");
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);  //return the transfer as a string
	curl_setopt($ch, CURLOPT_REFERER, $fritz->config->getItem('fritzbox_url') . '/reboot.lua?sid=' . $fritz->getSID() .'');
        $output = curl_exec($ch);
	curl_close($ch);
	echo $output;


  	$fritz = null; // destroy the object to log out

}
catch (Exception $e)
{
  $message .= $e->getMessage();
}

// log the result
if ( isset($fritz) && is_object($fritz) && get_class($fritz) == 'fritzbox_api' )
{
  $fritz->logMessage($message);
}
else
{
  echo($message);
}
$fritz = null; // destroy the object to log out
?>

Ergebnis muss
Code:
{"reboot_state":"0"}
sein.

Bei
Code:
{"reboot_state":"extern"}
passiert nichts, was auch immer mit 'extern' gemeint ist...
 
Zuletzt bearbeitet:
Port

Bei der neueren Firmware lässt sich der Port ändern.
Bei der zuletzt grassierenden Sicherheitslücke vielleicht nicht die schlechteste Idee.

Bildschirmfoto-1.png


fritzbox_api.class.php :
PHP:
    // make some config consistency checks
    if ( $this->config->getItem('enable_remote_config') === true )
    {
      if ( !$this->config->getItem('remote_config_user') || !$this->config->getItem('remote_config_password') )
      {
        $this->error('ERROR: Remote config mode enabled, but no username or no password provided');
      }
      /* <-- CHANGE 
		@date: 2014.03.17
		@author: nobodz
      */
	      //$this->config->setItem('fritzbox_url', 'https://' . $this->config->getItem('fritzbox_ip'));
	      if($this->config->getItem('remote_port')=="")
	      {
			$this->config->setItem('fritzbox_url', 'https://' . $this->config->getItem('fritzbox_ip'));
	      }
	      else
	      {
		$this->config->setItem('fritzbox_url', 'https://' . $this->config->getItem('fritzbox_ip') . ':' . $this->config->getItem('remote_port'));
	      }
	// --> CHANGE
      
    }

fritzbox_user.conf.php
PHP:
# if needed, enable remote config here
$this->config->setItem('enable_remote_config', true);
$this->config->setItem('remote_config_user', 'test');
$this->config->setItem('remote_config_password', 'test123');
$this->config->setItem('remote_port', '443');

Vielleicht könnte das so oder so ähnlich übernommen werden.
 
hi sorry for english but I cannot speak deutch. I just wuold like to tell that if you use a fritzbox 7170 with no password there is a little bug because you forget to cast SID to string.
 
Bei der neueren Firmware lässt sich der Port ändern.
Bei der zuletzt grassierenden Sicherheitslücke vielleicht nicht die schlechteste Idee.

[…]

Vielleicht könnte das so oder so ähnlich übernommen werden.

Wenn man einen abweichenden Port für den Remotezugang benutzt, muss man gar nichts patchen, da reicht es, den an die Adresse der Box in der Config anzugängen, also etwa:

$this->config->setItem('fritzbox_ip', 'meindnsname.myfritz.net:64258');
 
Ha! so gehts. Einfach jeden Schritt im Webinterface nachgearmt.

[…]

Ergebnis muss
Code:
{"reboot_state":"0"}
sein.

Bei
Code:
{"reboot_state":"extern"}
passiert nichts, was auch immer mit 'extern' gemeint ist...

Ich habe mal das Rebootscript aktualisiert, es ist eigentlich recht einfach, siehe Anhang. Der Trick ist, dass man nach dem POST-Request mit dem Reboot noch einen AJAX-Rebootstatus-Abfrage-Request gegen /reboot.lua simuliert (übrigens nicht /system/reboot.lua). Danke für den Input an der Stelle!
Anhang anzeigen 75588

PHP:
<?php
/**
 * Fritz!Box PHP tools CLI script to reboot the Fritz!Box
 *
 * Check the config file fritzbox.conf.php!
 * 
 * @author   Gregor Nathanael Meyer <Gregor [at] der-meyer.de>
 * @license  http://creativecommons.org/licenses/by-sa/3.0/de/ Creative Commons cc-by-sa
 * @version  0.1 2014-04-15
 * @package  Fritz!Box PHP tools
 */

try
{ 
  // load the fritzbox_api class
  require_once(__DIR__ . '/fritzbox_api.class.php');
  $fritz = new fritzbox_api();
  
  // send a simple reboot request
  $formfields = array(
    'getpage' => '/system/reboot.lua',
    'sid'     => $fritz->getSID(),
    'reboot'  => '',
  );
  $output = $fritz->doPostForm($formfields);
  
  // the box won't perform a reboot unless at least one ajax reboot state request comes in, so give it to her…
  $formfields = array(
    'getpage'         => '/reboot.lua', // not /system/reboot.lua for this request!
    'ajax'            => '1',
    'xhr'             => '1',
    't' . microtime() => 'nocache',
  );
  $output = $fritz->doGetRequest($formfields);
  
  if ( $output == '{"reboot_state":"0"}' )
  {
    $fritz->logMessage('Reboot request sucessfully sent');
  }
  else
  {
    $fritz->logMessage('Reboot request failed, some debugging needed in ' . basename(__FILE__) . ' at line ' . __LINE__);
  }  
}
catch (Exception $e)
{
  if ( isset($fritz) && is_object($fritz) && get_class($fritz) == 'fritzbox_api' )
  {
    $fritz->logMessage($e->getMessage());
  }
  else
  {
    echo(date('Y-m-d H:i') . ' ' . $e->getMessage());
  }
}
$fritz = null; // destroy the object to log out


Zudem habe ich als Auftragsarbeit ein Script geschrieben, das ungenutzte Netzwerkgeräte löscht. Das braucht man immer dann, wenn man viele wechselnde Geräte hat, etwa bei einem Gastzugang in einem Café oder sowas. Der Auftraggeber stellt das gerne für die Allgemeinheit zur Verfügung, getestet haben wir das gegen eine 7390 und eine 7490 mit Fritz!OS 6.05. Da das viel mit Regulären Ausdrücken arbeitet, um die richtigen Geräte zu finden, halte ich das nicht für sonderlich stabil, bei anderen Firmwares muss man also ggf. die Regulären Ausdrücke anpassen. Das Script nimmt zwei optionale Parameter entgegen: Eine Start-IP-Adresse und eine End-IP-Adresse (IPv4 im gleichen /24er-Subnetz), also etwa 192.168.0.100 192.168.0.110. Dann werden nur gerade nicht aktive Geräte gelöscht, deren DHCP-Lease zwischen den beiden Adressen liegt (inklusiv). lässt man die Parameter weg, werden alle ungenutzten Geräte gelöscht.
Anhang anzeigen 75587
PHP:
<?php
/**
 * Fritz!Box PHP tools CLI script to purce unused DHCP leases
 *
 * Must be called via a command line, shows a help message if called without any or an invalid argument
 *
 * If your box shows lease entries with - instead of an IP-address, you must restart the box as a workaround for this bug
 *
 * Check the config file fritzbox.conf.php!
 * 
 * @author   Gregor Nathanael Meyer <Gregor [at] der-meyer.de>
 * @license  http://creativecommons.org/licenses/by-sa/3.0/de/ Creative Commons cc-by-sa
 * @version  0.1.1 2014-05-03
 * @package  Fritz!Box PHP tools
 */

/**
 * validates an IP4-address for formnal validity
 *
 * @param  $ip  string  an IP4-address to validate
 * @return      bool    true, if the $ip is a formal valid IP4-address
 */
function validateIp($ip)
{
  if ( !preg_match('/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/', $ip, $ip_matches) )
  {
    return false;
  }
  foreach ( array_slice($ip_matches, 1) as $ip_part )
  {
    if ( intval($ip_part) > 255 )
    {
      return false;
    }
  }
  return true;
}
/**
 * extracts the first IP4-address out of a given string
 *
 * validates this address with a validateIp($ip) function, so if the given
 * string has something just looking like an IP4-address before the first
 * correct IP4-address, this function will return false
 *
 * @param  $haystack  string      an string with IP4-address to extract
 * @return            stringbool  a formal valid IP4-address of false
 */
function extractIp($haystack)
{
  if ( !preg_match('/((\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3}))/', $haystack, $ip_parts) || !validateIp($ip_parts[1]) )
  {
    return false;
  }
  return array_slice($ip_parts, 1);
}


try
{
  // load the fritzbox_api class
  require_once('fritzbox_api.class.php');
  $fritz = new fritzbox_api();
  
  // handle the CLI arguments or give a help message
  if ( ( isset($argv[1]) && !validateIp($argv[1]) ) || ( isset($argv[2]) && !validateIp($argv[2]) ) )
  {
    if ( $fritz->config->getItem('logging') == 'console' )
    {
      echo '
  Purges unused DHCP leases of a Fritz!Box
  Can be filtered for a certain IP range (e.g. for guest-access)
  
  Usage on UNIX systems:
    /path/to/php ' .  $argv[0] . ' [optional: FIRSTIP] [optional: LASTIP]
  
  Usage on Windows systems:
    c:\path\to\php.exe ' .  $argv[0] . ' [optional: FIRSTIP] [optional: LASTIP]
  
  FIRSTIP and LASTIP must be in the same subnet, if they are omitted, all unused leases will be removed
  ';
    }
    else
    {
      $fritz->logMessage('ERROR: Script was called without or with an invalid argument');
    }
    exit;
  }
  $firstip = isset($argv[1]) ? extractIp($argv[1]) : false;
  $lastip = isset($argv[2]) ? extractIp($argv[2]) : false;
  
  
  // read the current leases list
  $formfields = array(
    'getpage' => '/net/network_user_devices.lua',
  );
  $output = $fritz->doGetRequest($formfields);
  
  // find the unused leases rows area
  preg_match('/<span> Ungenutzte Verbindungen.*?<\/tr>(.*?)<\/table>/iu', $output, $matches);
  if ( !isset($matches[1]) )
  {
    $fritz->logMessage('ERROR: Fritz!Box didn\'t return a list of unused leases or nothing at all via /net/network_user_devices.lua');
    exit;
  }
  
  // extract the unused rows as an array
  preg_match_all('/<tr>.*?<\/tr>/iu', $matches[1], $rows);
  if ( !isset($rows[0]) || !is_array($rows[0]) )
  {
    $fritz->logMessage('ERROR: Fritz!Box didn\'t return a parseable list of unused leases via /net/network_user_devices.lua');
    exit;
  }
  
  // loop the unused rows
  foreach ( $rows[0] as $row )
  {
    // skip rows without a valid IP
    $ip = extractIp($row);
    if ( ( $firstip != false || $lastip != false ) && $ip == false )
    {
      $fritz->logMessage('WARNING: skipped row, no valid IP found, check your script or restart the box as this seems to be a firmware bug');
      continue;
    }
    // check against first ip
    if ( $firstip != false && ( $firstip[1] . '.' . $firstip[2] . '.' . $firstip[3] != $ip[1] . '.' . $ip[2] . '.' . $ip[3] || $ip[4] < $firstip[4] ) )
    {
      continue;
    }
    // check against last ip
    if ( $lastip != false && ( $lastip[1] . '.' . $lastip[2] . '.' . $lastip[3] != $ip[1] . '.' . $ip[2] . '.' . $ip[3] || $ip[4] > $lastip[4]) )
    {
      continue;
    }
    
    // OK, we want to delete this lease
    preg_match('/name="delete" value="(landevice\d+)"/iu', $row, $matches);
    if ( !isset($matches[1]) )
    {
      $fritz->logMessage('WARNING: skipped row, no valid internal name (landevicexxxx) found, check your script');
      continue;
    }
    
    // do the deletion request
    $formfields = array(
      'getpage' => '/net/network_user_devices.lua',
      'delete'  => $matches[1],
    );
    $output = $fritz->doPostForm($formfields);
    $fritz->logMessage('SUCCESS: ' . $matches[1] . ' with IP ' . $ip[0] . ' was deleted from the list of unused leases');
  }
}
catch (Exception $e)
{
  if ( isset($fritz) && is_object($fritz) && get_class($fritz) == 'fritzbox_api' )
  {
    $fritz->logMessage($e->getMessage());
  }
  else
  {
    echo(date('Y-m-d H:i') . ' ' . $e->getMessage());
  }
}
$fritz = null; // destroy the object to log out

Viel Spaß damit :)

UPDATE 03.05.2014: Mit wurde ein Problem gemeldet, das scheinbar ein Bug in der AVM-Firmware ist. Dieses äußert sich so, dass in der Liste etliche Einträge ohne IP-Adresse auftauchen, die stattdessen einfach ein - in der entsprechenden Spalte stehen haben. Wenn das bei einem auftritt, muss man scheinbar die Box neu starten, dann stimmt die Anzeige wieder und das Purge-Skript kann seiner Arbeit nachgehen. Zudem habe ich gesehen, dass der hier publizierten Version des reboot-Skripts eine wichtige Zeile fehlte, warum auch immer. Ist ebenfalls gefixt.
 
Zuletzt bearbeitet:
hi sorry for english but I cannot speak deutch. I just wuold like to tell that if you use a fritzbox 7170 with no password there is a little bug because you forget to cast SID to string.

Thank you for your input, I fixed this in my current dev-version. Now all output of SimpleXML in initSID() is casted as a string. I always forget this with SimpleXML.


Wenn sonst jemand Probleme damit hat, ein kleines (string) direkt vor $session_status_simplexml->SID hilft :)
 
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.