Browse Source
Merge pull request #16 from jrmhaig/csrf
Merge pull request #16 from jrmhaig/csrf
Adding CSRF verification to DHCP formpull/19/head
committed by
GitHub
5 changed files with 307 additions and 254 deletions
-
134includes/admin.php
-
220includes/dhcp.php
-
182includes/functions.php
-
22includes/status_messages.php
-
3index.php
@ -1,82 +1,74 @@ |
|||
<?php |
|||
|
|||
function Status($message, $level='success', $dismissable=true) { |
|||
$status = '<div class="alert alert-'.$level; |
|||
if ($dismissable) $status .= ' alert-dismissable'; |
|||
$status .= '">'.$message; |
|||
if ($dismissable) $status .= '<button type="button" class="close" data-dismiss="alert" aria-hidden="true">x</button>'; |
|||
$status .= '</div>'; |
|||
|
|||
return $status; |
|||
} |
|||
include_once( 'includes/status_messages.php' ); |
|||
|
|||
function DisplayAuthConfig($username, $password){ |
|||
$status = ''; |
|||
if (isset($_POST['UpdateAdminPassword'])) { |
|||
if (CSRFValidate()) { |
|||
if (password_verify($_POST['oldpass'], $password)) { |
|||
$new_username=trim($_POST['username']); |
|||
if ($_POST['newpass'] != $_POST['newpassagain']) { |
|||
$status = Status('New passwords do not match', 'danger'); |
|||
} else if ($new_username == '') { |
|||
$status = Status('Username must not be empty', 'danger'); |
|||
} else { |
|||
if ($auth_file = fopen(RASPI_ADMIN_DETAILS, 'w')) { |
|||
fwrite($auth_file, $new_username.PHP_EOL); |
|||
fwrite($auth_file, password_hash($_POST['newpass'], PASSWORD_BCRYPT).PHP_EOL); |
|||
fclose($auth_file); |
|||
$username = $new_username; |
|||
$status = Status('Admin password updated'); |
|||
} else { |
|||
$status = Status('Failed to update admin password', 'danger'); |
|||
} |
|||
} |
|||
} else { |
|||
$status = Status('Old password does not match', 'danger'); |
|||
} |
|||
$status = new StatusMessages(); |
|||
if (isset($_POST['UpdateAdminPassword'])) { |
|||
if (CSRFValidate()) { |
|||
if (password_verify($_POST['oldpass'], $password)) { |
|||
$new_username=trim($_POST['username']); |
|||
if ($_POST['newpass'] != $_POST['newpassagain']) { |
|||
$status->addMessage('New passwords do not match', 'danger'); |
|||
} else if ($new_username == '') { |
|||
$status->addMessage('Username must not be empty', 'danger'); |
|||
} else { |
|||
if ($auth_file = fopen(RASPI_ADMIN_DETAILS, 'w')) { |
|||
fwrite($auth_file, $new_username.PHP_EOL); |
|||
fwrite($auth_file, password_hash($_POST['newpass'], PASSWORD_BCRYPT).PHP_EOL); |
|||
fclose($auth_file); |
|||
$username = $new_username; |
|||
$status->addMessage('Admin password updated'); |
|||
} else { |
|||
$status->addMessage('Failed to update admin password', 'danger'); |
|||
} |
|||
} |
|||
} else { |
|||
$status->addMessage('Old password does not match', 'danger'); |
|||
} |
|||
} else { |
|||
error_log('CSRF violation'); |
|||
error_log('CSRF violation'); |
|||
} |
|||
} |
|||
?>
|
|||
<div class="row"> |
|||
<div class="col-lg-12"> |
|||
<div class="panel panel-primary"> |
|||
<div class="panel-heading"><i class="fa fa-lock fa-fw"></i>Configure Auth</div> |
|||
<div class="panel-body"> |
|||
<p><?php echo $status; ?></p>
|
|||
<form role="form" action="/?page=auth_conf" method="POST"> |
|||
<?php CSRFToken() ?>
|
|||
<div class="row"> |
|||
<div class="form-group col-md-4"> |
|||
<label for="username">Username</label> |
|||
<input type="text" class="form-control" name="username" value="<?php echo $username; ?>"/> |
|||
</div> |
|||
</div> |
|||
<div class="row"> |
|||
<div class="form-group col-md-4"> |
|||
<label for="password">Old password</label> |
|||
<input type="password" class="form-control" name="oldpass"/> |
|||
</div> |
|||
</div> |
|||
<div class="row"> |
|||
<div class="form-group col-md-4"> |
|||
<label for="password">New password</label> |
|||
<input type="password" class="form-control" name="newpass"/> |
|||
</div> |
|||
</div> |
|||
<div class="row"> |
|||
<div class="form-group col-md-4"> |
|||
<label for="password">Repeat new password</label> |
|||
<input type="password" class="form-control" name="newpassagain"/> |
|||
</div> |
|||
</div> |
|||
<input type="submit" class="btn btn-outline btn-primary" name="UpdateAdminPassword" value="Save settings" /> |
|||
</form> |
|||
</div><!-- /.panel-body --> |
|||
</div><!-- /.panel-default --> |
|||
</div><!-- /.col-lg-12 --> |
|||
</div><!-- /.row --> |
|||
<div class="row"> |
|||
<div class="col-lg-12"> |
|||
<div class="panel panel-primary"> |
|||
<div class="panel-heading"><i class="fa fa-lock fa-fw"></i>Configure Auth</div> |
|||
<div class="panel-body"> |
|||
<p><?php $status->showMessages(); ?></p>
|
|||
<form role="form" action="/?page=auth_conf" method="POST"> |
|||
<?php CSRFToken() ?>
|
|||
<div class="row"> |
|||
<div class="form-group col-md-4"> |
|||
<label for="username">Username</label> |
|||
<input type="text" class="form-control" name="username" value="<?php echo $username; ?>"/> |
|||
</div> |
|||
</div> |
|||
<div class="row"> |
|||
<div class="form-group col-md-4"> |
|||
<label for="password">Old password</label> |
|||
<input type="password" class="form-control" name="oldpass"/> |
|||
</div> |
|||
</div> |
|||
<div class="row"> |
|||
<div class="form-group col-md-4"> |
|||
<label for="password">New password</label> |
|||
<input type="password" class="form-control" name="newpass"/> |
|||
</div> |
|||
</div> |
|||
<div class="row"> |
|||
<div class="form-group col-md-4"> |
|||
<label for="password">Repeat new password</label> |
|||
<input type="password" class="form-control" name="newpassagain"/> |
|||
</div> |
|||
</div> |
|||
<input type="submit" class="btn btn-outline btn-primary" name="UpdateAdminPassword" value="Save settings" /> |
|||
</form> |
|||
</div><!-- /.panel-body --> |
|||
</div><!-- /.panel-default --> |
|||
</div><!-- /.col-lg-12 --> |
|||
</div><!-- /.row --> |
|||
<?php |
|||
} |
|||
|
|||
|
@ -0,0 +1,220 @@ |
|||
<?php |
|||
|
|||
include_once( 'includes/status_messages.php' ); |
|||
|
|||
/** |
|||
* |
|||
* Manage DHCP configuration |
|||
* |
|||
*/ |
|||
function DisplayDHCPConfig() { |
|||
|
|||
$status = new StatusMessages(); |
|||
if( isset( $_POST['savedhcpdsettings'] ) ) { |
|||
if (CSRFValidate()) { |
|||
$config = 'interface='.$_POST['interface'].PHP_EOL |
|||
.'dhcp-range='.$_POST['RangeStart'].','.$_POST['RangeEnd'].',255.255.255.0,'.$_POST['RangeLeaseTime'].''.$_POST['RangeLeaseTimeUnits']; |
|||
exec( 'echo "'.$config.'" > /tmp/dhcpddata',$temp ); |
|||
system( 'sudo cp /tmp/dhcpddata '. RASPI_DNSMASQ_CONFIG, $return ); |
|||
|
|||
if( $return == 0 ) { |
|||
$status->addMessage('Dnsmasq configuration updated successfully', 'success'); |
|||
} else { |
|||
$status->addMessage('Dnsmasq configuration failed to be updated', 'danger'); |
|||
} |
|||
} else { |
|||
error_log('CSRF violation'); |
|||
} |
|||
} |
|||
|
|||
exec( 'pidof dnsmasq | wc -l',$dnsmasq ); |
|||
$dnsmasq_state = ($dnsmasq[0] > 0); |
|||
|
|||
if( isset( $_POST['startdhcpd'] ) ) { |
|||
if (CSRFValidate()) { |
|||
if ($dnsmasq_state) { |
|||
$status->addMessage('dnsmasq already running', 'info'); |
|||
} else { |
|||
exec('sudo /etc/init.d/dnsmasq start', $dnsmasq, $return); |
|||
if ($return == 0) { |
|||
$status->addMessage('Successfully started dnsmasq', 'success'); |
|||
$dnsmasq_state = true; |
|||
} else { |
|||
$status->addMessage('Failed to start dnsmasq', 'danger'); |
|||
} |
|||
} |
|||
} else { |
|||
error_log('CSRF violation'); |
|||
} |
|||
} elseif( isset($_POST['stopdhcpd'] ) ) { |
|||
if (CSRFValidate()) { |
|||
if ($dnsmasq_state) { |
|||
exec('sudo /etc/init.d/dnsmasq stop', $dnsmasq, $return); |
|||
if ($return == 0) { |
|||
$status->addMessage('Successfully stopped dnsmasq', 'success'); |
|||
$dnsmasq_state = false; |
|||
} else { |
|||
$status->addMessage('Failed to stop dnsmasq', 'danger'); |
|||
} |
|||
} else { |
|||
$status->addMessage('dnsmasq already stopped', 'info'); |
|||
} |
|||
} else { |
|||
error_log('CSRF violation'); |
|||
} |
|||
} else { |
|||
if( $dnsmasq_state ) { |
|||
$status->addMessage('Dnsmasq is running', 'success'); |
|||
} else { |
|||
$status->addMessage('Dnsmasq is not running', 'warning'); |
|||
} |
|||
} |
|||
|
|||
exec( 'cat '. RASPI_DNSMASQ_CONFIG, $return ); |
|||
$conf = ParseConfig($return); |
|||
$arrRange = explode( ",", $conf['dhcp-range'] ); |
|||
$RangeStart = $arrRange[0]; |
|||
$RangeEnd = $arrRange[1]; |
|||
$RangeMask = $arrRange[2]; |
|||
preg_match( '/([0-9]*)([a-z])/i', $arrRange[3], $arrRangeLeaseTime ); |
|||
|
|||
switch( $arrRangeLeaseTime[2] ) { |
|||
case "h": |
|||
$hselected = " selected"; |
|||
break; |
|||
case "m": |
|||
$mselected = " selected"; |
|||
break; |
|||
case "d": |
|||
$dselected = " selected"; |
|||
break; |
|||
} |
|||
|
|||
?>
|
|||
<div class="row"> |
|||
<div class="col-lg-12"> |
|||
<div class="panel panel-primary"> |
|||
<div class="panel-heading"><i class="fa fa-exchange fa-fw"></i> Configure DHCP |
|||
</div> |
|||
<!-- /.panel-heading --> |
|||
<div class="panel-body"> |
|||
<p><?php $status->showMessages(); ?></p>
|
|||
<!-- Nav tabs --> |
|||
<ul class="nav nav-tabs"> |
|||
<li class="active"><a href="#server-settings" data-toggle="tab">Server settings</a> |
|||
</li> |
|||
<li><a href="#client-list" data-toggle="tab">Client list</a> |
|||
</li> |
|||
</ul> |
|||
<!-- Tab panes --> |
|||
<div class="tab-content"> |
|||
<div class="tab-pane fade in active" id="server-settings"> |
|||
<h4>DHCP server settings</h4> |
|||
<form method="POST" action="?page=dhcpd_conf"> |
|||
<?php CSRFToken() ?>
|
|||
<div class="row"> |
|||
<div class="form-group col-md-4"> |
|||
<label for="code">Interface</label> |
|||
<select class="form-control" name="interface"> |
|||
<?php |
|||
exec("ip -o link show | awk -F': ' '{print $2}'", $interfaces); |
|||
|
|||
foreach( $interfaces as $int ) { |
|||
$select = ''; |
|||
if( $int == $conf['interface'] ) { |
|||
$select = " selected"; |
|||
} |
|||
echo '<option value="'.$int.'"'.$select.'>'.$int.'</option>'; |
|||
} |
|||
?>
|
|||
</select> |
|||
</div> |
|||
</div> |
|||
<div class="row"> |
|||
<div class="form-group col-md-4"> |
|||
<label for="code">Starting IP Address</label> |
|||
<input type="text" class="form-control"name="RangeStart" value="<?php echo $RangeStart; ?>" /> |
|||
</div> |
|||
</div> |
|||
|
|||
<div class="row"> |
|||
<div class="form-group col-md-4"> |
|||
<label for="code">Ending IP Address</label> |
|||
<input type="text" class="form-control" name="RangeEnd" value="<?php echo $RangeEnd; ?>" /> |
|||
</div> |
|||
</div> |
|||
|
|||
<div class="row"> |
|||
<div class="form-group col-xs-2 col-sm-2"> |
|||
<label for="code">Lease Time</label> |
|||
<input type="text" class="form-control" name="RangeLeaseTime" value="<?php echo $arrRangeLeaseTime[1]; ?>" /> |
|||
</div> |
|||
<div class="col-xs-2 col-sm-2"> |
|||
<label for="code">Interval</label> |
|||
<select name="RangeLeaseTimeUnits" class="form-control" ><option value="m" <?php echo $mselected; ?>>Minutes</option><option value="h" <?php echo $hselected; ?>>Hours</option><option value="d" <?php echo $dselected; ?>>Days</option><option value="infinite">Infinite</option></select>
|
|||
</div> |
|||
</div> |
|||
|
|||
<input type="submit" class="btn btn-outline btn-primary" value="Save settings" name="savedhcpdsettings" /> |
|||
<?php |
|||
|
|||
if ( $dnsmasq_state ) { |
|||
echo '<input type="submit" class="btn btn-warning" value="Stop dnsmasq" name="stopdhcpd" />'; |
|||
} else { |
|||
echo'<input type="submit" class="btn btn-success" value="Start dnsmasq" name="startdhcpd" />'; |
|||
} |
|||
?>
|
|||
</form> |
|||
</div><!-- /.tab-pane --> |
|||
|
|||
<div class="tab-pane fade in" id="client-list"> |
|||
<h4>Client list</h4> |
|||
<div class="col-lg-12"> |
|||
<div class="panel panel-default"> |
|||
<div class="panel-heading"> |
|||
Active DHCP leases |
|||
</div> |
|||
<!-- /.panel-heading --> |
|||
<div class="panel-body"> |
|||
<div class="table-responsive"> |
|||
<table class="table table-hover"> |
|||
<thead> |
|||
<tr> |
|||
<th>Expire time</th> |
|||
<th>MAC Address</th> |
|||
<th>IP Address</th> |
|||
<th>Host name</th> |
|||
<th>Client ID</th> |
|||
</tr> |
|||
</thead> |
|||
<tbody> |
|||
<tr> |
|||
<?php |
|||
exec( 'cat ' . RASPI_DNSMASQ_LEASES, $leases ); |
|||
foreach( $leases as $lease ) { |
|||
$lease_items = explode(' ', $lease); |
|||
foreach( $lease_items as $lease_item ) { |
|||
echo '<td>' . $lease_item . '</td>'; |
|||
} |
|||
echo '</tr>'; |
|||
}; |
|||
?>
|
|||
</tr> |
|||
</tbody> |
|||
</table> |
|||
</div><!-- /.table-responsive --> |
|||
</div><!-- /.panel-body --> |
|||
</div><!-- /.panel --> |
|||
</div><!-- /.col-lg-6 --> |
|||
</div><!-- /.tab-pane --> |
|||
</div><!-- /.tab-content --> |
|||
</div><!-- ./ Panel body --> |
|||
<div class="panel-footer"> Information provided by Dnsmasq</div> |
|||
</div><!-- /.panel-primary --> |
|||
</div><!-- /.col-lg-12 --> |
|||
</div><!-- /.row --> |
|||
<?php |
|||
} |
|||
|
|||
?>
|
|||
|
@ -0,0 +1,22 @@ |
|||
<?php |
|||
class StatusMessages { |
|||
public $messages = array(); |
|||
|
|||
public function addMessage($message, $level='success', $dismissable=true) { |
|||
$status = '<div class="alert alert-'.$level; |
|||
if ($dismissable) $status .= ' alert-dismissable'; |
|||
$status .= '">'.$message; |
|||
if ($dismissable) $status .= '<button type="button" class="close" data-dismiss="alert" aria-hidden="true">x</button>'; |
|||
$status .= '</div>'; |
|||
|
|||
array_push($this->messages, $status); |
|||
} |
|||
|
|||
public function showMessages($clear = true) { |
|||
foreach($this->messages as $message) { |
|||
echo $message; |
|||
} |
|||
if ( $clear ) $this->messages = array(); |
|||
} |
|||
} |
|||
?>
|
Write
Preview
Loading…
Cancel
Save
Reference in new issue