PHP CURL script with CSRF support
-
I wanted to use a script I found to show my RRD graphs to the public. I found a nice PHP script, but it was pre2.0 so it didn't work.
CSRF was a royal pain to get working, but I managed.
I took this script here: http://captain-slow.dk/2010/09/24/public-rrd-graphs-from-pfsense/
graph_rrd.php
require_once("config.inc.php"); if (isset($_GET["file"]) && isset($_GET["interval"])) { //Get CSRF $ckfile = tempnam ("/tmp", "CURLCOOKIE"); $curl_handle = curl_init(); curl_setopt($curl_handle, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.0.12) Gecko/20070508 Firefox/1.5.0.12"); curl_setopt($curl_handle, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($curl_handle, CURLOPT_SSL_VERIFYHOST, 2); curl_setopt ($curl_handle, CURLOPT_COOKIEJAR, $ckfile); curl_setopt ($curl_handle, CURLOPT_COOKIEFILE, $ckfile); curl_setopt($curl_handle, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($curl_handle, CURLOPT_HEADER, 1); curl_setopt($curl_handle,CURLOPT_CONNECTTIMEOUT,2); curl_setopt($curl_handle,CURLOPT_RETURNTRANSFER,1); curl_setopt($curl_handle,CURLOPT_URL, $pfsenseprot . "://" . $pfsenseip . "/index.php"); $buffer = curl_exec($curl_handle); $csrf = substr($buffer, strpos($buffer,'sid:') , 110); //Login $post = array( '__csrf_magic' => $csrf, 'login' => urlencode('Login'), 'usernamefld' => urlencode($username), 'passwordfld' => urlencode($password) ); $post_string = ""; foreach($post as $key=>$value) { $post_string .= $key.'='.$value.'&'; } rtrim($post_string, '&'); $curl_handle = curl_init(); curl_setopt($curl_handle, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.0.12) Gecko/20070508 Firefox/1.5.0.12"); curl_setopt($curl_handle, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($curl_handle, CURLOPT_SSL_VERIFYHOST, 2); curl_setopt($curl_handle,CURLOPT_POST, count($post)); curl_setopt($curl_handle,CURLOPT_POSTFIELDS, $post_string); curl_setopt ($curl_handle, CURLOPT_COOKIEJAR, $ckfile); curl_setopt ($curl_handle, CURLOPT_COOKIEFILE, $ckfile); curl_setopt($curl_handle, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($curl_handle, CURLOPT_HEADER, 1); curl_setopt($curl_handle,CURLOPT_CONNECTTIMEOUT,2); curl_setopt($curl_handle,CURLOPT_RETURNTRANSFER,1); curl_setopt($curl_handle,CURLOPT_URL, $pfsenseprot . "://" . $pfsenseip . "/index.php"); $buffer = curl_exec($curl_handle); //Get PNG $end = time(); $start = time() - $_GET["interval"]; $curl_handle = curl_init(); curl_setopt($curl_handle, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.0.12) Gecko/20070508 Firefox/1.5.0.12"); curl_setopt($curl_handle, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($curl_handle, CURLOPT_SSL_VERIFYHOST, 2); curl_setopt($curl_handle, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); curl_setopt($curl_handle, CURLOPT_USERPWD, $username . ":" . $password); curl_setopt($curl_handle,CURLOPT_CONNECTTIMEOUT,2); curl_setopt($curl_handle, CURLOPT_COOKIEFILE, $ckfile); curl_setopt($curl_handle,CURLOPT_RETURNTRANSFER,1); curl_setopt($curl_handle,CURLOPT_URL, $pfsenseprot . "://" . $pfsenseip . "/status_rrd_graph_img.php?start=" . $start . "&end=" . $end . "&database=" . $_GET["file"] . "&style=inverse"); $buffer = curl_exec($curl_handle); if(curl_errno($curl_handle)) { echo 'Curl error: ' . curl_error($curl_handle); } else { if (empty($buffer)) { print "No picture avalible."; } else { header('Content-Type: image/png'); print $buffer; } } curl_close($curl_handle); } ?>
config.inc.php
Change the variables in here to match you config.
Don't forget to put in your default gateway name where it says [GATEWAY]
Easy way to set this is to goto the RRD quality page, and copy in image url for the graph.
You will find the .rrd line in the url.$username = "admin"; //username for pfSense $password = "password"; //password for pfSense $pfsenseip = "10.0.0.1"; //ip of pfSense $pfsenseprot = "http"; //http or https $refresh = 30; //Seconds between reload of the image $scale = array( 0 => array("14400", "4 Hours", 30), 1 => array("57600", "16 Hours", 30), 2 => array("172800", "2 Days", 180), 3 => array("2764800", "1 Month", 180), 4 => array("16588800", "6 Months", 180), 5 => array("33177600", "1 Year", 180) ); $graphs = array( 0 => array("wan-traffic.rrd", "WAN :: Traffic"), 1 => array("wan-packets.rrd", "WAN :: Packets"), 2 => array("[GATEWAY]-quality.rrd", "WAN :: Quality"), 3 => array("system-processor.rrd", "System :: Processor ") ); ?>
index.php
require_once("functions.php"); require_once("config.inc.php"); if (!isset($_GET["type"]) || !isset($_GET["interval"])) { header('Location: ?type=' . $graphs[0][0] . '&interval=' . $scale[0][0]) ; } ?> <title>pfSense stats @ <?php print $_SERVER['HTTP_HOST'] ?></title> ![](http://i.imgur.com/SqctVVa.jpg) print "[ "; for ($i = 0; $i < count($graphs); $i++) { $graphs = $GLOBALS['graphs']; $num = count($graphs); if ($num-1 == $i) { print "[" . $graphs[$i][1] . "](?" . url("type", $graphs[$i][0]) . ") ]"; } else { print "[" . $graphs[$i][1] . "](?" . url("type", $graphs[$i][0]) . ") | "; } } print " [ "; for ($i = 0; $i < count($scale); $i++) { $scale = $GLOBALS['scale']; $num = count($scale); if ($num-1 == $i) { print "[" . $scale[$i][1] . "](?" . url("interval", $scale[$i][0]) . ") ]"; } else { print "[" . $scale[$i][1] . "](?" . url("interval", $scale[$i][0]) . ") | "; } if ($scale[$i][0] == $_GET["interval"]) { $refresh = $scale[$i][2]; } } ?> ![](graph_rrd.php?file=<?php print $_GET[)&interval=" name="refresh"> [pfSense stats by bld @ bld.is-a-geek.com](http://bld.is-a-geek.com/2010/09/24/public-rrd-graphs-from-pfsense/) [pfSense 2.0 edit by ionstorm66](https://forum.pfsense.org/index.php/topic,72558.0.html)
functions.php
function url($q="empty", $value="empty") { $output = $_SERVER['QUERY_STRING']; if ($q != "empty" && $value != "empty") { if (strlen($output)) { $temp = explode("&", $output); for($i = 0; $i < count($temp); $i++) { $subtemp = explode("=", $temp[$i]); if ($subtemp[0] == $q) { $output = str_replace($subtemp[0] . "=" . $subtemp[1], $subtemp[0] . "=" . $value, $output); } } } } return $output; } ?>
style.css
html, body { height: 100%; } body { margin: 0; padding: 0; background-color: #b0c4de; font-family: serif; font-size: 14px; font-weight: normal; } A { font-family:serif; font-size: 14px; font-weight: bold; text-decoration: underline; color: #000000; } A:Visited { font-family:serif; font-size: 14px; font-weight: bold; text-decoration: underline; color: #000000; } A:Hover { font-family:serif; font-size: 14px; font-weight: bold; text-decoration: underline; color: #FFFFFF; } #top { position: absolute; } #container { min-height: 100%; margin-bottom: -20px; } * html #container { height: 100%; } #footer-spacer { height: 20px; } #footer { border-top: 1px solid #000; height: 19x; }
-
Is this script outdated or am i doing some thing wrong that dont get it to work?
Running 2.1.5-RELEASE (amd64)
http://familjenbjornsson.se/stats -
$csrf = substr($buffer, strpos($buffer,'sid:') , 110);
Actually needs to be $csrf = substr($buffer, strpos($buffer,'sid:') , 55); in order to get the csrf token working.
This is because the token length is 55.