Browse Source

Merge billz/raspap-webgui master

pull/1087/head
billz 1 year ago
parent
commit
5be1ad5844
  1. 23
      .travis.yml
  2. 4
      BACKERS.md
  3. 18
      README.md
  4. 12
      ajax/networking/gen_int_config.php
  5. 1
      ajax/networking/wifi_stations.php
  6. 47
      app/css/custom.php
  7. 8
      app/css/hackernews.css
  8. 22
      app/css/lightsout.css
  9. 15
      app/img/raspAP-logo.php
  10. 6
      app/img/wifi-qr-code.php
  11. 3
      app/js/custom.js
  12. 22
      app/js/huebee.js
  13. 31
      composer.json
  14. 8
      config/config.php
  15. 4
      config/wireless.json
  16. 83
      dist/huebee/huebee.css
  17. 4
      dist/huebee/huebee.min.css
  18. 1125
      dist/huebee/huebee.pkgd.js
  19. 22
      dist/huebee/huebee.pkgd.min.js
  20. 5
      gulpfile.js
  21. 0
      includes/adblock.php
  22. 7
      includes/configure_client.php
  23. 30
      includes/dashboard.php
  24. 7
      includes/defaults.php
  25. 35
      includes/functions.php
  26. 61
      includes/hostapd.php
  27. 30
      includes/internetRoute.php
  28. 7
      includes/openvpn.php
  29. 39
      includes/system.php
  30. 7
      includes/themes.php
  31. 938
      includes/webconsole.php
  32. 71
      includes/wifi_functions.php
  33. 54
      index.php
  34. 209
      installers/common.sh
  35. 35
      installers/configport.sh
  36. 2
      installers/raspap.sudoers
  37. 12
      installers/raspbian.sh
  38. 14
      installers/uninstall.sh
  39. 12
      locale/en_US/LC_MESSAGES/messages.po
  40. BIN
      locale/fr_FR/LC_MESSAGES/messages.mo
  41. 110
      locale/fr_FR/LC_MESSAGES/messages.po
  42. BIN
      locale/it_IT/LC_MESSAGES/messages.mo
  43. 56
      locale/it_IT/LC_MESSAGES/messages.po
  44. BIN
      locale/ru_RU/LC_MESSAGES/messages.mo
  45. 104
      locale/ru_RU/LC_MESSAGES/messages.po
  46. 24
      package.json
  47. 4
      templates/about/general.php
  48. 23
      templates/dashboard.php
  49. 506
      templates/hostapd.php
  50. 315
      templates/hostapd/advanced.php
  51. 56
      templates/hostapd/basic.php
  52. 17
      templates/hostapd/logging.php
  53. 28
      templates/hostapd/security.php
  54. 63
      templates/networking.php
  55. 97
      templates/system.php
  56. 25
      templates/system/advanced.php
  57. 48
      templates/system/basic.php
  58. 13
      templates/system/language.php
  59. 6
      templates/themes.php
  60. 107
      templates/wifi_stations.php
  61. 211
      yarn.lock

23
.travis.yml

@ -8,29 +8,16 @@ matrix:
- php: '7.0'
- php: '7.1'
- php: '7.2'
- php: '7.3'
- php: '7.4'
- php: 'nightly'
allow_failures:
- php: nightly
before_install:
- if [[ "$SNIFF" == "1" ]]; then export PHPCS_DIR=/tmp/phpcs; fi
- if [[ "$SNIFF" == "1" ]]; then export PHPCOMPAT_DIR=/tmp/PHPCompatibility; fi
# Install PHP CodeSniffer
- if [[ "$SNIFF" == "1" ]]; then git clone -b master --depth 1 https://github.com/squizlabs/PHP_CodeSniffer.git $PHPCS_DIR; fi
# Install PHP Compatibility Standard
- if [[ "$SNIFF" == "1" ]]; then git clone -b master --depth 1 https://github.com/wimg/PHPCompatibility.git $PHPCOMPAT_DIR; fi
# Set install path for PHP Compatibility Standard
# @link https://github.com/squizlabs/PHP_CodeSniffer/wiki/Configuration-Options#setting-the-installed-standard-paths
- if [[ "$SNIFF" == "1" ]]; then $PHPCS_DIR/bin/phpcs --config-set installed_paths $PHPCOMPAT_DIR; fi
# Refresh path
- if [[ "$SNIFF" == "1" ]]; then phpenv rehash; fi
before_script:
- composer install --prefer-source --quiet --no-interaction
# Run test script commands.
# All commands must exit with code 0 on success. Anything else is considered failure.
script:
# Search for PHP syntax errors
- find -L . -name '*.php' -print0 | xargs -0 -n 1 -P 4 php -l
# Run PHPCS
- if [[ "$SNIFF" == "1" ]]; then $PHPCS_DIR/bin/phpcs . ; fi
- composer test

4
BACKERS.md

@ -18,4 +18,6 @@ Recurring and one-time donors are vital to the continued development of this pro
Ray E - "This project is awesome and just works; saved me and my client tons of work. Thank you!" - $20
Erin C - "Just got Raspap up and running, looks very cool, thanks!" -$20 CAD
Ralf J - "Thanks for RaspAP including OpenVPN. It was a big help for me." -€15
Olivier G -€15 EUR
Felipe C - "Thanks for the good work on RaspAP!" -$6
Webagentur S - "Like what you and RaspAP are doing." -€20
Matthew B - "Great project, easy to set up." -£15

18
README.md

@ -1,5 +1,5 @@
![](https://i.imgur.com/xeKD93p.png)
[![Release 2.4](https://img.shields.io/badge/Release-2.4-green.svg)](https://github.com/billz/raspap-webgui/releases) [![Awesome](https://awesome.re/badge.svg)](https://github.com/thibmaek/awesome-raspberry-pi) [![Financial Contributors on Open Collective](https://opencollective.com/raspap/all/badge.svg?label=financial+contributors)](https://opencollective.com/raspap) ![https://travis-ci.com/billz/raspap-webgui/](https://img.shields.io/travis/com/billz/raspap-webgui/master) [![Twitter URL](https://img.shields.io/twitter/url?label=%40RaspAP&logoColor=%23d8224c&url=https%3A%2F%2Ftwitter.com%2Frasp_ap)](https://twitter.com/rasp_ap) [![Subreddit subscribers](https://img.shields.io/reddit/subreddit-subscribers/RaspAP?style=social)](https://www.reddit.com/r/RaspAP/)
[![Release 2.5](https://img.shields.io/badge/Release-2.5-green.svg)](https://github.com/billz/raspap-webgui/releases) [![Awesome](https://awesome.re/badge.svg)](https://github.com/thibmaek/awesome-raspberry-pi) [![Financial Contributors on Open Collective](https://opencollective.com/raspap/all/badge.svg?label=financial+contributors)](https://opencollective.com/raspap) ![https://travis-ci.com/billz/raspap-webgui/](https://img.shields.io/travis/com/billz/raspap-webgui/master) [![Crowdin](https://badges.crowdin.net/raspap/localized.svg)](https://crowdin.com/project/raspap) [![Twitter URL](https://img.shields.io/twitter/url?label=%40RaspAP&logoColor=%23d8224c&url=https%3A%2F%2Ftwitter.com%2Frasp_ap)](https://twitter.com/rasp_ap) [![Subreddit subscribers](https://img.shields.io/reddit/subreddit-subscribers/RaspAP?style=social)](https://www.reddit.com/r/RaspAP/)
RaspAP lets you quickly get a WiFi access point up and running to share the connectivity of many popular [Debian-based devices](#supported-operating-systems), including the Raspberry Pi. Our popular [Quick installer](#quick-installer) creates a known-good default configuration that "just works" on all current Raspberry Pis with onboard wireless. A responsive interface gives you control over the relevant services and networking options. Advanced DHCP settings, OpenVPN client support, SSL, security audits, themes and multilingual options are included.
@ -7,7 +7,7 @@ RaspAP has been featured on sites such as [Instructables](http://www.instructabl
We hope you enjoy using RaspAP as much as we do creating it. Tell us how you use this with [your own projects](https://github.com/billz/raspap-awesome).
![](https://i.imgur.com/BdEinwg.gif)
![](https://i.imgur.com/ikWvsMG.gif)
![](https://i.imgur.com/EiIpdOS.gif)
![](https://i.imgur.com/eCjUS1H.gif)
![](https://i.imgur.com/5FT2BcS.gif)
@ -31,7 +31,7 @@ We hope you enjoy using RaspAP as much as we do creating it. Tell us how you use
- [License](#license)
## Prerequisites
Start with a clean install of the [latest release of Raspbian](https://www.raspberrypi.org/downloads/raspbian/) (currently Buster). Raspbian Buster Lite is recommended.
Start with a clean install of the [latest release of Raspberry Pi OS (32-bit) Lite](https://www.raspberrypi.org/downloads/raspbian/). The Raspberry Pi OS desktop and 64-bit beta distros are unsupported.
1. Update Raspbian, including the kernel and firmware, followed by a reboot:
```
@ -61,7 +61,9 @@ configured as an access point as follows:
* SSID: `raspi-webgui`
* Password: ChangeMe
**Note:** As the name suggests, the Quick Installer is a great way to quickly setup a new AP. However, it does not automagically detect the unique configuration of your system. Best results are obtained by connecting to ethernet (`eth0`) or as a WiFi client, also known as managed mode, with `wlan0`. For the latter, refer to [this FAQ](https://github.com/billz/raspap-webgui/wiki/FAQs#how-do-i-prepare-the-sd-card-to-connect-to-wifi-in-headless-mode). Please [read this](https://github.com/billz/raspap-webgui/wiki/Reporting-issues) before reporting an issue.
**Note:** As the name suggests, the Quick Installer is a great way to quickly setup a new AP. However, it does not automagically detect the unique configuration of your system. Best results are obtained by connecting to ethernet (`eth0`) or as a WiFi client, also known as managed mode, with `wlan0`. For the latter, refer to [this FAQ](https://github.com/billz/raspap-webgui/wiki/FAQs#how-do-i-prepare-the-sd-card-to-connect-to-wifi-in-headless-mode). Special instructions for the Pi Zero W are [available here](https://github.com/billz/raspap-webgui/wiki/RPi-Zero-W-AP-STA-mode).
Please [read this](https://github.com/billz/raspap-webgui/wiki/Reporting-issues) before reporting an issue.
## Ad Blocking
This feature uses DNS blacklisting to block requests for ads, trackers and other undesirable hosts. To enable ad blocking, simply respond to the prompt during the installation. As a beta release, we encourage testing and feedback from users of RaspAP.
@ -78,9 +80,9 @@ By default RaspAP configures a routed AP for your clients to connect to. A bridg
More information on Bridged AP mode is provided [on our wiki](https://github.com/billz/raspap-webgui/wiki/Bridged-AP-mode).
## Simultaneous AP and Wifi client
RaspAP lets you easily create an AP with a Wifi client configuration. With your system configured in managed mode, enable the AP from the **Advanced** tab of **Configure hotspot** by sliding the **Wifi client AP mode** toggle. Save settings and start the hotspot. The managed mode AP is functional without restart.
RaspAP lets you create an AP with a Wifi client configuration, often called AP-STA mode. With your system configured in managed mode, enable the AP from the **Advanced** tab of **Configure hotspot** by sliding the **Wifi client AP mode** toggle. Save settings and start the hotspot. The managed mode AP is functional without restart.
**Note:** This option is disabled until you configure your system as a wireless client. For a device operating in [managed mode](https://github.com/billz/raspap-webgui/wiki/FAQs#how-do-i-prepare-the-sd-card-to-connect-to-wifi-in-headless-mode) without an `eth0` connection, this configuration must be enabled _before_ a reboot.
**Note:** This option is disabled until you configure your system as a wireless client. For a device operating in [managed mode](https://github.com/billz/raspap-webgui/wiki/FAQs#how-do-i-prepare-the-sd-card-to-connect-to-wifi-in-headless-mode) without an `eth0` connection, this configuration must be enabled [_before_ a reboot](https://github.com/billz/raspap-webgui/wiki/RPi-Zero-W-AP-STA-mode).
## Support us
RaspAP is free software, but powered by your support. If you find RaspAP useful for your personal or commercial projects, please [become a GitHub sponsor](https://github.com/sponsors/billz), join the project on [Open Collective](https://opencollective.com/raspap) or make a one-time donation with [PayPal](https://www.paypal.com/paypalme2/billzgithub). Any of these options makes a big difference!
@ -98,7 +100,7 @@ RaspAP was originally made for Raspbian, but now also installs on the following
| Distribution | Release | Architecture | Support |
|---|:---:|:---:|:---:|
| Raspbian | Buster | ARM | Official |
| Raspberry Pi OS | (32-bit) Lite Buster | ARM | Official |
| Armbian | Buster | [ARM](https://docs.armbian.com/#supported-chips) | Official |
| Debian | Buster | ARM / x86_64 | Beta |
| Ubuntu | 18.04 LTS / 19.10 | ARM / x86_64 | Beta |
@ -120,7 +122,7 @@ The following translations are currently maintained by the project:
- Español
- Finnish
- Français
- ελληνικό (Greek)
- Ελληνικά (Greek)
- Indonesian
- Italiano
- 日本語 (Japanese)

12
ajax/networking/gen_int_config.php

@ -6,18 +6,20 @@ require_once '../../includes/config.php';
require_once '../../includes/functions.php';
if (isset($_POST['generate'])) {
$cnfNetworking = array_diff(scandir(RASPI_CONFIG_NETWORKING, 1), array('..','.','dhcpcd.conf'));
$cnfNetworking = array_diff(scandir(RASPI_CONFIG_NETWORKING, 1), array('..','.','dhcpcd.conf','defaults'));
$cnfNetworking = array_combine($cnfNetworking, $cnfNetworking);
$strConfFile = "";
$strConfFile = file_get_contents(RASPI_CONFIG_NETWORKING.'/defaults')."\n";
foreach ($cnfNetworking as $index => $file) {
if ($index != "defaults") {
$cnfFile = parse_ini_file(RASPI_CONFIG_NETWORKING.'/'.$file, false, INI_SCANNER_RAW);
if ($cnfFile['static'] === 'true') {
$strConfFile .= "#Static IP configured for ".$cnfFile['interface']."\n";
$strConfFile .= "interface ".$cnfFile['interface']."\n";
$strConfFile .= "static ip_address=".$cnfFile['ip_address']."\n";
$strConfFile .= "static routers=".$cnfFile['routers']."\n";
$strConfFile .= "static domain_name_servers=".$cnfFile['domain_name_server']."\n";
$strConfFile .= "static domain_name_servers=".$cnfFile['domain_name_server']."\n\n";
} elseif ($cnfFile['static'] === 'false' && $cnfFile['failover'] === 'true') {
$strConfFile .= "#Failover static IP configured for ".$cnfFile['interface']."\n";
$strConfFile .= "profile static_".$cnfFile['interface']."\n";
$strConfFile .= "static ip_address=".$cnfFile['ip_address']."\n";
$strConfFile .= "static routers=".$cnfFile['routers']."\n";
@ -27,13 +29,11 @@ if (isset($_POST['generate'])) {
} else {
$strConfFile .= "#DHCP configured for ".$cnfFile['interface']."\n\n";
}
} else {
$strConfFile .= file_get_contents(RASPI_CONFIG_NETWORKING.'/'.$index)."\n\n";
}
}
if (file_put_contents(RASPI_CONFIG_NETWORKING.'/dhcpcd.conf', $strConfFile)) {
exec('sudo /bin/cp /etc/raspap/networking/dhcpcd.conf /etc/dhcpcd.conf');
exec('sudo /bin/cp '.RASPI_CONFIG_NETWORKING.'/dhcpcd.conf '.RASPI_DHCPCD_CONFIG);
$output = ['return'=>0,'output'=>'Settings successfully applied'];
} else {
$output = ['return'=>2,'output'=>'Unable to write to apply settings'];

1
ajax/networking/wifi_stations.php

@ -13,5 +13,6 @@ $ssid = null;
knownWifiStations($networks);
nearbyWifiStations($networks, !isset($_REQUEST["refresh"]));
connectedWifiStations($networks);
sortNetworksByRSSI($networks);
echo renderTemplate('wifi_stations', compact('networks'));

47
app/css/custom.css → app/css/custom.php

@ -1,3 +1,9 @@
<?php header("Content-Type: text/css; charset=utf-8"); ?>
<?php
require_once '../../includes/functions.php';
$color = getColorOpt();
?>
/*
Theme Name: RaspAP default
Author: @billz
@ -51,9 +57,15 @@ body {
}
.card .card-header {
border-color: #d8224c;
background-color: #d8224c;
border-color: <?php echo $color; ?>;
color: #fff;
background-color: <?php echo $color; ?>;
}
.btn-primary {
color: <?php echo $color; ?>;
border-color: <?php echo $color; ?>;
background-color: #fff;
}
.card-footer {
@ -86,9 +98,7 @@ a.nav-link.active {
}
.btn-primary {
color: #d8224c;
background-color: #fff;
border-color: #d8224c;
}
.btn-warning {
@ -96,8 +106,8 @@ a.nav-link.active {
}
.btn-primary:hover {
background-color: #c61931;
border-color: #c61931;
background-color: <?php echo $color; ?>;
border-color: <?php echo $color; ?>;
}
i.fa.fa-bars {
@ -123,21 +133,6 @@ i.fa.fa-bars:hover{
float: left;
}
.webconsole {
width:100%;
height:100%;
border:1px solid;
}
#console {
height:500px;
}
.systemtabcontent {
height:100%;
min-height:500px;
}
.service-status {
border-width: 0;
}
@ -232,10 +227,18 @@ canvas#divDBChartBandwidthhourly {
.check-updated {
opacity: 0;
color: #1cc88a;
color: #90ee90;
}
.check-progress {
color: #999;
}
.fa-check {
color: #90ee90;
}
.fa-times {
color: #ff4500;
}

8
app/css/hackernews.css

@ -271,3 +271,11 @@ canvas#divDBChartBandwidthhourly {
color: #999;
}
.fa-check {
color: #90ee90;
}
.fa-times {
color: #ff4500;
}

22
app/css/lightsout.css

@ -166,6 +166,10 @@ hr {
font-family: inherit;
}
.ra-raspap:before {
color: #ac1b3d !important;
}
.sidebar-light #sidebarToggle {
background-color: #202020;
border: 1px solid #afafaf !important
@ -353,16 +357,6 @@ color: #d2d2d2 !important
border-color: #404040;
}
.webconsole {
width: 100%;
height: 20rem;
border: 1px solid #404040;
}
#console {
height: 500px;
}
tspan, rect {
fill: #d2d2d2;
}
@ -452,3 +446,11 @@ canvas#divDBChartBandwidthhourly {
color: #999;
}
.fa-check {
color: #90ee90;
}
.fa-times {
color: #ff4500;
}

15
app/img/raspAP-logo.svg → app/img/raspAP-logo.php

@ -1,3 +1,8 @@
<?php header("Content-Type: image/svg+xml; charset=utf-8"); ?>
<?php
require_once '../../includes/functions.php';
$color = getColorOpt();
?>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
@ -27,20 +32,20 @@
transform="translate(192.6768,123.4365)"
id="g20"><path
id="path22"
style="fill:#d8224c;fill-opacity:1;fill-rule:nonzero;stroke:none"
style="fill:<?php echo $color; ?>;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 0,0 c 0,-37.169 -30.128,-67.3 -67.296,-67.3 -37.167,0 -67.294,30.131 -67.294,67.3 0,37.165 30.127,67.296 67.294,67.296 C -30.128,67.296 0,37.165 0,0" /></g><g
transform="translate(125.3823,219.0791)"
id="g24"><path
id="path26"
style="fill:#d8224c;fill-opacity:1;fill-rule:nonzero;stroke:none"
style="fill:<?php echo $color; ?>;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 0,0 c -52.737,0 -95.641,-42.905 -95.641,-95.643 0,-52.74 42.904,-95.647 95.641,-95.647 52.737,0 95.642,42.907 95.642,95.647 C 95.642,-42.905 52.737,0 0,0 m 0,-217.29 c -67.073,0 -121.641,54.571 -121.641,121.647 C -121.641,-28.569 -67.073,26 0,26 67.074,26 121.642,-28.569 121.642,-95.643 121.642,-162.719 67.074,-217.29 0,-217.29" /></g><g
transform="translate(144.4277,271.9385)"
id="g28"><path
id="path30"
style="fill:#d8224c;fill-opacity:1;fill-rule:nonzero;stroke:none"
style="fill:<?php echo $color; ?>;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 0,0 c 66.188,0 121.118,-49.055 130.392,-112.714 l 28.259,-1.874 C 150.044,-34.655 82.181,27.791 0,27.791 c -3.892,0 -7.75,-0.147 -11.571,-0.423 L -9.73,-0.397 C -6.513,-0.161 -3.275,0 0,0" /></g><g
transform="translate(144.4883,334.7588)"
id="g32"><path
id="path34"
style="fill:#d8224c;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 0,0 c 101.94,0 185.667,-79.438 192.56,-179.664 l 27.962,-1.857 C 214.513,-65.087 117.899,27.791 0,27.791 c -5.31,0 -10.576,-0.2 -15.792,-0.571 l 1.84,-27.728 C -9.343,-0.177 -4.691,0 0,0" /></g></g></g></g></svg>
style="fill:<?php echo $color; ?>;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 0,0 c 101.94,0 185.667,-79.438 192.56,-179.664 l 27.962,-1.857 C 214.513,-65.087 117.899,27.791 0,27.791 c -5.31,0 -10.576,-0.2 -15.792,-0.571 l 1.84,-27.728 C -9.343,-0.177 -4.691,0 0,0" /></g></g></g></g></svg>

6
app/img/wifi-qr-code.php

@ -4,6 +4,12 @@ require_once '../../includes/config.php';
require_once '../../includes/defaults.php';
require_once '../../includes/functions.php';
// prevent direct file access
if (!isset($_SERVER['HTTP_REFERER'])) {
header('HTTP/1.0 403 Forbidden');
exit;
}
function qr_encode($str)
{
return preg_replace('/(?<!\\\)([\":;,])/', '\\\\\1', $str);

3
app/js/custom.js

@ -375,8 +375,9 @@ function getCookie(cname) {
return (value != null) ? unescape(value[1]) : null;
}
// Define themes
var themes = {
"default": "custom.css",
"default": "custom.php",
"hackernews" : "hackernews.css",
"lightsout" : "lightsout.css",
}

22
app/js/huebee.js

@ -0,0 +1,22 @@
// Initialize Huebee color picker
var elem = document.querySelector('.color-input');
var hueb = new Huebee( elem, {
notation: 'hex',
saturations: 2,
customColors: [ '#d8224c', '#dd4814', '#ea0', '#19f', '#333' ],
className: 'light-picker',
hue0: 210
});
// Set custom color if defined
var color = getCookie('color');
if (color == null || color == '') {
color = '#d8224c';
}
hueb.setColor(color);
// Change event
hueb.on( 'change', function( color, hue, sat, lum ) {
setCookie('color',color,90);
})

31
composer.json

@ -0,0 +1,31 @@
{
"name": "billz/raspap-webgui",
"description": "Simple AP setup and wifi mangement for Debian-based devices",
"license": "GPL-3.0",
"homepage": "https://raspap.com/",
"keywords": ["raspberrypi", "debian", "armbian", "wifi"],
"type": "raspap-core",
"authors": [
{
"name": "RaspAP Team",
"email": "billzimmerman@gmail.com",
"homepage": "https://raspap.com/"
}
],
"require": {
"php": "^7.0"
},
"require-dev": {
"php-parallel-lint/php-parallel-lint": "^1.2.0",
"phpcompatibility/php-compatibility": "^9.3.5",
"squizlabs/php_codesniffer": "^3.5.5"
},
"scripts": {
"lint": "parallel-lint . --exclude vendor",
"phpcs": "phpcs -p -s --config-set installed_paths vendor/phpcompatibility/php-compatibility .",
"test": [
"composer lint",
"composer phpcs"
]
}
}

8
config/config.php

@ -1,10 +1,10 @@
<?php
define('RASPI_VERSION', '2.4');
define('RASPI_BRAND_TEXT', 'RaspAP');
define('RASPI_CONFIG', '/etc/raspap');
define('RASPI_CONFIG_NETWORKING', RASPI_CONFIG.'/networking');
define('RASPI_ADMIN_DETAILS', RASPI_CONFIG.'/raspap.auth');
define('RASPI_WIFI_CLIENT_INTERFACE', 'wlan0');
define('RASPI_WIFI_AP_INTERFACE', 'wlan0');
define('RASPI_CACHE_PATH', sys_get_temp_dir() . '/raspap');
// Constants for configuration file paths.
@ -25,9 +25,11 @@ define('RASPI_WIREGUARD_SERVER_CONFIG', '/etc/wireguard/wg0.conf');
define('RASPI_WIREGUARD_CLIENT_CONFIG', '/etc/wireguard/wg0-client.conf');
define('RASPI_TORPROXY_CONFIG', '/etc/tor/torrc');
define('RASPI_LIGHTTPD_CONFIG', '/etc/lighttpd/lighttpd.conf');
define('RASPI_ACCESS_CHECK_IP', '1.1.1.1');
define('RASPI_ACCESS_CHECK_DNS', 'one.one.one.one');
// Constant for the 5GHz wireless regulatory domain
define('RASPI_5GHZ_ISO_ALPHA2', array('US'));
define('RASPI_5GHZ_ISO_ALPHA2', array('NL','US'));
// Optional services, set to true to enable.
define('RASPI_WIFICLIENT_ENABLED', true);

4
config/wireless.json

@ -6,11 +6,11 @@
"channels": [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ]
},
"2_4GHz_max14ch": {
"countries": [ "JP" ],
"countries": [ "JP", "NL" ],
"channels": [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 ]
},
"5Ghz_max48ch": {
"countries": [ "US" ],
"countries": [ "NL","US" ],
"channels": [ 36, 40, 44, 48 ]
}
}}

83
dist/huebee/huebee.css

@ -0,0 +1,83 @@
/*! Huebee v2.1.0
https://huebee.buzz
---------------------------------------------- */
.huebee {
position: absolute;
z-index: 1;
transform: translateY(0px);
transition: opacity 0.15s, transform 0.15s;
}
.huebee.is-hidden {
opacity: 0;
transform: translateY(10px);
}
.huebee.is-static-open {
position: relative;
z-index: auto;
}
.huebee__container {
position: absolute;
left: 0;
top: 5px;
padding: 10px;
background: #EEE;
border-radius: 5px;
box-shadow: 0 5px 10px hsla(0, 0%, 0%, 0.3);
}
.huebee.is-static-open .huebee__container {
position: relative;
display: inline-block;
left: auto;
top: auto;
box-shadow: none;
}
.huebee__canvas {
display: block;
cursor: pointer;
}
.huebee__cursor {
width: 15px;
height: 15px;
position: absolute;
left: 0px;
top: 0px;
box-sizing: content-box;
border: 3px solid white;
border-radius: 5px;
pointer-events: none;
}
.huebee__cursor.is-hidden { opacity: 0; }
.huebee__close-button {
display: block;
position: absolute;
width: 24px;
height: 24px;
top: -9px;
right: -9px;
border-radius: 12px;
background: #222;
}
.huebee__close-button__x {
stroke: white;
stroke-width: 3;
stroke-linecap: round;
}
.huebee__close-button:hover {
background: white;
cursor: pointer;
}
.huebee__close-button:hover .huebee__close-button__x {
stroke: #222;
}

4
dist/huebee/huebee.min.css

@ -0,0 +1,4 @@
/*! Huebee v2.1.0
https://huebee.buzz
---------------------------------------------- */
.huebee{position:absolute;z-index:1;transform:translateY(0);transition:opacity .15s,transform .15s}.huebee.is-hidden{opacity:0;transform:translateY(10px)}.huebee.is-static-open{position:relative;z-index:auto}.huebee__container{position:absolute;left:0;top:5px;padding:10px;background:#eee;border-radius:5px;box-shadow:0 5px 10px hsla(0,0%,0%,.3)}.huebee.is-static-open .huebee__container{position:relative;display:inline-block;left:auto;top:auto;box-shadow:none}.huebee__canvas{display:block;cursor:pointer}.huebee__cursor{width:15px;height:15px;position:absolute;left:0;top:0;box-sizing:content-box;border:3px solid #fff;border-radius:5px;pointer-events:none}.huebee__cursor.is-hidden{opacity:0}.huebee__close-button{display:block;position:absolute;width:24px;height:24px;top:-9px;right:-9px;border-radius:12px;background:#222}.huebee__close-button__x{stroke:#fff;stroke-width:3;stroke-linecap:round}.huebee__close-button:hover{background:#fff;cursor:pointer}.huebee__close-button:hover .huebee__close-button__x{stroke:#222}

1125
dist/huebee/huebee.pkgd.js
File diff suppressed because it is too large
View File

22
dist/huebee/huebee.pkgd.min.js
File diff suppressed because it is too large
View File

5
gulpfile.js

@ -77,7 +77,10 @@ function modules() {
// SB Admin2 CSS
var sbadmin2CSS = gulp.src('./node_modules/startbootstrap-sb-admin-2/css/*')
.pipe(gulp.dest('./dist/sb-admin-2/css'));
return merge(bootstrapJS, bootstrapSCSS, chartJS, dataTables, fontAwesome, jquery, jqueryEasing, sbadmin2JS, sbadmin2CSS);
// Huebee
var huebee = gulp.src('./node_modules/huebee/dist/*')
.pipe(gulp.dest('./dist/huebee'));
return merge(bootstrapJS, bootstrapSCSS, chartJS, dataTables, fontAwesome, jquery, jqueryEasing, sbadmin2JS, sbadmin2CSS, huebee);
}
// CSS task

0
includes/adblock.php

7
includes/configure_client.php

@ -12,11 +12,13 @@ function DisplayWPAConfig()
$status = new StatusMessages();
$networks = [];
getWifiInterface();
knownWifiStations($networks);
if (isset($_POST['connect'])) {
$result = 0;
exec('sudo wpa_cli -i ' . RASPI_WPA_CTRL_INTERFACE . ' select_network '.strval($_POST['connect']));
exec('sudo wpa_cli -i ' . $_SESSION['wifi_client_interface'] . ' select_network '.strval($_POST['connect']));
$status->addMessage('New network selected', 'success');
} elseif (isset($_POST['client_settings'])) {
$tmp_networks = $networks;
if ($wpa_file = fopen('/tmp/wifidata', 'w')) {
@ -75,7 +77,7 @@ function DisplayWPAConfig()
if ($ok) {
system('sudo cp /tmp/wifidata ' . RASPI_WPA_SUPPLICANT_CONFIG, $returnval);
if ($returnval == 0) {
exec('sudo wpa_cli -i ' . RASPI_WIFI_CLIENT_INTERFACE . ' reconfigure', $reconfigure_out, $reconfigure_return);
exec('sudo wpa_cli -i ' . $_SESSION['wifi_client_interface'] . ' reconfigure', $reconfigure_out, $reconfigure_return);
if ($reconfigure_return == 0) {
$status->addMessage('Wifi settings updated successfully', 'success');
$networks = $tmp_networks;
@ -93,6 +95,7 @@ function DisplayWPAConfig()
nearbyWifiStations($networks);
connectedWifiStations($networks);
sortNetworksByRSSI($networks);
echo renderTemplate("configure_client", compact("status"));
}

30
includes/dashboard.php

@ -1,16 +1,17 @@
<?php
require_once 'config.php';
require_once 'includes/config.php';
require_once 'includes/wifi_functions.php';
/**
* Show dashboard page.
*/
function DisplayDashboard(&$extraFooterScripts)
{
getWifiInterface();
$status = new StatusMessages();
// Need this check interface name for proper shell execution.
if (!preg_match('/^([a-zA-Z0-9]+)$/', RASPI_WIFI_CLIENT_INTERFACE)) {
if (!preg_match('/^([a-zA-Z0-9]+)$/', $_SESSION['wifi_client_interface'])) {
$status->addMessage(_('Interface name invalid.'), 'danger');
$status->showMessages();
return;
@ -21,8 +22,7 @@ function DisplayDashboard(&$extraFooterScripts)
$status->showMessages();
return;
}
exec('ip a show '.RASPI_WIFI_CLIENT_INTERFACE, $stdoutIp);
exec('ip a show '.$_SESSION['ap_interface'], $stdoutIp);
$stdoutIpAllLinesGlued = implode(" ", $stdoutIp);
$stdoutIpWRepeatedSpaces = preg_replace('/\s\s+/', ' ', $stdoutIpAllLinesGlued);
@ -61,26 +61,26 @@ function DisplayDashboard(&$extraFooterScripts)
// Because of table layout used in the ip output we get the interface statistics directly from
// the system. One advantage of this is that it could work when interface is disable.
exec('cat /sys/class/net/'.RASPI_WIFI_CLIENT_INTERFACE.'/statistics/rx_packets ', $stdoutCatRxPackets);
exec('cat /sys/class/net/'.$_SESSION['ap_interface'].'/statistics/rx_packets ', $stdoutCatRxPackets);
$strRxPackets = _('No data');
if (ctype_digit($stdoutCatRxPackets[0])) {
$strRxPackets = $stdoutCatRxPackets[0];
}
exec('cat /sys/class/net/'.RASPI_WIFI_CLIENT_INTERFACE.'/statistics/tx_packets ', $stdoutCatTxPackets);
exec('cat /sys/class/net/'.$_SESSION['ap_interface'].'/statistics/tx_packets ', $stdoutCatTxPackets);
$strTxPackets = _('No data');
if (ctype_digit($stdoutCatTxPackets[0])) {
$strTxPackets = $stdoutCatTxPackets[0];
}
exec('cat /sys/class/net/'.RASPI_WIFI_CLIENT_INTERFACE.'/statistics/rx_bytes ', $stdoutCatRxBytes);
exec('cat /sys/class/net/'.$_SESSION['ap_interface'].'/statistics/rx_bytes ', $stdoutCatRxBytes);
$strRxBytes = _('No data');
if (ctype_digit($stdoutCatRxBytes[0])) {
$strRxBytes = $stdoutCatRxBytes[0];
$strRxBytes .= getHumanReadableDatasize($strRxBytes);
}
exec('cat /sys/class/net/'.RASPI_WIFI_CLIENT_INTERFACE.'/statistics/tx_bytes ', $stdoutCatTxBytes);
exec('cat /sys/class/net/'.$_SESSION['ap_interface'].'/statistics/tx_bytes ', $stdoutCatTxBytes);
$strTxBytes = _('No data');
if (ctype_digit($stdoutCatTxBytes[0])) {
$strTxBytes = $stdoutCatTxBytes[0];
@ -89,7 +89,7 @@ function DisplayDashboard(&$extraFooterScripts)
define('SSIDMAXLEN', 32);
// Warning iw comes with: "Do NOT screenscrape this tool, we don't consider its output stable."
exec('iw dev '.RASPI_WIFI_CLIENT_INTERFACE.' link ', $stdoutIw);
exec('iw dev ' .$_SESSION['wifi_client_interface']. ' link ', $stdoutIw);
$stdoutIwAllLinesGlued = implode(' ', $stdoutIw);
$stdoutIwWRepSpaces = preg_replace('/\s\s+/', ' ', $stdoutIwAllLinesGlued);
@ -121,7 +121,7 @@ function DisplayDashboard(&$extraFooterScripts)
$bitrate = empty($bitrate) ? "-" : $bitrate;
// txpower is now displayed on iw dev(..) info command, not on link command.
exec('iw dev '.RASPI_WIFI_CLIENT_INTERFACE.' info ', $stdoutIwInfo);
exec('iw dev '.$_SESSION['wifi_client_interface'].' info ', $stdoutIwInfo);
$stdoutIwInfoAllLinesGlued = implode(' ', $stdoutIwInfo);
$stdoutIpInfoWRepSpaces = preg_replace('/\s\s+/', ' ', $stdoutIwInfoAllLinesGlued);
@ -147,13 +147,12 @@ function DisplayDashboard(&$extraFooterScripts)
$classMsgDevicestatus = 'success';
}
if (!RASPI_MONITOR_ENABLED) {
if (isset($_POST['ifdown_wlan0'])) {
// Pressed stop button
if ($interfaceState === 'UP') {
$status->addMessage(sprintf(_('Interface is going %s.'), _('down')), 'warning');
exec('sudo ip link set '.RASPI_WIFI_CLIENT_INTERFACE.' down');
exec('sudo ip link set '.$_SESSION['wifi_client_interface'].' down');
$wlan0up = false;
$status->addMessage(sprintf(_('Interface is now %s.'), _('down')), 'success');
} elseif ($interfaceState === 'unknown') {
@ -165,8 +164,8 @@ function DisplayDashboard(&$extraFooterScripts)
// Pressed start button
if ($interfaceState === 'DOWN') {
$status->addMessage(sprintf(_('Interface is going %s.'), _('up')), 'warning');
exec('sudo ip link set ' . RASPI_WIFI_CLIENT_INTERFACE . ' up');
exec('sudo ip -s a f label ' . RASPI_WIFI_CLIENT_INTERFACE);
exec('sudo ip link set ' .$_SESSION['wifi_client_interface']. ' up');
exec('sudo ip -s a f label ' . $_SESSION['wifi_client_interface']);
$wlan0up = true;
$status->addMessage(sprintf(_('Interface is now %s.'), _('up')), 'success');
} elseif ($interfaceState === 'unknown') {
@ -201,6 +200,7 @@ function DisplayDashboard(&$extraFooterScripts)
)
);
$extraFooterScripts[] = array('src'=>'app/js/dashboardchart.js', 'defer'=>false);
$extraFooterScripts[] = array('src'=>'app/js/linkquality.js', 'defer'=>false);
}

7
includes/defaults.php

@ -5,10 +5,11 @@ if (!defined('RASPI_CONFIG')) {
}
$defaults = [
'RASPI_VERSION' => '2.4',
'RASPI_BRAND_TEXT' => 'RaspAP',
'RASPI_VERSION' => '2.5',
'RASPI_CONFIG_NETWORKING' => RASPI_CONFIG.'/networking',
'RASPI_ADMIN_DETAILS' => RASPI_CONFIG.'/raspap.auth',
'RASPI_WIFI_CLIENT_INTERFACE' => 'wlan0',
'RASPI_WIFI_AP_INTERFACE' => 'wlan0',
'RASPI_CACHE_PATH' => sys_get_temp_dir() . '/raspap',
// Constants for configuration file paths.
@ -29,6 +30,8 @@ $defaults = [
'RASPI_WIREGUARD_CLIENT_CONFIG' => '/etc/wireguard/wg0-client.conf',
'RASPI_TORPROXY_CONFIG' => '/etc/tor/torrc',
'RASPI_LIGHTTPD_CONFIG' => '/etc/lighttpd/lighttpd.conf',
'RASPI_ACCESS_CHECK_IP' => '1.1.1.1',
'RASPI_ACCESS_CHECK_DNS' => 'one.one.one.one',
// Optional services, set to true to enable.
'RASPI_WIFICLIENT_ENABLED' => true,

35
includes/functions.php

@ -417,3 +417,38 @@ function formatDateAgo($datetime, $full = false)
if (!$full) $string = array_slice($string, 0, 1);
return $string ? implode(', ', $string) . ' ago' : 'just now';
}
function getThemeOpt()
{
if (!isset($_COOKIE['theme'])) {
$theme = "custom.php";
} else {
$theme = $_COOKIE['theme'];
}
return 'app/css/'.htmlspecialchars($theme, ENT_QUOTES);
}
function getColorOpt()
{
if (!isset($_COOKIE['color'])) {
$color = "#d8224c";
} else {
$color = $_COOKIE['color'];
}
return $color;
}
function getSidebarState()
{
if ($_COOKIE['sidebarToggled'] == 'true' ) {
return"toggled";
}
}
// Returns bridged AP mode status
function getBridgedState()
{
$arrHostapdConf = parse_ini_file(RASPI_CONFIG.'/hostapd.ini');
// defaults to false
return $arrHostapdConf['BridgedEnable'];
}

61
includes/hostapd.php

@ -1,8 +1,11 @@
<?php
require_once 'includes/status_messages.php';
require_once 'status_messages.php';
require_once 'app/lib/system.php';
require_once 'config.php';
require_once 'includes/wifi_functions.php';
require_once 'includes/config.php';
getWifiInterface();
/**
*
@ -24,6 +27,7 @@ function DisplayHostAPDConfig()
$arrEncType = array('TKIP' => 'TKIP', 'CCMP' => 'CCMP', 'TKIP CCMP' => 'TKIP+CCMP');
$managedModeEnabled = false;
exec("ip -o link show | awk -F': ' '{print $2}'", $interfaces);
exec("iw reg get | awk '/country / { sub(/:/,\"\",$2); print $2 }'", $country_code);
if (!RASPI_MONITOR_ENABLED) {
if (isset($_POST['SaveHostAPDSettings'])) {
@ -56,7 +60,7 @@ function DisplayHostAPDConfig()
}
exec('cat '. RASPI_HOSTAPD_CONFIG, $hostapdconfig);
exec('iwgetid '. RASPI_WIFI_CLIENT_INTERFACE. ' -r', $wifiNetworkID);
exec('iwgetid '. $_POST['interface']. ' -r', $wifiNetworkID);
if (!empty($wifiNetworkID[0])) {
$managedModeEnabled = true;
}
@ -74,6 +78,11 @@ function DisplayHostAPDConfig()
}
};
// assign country_code from iw reg if not set in config
if (!isset($arrConfig['country_code']) && isset($country_code[0])) {
$arrConfig['country_code'] = $country_code[0];
}
echo renderTemplate(
"hostapd", compact(
"status",
@ -146,27 +155,29 @@ function SaveHostAPDConfig($wpa_array, $enc_types, $modes, $interfaces, $status)
if ($arrHostapdConf['LogEnable'] == 0) {
if (isset($_POST['logEnable'])) {
$logEnable = 1;
exec('sudo /etc/raspap/hostapd/enablelog.sh');
exec('sudo '.RASPI_CONFIG.'/hostapd/enablelog.sh');
} else {
exec('sudo /etc/raspap/hostapd/disablelog.sh');
exec('sudo '.RASPI_CONFIG.'/hostapd/disablelog.sh');
}
} else {
if (isset($_POST['logEnable'])) {
$logEnable = 1;
exec('sudo /etc/raspap/hostapd/enablelog.sh');
exec('sudo '.RASPI_CONFIG.'/hostapd/enablelog.sh');
} else {
exec('sudo /etc/raspap/hostapd/disablelog.sh');
exec('sudo '.RASPI_CONFIG.'/hostapd/disablelog.sh');
}
}
$cfg = [];
$cfg['WifiInterface'] = $_POST['interface'];
$cfg['LogEnable'] = $logEnable;
// Save previous Client mode status when Bridged
$cfg['WifiAPEnable'] = ($bridgedEnable == 1 ?
$arrHostapdConf['WifiAPEnable'] : $wifiAPEnable);
$cfg['BridgedEnable'] = $bridgedEnable;
$cfg['WifiManaged'] = RASPI_WIFI_CLIENT_INTERFACE;
write_php_ini($cfg, '/etc/raspap/hostapd.ini');
$cfg['WifiManaged'] = $_POST['interface'];
write_php_ini($cfg, RASPI_CONFIG.'/hostapd.ini');
$_SESSION['ap_interface'] = $_POST['interface'];
// Verify input
if (empty($_POST['ssid']) || strlen($_POST['ssid']) > 32) {
@ -242,6 +253,9 @@ function SaveHostAPDConfig($wpa_array, $enc_types, $modes, $interfaces, $status)
$config.= 'vht_capab=[MAX-AMSDU-3839][SHORT-GI-80]'.PHP_EOL;
$config.= 'vht_oper_chwidth=1'.PHP_EOL;
$config.= 'vht_oper_centr_freq_seg0_idx=42'.PHP_EOL.PHP_EOL;
} elseif ($_POST['hw_mode'] === 'w') {
$config.= 'ieee80211w=2'.PHP_EOL;
$config.= 'wpa_key_mgmt=WPA-EAP-SHA256'.PHP_EOL;
} else {
$config.= 'hw_mode='.$_POST['hw_mode'].PHP_EOL;
$config.= 'ieee80211n=0'.PHP_EOL;
@ -252,7 +266,7 @@ function SaveHostAPDConfig($wpa_array, $enc_types, $modes, $interfaces, $status)
if ($wifiAPEnable == 1) {
$config.= 'interface=uap0'.PHP_EOL;
} elseif ($bridgedEnable == 1) {
$config.='interface='.RASPI_WIFI_CLIENT_INTERFACE.PHP_EOL;
$config.='interface='.$_POST['interface'].PHP_EOL;
$config.= 'bridge=br0'.PHP_EOL;
} else {
$config.= 'interface='.$_POST['interface'].PHP_EOL;
@ -300,11 +314,12 @@ function SaveHostAPDConfig($wpa_array, $enc_types, $modes, $interfaces, $status)
system('sudo cp /tmp/dnsmasqdata '.RASPI_DNSMASQ_CONFIG, $return);
// Set dnsmasq values from ini, fallback to default if undefined
$intConfig = parse_ini_file(RASPI_CONFIG_NETWORKING.'/'.RASPI_WIFI_CLIENT_INTERFACE.'.ini', false, INI_SCANNER_RAW);
$intConfig = parse_ini_file(RASPI_CONFIG_NETWORKING.'/'.$_POST['interface'].'.ini', false, INI_SCANNER_RAW);
$domain_name_server = ($intConfig['domain_name_server'] =='') ? '1.1.1.1 8.8.8.8' : $intConfig['domain_name_server'];
$routers = ($intConfig['routers'] == '') ? '10.3.141.1' : $intConfig['routers'];
$config = [ '# RaspAP wlan0 configuration' ];
// write options to dhcpcd.conf
$config = [ '# RaspAP '.$_POST['interface'].' configuration' ];
$config[] = 'hostname';
$config[] = 'clientid';
$config[] = 'persistent';
@ -327,12 +342,26 @@ function SaveHostAPDConfig($wpa_array, $enc_types, $modes, $interfaces, $status)
$config[] = 'static ip_address='.$ip_address;
$config[] = 'nohook wpa_supplicant';
} else {
// Default config
$ip_address = ($intConfig['ip_address'] == '') ? '10.3.141.1/24' : $intConfig['ip_address'];
$config[] = 'interface '.RASPI_WIFI_CLIENT_INTERFACE;
// Default config
$ip_address = "10.3.141.1/24"; // fallback IP
// default IP of the AP xxx.xxx.xxx.1/24 of the selected dhcp range
$def_ip = array();
if (preg_match("/^([0-9]{1,3}\.){3}/",$dhcp_range,$def_ip) ) $ip_address = $def_ip[0]."1/24";
// use static IP assigned to interface only, if consistent with the selected dhcp range
if (preg_match("/^([0-9]{1,3}\.){3}/",$intConfig['ip_address'],$int_ip) && $def_ip[0] === $int_ip[0]) $ip_address = $intConfig['ip_address'];
$config[] = 'interface '.$_POST['interface'];
$config[] = 'static ip_address='.$ip_address;
$config[] = 'static routers='.$routers;
$config[] = 'static domain_name_server='.$domain_name_server;
$config[] = PHP_EOL;
// write the static IP back to the $_POST['interface'].ini file
$intConfig['interface'] = $_POST['interface'];
$intConfig['ip_address'] = $ip_address;
$intConfig['domain_name_server'] = $domain_name_server;
$intConfig['routers'] = $routers;
$intConfig['static'] = "true";
$intConfig['failover'] = "false";
write_php_ini($intConfig, RASPI_CONFIG_NETWORKING.'/'.$_POST['interface'].".ini");
}
$config = join(PHP_EOL, $config);

30
includes/internetRoute.php

@ -0,0 +1,30 @@
<?php
$rInfo=array();
// get all default routes
exec('ip route list | sed -rn "s/default via (([0-9]{1,3}\.){3}[0-9]{1,3}).*dev (\w*).*src (([0-9]{1,3}\.){3}[0-9]{1,3}).*/\3 \4 \1/p"', $routes);
if (!empty($routes) ) {
foreach ($routes as $i => $route) {
$prop=explode(' ', $route);
$rInfo[$i]["interface"]=$prop[0];
$rInfo[$i]["ip-address"]=$prop[1];
$rInfo[$i]["gateway"]=$prop[2];
// resolve the name of the gateway (if possible)
unset($host);
exec('host '.$prop[2].' | sed -rn "s/.*domain name pointer (.*)\./\1/p" | head -n 1', $host);
$rInfo[$i]["gw-name"] = empty($host) ? "*" : $host[0];
if (isset($checkAccess) && $checkAccess) {
// check internet connectivity w/ and w/o DNS resolution
unset($okip);
exec('ping -W1 -c 1 -I '.$prop[0].' '.RASPI_ACCESS_CHECK_IP.' | sed -rn "s/.*icmp_seq=1.*time=.*/OK/p"',$okip);
$rInfo[$i]["access-ip"] = empty($okip) ? false : true;
unset($okdns);
exec('ping -W1 -c 1 -I '.$prop[0].' '.RASPI_ACCESS_CHECK_DNS.' | sed -rn "s/.*icmp_seq=1.*time=.*/OK/p"',$okdns);
$rInfo[$i]["access-dns"] = empty($okdns) ? false : true;
}
}
} else {
$rInfo = array("error"=>"No route to the internet found");
}
$rInfo_json = json_encode($rInfo);
?>

7
includes/openvpn.php

@ -1,7 +1,10 @@
<?php
require_once 'includes/status_messages.php';
require_once 'config.php';
require_once 'includes/config.php';
require_once 'includes/wifi_functions.php';
getWifiInterface();
/**
* Manage OpenVPN configuration
@ -146,7 +149,7 @@ function SaveOpenVPNConfig($status, $file, $authUser, $authPassword)
}
// Set iptables rules and, optionally, auth-user-pass
exec("sudo /etc/raspap/openvpn/configauth.sh $tmp_ovpnclient $auth_flag " .RASPI_WIFI_CLIENT_INTERFACE, $return);
exec("sudo /etc/raspap/openvpn/configauth.sh $tmp_ovpnclient $auth_flag " .$_SESSION['ap_interface'], $return);
foreach ($return as $line) {
$status->addMessage($line, 'info');
}

39
includes/system.php

@ -51,7 +51,12 @@ function RPiVersion()
if (array_key_exists($rev, $revisions)) {
return $revisions[$rev];
} else {
return 'Unknown Pi';
exec('cat /proc/device-tree/model', $model);
if (isset($model[0])) {
return $model[0];
} else {
return 'Unknown Device';
}
}
}
@ -72,19 +77,36 @@ function DisplaySystem()
}
if (!RASPI_MONITOR_ENABLED) {
if (isset($_POST['SaveServerPort'])) {
if (isset($_POST['SaveServerSettings'])) {
$good_input = true;
// Validate server port
if (isset($_POST['serverPort'])) {
if (strlen($_POST['serverPort']) > 4 || !is_numeric($_POST['serverPort'])) {
$status->addMessage('Invalid value for port number', 'danger');
$good_input = false;
} else {
$serverPort = escapeshellarg($_POST['serverPort']);
exec("sudo /etc/raspap/lighttpd/configport.sh $serverPort " .RASPI_LIGHTTPD_CONFIG. " ".$_SERVER['SERVER_NAME'], $return);
foreach ($return as $line) {
$status->addMessage($line, 'info');
}
}
}
// Validate server bind address
$serverBind = escapeshellarg('');
if ($_POST['serverBind'] && $_POST['serverBind'] !== null ) {
if (!filter_var($_POST['serverBind'], FILTER_VALIDATE_IP)) {
$status->addMessage('Invalid value for bind address', 'danger');
$good_input = false;
} else {
$serverBind = escapeshellarg($_POST['serverBind']);
}
}
// Save settings
if ($good_input) {
exec("sudo /etc/raspap/lighttpd/configport.sh $serverPort $serverBind " .RASPI_LIGHTTPD_CONFIG. " ".$_SERVER['SERVER_NAME'], $return);
foreach ($return as $line) {
$status->addMessage($line, 'info');
}
}
}
if (isset($_POST['system_reboot'])) {
$status->addMessage("System Rebooting Now!", "warning", false);
$result = shell_exec("sudo /sbin/reboot");
@ -101,7 +123,8 @@ function DisplaySystem()
}
exec('cat '. RASPI_LIGHTTPD_CONFIG, $return);
$conf = ParseConfig($return);
$ServerPort = $conf['server.port'];
$serverPort = $conf['server.port'];
$serverBind = str_replace('"', '',$conf['server.bind']);
// define locales
$arrLocales = array(
@ -127,5 +150,5 @@ function DisplaySystem()
'vi_VN.UTF-8' => 'Tiếng Việt (Vietnamese)'
);
echo renderTemplate("system", compact("arrLocales", "status", "system", "ServerPort"));
echo renderTemplate("system", compact("arrLocales", "status", "serverPort", "serverBind"));
}

7
includes/themes.php

@ -3,7 +3,7 @@
*
*
*/
function DisplayThemeConfig()
function DisplayThemeConfig(&$extraFooterScripts)
{
$themes = [
"default" => "RaspAP (default)",
@ -11,11 +11,14 @@ function DisplayThemeConfig()
"lightsout" => "Lights Out"
];
$themeFiles = [
"default" => "custom.css",
"default" => "custom.php",
"hackernews" => "hackernews.css",
"lightsout" => "lightsout.css"
];
$selectedTheme = array_search($_COOKIE['theme'], $themeFiles);
echo renderTemplate("themes", compact("themes", "selectedTheme"));
$extraFooterScripts[] = array('src'=>'dist/huebee/huebee.pkgd.min.js', 'defer'=>false);
$extraFooterScripts[] = array('src'=>'app/js/huebee.js', 'defer'=>false);
}

938
includes/webconsole.php
File diff suppressed because it is too large
View File

71
includes/wifi_functions.php

@ -53,26 +53,40 @@ function nearbyWifiStations(&$networks, $cached = true)
$scan_results = cache(
$cacheKey, function () {
exec('sudo wpa_cli -i ' . RASPI_WIFI_CLIENT_INTERFACE . ' scan');
exec('sudo wpa_cli -i ' .$_SESSION['wifi_client_interface']. ' scan');
sleep(3);
exec('sudo wpa_cli -i ' . RASPI_WIFI_CLIENT_INTERFACE . ' scan_results', $stdout);
exec('sudo wpa_cli -i ' .$_SESSION['wifi_client_interface']. ' scan_results', $stdout);
array_shift($stdout);
return implode("\n", $stdout);
}
);
// get the name of the AP. Should be excluded from nearby networks
exec('cat '.RASPI_HOSTAPD_CONFIG.' | sed -rn "s/ssid=(.*)\s*$/\1/p" ', $ap_ssid);
$ap_ssid = $ap_ssid[0];
foreach (explode("\n", $scan_results) as $network) {
$arrNetwork = preg_split("/[\t]+/", $network); // split result into array
if (!array_key_exists(4, $arrNetwork) ||
trim($arrNetwork[4]) == $ap_ssid) {
continue;
}
$ssid = trim($arrNetwork[4]);
// filter SSID string: anything invisible in 7bit ASCII or quotes -> ignore network
if (preg_match('[\x00-\x1f\x7f-\xff\'\`\´\"]', $ssid)) {
continue;
}
// If network is saved
if (array_key_exists(4, $arrNetwork) && array_key_exists($arrNetwork[4], $networks)) {
$networks[$arrNetwork[4]]['visible'] = true;
$networks[$arrNetwork[4]]['channel'] = ConvertToChannel($arrNetwork[1]);
if (array_key_exists($ssid, $networks)) {
$networks[$ssid]['visible'] = true;
$networks[$ssid]['channel'] = ConvertToChannel($arrNetwork[1]);
// TODO What if the security has changed?
} else {
$networks[$arrNetwork[4]] = array(
$networks[$ssid] = array(
'configured' => false,
'protocol' => ConvertToSecurity($arrNetwork[3]),
'channel' => ConvertToChannel($arrNetwork[1]),
@ -82,19 +96,56 @@ function nearbyWifiStations(&$networks, $cached = true)
);
}
// Save RSSI
if (array_key_exists(4, $arrNetwork)) {
$networks[$arrNetwork[4]]['RSSI'] = $arrNetwork[2];
// Save RSSI, if the current value is larger than the already stored
if (array_key_exists(4, $arrNetwork) && array_key_exists($arrNetwork[4], $networks)) {
if (! array_key_exists('RSSI', $networks[$arrNetwork[4]]) || $networks[$ssid]['RSSI'] < $arrNetwork[2]) {
$networks[$ssid]['RSSI'] = $arrNetwork[2];
}
}
}
}
function connectedWifiStations(&$networks)
{
exec('iwconfig ' . RASPI_WIFI_CLIENT_INTERFACE, $iwconfig_return);
exec('iwconfig ' .$_SESSION['wifi_client_interface'], $iwconfig_return);
foreach ($iwconfig_return as $line) {
if (preg_match('/ESSID:\"([^"]+)\"/i', $line, $iwconfig_ssid)) {
$networks[$iwconfig_ssid[1]]['connected'] = true;
}
}
}
function sortNetworksByRSSI(&$networks)
{
$valRSSI = array();
foreach ($networks as $SSID => $net) {
if (!array_key_exists('RSSI', $net)) {
$net['RSSI'] = -1000;
}
$valRSSI[$SSID] = $net['RSSI'];
}
$nets = $networks;
arsort($valRSSI);
$networks = array();
foreach ($valRSSI as $SSID => $RSSI) {
$networks[$SSID] = $nets[$SSID];
$networks[$SSID]['RSSI'] = $RSSI;
}
}
/*
* Determines the configured wireless AP interface
*
* If not saved in /etc/raspap/hostapd.ini, check for a second
* wireless interface with iw dev. Fallback to the constant
* value defined in config.php
*/
function getWifiInterface()
{
$arrHostapdConf = parse_ini_file(RASPI_CONFIG.'/hostapd.ini');
$iface = $_SESSION['ap_interface'] = isset($arrHostapdConf['WifiInterface']) ? $arrHostapdConf['WifiInterface'] : RASPI_WIFI_AP_INTERFACE;
// check for 2nd wifi interface -> wifi client on different interface
exec("iw dev | awk '$1==\"Interface\" && $2!=\"$iface\" {print $2}'",$iface2);
$_SESSION['wifi_client_interface'] = empty($iface2) ? $iface : trim($iface2[0]);
}

54
index.php

@ -3,19 +3,24 @@
/**
* Raspbian WiFi Configuration Portal (RaspAP)
*
* Enables use of simple web interface rather than SSH to control wifi and hostapd on the Raspberry Pi.
* Recommended distribution is Raspbian Buster Lite. Specific instructions to install the supported software are
* Simple AP setup & WiFi management for Debian-based devices.
* Enables use of simple web interface rather than SSH to control WiFi and related services on the Raspberry Pi.
* Recommended distribution is Raspberry Pi OS (32-bit) Lite. Specific instructions to install the supported software are
* in the README and original post by @SirLagz. For a quick run through, the packages required for the WebGUI are:
* lighttpd (version 1.4.53 installed via apt)
* php-cgi (version 7.3.14-1 installed via apt)
* php-cgi (version 7.3.19-1 installed via apt)
* along with their supporting packages, php7.3 will also need to be enabled.
*
* @author Lawrence Yau <sirlagz@gmail.com>
* @author Bill Zimmerman <billzimmerman@gmail.com>
* @license GNU General Public License, version 3 (GPL-3.0)
* @version 2.4
* @link https://github.com/billz/raspap-webgui
* @version 2.5
* @link https://github.com/billz/raspap-webgui/
* @link https://raspap.com/
* @see http://sirlagz.net/2013/02/08/raspap-webgui/
*
* You are not obligated to bundle the LICENSE file with your RaspAP projects as long
* as you leave these references intact in the header comments of your source files.
*/
require 'includes/csrf.php';
@ -46,21 +51,9 @@ require_once 'includes/torproxy.php';
$output = $return = 0;
$page = $_GET['page'];
if (!isset($_COOKIE['theme'])) {
$theme = "custom.css";
} else {
$theme = $_COOKIE['theme'];
}
$theme_url = 'app/css/'.htmlspecialchars($theme, ENT_QUOTES);
if ($_COOKIE['sidebarToggled'] == 'true' ) {
$toggleState = "toggled";
}
// Get Bridged AP mode status
$arrHostapdConf = parse_ini_file('/etc/raspap/hostapd.ini');
// defaults to false
$bridgedEnabled = $arrHostapdConf['BridgedEnable'];
$theme_url = getThemeOpt();
$toggleState = getSidebarState();
$bridgedEnabled = getBridgedState();
?><!DOCTYPE html>
<html lang="en">
@ -83,7 +76,10 @@ $bridgedEnabled = $arrHostapdConf['BridgedEnable'];
<!-- DataTables CSS -->
<link href="dist/datatables/dataTables.bootstrap4.min.css" rel="stylesheet">
<!-- Font Awesome -->
<!-- Huebee CSS -->
<link href="dist/huebee/huebee.min.css" rel="stylesheet">
<!-- Custom Fonts -->
<link href="dist/fontawesome-free/css/all.min.css" rel="stylesheet" type="text/css">
<!-- RaspAP Fonts -->
@ -116,13 +112,13 @@ $bridgedEnabled = $arrHostapdConf['BridgedEnable'];
<ul class="navbar-nav sidebar sidebar-light d-none d-md-block accordion <?php echo (isset($toggleState)) ? $toggleState : null ; ?>" id="accordionSidebar">
<!-- Sidebar - Brand -->
<a class="sidebar-brand d-flex align-items-center justify-content-center" href="index.php?page=wlan0_info">
<div class="sidebar-brand-text ml-1">RaspAP</div>
<div class="sidebar-brand-text ml-1"><?php echo RASPI_BRAND_TEXT; ?></div>
</a>
<!-- Divider -->
<hr class="sidebar-divider my-0">
<div class="row">
<div class="col-xs ml-3 sidebar-brand-icon">
<span class="ra-raspap"></span>
<img src="app/img/raspAP-logo.php" class="navbar-logo" width="64" height="64">
</div>
<div class="col-xs ml-2">
<div class="ml-1">Status</div>
@ -150,7 +146,7 @@ $bridgedEnabled = $arrHostapdConf['BridgedEnable'];
<a class="nav-link" href="index.php?page=dhcpd_conf"><i class="fas fa-exchange-alt fa-fw mr-2"></i><span class="nav-label"><?php echo _("DHCP Server"); ?></a>
</li>
<?php endif; ?>
<?php if (RASPI_ADBLOCK_ENABLED) : ?>
<?php if (RASPI_ADBLOCK_ENABLED && !$bridgedEnabled) : ?>
<li class="nav-item">
<a class="nav-link" href="index.php?page=adblock_conf"><i class="far fa-hand-paper fa-fw mr-2"></i><span class="nav-label"><?php echo _("Ad Blocking"); ?></a>
</li>
@ -279,7 +275,7 @@ $bridgedEnabled = $arrHostapdConf['BridgedEnable'];
SaveTORAndVPNConfig();
break;
case "theme_conf":
DisplayThemeConfig();
DisplayThemeConfig($extraFooterScripts);
break;
case "data_use":
DisplayDataUsage($extraFooterScripts);
@ -330,14 +326,10 @@ $bridgedEnabled = $arrHostapdConf['BridgedEnable'];
<!-- Custom RaspAP JS -->
<script src="app/js/custom.js"></script>
<?php if ($page == "wlan0_info" || !isset($page)) { ?>
<!-- Link Quality Chart -->
<script src="app/js/linkquality.js"></script>
<?php }
<?php
// Load non default JS/ECMAScript in footer.
foreach ($extraFooterScripts as $script) {
echo ' <script type="text/javascript" src="' , $script['src'] , '"';
echo '<script type="text/javascript" src="' , $script['src'] , '"';
if ($script['defer']) {
echo ' defer="defer"';
}

209
installers/common.sh