mirror of
https://github.com/billz/raspap-webgui.git
synced 2025-12-26 23:26:47 +01:00
Merge remote-tracking branch 'origin/master' into feat/80211ax-80211be
This commit is contained in:
43
README.md
43
README.md
@@ -1,5 +1,5 @@
|
|||||||

|

|
||||||
[](https://github.com/raspap/raspap-webgui/releases) [](https://github.com/thibmaek/awesome-raspberry-pi) [](https://github.com/sponsors/RaspAP) [](https://app.travis-ci.com/RaspAP/raspap-webgui) [](https://crowdin.com/project/raspap) [](https://twitter.com/rasp_ap) [](https://reddit.com/r/RaspAP) [](https://discord.gg/KVAsaAR)
|
[](https://github.com/raspap/raspap-webgui/releases) [](https://github.com/thibmaek/awesome-raspberry-pi) [](https://github.com/sponsors/RaspAP) [](https://app.travis-ci.com/RaspAP/raspap-webgui) [](https://crowdin.com/project/raspap) [](https://twitter.com/rasp_ap) [](https://reddit.com/r/RaspAP) [](https://discord.gg/KVAsaAR)
|
||||||
|
|
||||||
RaspAP is feature-rich wireless router software that _just works_ on many popular [Debian-based devices](#supported-operating-systems), including the Raspberry Pi. Our [custom OS images](#pre-built-image), [Quick installer](#quick-installer) and [Docker container](#docker-support) create a known-good default configuration for all current Raspberry Pis with onboard wireless. A fully responsive, mobile-ready interface gives you control over the relevant services and networking options. Advanced DHCP settings, [WireGuard](https://docs.raspap.com/wireguard/), [Tailscale](https://docs.raspap.com/tailscale/) and [OpenVPN](https://docs.raspap.com/openvpn/) support, [SSL certificates](https://docs.raspap.com/ssl/), [ad blocking](#ad-blocking), security audits, [captive portal integration](https://docs.raspap.com/captive/), themes and [multilingual options](https://docs.raspap.com/translations/) are included.
|
RaspAP is feature-rich wireless router software that _just works_ on many popular [Debian-based devices](#supported-operating-systems), including the Raspberry Pi. Our [custom OS images](#pre-built-image), [Quick installer](#quick-installer) and [Docker container](#docker-support) create a known-good default configuration for all current Raspberry Pis with onboard wireless. A fully responsive, mobile-ready interface gives you control over the relevant services and networking options. Advanced DHCP settings, [WireGuard](https://docs.raspap.com/wireguard/), [Tailscale](https://docs.raspap.com/tailscale/) and [OpenVPN](https://docs.raspap.com/openvpn/) support, [SSL certificates](https://docs.raspap.com/ssl/), [ad blocking](#ad-blocking), security audits, [captive portal integration](https://docs.raspap.com/captive/), themes and [multilingual options](https://docs.raspap.com/translations/) are included.
|
||||||
|
|
||||||
@@ -72,12 +72,12 @@ The Quick installer will respond to several [command line arguments](https://doc
|
|||||||
### Initial settings
|
### Initial settings
|
||||||
After completing either of these setup options, the wireless AP network will be configured as follows:
|
After completing either of these setup options, the wireless AP network will be configured as follows:
|
||||||
|
|
||||||
* IP address: 10.3.141.1
|
* IP address: `10.3.141.1`
|
||||||
* Username: admin
|
* Username: `admin`
|
||||||
* Password: secret
|
* Password: `secret`
|
||||||
* DHCP range: 10.3.141.50 — 10.3.141.254
|
* DHCP range: `10.3.141.50` — `10.3.141.254`
|
||||||
* SSID: `raspi-webgui`
|
* SSID: `RaspAP`
|
||||||
* Password: ChangeMe
|
* Password: `ChangeMe`
|
||||||
|
|
||||||
It's _strongly recommended_ that your first post-install action is to change the default admin [authentication](https://docs.raspap.com/authentication/) settings. Thereafter, your AP's [basic settings](https://docs.raspap.com/ap-basics/) and many [advanced options](https://docs.raspap.com/ap-basics#advanced-options) are now ready to be modified by RaspAP.
|
It's _strongly recommended_ that your first post-install action is to change the default admin [authentication](https://docs.raspap.com/authentication/) settings. Thereafter, your AP's [basic settings](https://docs.raspap.com/ap-basics/) and many [advanced options](https://docs.raspap.com/ap-basics#advanced-options) are now ready to be modified by RaspAP.
|
||||||
|
|
||||||
@@ -95,13 +95,13 @@ A tangible side benefit of sponsorship is that **Insiders** are able to help _st
|
|||||||
|
|
||||||
WireGuard® is an extremely simple yet fast and modern VPN that utilizes state-of-the-art cryptography. It aims to be considerably more performant than OpenVPN, and is generally regarded as the most secure, easiest to use, and simplest VPN solution for modern Linux distributions.
|
WireGuard® is an extremely simple yet fast and modern VPN that utilizes state-of-the-art cryptography. It aims to be considerably more performant than OpenVPN, and is generally regarded as the most secure, easiest to use, and simplest VPN solution for modern Linux distributions.
|
||||||
|
|
||||||
WireGuard may be optionally installed by the [Quick Installer](https://docs.raspap.com/quick/). Once this is done, you can manage local (server) settings, create a peer configuration and control the `wg-quick` service with RaspAP.
|
WireGuard is included in the pre-built OS and may be optionally installed by the [Quick Installer](https://docs.raspap.com/quick/). Once this is done, you can manage local (server) settings, create a peer configuration and control the `wg-quick` service with RaspAP.
|
||||||
|
|
||||||
Details are [provided here](https://docs.raspap.com/wireguard/).
|
Details are [provided here](https://docs.raspap.com/wireguard/).
|
||||||
|
|
||||||
## OpenVPN support
|
## OpenVPN support
|
||||||
|
|
||||||
OpenVPN may be optionally installed by the Quick Installer. Once this is done, you can [manage client configurations](https://docs.raspap.com/openvpn/) and the `openvpn-client` service with RaspAP.
|
OpenVPN is included in the pre-built OS and may be optionally installed by the Quick Installer. Once this is done, you can [manage client configurations](https://docs.raspap.com/openvpn/) and the `openvpn-client` service with RaspAP.
|
||||||
|
|
||||||
To configure an OpenVPN client, upload a valid .ovpn file and, optionally, specify your login credentials. RaspAP will store your client configuration and add firewall rules to forward traffic from OpenVPN's `tun0` interface to your configured wireless interface.
|
To configure an OpenVPN client, upload a valid .ovpn file and, optionally, specify your login credentials. RaspAP will store your client configuration and add firewall rules to forward traffic from OpenVPN's `tun0` interface to your configured wireless interface.
|
||||||
|
|
||||||
@@ -114,22 +114,20 @@ Several popular VPN providers include a Linux Command Line Interface (CLI) for i
|
|||||||
See our [VPN provider documentation](https://docs.raspap.com/providers/) for more information.
|
See our [VPN provider documentation](https://docs.raspap.com/providers/) for more information.
|
||||||
|
|
||||||
## Ad Blocking
|
## 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.
|
This feature uses DNS blacklisting to block requests for ads, trackers and other undesirable hosts. Ad blocking is included in the pre-built OS and may be optionally installed by the [Quick Installer](https://docs.raspap.com/quick/). Thereafter, you may choose between several of the best available [blocklist sources](https://docs.raspap.com/features-core/adblock/#blocklist-sources) to suit your needs.
|
||||||
|
|
||||||
Details are [provided here](https://docs.raspap.com/adblock/).
|
Details are [provided here](https://docs.raspap.com/adblock/).
|
||||||
|
|
||||||
## Bridged AP
|
## Bridged AP
|
||||||
By default RaspAP configures a routed AP for your clients to connect to. A bridged AP configuration is also possible. Slide the **Bridged AP mode** toggle under the **Advanced** tab of **Configure hotspot**, then save and restart the hotspot.
|
By default RaspAP configures a routed AP for your clients to connect to. A bridged AP configuration is also possible. Select the **Bridged AP mode** toggle under the **Advanced** tab of **Hotspot**, configure a static IP address for the bridge interface, then save and restart the AP.
|
||||||
|
|
||||||
**Note:** In bridged mode, all routing capabilities are handled by your upstream router. Because your router assigns IP addresses to your device's hotspot and its clients, you might not be able to reach the RaspAP web interface from the default `10.3.141.1` address. Instead use your RPi's hostname followed by `.local` to access the RaspAP web interface. With Raspbian default settings, this should look like `raspberrypi.local`. Alternate methods are [discussed here](https://www.raspberrypi.org/documentation/remote-access/ip-address.md).
|
Details on Bridged AP mode are [provided here](https://docs.raspap.com/bridged/).
|
||||||
|
|
||||||
More information on Bridged AP mode is provided [in our documentation](https://docs.raspap.com/bridged/).
|
|
||||||
|
|
||||||
## Manual installation
|
## Manual installation
|
||||||
Detailed manual setup instructions are provided [on our documentation site](https://docs.raspap.com/manual/).
|
Detailed manual setup instructions are [provided here](https://docs.raspap.com/manual/).
|
||||||
|
|
||||||
## 802.11ac 5GHz support
|
## 802.11ac 5GHz support
|
||||||
RaspAP provides an 802.11ac wireless mode option for supported hardware (currently the RPi 3B+/4 and compatible Orange Pi models) and wireless regulatory domains. See [this](https://docs.raspap.com/ap-basics/#80211ac-5-ghz) for more information.
|
RaspAP provides an 802.11ac wireless mode option for supported hardware (currently the RPi 3B+, 4, 5 and compatible Orange Pi models) and wireless regulatory domains. See [this](https://docs.raspap.com/ap-basics/#80211ac-5-ghz) for more information.
|
||||||
|
|
||||||
## Supported operating systems
|
## Supported operating systems
|
||||||
RaspAP was originally made for Raspbian, but now also installs on the following Debian-based distros.
|
RaspAP was originally made for Raspbian, but now also installs on the following Debian-based distros.
|
||||||
@@ -143,10 +141,13 @@ RaspAP was originally made for Raspbian, but now also installs on the following
|
|||||||
| Raspberry Pi OS Desktop | 64-bit Debian 12 (bookworm) | ARM | Official |
|
| Raspberry Pi OS Desktop | 64-bit Debian 12 (bookworm) | ARM | Official |
|
||||||
| Raspberry Pi OS Lite | 64-bit Debian 11 (bullseye) | ARM | Official |
|
| Raspberry Pi OS Lite | 64-bit Debian 11 (bullseye) | ARM | Official |
|
||||||
| Raspberry Pi OS Lite | 32-bit Debian 11 (bullseye) | ARM | Official |
|
| Raspberry Pi OS Lite | 32-bit Debian 11 (bullseye) | ARM | Official |
|
||||||
|
| Kali Linux | 2025.3 | [ARM 64-bit](https://www.kali.org/get-kali/#kali-arm) | Beta |
|
||||||
|
| Kali Linux | 2025.3 | [ARM 32-bit](https://www.kali.org/get-kali/#kali-arm) | Beta |
|
||||||
|
| Debian 13 | trixie | [ARM](https://raspi.debian.net/tested-images/) | Beta |
|
||||||
|
| Debian 12 | bookworm | [ARM](https://raspi.debian.net/tested-images/) | Beta |
|
||||||
| Armbian | 23.11 (jammy) | ARM | Beta |
|
| Armbian | 23.11 (jammy) | ARM | Beta |
|
||||||
| Debian | 12 (bookworm) | ARM / x86_64 | Beta |
|
|
||||||
|
|
||||||
<img src="https://i.imgur.com/XiAJNKb.png" style="width:480px;" />
|
<img src="https://i.imgur.com/L27nH8f.png" style="width:540px;" />
|
||||||
|
|
||||||
You are also encouraged to use RaspAP's community-led [Docker container](#docker-support). Please note that "supported" is not a guarantee. If you are able to improve support for your preferred distro, we encourage you to [actively contribute](#how-to-contribute) to the project.
|
You are also encouraged to use RaspAP's community-led [Docker container](#docker-support). Please note that "supported" is not a guarantee. If you are able to improve support for your preferred distro, we encourage you to [actively contribute](#how-to-contribute) to the project.
|
||||||
|
|
||||||
@@ -164,8 +165,6 @@ curl -sL https://install.raspap.com | bash -s -- --cert
|
|||||||
More information on SSL certificates and HTTPS support is available [in our documentation](https://docs.raspap.com/ssl/).
|
More information on SSL certificates and HTTPS support is available [in our documentation](https://docs.raspap.com/ssl/).
|
||||||
|
|
||||||
## Docker support
|
## Docker support
|
||||||
<img src="https://github.com/RaspAP/raspap-webgui/assets/229399/dc40dfc4-e9b8-405f-8ffb-6c5f88482b8e" width="450">
|
|
||||||
|
|
||||||
As an alternative to the [Quick installer](#quick-installer), RaspAP may be run in an isolated, portable [Docker container](https://docs.raspap.com/docker/).
|
As an alternative to the [Quick installer](#quick-installer), RaspAP may be run in an isolated, portable [Docker container](https://docs.raspap.com/docker/).
|
||||||
|
|
||||||
See the [RaspAP-docker repo](https://github.com/RaspAP/raspap-docker/) for more information.
|
See the [RaspAP-docker repo](https://github.com/RaspAP/raspap-docker/) for more information.
|
||||||
@@ -174,7 +173,9 @@ See the [RaspAP-docker repo](https://github.com/RaspAP/raspap-docker/) for more
|
|||||||
RaspAP's integrated `PluginManager` provides a framework for developers to create custom plugins. To facilitate this, a `SamplePlugin` [repository](https://github.com/RaspAP/SamplePlugin) is available to get developers started on the right track. If you'd like to develop your own plugin for RaspAP, see the [documentation](https://docs.raspap.com/custom-plugins/) or get started right away by forking the [SamplePlugin](https://github.com/RaspAP/SamplePlugin).
|
RaspAP's integrated `PluginManager` provides a framework for developers to create custom plugins. To facilitate this, a `SamplePlugin` [repository](https://github.com/RaspAP/SamplePlugin) is available to get developers started on the right track. If you'd like to develop your own plugin for RaspAP, see the [documentation](https://docs.raspap.com/custom-plugins/) or get started right away by forking the [SamplePlugin](https://github.com/RaspAP/SamplePlugin).
|
||||||
|
|
||||||
## Multilingual support
|
## Multilingual support
|
||||||
RaspAP uses [GNU Gettext](https://www.gnu.org/software/gettext/) to manage multilingual messages. In order to use RaspAP with one of our supported translations, you must configure a corresponding language package on your RPi. To list languages currently installed on your system, use `locale -a` at the shell prompt. To generate new locales, run `sudo dpkg-reconfigure locales` and select any other desired locales. Details are provided on our [documentation site](https://docs.raspap.com/translations/).
|
RaspAP uses [GNU Gettext](https://www.gnu.org/software/gettext/) to manage multilingual messages. Our pre-built OS includes the `locales-all` package, eliminating the need to manually generate locales.
|
||||||
|
|
||||||
|
If you're using the Quick Installer or Manual setup methods, you must configure a corresponding language package for your system. To list languages currently installed on your system, use `locale -a` at the shell prompt. To generate new locales, run `sudo dpkg-reconfigure locales` and select any other desired locales. Details are provided [here](https://docs.raspap.com/translations/).
|
||||||
|
|
||||||
See this list of [supported languages](https://docs.raspap.com/translations/#supported-languages) that are actively maintained by volunteer translators. If your language is not supported, why not [contribute a translation](https://docs.raspap.com/translations/#contributing-to-a-translation)? Contributors will receive credit as the original translators.
|
See this list of [supported languages](https://docs.raspap.com/translations/#supported-languages) that are actively maintained by volunteer translators. If your language is not supported, why not [contribute a translation](https://docs.raspap.com/translations/#contributing-to-a-translation)? Contributors will receive credit as the original translators.
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
header("Content-Type: image/svg+xml");
|
header("Content-Type: image/svg+xml");
|
||||||
|
|
||||||
|
require_once '../../includes/functions.php';
|
||||||
|
$color = getColorOpt();
|
||||||
$showDevice1 = isset($_GET['device-1']);
|
$showDevice1 = isset($_GET['device-1']);
|
||||||
$showOut = isset($_GET['out']);
|
$showOut = isset($_GET['out']);
|
||||||
$showDevice2 = isset($_GET['device-2']);
|
$showDevice2 = isset($_GET['device-2']);
|
||||||
@@ -12,33 +15,33 @@ $showDevice2 = isset($_GET['device-2']);
|
|||||||
<?php if ($showDevice2): ?>
|
<?php if ($showDevice2): ?>
|
||||||
<line id="joint-device-2" y1="-0.75" x2="154" y2="-0.75"
|
<line id="joint-device-2" y1="-0.75" x2="154" y2="-0.75"
|
||||||
transform="matrix(4.37114e-08 1 1 -4.37114e-08 114 297)"
|
transform="matrix(4.37114e-08 1 1 -4.37114e-08 114 297)"
|
||||||
stroke="#008281" stroke-width="4"/>
|
stroke="<?php echo htmlspecialchars($color, ENT_QUOTES, 'UTF-8'); ?>" stroke-width="4"/>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
<?php if ($showDevice1): ?>
|
<?php if ($showDevice1): ?>
|
||||||
<line id="joint-device-1" style="display: inline;"
|
<line id="joint-device-1" style="display: inline;"
|
||||||
y1="-0.75" x2="154" y2="-0.75"
|
y1="-0.75" x2="154" y2="-0.75"
|
||||||
transform="matrix(4.37114e-08 1 1 -4.37114e-08 114 144)"
|
transform="matrix(4.37114e-08 1 1 -4.37114e-08 114 144)"
|
||||||
stroke="#008281" stroke-width="4"/>
|
stroke="<?php echo htmlspecialchars($color, ENT_QUOTES, 'UTF-8'); ?>" stroke-width="4"/>
|
||||||
|
|
||||||
<line id="device-1" style="display: inline;"
|
<line id="device-1" style="display: inline;"
|
||||||
y1="-0.75" x2="113.231" y2="-0.75"
|
y1="-0.75" x2="113.231" y2="-0.75"
|
||||||
transform="matrix(1 8.74228e-08 8.74228e-08 -1 114 144)"
|
transform="matrix(1 8.74228e-08 8.74228e-08 -1 114 144)"
|
||||||
stroke="#008281" stroke-width="4"/>
|
stroke="<?php echo htmlspecialchars($color, ENT_QUOTES, 'UTF-8'); ?>" stroke-width="4"/>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
<?php if ($showOut): ?>
|
<?php if ($showOut): ?>
|
||||||
<line id="out" style="display: inline;"
|
<line id="out" style="display: inline;"
|
||||||
y1="-0.75" x2="113.231" y2="-0.75"
|
y1="-0.75" x2="113.231" y2="-0.75"
|
||||||
transform="matrix(1 8.74228e-08 8.74228e-08 -1 -0.000305176 297)"
|
transform="matrix(1 8.74228e-08 8.74228e-08 -1 -0.000305176 297)"
|
||||||
stroke="#008281" stroke-width="4"/>
|
stroke="<?php echo htmlspecialchars($color, ENT_QUOTES, 'UTF-8'); ?>" stroke-width="4"/>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
<?php if ($showDevice2): ?>
|
<?php if ($showDevice2): ?>
|
||||||
<line id="device-2" style="display: inline;"
|
<line id="device-2" style="display: inline;"
|
||||||
y1="-0.75" x2="113.231" y2="-0.75"
|
y1="-0.75" x2="113.231" y2="-0.75"
|
||||||
transform="matrix(1 8.74228e-08 8.74228e-08 -1 113 450)"
|
transform="matrix(1 8.74228e-08 8.74228e-08 -1 113 450)"
|
||||||
stroke="#008281" stroke-width="4"/>
|
stroke="<?php echo htmlspecialchars($color, ENT_QUOTES, 'UTF-8'); ?>" stroke-width="4"/>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</g>
|
</g>
|
||||||
</g>
|
</g>
|
||||||
|
|||||||
@@ -457,6 +457,36 @@ function setDhcpFieldsDisabled() {
|
|||||||
$('#txtmetric').prop('disabled', true);
|
$('#txtmetric').prop('disabled', true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
const dhcpCheckbox = document.getElementById('dhcp-iface');
|
||||||
|
const rangeStart = document.getElementById('txtrangestart');
|
||||||
|
const rangeEnd = document.getElementById('txtrangeend');
|
||||||
|
const leaseTime = document.getElementById('txtrangeleasetime');
|
||||||
|
|
||||||
|
function updateRequiredFields() {
|
||||||
|
const isChecked = dhcpCheckbox.checked === true;
|
||||||
|
|
||||||
|
if (isChecked) {
|
||||||
|
rangeStart.setAttribute('required', 'required');
|
||||||
|
rangeEnd.setAttribute('required', 'required');
|
||||||
|
leaseTime.setAttribute('required', 'required');
|
||||||
|
} else {
|
||||||
|
rangeStart.removeAttribute('required');
|
||||||
|
rangeEnd.removeAttribute('required');
|
||||||
|
leaseTime.removeAttribute('required');
|
||||||
|
|
||||||
|
rangeStart.classList.remove('is-invalid', 'is-valid');
|
||||||
|
rangeEnd.classList.remove('is-invalid', 'is-valid');
|
||||||
|
leaseTime.classList.remove('is-invalid', 'is-valid');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// set initial state
|
||||||
|
updateRequiredFields();
|
||||||
|
setTimeout(updateRequiredFields, 100);
|
||||||
|
dhcpCheckbox.addEventListener('change', updateRequiredFields);
|
||||||
|
});
|
||||||
|
|
||||||
// Static Array method
|
// Static Array method
|
||||||
Array.range = (start, end) => Array.from({length: (end - start)}, (v, k) => k + start);
|
Array.range = (start, end) => Array.from({length: (end - start)}, (v, k) => k + start);
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ define('RASPI_ADBLOCK_CONFIG', RASPI_DNSMASQ_PREFIX.'adblock.conf');
|
|||||||
define('RASPI_HOSTAPD_CONFIG', '/etc/hostapd/hostapd.conf');
|
define('RASPI_HOSTAPD_CONFIG', '/etc/hostapd/hostapd.conf');
|
||||||
define('RASPI_DHCPCD_CONFIG', '/etc/dhcpcd.conf');
|
define('RASPI_DHCPCD_CONFIG', '/etc/dhcpcd.conf');
|
||||||
define('RASPI_DHCPCD_LOG', '/var/log/dnsmasq.log');
|
define('RASPI_DHCPCD_LOG', '/var/log/dnsmasq.log');
|
||||||
define('RASPI_HOSTAPD_LOG', '/tmp/hostapd.log');
|
|
||||||
define('RASPI_WPA_SUPPLICANT_CONFIG', '/etc/wpa_supplicant/wpa_supplicant.conf');
|
define('RASPI_WPA_SUPPLICANT_CONFIG', '/etc/wpa_supplicant/wpa_supplicant.conf');
|
||||||
define('RASPI_HOSTAPD_CTRL_INTERFACE', '/var/run/hostapd');
|
define('RASPI_HOSTAPD_CTRL_INTERFACE', '/var/run/hostapd');
|
||||||
define('RASPI_WPA_CTRL_INTERFACE', '/var/run/wpa_supplicant');
|
define('RASPI_WPA_CTRL_INTERFACE', '/var/run/wpa_supplicant');
|
||||||
|
|||||||
152
includes/configure_client.php
Executable file → Normal file
152
includes/configure_client.php
Executable file → Normal file
@@ -3,7 +3,7 @@
|
|||||||
use RaspAP\Networking\Hotspot\WiFiManager;
|
use RaspAP\Networking\Hotspot\WiFiManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* WiFi client configuration page handler
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
function DisplayWPAConfig()
|
function DisplayWPAConfig()
|
||||||
@@ -16,17 +16,15 @@ function DisplayWPAConfig()
|
|||||||
$wifi->knownWifiStations($networks);
|
$wifi->knownWifiStations($networks);
|
||||||
$wifi->setKnownStationsWPA($networks);
|
$wifi->setKnownStationsWPA($networks);
|
||||||
|
|
||||||
$iface = escapeshellarg($_SESSION['wifi_client_interface']);
|
$clientInterface = $_SESSION['wifi_client_interface'];
|
||||||
|
|
||||||
if (isset($_POST['connect'])) {
|
if (isset($_POST['connect'])) {
|
||||||
$netid = intval($_POST['connect']);
|
$netid = intval($_POST['connect']);
|
||||||
$cmd = "sudo wpa_cli -i $iface select_network $netid";
|
|
||||||
$return = shell_exec($cmd);
|
if ($wifi->connectToNetwork($clientInterface, $netid)) {
|
||||||
sleep(2);
|
|
||||||
if (trim($return) == "FAIL") {
|
|
||||||
$status->addMessage('WPA command line client returned failure. Check your adapter.', 'danger');
|
|
||||||
} else {
|
|
||||||
$status->addMessage('New network selected', 'success');
|
$status->addMessage('New network selected', 'success');
|
||||||
|
} else {
|
||||||
|
$status->addMessage('WPA command line client returned failure. Check your adapter.', 'danger');
|
||||||
}
|
}
|
||||||
} elseif (isset($_POST['wpa_reinit'])) {
|
} elseif (isset($_POST['wpa_reinit'])) {
|
||||||
$status->addMessage('Attempting to reinitialize wpa_supplicant', 'warning');
|
$status->addMessage('Attempting to reinitialize wpa_supplicant', 'warning');
|
||||||
@@ -34,120 +32,52 @@ function DisplayWPAConfig()
|
|||||||
$result = $wifi->reinitializeWPA($force_remove);
|
$result = $wifi->reinitializeWPA($force_remove);
|
||||||
} elseif (isset($_POST['client_settings'])) {
|
} elseif (isset($_POST['client_settings'])) {
|
||||||
$tmp_networks = $networks;
|
$tmp_networks = $networks;
|
||||||
if ($wpa_file = fopen('/tmp/wifidata', 'w')) {
|
|
||||||
fwrite($wpa_file, 'ctrl_interface=DIR=' . RASPI_WPA_CTRL_INTERFACE . ' GROUP=netdev' . PHP_EOL);
|
|
||||||
fwrite($wpa_file, 'update_config=1' . PHP_EOL);
|
|
||||||
|
|
||||||
foreach (array_keys($_POST) as $post) {
|
foreach (array_keys($_POST) as $post) {
|
||||||
|
|
||||||
if (preg_match('/delete(\d+)/', $post, $post_match)) {
|
if (preg_match('/delete(\d+)/', $post, $post_match)) {
|
||||||
$network = $tmp_networks[$_POST['ssid' . $post_match[1]]];
|
$network = $tmp_networks[$_POST['ssid' . $post_match[1]]];
|
||||||
$netid = $network['index'];
|
$netid = $network['index'];
|
||||||
exec('sudo wpa_cli -i ' . $iface . ' disconnect ' . $netid);
|
$wifi->deleteNetwork($clientInterface, $netid);
|
||||||
exec('sudo wpa_cli -i ' . $iface . ' remove_network ' . $netid);
|
unset($tmp_networks[$_POST['ssid' . $post_match[1]]]);
|
||||||
unset($tmp_networks[$_POST['ssid' . $post_match[1]]]);
|
} elseif (preg_match('/disconnect(\d+)/', $post, $post_match)) {
|
||||||
|
$network = $tmp_networks[$_POST['ssid' . $post_match[1]]];
|
||||||
|
$netid = $network['index'];
|
||||||
|
$wifi->disconnectNetwork($clientInterface, $netid);
|
||||||
|
} elseif (preg_match('/update(\d+)/', $post, $post_match)) {
|
||||||
|
// NB, multiple protocols are separated with a forward slash ('/')
|
||||||
|
$protocol = $_POST['protocol' . $post_match[1]] === $wifi::SECURITY_OPEN ? $wifi::SECURITY_OPEN : 'WPA';
|
||||||
|
$tmp_networks[$_POST['ssid' . $post_match[1]]] = array(
|
||||||
|
'protocol' => $protocol,
|
||||||
|
'passphrase' => $_POST['passphrase' . $post_match[1]] ?? '',
|
||||||
|
'configured' => true
|
||||||
|
);
|
||||||
|
if (array_key_exists('priority' . $post_match[1], $_POST)) {
|
||||||
|
$tmp_networks[$_POST['ssid' . $post_match[1]]]['priority'] = $_POST['priority' . $post_match[1]];
|
||||||
|
}
|
||||||
|
$network = $tmp_networks[$_POST['ssid' . $post_match[1]]];
|
||||||
|
|
||||||
} elseif (preg_match('/update(\d+)/', $post, $post_match)) {
|
$ssid = $_POST['ssid' . $post_match[1]];
|
||||||
// NB, multiple protocols are separated with a forward slash ('/')
|
$passphrase = $_POST['passphrase' . $post_match[1]] ?? '';
|
||||||
$tmp_networks[$_POST['ssid' . $post_match[1]]] = array(
|
|
||||||
'protocol' => ( $_POST['protocol' . $post_match[1]] === 'Open' ? 'Open' : 'WPA' ),
|
$netid = $wifi->updateNetwork($clientInterface, $ssid, $passphrase, $protocol);
|
||||||
'passphrase' => $_POST['passphrase' . $post_match[1]],
|
if ($netid === null) {
|
||||||
'configured' => true
|
$status->addMessage('Unable to add network with WPA command line client', 'warning');
|
||||||
);
|
|
||||||
if (array_key_exists('priority' . $post_match[1], $_POST)) {
|
|
||||||
$tmp_networks[$_POST['ssid' . $post_match[1]]]['priority'] = $_POST['priority' . $post_match[1]];
|
|
||||||
}
|
|
||||||
$network = $tmp_networks[$_POST['ssid' . $post_match[1]]];
|
|
||||||
$ssid = escapeshellarg('"'.$_POST['ssid' . $post_match[1]].'"');
|
|
||||||
$psk = escapeshellarg('"'.$_POST['passphrase' . $post_match[1]].'"');
|
|
||||||
$netid = trim(shell_exec("sudo wpa_cli -i $iface add_network"));
|
|
||||||
if (isset($netid)) {
|
|
||||||
$commands = [
|
|
||||||
"sudo wpa_cli -i $iface set_network $netid ssid $ssid",
|
|
||||||
"sudo wpa_cli -i $iface set_network $netid psk $psk",
|
|
||||||
"sudo wpa_cli -i $iface enable_network $netid"
|
|
||||||
];
|
|
||||||
foreach ($commands as $cmd) {
|
|
||||||
exec($cmd);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$status->addMessage('Unable to add network with WPA command line client', 'warning');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$ok = true;
|
$result = $wifi->writeWpaSupplicant($tmp_networks, $clientInterface);
|
||||||
foreach ($tmp_networks as $ssid => $network) {
|
|
||||||
if ($network['protocol'] === 'Open') {
|
|
||||||
fwrite($wpa_file, "network={".PHP_EOL);
|
|
||||||
fwrite($wpa_file, "\tssid=\"".$ssid."\"".PHP_EOL);
|
|
||||||
fwrite($wpa_file, "\tkey_mgmt=NONE".PHP_EOL);
|
|
||||||
fwrite($wpa_file, "\tscan_ssid=1".PHP_EOL);
|
|
||||||
if (array_key_exists('priority', $network)) {
|
|
||||||
fwrite($wpa_file, "\tpriority=".$network['priority'].PHP_EOL);
|
|
||||||
}
|
|
||||||
fwrite($wpa_file, "}".PHP_EOL);
|
|
||||||
} else {
|
|
||||||
if (strlen($network['passphrase']) >=8 && strlen($network['passphrase']) <= 63) {
|
|
||||||
unset($wpa_passphrase);
|
|
||||||
unset($line);
|
|
||||||
exec('wpa_passphrase '. $wifi->ssid2utf8( escapeshellarg($ssid) ) . ' ' . escapeshellarg($network['passphrase']), $wpa_passphrase);
|
|
||||||
foreach ($wpa_passphrase as $line) {
|
|
||||||
if (preg_match('/^\s*}\s*$/', $line)) {
|
|
||||||
if (array_key_exists('priority', $network)) {
|
|
||||||
fwrite($wpa_file, "\tpriority=".$network['priority'].PHP_EOL);
|
|
||||||
}
|
|
||||||
fwrite($wpa_file, $line.PHP_EOL);
|
|
||||||
} else {
|
|
||||||
if ( preg_match('/\\\\x[0-9A-Fa-f]{2}/',$ssid) && strpos($line, "ssid=\"") !== false ) {
|
|
||||||
fwrite($wpa_file, "\tssid=P\"".$ssid."\"".PHP_EOL);
|
|
||||||
} else {
|
|
||||||
fwrite($wpa_file, $line.PHP_EOL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} elseif (strlen($network['passphrase']) == 0 && strlen($network['passkey']) == 64) {
|
|
||||||
$line = "\tpsk=" . $network['passkey'];
|
|
||||||
fwrite($wpa_file, "network={".PHP_EOL);
|
|
||||||
fwrite($wpa_file, "\tssid=\"".$ssid."\"".PHP_EOL);
|
|
||||||
fwrite($wpa_file, $line.PHP_EOL);
|
|
||||||
if (array_key_exists('priority', $network)) {
|
|
||||||
fwrite($wpa_file, "\tpriority=".$network['priority'].PHP_EOL);
|
|
||||||
}
|
|
||||||
fwrite($wpa_file, "}".PHP_EOL);
|
|
||||||
} else {
|
|
||||||
$status->addMessage('WPA passphrase must be between 8 and 63 characters', 'danger');
|
|
||||||
$ok = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($ok) {
|
if ($result['success']) {
|
||||||
system('sudo cp /tmp/wifidata ' . RASPI_WPA_SUPPLICANT_CONFIG, $returnval);
|
$status->addMessage($result['message'], 'success');
|
||||||
if ($returnval == 0) {
|
$networks = $tmp_networks;
|
||||||
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;
|
|
||||||
} else {
|
|
||||||
$status->addMessage('Wifi settings updated but cannot restart (cannot execute "wpa_cli reconfigure")', 'danger');
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$status->addMessage('Wifi settings failed to be updated', 'danger');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
$status->addMessage('Failed to update wifi settings', 'danger');
|
$status->addMessage($result['message'], 'danger');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$clientInterface = $_SESSION['wifi_client_interface'];
|
$ifaceStatus = $wifi->getInterfaceStatus($clientInterface);
|
||||||
|
|
||||||
exec('ip a show '.$clientInterface, $stdoutIp);
|
|
||||||
$stdoutIpAllLinesGlued = implode(" ", $stdoutIp);
|
|
||||||
$stdoutIpWRepeatedSpaces = preg_replace('/\s\s+/', ' ', $stdoutIpAllLinesGlued);
|
|
||||||
preg_match('/state (UP|DOWN)/i', $stdoutIpWRepeatedSpaces, $matchesState) || $matchesState[1] = 'unknown';
|
|
||||||
$ifaceStatus = strtolower($matchesState[1]) ? "up" : "down";
|
|
||||||
|
|
||||||
echo renderTemplate("configure_client", compact("status", "clientInterface", "ifaceStatus"));
|
echo renderTemplate("configure_client", compact("status", "clientInterface", "ifaceStatus"));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ if (!defined('RASPI_CONFIG')) {
|
|||||||
$defaults = [
|
$defaults = [
|
||||||
'RASPI_BRAND_TEXT' => 'RaspAP',
|
'RASPI_BRAND_TEXT' => 'RaspAP',
|
||||||
'RASPI_BRAND_TITLE' => RASPI_BRAND_TEXT.' Admin Panel',
|
'RASPI_BRAND_TITLE' => RASPI_BRAND_TEXT.' Admin Panel',
|
||||||
'RASPI_VERSION' => '3.4.6',
|
'RASPI_VERSION' => '3.5.0',
|
||||||
'RASPI_CONFIG_NETWORK' => RASPI_CONFIG.'/networking/defaults.json',
|
'RASPI_CONFIG_NETWORK' => RASPI_CONFIG.'/networking/defaults.json',
|
||||||
'RASPI_CONFIG_PROVIDERS' => 'config/vpn-providers.json',
|
'RASPI_CONFIG_PROVIDERS' => 'config/vpn-providers.json',
|
||||||
'RASPI_CONFIG_API' => RASPI_CONFIG.'/api',
|
'RASPI_CONFIG_API' => RASPI_CONFIG.'/api',
|
||||||
@@ -28,7 +28,6 @@ $defaults = [
|
|||||||
'RASPI_HOSTAPD_CONFIG' => '/etc/hostapd/hostapd.conf',
|
'RASPI_HOSTAPD_CONFIG' => '/etc/hostapd/hostapd.conf',
|
||||||
'RASPI_DHCPCD_CONFIG' => '/etc/dhcpcd.conf',
|
'RASPI_DHCPCD_CONFIG' => '/etc/dhcpcd.conf',
|
||||||
'RASPI_DHCPCD_LOG' => '/var/log/dnsmasq.log',
|
'RASPI_DHCPCD_LOG' => '/var/log/dnsmasq.log',
|
||||||
'RASPI_HOSTAPD_LOG' => '/tmp/hostapd.log',
|
|
||||||
'RASPI_WPA_SUPPLICANT_CONFIG' => '/etc/wpa_supplicant/wpa_supplicant.conf',
|
'RASPI_WPA_SUPPLICANT_CONFIG' => '/etc/wpa_supplicant/wpa_supplicant.conf',
|
||||||
'RASPI_HOSTAPD_CTRL_INTERFACE' => '/var/run/hostapd',
|
'RASPI_HOSTAPD_CTRL_INTERFACE' => '/var/run/hostapd',
|
||||||
'RASPI_WPA_CTRL_INTERFACE' => '/var/run/wpa_supplicant',
|
'RASPI_WPA_CTRL_INTERFACE' => '/var/run/wpa_supplicant',
|
||||||
|
|||||||
@@ -112,6 +112,9 @@ function getProviderValue($id, $key)
|
|||||||
if (!isset($obj['providers']) || !is_array($obj['providers'])) {
|
if (!isset($obj['providers']) || !is_array($obj['providers'])) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if ($id === null || !is_numeric($id)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
$id--;
|
$id--;
|
||||||
if (!isset($obj['providers'][$id]) || !is_array($obj['providers'][$id])) {
|
if (!isset($obj['providers'][$id]) || !is_array($obj['providers'][$id])) {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -45,8 +45,10 @@ function DisplayHostAPDConfig()
|
|||||||
} else {
|
} else {
|
||||||
$interface = $_SESSION['ap_interface'];
|
$interface = $_SESSION['ap_interface'];
|
||||||
}
|
}
|
||||||
|
|
||||||
$txpower = $hotspot->getTxPower($interface);
|
$txpower = $hotspot->getTxPower($interface);
|
||||||
$arrHostapdConf = $hotspot->getHostapdIni();
|
$arrHostapdConf = $hotspot->getHostapdIni();
|
||||||
|
$logOutput = [];
|
||||||
|
|
||||||
if (!RASPI_MONITOR_ENABLED) {
|
if (!RASPI_MONITOR_ENABLED) {
|
||||||
if (isset($_POST['StartHotspot']) || isset($_POST['RestartHotspot'])) {
|
if (isset($_POST['StartHotspot']) || isset($_POST['RestartHotspot'])) {
|
||||||
@@ -77,6 +79,10 @@ function DisplayHostAPDConfig()
|
|||||||
$reg_domain,
|
$reg_domain,
|
||||||
$status
|
$status
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// reload hostapi.ini
|
||||||
|
$arrHostapdConf = $hotspot->getHostapdIni();
|
||||||
|
|
||||||
} elseif (isset($_POST['StopHotspot'])) {
|
} elseif (isset($_POST['StopHotspot'])) {
|
||||||
$status->addMessage('Attempting to stop hotspot', 'info');
|
$status->addMessage('Attempting to stop hotspot', 'info');
|
||||||
exec('sudo /bin/systemctl stop hostapd.service', $return);
|
exec('sudo /bin/systemctl stop hostapd.service', $return);
|
||||||
@@ -135,15 +141,21 @@ function DisplayHostAPDConfig()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fetch hostapd logs if enabled
|
||||||
|
if ((string)$arrHostapdConf['LogEnable'] === "1") {
|
||||||
|
$logResult = $hotspot->getHostapdLogs(5000);
|
||||||
|
if ($logResult['success']) {
|
||||||
|
$joined = implode("\n", $logResult['logs']);
|
||||||
|
$limited = getLogLimited('', $joined);
|
||||||
|
$logOutput = explode("\n", $limited);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// assign disassoc_low_ack boolean if value is set
|
// assign disassoc_low_ack boolean if value is set
|
||||||
$arrConfig['disassoc_low_ack_bool'] = isset($arrConfig['disassoc_low_ack']) ? 1 : 0;
|
$arrConfig['disassoc_low_ack_bool'] = isset($arrConfig['disassoc_low_ack']) ? 1 : 0;
|
||||||
$hostapdstatus = $system->hostapdStatus();
|
$hostapdstatus = $system->hostapdStatus();
|
||||||
$serviceStatus = $hostapdstatus[0] == 0 ? "down" : "up";
|
$serviceStatus = $hostapdstatus[0] == 0 ? "down" : "up";
|
||||||
|
|
||||||
// ensure log is writeable
|
|
||||||
exec('sudo /bin/chmod o+r '.RASPI_HOSTAPD_LOG);
|
|
||||||
$logdata = getLogLimited(RASPI_HOSTAPD_LOG);
|
|
||||||
|
|
||||||
echo renderTemplate(
|
echo renderTemplate(
|
||||||
"hostapd", compact(
|
"hostapd", compact(
|
||||||
"status",
|
"status",
|
||||||
@@ -161,7 +173,7 @@ function DisplayHostAPDConfig()
|
|||||||
"arrHostapdConf",
|
"arrHostapdConf",
|
||||||
"operatingSystem",
|
"operatingSystem",
|
||||||
"countryCodes",
|
"countryCodes",
|
||||||
"logdata"
|
"logOutput"
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
* @author Lawrence Yau <sirlagz@gmail.com>
|
* @author Lawrence Yau <sirlagz@gmail.com>
|
||||||
* @author Bill Zimmerman <billzimmerman@gmail.com>
|
* @author Bill Zimmerman <billzimmerman@gmail.com>
|
||||||
* @license GNU General Public License, version 3 (GPL-3.0)
|
* @license GNU General Public License, version 3 (GPL-3.0)
|
||||||
* @version 3.4.6
|
* @version 3.5.0
|
||||||
* @link https://github.com/RaspAP/raspap-webgui/
|
* @link https://github.com/RaspAP/raspap-webgui/
|
||||||
* @link https://raspap.com/
|
* @link https://raspap.com/
|
||||||
* @see http://sirlagz.net/2013/02/08/raspap-webgui/
|
* @see http://sirlagz.net/2013/02/08/raspap-webgui/
|
||||||
|
|||||||
42
installers/common.sh
Executable file → Normal file
42
installers/common.sh
Executable file → Normal file
@@ -158,7 +158,7 @@ function _get_linux_distro() {
|
|||||||
# Sets php package option based on Linux version, abort if unsupported distro
|
# Sets php package option based on Linux version, abort if unsupported distro
|
||||||
function _set_php_package() {
|
function _set_php_package() {
|
||||||
case $RELEASE in
|
case $RELEASE in
|
||||||
13) # Debian 13 trixie
|
13|2025.*) # Debian 13 trixie, Kali Linux 2025
|
||||||
php_package="php8.4-fpm"
|
php_package="php8.4-fpm"
|
||||||
phpiniconf="/etc/php/8.4/fpm/php.ini" ;;
|
phpiniconf="/etc/php/8.4/fpm/php.ini" ;;
|
||||||
23.05|12*) # Debian 12 & Armbian 23.05
|
23.05|12*) # Debian 12 & Armbian 23.05
|
||||||
@@ -246,7 +246,7 @@ function _install_dependencies() {
|
|||||||
else
|
else
|
||||||
echo "${php_package} will be installed from the main deb sources list"
|
echo "${php_package} will be installed from the main deb sources list"
|
||||||
fi
|
fi
|
||||||
if [ ${OS,,} = "debian" ] || [ ${OS,,} = "ubuntu" ]; then
|
if [ ${OS,,} = "debian" ] || [ ${OS,,} = "ubuntu" ] || [ ${OS,,} = "kali" ]; then
|
||||||
dhcpcd_package="dhcpcd5"
|
dhcpcd_package="dhcpcd5"
|
||||||
iw_package="iw"
|
iw_package="iw"
|
||||||
rsync_package="rsync"
|
rsync_package="rsync"
|
||||||
@@ -287,9 +287,10 @@ function _install_dependencies() {
|
|||||||
|
|
||||||
if [[ "$php_package" == *"-fpm" ]]; then
|
if [[ "$php_package" == *"-fpm" ]]; then
|
||||||
_install_log "Enabling lighttpd fastcgi-php-fpm module for $php_package"
|
_install_log "Enabling lighttpd fastcgi-php-fpm module for $php_package"
|
||||||
sudo lighty-enable-mod fastcgi-php-fpm || _install_status 1 "Unable to enable fastcgi-php-fpm module"
|
sudo lighty-enable-mod fastcgi-php-fpm 2>&1 | grep -qE "already enabled" || \
|
||||||
|
_install_status 1 "Unable to enable fastcgi-php-fpm module"
|
||||||
|
sudo systemctl restart $php_package.service || _install_status 1 "Unable to restart $php_package.service"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
_install_status 0
|
_install_status 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -324,9 +325,6 @@ function _create_hostapd_scripts() {
|
|||||||
_install_log "Creating hostapd logging & control scripts"
|
_install_log "Creating hostapd logging & control scripts"
|
||||||
sudo mkdir $raspap_dir/hostapd || _install_status 1 "Unable to create directory '$raspap_dir/hostapd'"
|
sudo mkdir $raspap_dir/hostapd || _install_status 1 "Unable to create directory '$raspap_dir/hostapd'"
|
||||||
|
|
||||||
# Copy logging shell scripts
|
|
||||||
sudo cp "$webroot_dir/installers/"enablelog.sh "$raspap_dir/hostapd" || _install_status 1 "Unable to move logging scripts"
|
|
||||||
sudo cp "$webroot_dir/installers/"disablelog.sh "$raspap_dir/hostapd" || _install_status 1 "Unable to move logging scripts"
|
|
||||||
# Copy service control shell scripts
|
# Copy service control shell scripts
|
||||||
sudo cp "$webroot_dir/installers/"servicestart.sh "$raspap_dir/hostapd" || _install_status 1 "Unable to move service control scripts"
|
sudo cp "$webroot_dir/installers/"servicestart.sh "$raspap_dir/hostapd" || _install_status 1 "Unable to move service control scripts"
|
||||||
# Change ownership and permissions of hostapd control scripts
|
# Change ownership and permissions of hostapd control scripts
|
||||||
@@ -641,18 +639,36 @@ function _download_latest_files() {
|
|||||||
if [ -d "$webroot_dir" ] && [ "$update" == 0 ]; then
|
if [ -d "$webroot_dir" ] && [ "$update" == 0 ]; then
|
||||||
sudo mv $webroot_dir "$webroot_dir.`date +%F-%R`" || _install_status 1 "Unable to move existing webroot directory"
|
sudo mv $webroot_dir "$webroot_dir.`date +%F-%R`" || _install_status 1 "Unable to move existing webroot directory"
|
||||||
elif [ "$upgrade" == 1 ] || [ "$update" == 1 ]; then
|
elif [ "$upgrade" == 1 ] || [ "$update" == 1 ]; then
|
||||||
exclude='--exclude=ajax/system/sys_read_logfile.php'
|
# Preserve user plugins temporarily
|
||||||
shopt -s extglob
|
if [ -d "$webroot_dir/plugins" ]; then
|
||||||
sudo find "$webroot_dir" ! -path "${webroot_dir}/ajax/system/sys_read_logfile.php" -delete 2>/dev/null
|
sudo cp -r "$webroot_dir/plugins" "/tmp/raspap-user-plugins"
|
||||||
|
fi
|
||||||
|
|
||||||
|
sudo find "$webroot_dir" -mindepth 1 \
|
||||||
|
! -path "${webroot_dir}/ajax/system/sys_read_logfile.php" \
|
||||||
|
! -path "${webroot_dir}/plugins" \
|
||||||
|
! -path "${webroot_dir}/plugins/*" \
|
||||||
|
-delete 2>/dev/null
|
||||||
|
|
||||||
|
# Remove plugins to permit clean rsync
|
||||||
|
sudo rm -rf "$webroot_dir/plugins"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
_install_log "Installing application to $webroot_dir"
|
_install_log "Installing application to $webroot_dir"
|
||||||
sudo rsync -av $exclude "$source_dir"/ "$webroot_dir"/ >/dev/null 2>&1 || _install_status 1 "Unable to install files to $webroot_dir"
|
sudo rsync -av $exclude "$source_dir"/ "$webroot_dir"/ >/dev/null 2>&1 || _install_status 1 "Unable to install files to $webroot_dir"
|
||||||
|
|
||||||
|
# Restore user plugins after rsync
|
||||||
|
if [ "$upgrade" == 1 ] || [ "$update" == 1 ]; then
|
||||||
|
if [ -d "/tmp/raspap-user-plugins" ]; then
|
||||||
|
sudo find /tmp/raspap-user-plugins -mindepth 1 -maxdepth 1 -type d -exec cp -r {} "$webroot_dir/plugins/" \; 2>/dev/null
|
||||||
|
sudo rm -rf "/tmp/raspap-user-plugins"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
if [ "$update" == 1 ]; then
|
if [ "$update" == 1 ]; then
|
||||||
_install_log "Applying existing configuration to ${webroot_dir}/includes"
|
_install_log "Applying existing configuration to ${webroot_dir}/includes"
|
||||||
sudo mv /tmp/config.php $webroot_dir/includes || _install_status 1 "Unable to move config.php to ${webroot_dir}/includes"
|
sudo mv /tmp/config.php $webroot_dir/includes || _install_status 1 "Unable to move config.php to ${webroot_dir}/includes"
|
||||||
|
|
||||||
if [ -f /tmp/raspap.auth ]; then
|
if [ -f /tmp/raspap.auth ]; then
|
||||||
_install_log "Applying existing authentication file to ${raspap_dir}"
|
_install_log "Applying existing authentication file to ${raspap_dir}"
|
||||||
sudo mv /tmp/raspap.auth $raspap_dir || _install_status 1 "Unable to restore authentification credentials file to ${raspap_dir}"
|
sudo mv /tmp/raspap.auth $raspap_dir || _install_status 1 "Unable to restore authentification credentials file to ${raspap_dir}"
|
||||||
@@ -820,8 +836,8 @@ function _configure_networking() {
|
|||||||
"-A POSTROUTING -s 192.168.50.0/24 ! -d 192.168.50.0/24 -j MASQUERADE"
|
"-A POSTROUTING -s 192.168.50.0/24 ! -d 192.168.50.0/24 -j MASQUERADE"
|
||||||
)
|
)
|
||||||
for rule in "${rules[@]}"; do
|
for rule in "${rules[@]}"; do
|
||||||
if grep -- "$rule" $rulesv4 > /dev/null; then
|
if sudo grep -- "$rule" $rulesv4 > /dev/null; then
|
||||||
echo "Rule already exits: ${rule}"
|
echo "Rule already exists: ${rule}"
|
||||||
else
|
else
|
||||||
rule=$(sed -e 's/^\(-A POSTROUTING\)/-t nat \1/' <<< $rule)
|
rule=$(sed -e 's/^\(-A POSTROUTING\)/-t nat \1/' <<< $rule)
|
||||||
echo "Adding rule: ${rule}"
|
echo "Adding rule: ${rule}"
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
/bin/sed -i 's|DAEMON_OPTS=" -f /tmp/hostapd.log"|#DAEMON_OPTS=""|' /etc/default/hostapd
|
|
||||||
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
/bin/sed -i 's|#DAEMON_OPTS=""|DAEMON_OPTS=" -f /tmp/hostapd.log"|' /etc/default/hostapd
|
|
||||||
touch /tmp/hostapd.log
|
|
||||||
@@ -9,14 +9,16 @@ www-data ALL=(ALL) NOPASSWD:/sbin/wpa_supplicant -i [a-zA-Z0-9]* -c /etc/wpa_sup
|
|||||||
www-data ALL=(ALL) NOPASSWD:/bin/rm /var/run/wpa_supplicant/[a-zA-Z0-9]*
|
www-data ALL=(ALL) NOPASSWD:/bin/rm /var/run/wpa_supplicant/[a-zA-Z0-9]*
|
||||||
www-data ALL=(ALL) NOPASSWD:/sbin/wpa_cli -i [a-zA-Z0-9]* scan_results
|
www-data ALL=(ALL) NOPASSWD:/sbin/wpa_cli -i [a-zA-Z0-9]* scan_results
|
||||||
www-data ALL=(ALL) NOPASSWD:/sbin/wpa_cli -i [a-zA-Z0-9]* scan
|
www-data ALL=(ALL) NOPASSWD:/sbin/wpa_cli -i [a-zA-Z0-9]* scan
|
||||||
|
www-data ALL=(ALL) NOPASSWD:/sbin/wpa_cli -i [a-zA-Z0-9]* status
|
||||||
www-data ALL=(ALL) NOPASSWD:/sbin/wpa_cli -i [a-zA-Z0-9]* reconfigure
|
www-data ALL=(ALL) NOPASSWD:/sbin/wpa_cli -i [a-zA-Z0-9]* reconfigure
|
||||||
www-data ALL=(ALL) NOPASSWD:/sbin/wpa_cli -i [a-zA-Z0-9]* add_network
|
www-data ALL=(ALL) NOPASSWD:/sbin/wpa_cli -i [a-zA-Z0-9]* add_network
|
||||||
www-data ALL=(ALL) NOPASSWD:/sbin/wpa_cli -i [a-zA-Z0-9]* list_networks
|
www-data ALL=(ALL) NOPASSWD:/sbin/wpa_cli -i [a-zA-Z0-9]* list_networks
|
||||||
www-data ALL=(ALL) NOPASSWD:/sbin/wpa_cli -i enable_network [0-9]
|
www-data ALL=(ALL) NOPASSWD:/sbin/wpa_cli -i [a-zA-Z0-9]* enable_network [0-9]
|
||||||
www-data ALL=(ALL) NOPASSWD:/sbin/wpa_cli -i disconnect [0-9]
|
www-data ALL=(ALL) NOPASSWD:/sbin/wpa_cli -i [a-zA-Z0-9]* disconnect [0-9]
|
||||||
www-data ALL=(ALL) NOPASSWD:/sbin/wpa_cli -i [a-zA-Z0-9]* select_network [0-9]
|
www-data ALL=(ALL) NOPASSWD:/sbin/wpa_cli -i [a-zA-Z0-9]* select_network [0-9]
|
||||||
www-data ALL=(ALL) NOPASSWD:/sbin/wpa_cli -i [a-zA-Z0-9]* set_network [0-9] *
|
www-data ALL=(ALL) NOPASSWD:/sbin/wpa_cli -i [a-zA-Z0-9]* set_network [0-9] *
|
||||||
www-data ALL=(ALL) NOPASSWD:/sbin/wpa_cli -i [a-zA-Z0-9]* remove_network [0-9]
|
www-data ALL=(ALL) NOPASSWD:/sbin/wpa_cli -i [a-zA-Z0-9]* remove_network [0-9]
|
||||||
|
www-data ALL=(ALL) NOPASSWD:/bin/rm -f /var/run/wpa_supplicant/wlan[0-9]
|
||||||
www-data ALL=(ALL) NOPASSWD:/bin/cp /tmp/hostapddata /etc/hostapd/hostapd.conf
|
www-data ALL=(ALL) NOPASSWD:/bin/cp /tmp/hostapddata /etc/hostapd/hostapd.conf
|
||||||
www-data ALL=(ALL) NOPASSWD:/bin/systemctl start hostapd.service
|
www-data ALL=(ALL) NOPASSWD:/bin/systemctl start hostapd.service
|
||||||
www-data ALL=(ALL) NOPASSWD:/bin/systemctl stop hostapd.service
|
www-data ALL=(ALL) NOPASSWD:/bin/systemctl stop hostapd.service
|
||||||
@@ -47,6 +49,7 @@ www-data ALL=(ALL) NOPASSWD:/sbin/ip -s a f label wl*
|
|||||||
www-data ALL=(ALL) NOPASSWD:/sbin/ifup *
|
www-data ALL=(ALL) NOPASSWD:/sbin/ifup *
|
||||||
www-data ALL=(ALL) NOPASSWD:/sbin/ifdown *
|
www-data ALL=(ALL) NOPASSWD:/sbin/ifdown *
|
||||||
www-data ALL=(ALL) NOPASSWD:/sbin/iw dev*
|
www-data ALL=(ALL) NOPASSWD:/sbin/iw dev*
|
||||||
|
www-data ALL=(ALL) NOPASSWD:/sbin/iw reg set*
|
||||||
www-data ALL=(ALL) NOPASSWD:/bin/cp /etc/raspap/networking/dhcpcd.conf /etc/dhcpcd.conf
|
www-data ALL=(ALL) NOPASSWD:/bin/cp /etc/raspap/networking/dhcpcd.conf /etc/dhcpcd.conf
|
||||||
www-data ALL=(ALL) NOPASSWD:/etc/raspap/hostapd/enablelog.sh
|
www-data ALL=(ALL) NOPASSWD:/etc/raspap/hostapd/enablelog.sh
|
||||||
www-data ALL=(ALL) NOPASSWD:/etc/raspap/hostapd/disablelog.sh
|
www-data ALL=(ALL) NOPASSWD:/etc/raspap/hostapd/disablelog.sh
|
||||||
@@ -90,3 +93,4 @@ www-data ALL=(ALL) NOPASSWD:/etc/raspap/plugins/plugin_helper.sh
|
|||||||
www-data ALL=(ALL) NOPASSWD:/bin/systemctl start raspap-network-activity@*.service
|
www-data ALL=(ALL) NOPASSWD:/bin/systemctl start raspap-network-activity@*.service
|
||||||
www-data ALL=(ALL) NOPASSWD:/bin/systemctl stop raspap-network-activity@*.service
|
www-data ALL=(ALL) NOPASSWD:/bin/systemctl stop raspap-network-activity@*.service
|
||||||
www-data ALL=(ALL) NOPASSWD:/bin/cp /tmp/wpa_conf_* /etc/wpa_supplicant/wpa_supplicant.conf
|
www-data ALL=(ALL) NOPASSWD:/bin/cp /tmp/wpa_conf_* /etc/wpa_supplicant/wpa_supplicant.conf
|
||||||
|
www-data ALL=(ALL) NOPASSWD:/usr/bin/journalctl -u hostapd.service *
|
||||||
|
|||||||
Binary file not shown.
@@ -3,7 +3,7 @@ msgstr ""
|
|||||||
"Project-Id-Version: raspap\n"
|
"Project-Id-Version: raspap\n"
|
||||||
"Report-Msgid-Bugs-To: Bill Zimmerman <billzimmerman@gmail.com>\n"
|
"Report-Msgid-Bugs-To: Bill Zimmerman <billzimmerman@gmail.com>\n"
|
||||||
"POT-Creation-Date: 2017-10-19 08:56+0000\n"
|
"POT-Creation-Date: 2017-10-19 08:56+0000\n"
|
||||||
"PO-Revision-Date: 2025-10-25 16:03\n"
|
"PO-Revision-Date: 2025-11-20 12:20\n"
|
||||||
"Last-Translator: Bill Zimmerman <billzimmerman@gmail.com>\n"
|
"Last-Translator: Bill Zimmerman <billzimmerman@gmail.com>\n"
|
||||||
"Language-Team: German\n"
|
"Language-Team: German\n"
|
||||||
"Language: de_DE\n"
|
"Language: de_DE\n"
|
||||||
@@ -33,15 +33,15 @@ msgstr "Übersicht"
|
|||||||
msgid "WiFi client"
|
msgid "WiFi client"
|
||||||
msgstr "WLAN Client"
|
msgstr "WLAN Client"
|
||||||
|
|
||||||
|
msgid "Status"
|
||||||
|
msgstr "Status"
|
||||||
|
|
||||||
msgid "Hotspot"
|
msgid "Hotspot"
|
||||||
msgstr "Hotspot"
|
msgstr "Hotspot"
|
||||||
|
|
||||||
msgid "Logging"
|
msgid "Logging"
|
||||||
msgstr "Protokollierung"
|
msgstr "Protokollierung"
|
||||||
|
|
||||||
msgid "Status"
|
|
||||||
msgstr "Status"
|
|
||||||
|
|
||||||
msgid "Mem Use"
|
msgid "Mem Use"
|
||||||
msgstr "RAM Nutzung"
|
msgstr "RAM Nutzung"
|
||||||
|
|
||||||
@@ -743,6 +743,27 @@ msgstr "Aktiviere Protokoll"
|
|||||||
msgid "Logfile output"
|
msgid "Logfile output"
|
||||||
msgstr "Logfile Ausgabe"
|
msgstr "Logfile Ausgabe"
|
||||||
|
|
||||||
|
msgid "Log level"
|
||||||
|
msgstr "Log-Stufe"
|
||||||
|
|
||||||
|
msgid "Higher levels reduce log verbosity. Informational is recommended."
|
||||||
|
msgstr "Höhere Stufen reduzieren die Ausführlichkeit des Protokolls. Informational wird empfohlen."
|
||||||
|
|
||||||
|
msgid "Verbose debugging"
|
||||||
|
msgstr "Ausführliche Fehlersuche"
|
||||||
|
|
||||||
|
msgid "Debugging"
|
||||||
|
msgstr "Fehlersuche"
|
||||||
|
|
||||||
|
msgid "Informational"
|
||||||
|
msgstr "Informativ"
|
||||||
|
|
||||||
|
msgid "Notification"
|
||||||
|
msgstr "Benachrichtigung"
|
||||||
|
|
||||||
|
msgid "Warning"
|
||||||
|
msgstr "Warnung"
|
||||||
|
|
||||||
msgid "WiFi client AP mode"
|
msgid "WiFi client AP mode"
|
||||||
msgstr "AP-Modus von WiFI-Client"
|
msgstr "AP-Modus von WiFI-Client"
|
||||||
|
|
||||||
@@ -1375,6 +1396,9 @@ msgstr "Adapter-Zustandsprüfung"
|
|||||||
msgid "Inspect adapters"
|
msgid "Inspect adapters"
|
||||||
msgstr "Adapter überprüfen"
|
msgstr "Adapter überprüfen"
|
||||||
|
|
||||||
|
msgid "Theme"
|
||||||
|
msgstr "Thema"
|
||||||
|
|
||||||
#: includes/data_usage.php
|
#: includes/data_usage.php
|
||||||
msgid "Data usage"
|
msgid "Data usage"
|
||||||
msgstr "Datennutzung"
|
msgstr "Datennutzung"
|
||||||
|
|||||||
Binary file not shown.
@@ -744,6 +744,27 @@ msgstr "Enable logging"
|
|||||||
msgid "Logfile output"
|
msgid "Logfile output"
|
||||||
msgstr "Logfile output"
|
msgstr "Logfile output"
|
||||||
|
|
||||||
|
msgid "Log level"
|
||||||
|
msgstr "Log level"
|
||||||
|
|
||||||
|
msgid "Higher levels reduce log verbosity. Informational is recommended."
|
||||||
|
msgstr "Higher levels reduce log verbosity. Informational is recommended."
|
||||||
|
|
||||||
|
msgid "Verbose debugging"
|
||||||
|
msgstr "Verbose debugging"
|
||||||
|
|
||||||
|
msgid "Debugging"
|
||||||
|
msgstr "Debugging"
|
||||||
|
|
||||||
|
msgid "Informational"
|
||||||
|
msgstr "Informational"
|
||||||
|
|
||||||
|
msgid "Notification"
|
||||||
|
msgstr "Notification"
|
||||||
|
|
||||||
|
msgid "Warning"
|
||||||
|
msgstr "Warning"
|
||||||
|
|
||||||
msgid "WiFi client AP mode"
|
msgid "WiFi client AP mode"
|
||||||
msgstr "WiFi client AP mode"
|
msgstr "WiFi client AP mode"
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
@@ -3,7 +3,7 @@ msgstr ""
|
|||||||
"Project-Id-Version: raspap\n"
|
"Project-Id-Version: raspap\n"
|
||||||
"Report-Msgid-Bugs-To: Bill Zimmerman <billzimmerman@gmail.com>\n"
|
"Report-Msgid-Bugs-To: Bill Zimmerman <billzimmerman@gmail.com>\n"
|
||||||
"POT-Creation-Date: 2017-10-19 08:56+0000\n"
|
"POT-Creation-Date: 2017-10-19 08:56+0000\n"
|
||||||
"PO-Revision-Date: 2025-10-24 10:03\n"
|
"PO-Revision-Date: 2025-11-20 12:21\n"
|
||||||
"Last-Translator: Bill Zimmerman <billzimmerman@gmail.com>\n"
|
"Last-Translator: Bill Zimmerman <billzimmerman@gmail.com>\n"
|
||||||
"Language-Team: Spanish\n"
|
"Language-Team: Spanish\n"
|
||||||
"Language: es_ES\n"
|
"Language: es_ES\n"
|
||||||
@@ -31,17 +31,17 @@ msgid "Dashboard"
|
|||||||
msgstr "Tablero"
|
msgstr "Tablero"
|
||||||
|
|
||||||
msgid "WiFi client"
|
msgid "WiFi client"
|
||||||
msgstr "Cliente WiFi"
|
msgstr "Cliente wiFi"
|
||||||
|
|
||||||
msgid "Hotspot"
|
|
||||||
msgstr "Punto AP"
|
|
||||||
|
|
||||||
msgid "Logging"
|
|
||||||
msgstr "Registro"
|
|
||||||
|
|
||||||
msgid "Status"
|
msgid "Status"
|
||||||
msgstr "Estado"
|
msgstr "Estado"
|
||||||
|
|
||||||
|
msgid "Hotspot"
|
||||||
|
msgstr "Punto de acceso"
|
||||||
|
|
||||||
|
msgid "Logging"
|
||||||
|
msgstr "Registro"
|
||||||
|
|
||||||
msgid "Mem Use"
|
msgid "Mem Use"
|
||||||
msgstr "Uso de mem"
|
msgstr "Uso de mem"
|
||||||
|
|
||||||
@@ -361,13 +361,13 @@ msgid "Cellular"
|
|||||||
msgstr "Celular"
|
msgstr "Celular"
|
||||||
|
|
||||||
msgid "AP"
|
msgid "AP"
|
||||||
msgstr "AP"
|
msgstr "Punto de acceso"
|
||||||
|
|
||||||
msgid "Bridged"
|
msgid "Bridged"
|
||||||
msgstr "Puente"
|
msgstr "Puente"
|
||||||
|
|
||||||
msgid "Adblock"
|
msgid "Adblock"
|
||||||
msgstr "Adblock"
|
msgstr "Bloqueador de anuncios"
|
||||||
|
|
||||||
msgid "VPN"
|
msgid "VPN"
|
||||||
msgstr "VPN"
|
msgstr "VPN"
|
||||||
@@ -743,6 +743,27 @@ msgstr "Habilitar registro"
|
|||||||
msgid "Logfile output"
|
msgid "Logfile output"
|
||||||
msgstr "Salida del archivo de registro"
|
msgstr "Salida del archivo de registro"
|
||||||
|
|
||||||
|
msgid "Log level"
|
||||||
|
msgstr "Nivel de registro"
|
||||||
|
|
||||||
|
msgid "Higher levels reduce log verbosity. Informational is recommended."
|
||||||
|
msgstr "Los niveles más altos reducen la verbosidad del registro. Se recomienda el nivel informativo."
|
||||||
|
|
||||||
|
msgid "Verbose debugging"
|
||||||
|
msgstr "Depuración detallada"
|
||||||
|
|
||||||
|
msgid "Debugging"
|
||||||
|
msgstr "Depuración"
|
||||||
|
|
||||||
|
msgid "Informational"
|
||||||
|
msgstr "Información"
|
||||||
|
|
||||||
|
msgid "Notification"
|
||||||
|
msgstr "Notificación"
|
||||||
|
|
||||||
|
msgid "Warning"
|
||||||
|
msgstr "Advertencia"
|
||||||
|
|
||||||
msgid "WiFi client AP mode"
|
msgid "WiFi client AP mode"
|
||||||
msgstr "Modo AP de WiFi de cliente"
|
msgstr "Modo AP de WiFi de cliente"
|
||||||
|
|
||||||
@@ -1012,7 +1033,7 @@ msgid "Access Point Name (APN)"
|
|||||||
msgstr "Nombre del punto de acceso (APN)"
|
msgstr "Nombre del punto de acceso (APN)"
|
||||||
|
|
||||||
msgid "Password"
|
msgid "Password"
|
||||||
msgstr "Contraseña"
|
msgstr "Password"
|
||||||
|
|
||||||
msgid "Successfully Updated Network Configuration"
|
msgid "Successfully Updated Network Configuration"
|
||||||
msgstr "Configuración de red actualizada correctamente"
|
msgstr "Configuración de red actualizada correctamente"
|
||||||
@@ -1375,6 +1396,9 @@ msgstr "Verificación de salud del adaptador"
|
|||||||
msgid "Inspect adapters"
|
msgid "Inspect adapters"
|
||||||
msgstr "Inspeccionar adaptadores"
|
msgstr "Inspeccionar adaptadores"
|
||||||
|
|
||||||
|
msgid "Theme"
|
||||||
|
msgstr "Temas"
|
||||||
|
|
||||||
#: includes/data_usage.php
|
#: includes/data_usage.php
|
||||||
msgid "Data usage"
|
msgid "Data usage"
|
||||||
msgstr "Uso de datos"
|
msgstr "Uso de datos"
|
||||||
@@ -1382,9 +1406,6 @@ msgstr "Uso de datos"
|
|||||||
msgid "Data usage monitoring"
|
msgid "Data usage monitoring"
|
||||||
msgstr "Monitor de uso de datos"
|
msgstr "Monitor de uso de datos"
|
||||||
|
|
||||||
msgid "Hourly traffic"
|
|
||||||
msgstr "Tráfico por hora"
|
|
||||||
|
|
||||||
msgid "Hourly traffic amount"
|
msgid "Hourly traffic amount"
|
||||||
msgstr "Cantidad de tráfico por hora"
|
msgstr "Cantidad de tráfico por hora"
|
||||||
|
|
||||||
@@ -1576,7 +1597,7 @@ msgstr "Modo AP Bridged habilitado. Para Hostname e IP, consulte la página de a
|
|||||||
|
|
||||||
#: common form controls
|
#: common form controls
|
||||||
msgid "Save settings"
|
msgid "Save settings"
|
||||||
msgstr "Guardar configuraciones"
|
msgstr "Guardar Configuraciones"
|
||||||
|
|
||||||
msgid "Refresh"
|
msgid "Refresh"
|
||||||
msgstr "Refrescar"
|
msgstr "Refrescar"
|
||||||
@@ -1603,7 +1624,7 @@ msgid "adblock"
|
|||||||
msgstr "Bloqueador de anuncios"
|
msgstr "Bloqueador de anuncios"
|
||||||
|
|
||||||
msgid "Ad Blocking"
|
msgid "Ad Blocking"
|
||||||
msgstr "Ad Blocking"
|
msgstr "Bloqueo de anuncios"
|
||||||
|
|
||||||
msgid "Start Ad Blocking"
|
msgid "Start Ad Blocking"
|
||||||
msgstr "Iniciar bloqueo de anuncios"
|
msgstr "Iniciar bloqueo de anuncios"
|
||||||
@@ -2007,8 +2028,6 @@ msgstr "Conectar %s"
|
|||||||
msgid "Disconnect %s"
|
msgid "Disconnect %s"
|
||||||
msgstr "Desconectar %s"
|
msgstr "Desconectar %s"
|
||||||
|
|
||||||
#: includes/about.php
|
|
||||||
|
|
||||||
msgid "About"
|
msgid "About"
|
||||||
msgstr "Acerca de"
|
msgstr "Acerca de"
|
||||||
|
|
||||||
@@ -2096,16 +2115,12 @@ msgstr "patrocinador financiero"
|
|||||||
msgid "exclusive features"
|
msgid "exclusive features"
|
||||||
msgstr "funciones exclusivas"
|
msgstr "funciones exclusivas"
|
||||||
|
|
||||||
#: includes/exceptions.php
|
|
||||||
|
|
||||||
msgid "RaspAP Exception"
|
msgid "RaspAP Exception"
|
||||||
msgstr "Excepción de RaspAP"
|
msgstr "Excepción de RaspAP"
|
||||||
|
|
||||||
msgid "An exception occurred"
|
msgid "An exception occurred"
|
||||||
msgstr "Ocurrió una excepción"
|
msgstr "Ocurrió una excepción"
|
||||||
|
|
||||||
#: includes/restapi.php
|
|
||||||
|
|
||||||
msgid "RestAPI"
|
msgid "RestAPI"
|
||||||
msgstr "RestAPI"
|
msgstr "RestAPI"
|
||||||
|
|
||||||
@@ -2139,8 +2154,6 @@ msgstr "Reiniciando restapi.service"
|
|||||||
msgid "Information provided by restapi.service"
|
msgid "Information provided by restapi.service"
|
||||||
msgstr "Información proporcionada por restapi.service"
|
msgstr "Información proporcionada por restapi.service"
|
||||||
|
|
||||||
#: includes/login.php
|
|
||||||
|
|
||||||
msgid "Session Expired"
|
msgid "Session Expired"
|
||||||
msgstr "Sesión expirada"
|
msgstr "Sesión expirada"
|
||||||
|
|
||||||
@@ -2159,8 +2172,6 @@ msgstr "Olvidé mi contraseña"
|
|||||||
msgid "Login failed"
|
msgid "Login failed"
|
||||||
msgstr "Error de inicio de sesión"
|
msgstr "Error de inicio de sesión"
|
||||||
|
|
||||||
#: includes/ntp.php
|
|
||||||
|
|
||||||
msgid "NTP Server"
|
msgid "NTP Server"
|
||||||
msgstr "Servidor NTP"
|
msgstr "Servidor NTP"
|
||||||
|
|
||||||
@@ -2224,8 +2235,6 @@ msgstr "Configuración NTP no encontrada en %s"
|
|||||||
msgid "NTP configuration updated"
|
msgid "NTP configuration updated"
|
||||||
msgstr "Configuración NTP actualizada"
|
msgstr "Configuración NTP actualizada"
|
||||||
|
|
||||||
#: tailscale plugin
|
|
||||||
|
|
||||||
msgid "Advertising device as a Tailscale exit node"
|
msgid "Advertising device as a Tailscale exit node"
|
||||||
msgstr "Anunciando dispositivo como nodo de salida de Tailscale"
|
msgstr "Anunciando dispositivo como nodo de salida de Tailscale"
|
||||||
|
|
||||||
@@ -2427,8 +2436,6 @@ msgstr "Si las claves expiran para un dispositivo, las conexiones hacia/desde el
|
|||||||
msgid "This option uses <code>--force-reauth</code> to renew the keys for this device."
|
msgid "This option uses <code>--force-reauth</code> to renew the keys for this device."
|
||||||
msgstr "Esta opción usa <code>--force-reauth</code> para renovar las claves para este dispositivo."
|
msgstr "Esta opción usa <code>--force-reauth</code> para renovar las claves para este dispositivo."
|
||||||
|
|
||||||
#: wireshark plugin
|
|
||||||
|
|
||||||
msgid "Start capture"
|
msgid "Start capture"
|
||||||
msgstr "Iniciar captura"
|
msgstr "Iniciar captura"
|
||||||
|
|
||||||
@@ -2567,8 +2574,6 @@ msgstr "Información proporcionada por tshark"
|
|||||||
msgid "Total: %d file(s), %s"
|
msgid "Total: %d file(s), %s"
|
||||||
msgstr "Total: %d archivo(s), %s"
|
msgstr "Total: %d archivo(s), %s"
|
||||||
|
|
||||||
#: captive portal plugin
|
|
||||||
|
|
||||||
msgid "Captive portal"
|
msgid "Captive portal"
|
||||||
msgstr "Portal cautivo"
|
msgstr "Portal cautivo"
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
@@ -3,7 +3,7 @@ msgstr ""
|
|||||||
"Project-Id-Version: raspap\n"
|
"Project-Id-Version: raspap\n"
|
||||||
"Report-Msgid-Bugs-To: Bill Zimmerman <billzimmerman@gmail.com>\n"
|
"Report-Msgid-Bugs-To: Bill Zimmerman <billzimmerman@gmail.com>\n"
|
||||||
"POT-Creation-Date: 2017-10-19 08:56+0000\n"
|
"POT-Creation-Date: 2017-10-19 08:56+0000\n"
|
||||||
"PO-Revision-Date: 2025-10-25 16:03\n"
|
"PO-Revision-Date: 2025-11-20 12:20\n"
|
||||||
"Last-Translator: Bill Zimmerman <billzimmerman@gmail.com>\n"
|
"Last-Translator: Bill Zimmerman <billzimmerman@gmail.com>\n"
|
||||||
"Language-Team: French\n"
|
"Language-Team: French\n"
|
||||||
"Language: fr_FR\n"
|
"Language: fr_FR\n"
|
||||||
@@ -33,15 +33,15 @@ msgstr "Tableau de bord"
|
|||||||
msgid "WiFi client"
|
msgid "WiFi client"
|
||||||
msgstr "Client WiFi"
|
msgstr "Client WiFi"
|
||||||
|
|
||||||
|
msgid "Status"
|
||||||
|
msgstr "État"
|
||||||
|
|
||||||
msgid "Hotspot"
|
msgid "Hotspot"
|
||||||
msgstr "Hotspot"
|
msgstr "Hotspot"
|
||||||
|
|
||||||
msgid "Logging"
|
msgid "Logging"
|
||||||
msgstr "Journalisation"
|
msgstr "Journalisation"
|
||||||
|
|
||||||
msgid "Status"
|
|
||||||
msgstr "État"
|
|
||||||
|
|
||||||
msgid "Mem Use"
|
msgid "Mem Use"
|
||||||
msgstr "Mémoire"
|
msgstr "Mémoire"
|
||||||
|
|
||||||
@@ -743,6 +743,27 @@ msgstr "Activer la journalisation"
|
|||||||
msgid "Logfile output"
|
msgid "Logfile output"
|
||||||
msgstr "Sortie de journal"
|
msgstr "Sortie de journal"
|
||||||
|
|
||||||
|
msgid "Log level"
|
||||||
|
msgstr "Niveau d'enregistrement"
|
||||||
|
|
||||||
|
msgid "Higher levels reduce log verbosity. Informational is recommended."
|
||||||
|
msgstr "Des niveaux plus élevés réduisent la verbosité des journaux. Il est recommandé d'opter pour un niveau d'information."
|
||||||
|
|
||||||
|
msgid "Verbose debugging"
|
||||||
|
msgstr "Débogage verbeux"
|
||||||
|
|
||||||
|
msgid "Debugging"
|
||||||
|
msgstr "Débogage"
|
||||||
|
|
||||||
|
msgid "Informational"
|
||||||
|
msgstr "Information"
|
||||||
|
|
||||||
|
msgid "Notification"
|
||||||
|
msgstr "Notification"
|
||||||
|
|
||||||
|
msgid "Warning"
|
||||||
|
msgstr "Avertissement"
|
||||||
|
|
||||||
msgid "WiFi client AP mode"
|
msgid "WiFi client AP mode"
|
||||||
msgstr "Mode AP client WiFi"
|
msgstr "Mode AP client WiFi"
|
||||||
|
|
||||||
@@ -976,7 +997,7 @@ msgid "Devices"
|
|||||||
msgstr "Appareils"
|
msgstr "Appareils"
|
||||||
|
|
||||||
msgid "Diagnostics"
|
msgid "Diagnostics"
|
||||||
msgstr "Diagnostics"
|
msgstr "Diagnostiques"
|
||||||
|
|
||||||
msgid "Network devices"
|
msgid "Network devices"
|
||||||
msgstr "Appareils réseau"
|
msgstr "Appareils réseau"
|
||||||
@@ -1163,7 +1184,7 @@ msgid "CPU Load"
|
|||||||
msgstr "Charge du processeur"
|
msgstr "Charge du processeur"
|
||||||
|
|
||||||
msgid "CPU Temp"
|
msgid "CPU Temp"
|
||||||
msgstr "Température du CPU"
|
msgstr "Temp. CPU"
|
||||||
|
|
||||||
msgid "Reboot"
|
msgid "Reboot"
|
||||||
msgstr "Redémarrer"
|
msgstr "Redémarrer"
|
||||||
@@ -1375,9 +1396,12 @@ msgstr "Vérification de l'état de l'adaptateur"
|
|||||||
msgid "Inspect adapters"
|
msgid "Inspect adapters"
|
||||||
msgstr "Inspecter les adaptateurs"
|
msgstr "Inspecter les adaptateurs"
|
||||||
|
|
||||||
|
msgid "Theme"
|
||||||
|
msgstr "Thème"
|
||||||
|
|
||||||
#: includes/data_usage.php
|
#: includes/data_usage.php
|
||||||
msgid "Data usage"
|
msgid "Data usage"
|
||||||
msgstr "Données utilisées"
|
msgstr "Utilisation des données"
|
||||||
|
|
||||||
msgid "Data usage monitoring"
|
msgid "Data usage monitoring"
|
||||||
msgstr "Surveillance de l'utilisation des données"
|
msgstr "Surveillance de l'utilisation des données"
|
||||||
@@ -1600,7 +1624,7 @@ msgid "adblock"
|
|||||||
msgstr "AdBlock"
|
msgstr "AdBlock"
|
||||||
|
|
||||||
msgid "Ad Blocking"
|
msgid "Ad Blocking"
|
||||||
msgstr "Ad Blocking"
|
msgstr "Blocage de la pub"
|
||||||
|
|
||||||
msgid "Start Ad Blocking"
|
msgid "Start Ad Blocking"
|
||||||
msgstr "Lancer le blocage des publicités"
|
msgstr "Lancer le blocage des publicités"
|
||||||
|
|||||||
Binary file not shown.
@@ -3,7 +3,7 @@ msgstr ""
|
|||||||
"Project-Id-Version: raspap\n"
|
"Project-Id-Version: raspap\n"
|
||||||
"Report-Msgid-Bugs-To: Bill Zimmerman <billzimmerman@gmail.com>\n"
|
"Report-Msgid-Bugs-To: Bill Zimmerman <billzimmerman@gmail.com>\n"
|
||||||
"POT-Creation-Date: 2017-10-19 08:56+0000\n"
|
"POT-Creation-Date: 2017-10-19 08:56+0000\n"
|
||||||
"PO-Revision-Date: 2025-10-25 14:18\n"
|
"PO-Revision-Date: 2025-11-20 12:20\n"
|
||||||
"Last-Translator: Bill Zimmerman <billzimmerman@gmail.com>\n"
|
"Last-Translator: Bill Zimmerman <billzimmerman@gmail.com>\n"
|
||||||
"Language-Team: Italian\n"
|
"Language-Team: Italian\n"
|
||||||
"Language: it_IT\n"
|
"Language: it_IT\n"
|
||||||
@@ -33,15 +33,15 @@ msgstr "Dashboard"
|
|||||||
msgid "WiFi client"
|
msgid "WiFi client"
|
||||||
msgstr "Client WiFi"
|
msgstr "Client WiFi"
|
||||||
|
|
||||||
|
msgid "Status"
|
||||||
|
msgstr "Stato"
|
||||||
|
|
||||||
msgid "Hotspot"
|
msgid "Hotspot"
|
||||||
msgstr "Hotspot"
|
msgstr "Hotspot"
|
||||||
|
|
||||||
msgid "Logging"
|
msgid "Logging"
|
||||||
msgstr "Registrazione"
|
msgstr "Registrazione"
|
||||||
|
|
||||||
msgid "Status"
|
|
||||||
msgstr "Stato"
|
|
||||||
|
|
||||||
msgid "Mem Use"
|
msgid "Mem Use"
|
||||||
msgstr "Uso Mem"
|
msgstr "Uso Mem"
|
||||||
|
|
||||||
@@ -67,7 +67,7 @@ msgid "System"
|
|||||||
msgstr "Sistema"
|
msgstr "Sistema"
|
||||||
|
|
||||||
msgid "About RaspAP"
|
msgid "About RaspAP"
|
||||||
msgstr "Info RaspAP"
|
msgstr "Informazioni su RaspAP"
|
||||||
|
|
||||||
#: includes/admin.php
|
#: includes/admin.php
|
||||||
msgid "Authentication settings"
|
msgid "Authentication settings"
|
||||||
@@ -743,6 +743,27 @@ msgstr "Abilita la registrazione"
|
|||||||
msgid "Logfile output"
|
msgid "Logfile output"
|
||||||
msgstr "File di log in uscita"
|
msgstr "File di log in uscita"
|
||||||
|
|
||||||
|
msgid "Log level"
|
||||||
|
msgstr "Livello di registro"
|
||||||
|
|
||||||
|
msgid "Higher levels reduce log verbosity. Informational is recommended."
|
||||||
|
msgstr "Livelli più alti riducono la verbosità dei registri. Si consiglia di utilizzare il livello informativo."
|
||||||
|
|
||||||
|
msgid "Verbose debugging"
|
||||||
|
msgstr "Debug verboso"
|
||||||
|
|
||||||
|
msgid "Debugging"
|
||||||
|
msgstr "Debug"
|
||||||
|
|
||||||
|
msgid "Informational"
|
||||||
|
msgstr "Informativo"
|
||||||
|
|
||||||
|
msgid "Notification"
|
||||||
|
msgstr "Notifica"
|
||||||
|
|
||||||
|
msgid "Warning"
|
||||||
|
msgstr "Avvertenze"
|
||||||
|
|
||||||
msgid "WiFi client AP mode"
|
msgid "WiFi client AP mode"
|
||||||
msgstr "AP WiFi modalità client"
|
msgstr "AP WiFi modalità client"
|
||||||
|
|
||||||
@@ -1163,7 +1184,7 @@ msgid "CPU Load"
|
|||||||
msgstr "Carico CPU"
|
msgstr "Carico CPU"
|
||||||
|
|
||||||
msgid "CPU Temp"
|
msgid "CPU Temp"
|
||||||
msgstr "Temperatura CPU"
|
msgstr "Temp. CPU"
|
||||||
|
|
||||||
msgid "Reboot"
|
msgid "Reboot"
|
||||||
msgstr "Riavvia"
|
msgstr "Riavvia"
|
||||||
@@ -1375,6 +1396,9 @@ msgstr "Controllo dello stato di salute dell'adattatore"
|
|||||||
msgid "Inspect adapters"
|
msgid "Inspect adapters"
|
||||||
msgstr "Ispezionare gli adattatori"
|
msgstr "Ispezionare gli adattatori"
|
||||||
|
|
||||||
|
msgid "Theme"
|
||||||
|
msgstr "Tema"
|
||||||
|
|
||||||
#: includes/data_usage.php
|
#: includes/data_usage.php
|
||||||
msgid "Data usage"
|
msgid "Data usage"
|
||||||
msgstr "Utilizzo dei dati"
|
msgstr "Utilizzo dei dati"
|
||||||
@@ -1600,13 +1624,13 @@ msgid "adblock"
|
|||||||
msgstr "AdBlock"
|
msgstr "AdBlock"
|
||||||
|
|
||||||
msgid "Ad Blocking"
|
msgid "Ad Blocking"
|
||||||
msgstr "Ad Blocking"
|
msgstr "Blocco degli annunci"
|
||||||
|
|
||||||
msgid "Start Ad Blocking"
|
msgid "Start Ad Blocking"
|
||||||
msgstr "Avvia Ad Blocking"
|
msgstr "Avvia blocco degli annunci"
|
||||||
|
|
||||||
msgid "Restart Ad Blocking"
|
msgid "Restart Ad Blocking"
|
||||||
msgstr "Riavvia Ad Blocking"
|
msgstr "Riavvia blocco degli annunci"
|
||||||
|
|
||||||
msgid "Blocklist settings"
|
msgid "Blocklist settings"
|
||||||
msgstr "Impostazioni Blocklist"
|
msgstr "Impostazioni Blocklist"
|
||||||
|
|||||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -3,7 +3,7 @@ msgstr ""
|
|||||||
"Project-Id-Version: raspap\n"
|
"Project-Id-Version: raspap\n"
|
||||||
"Report-Msgid-Bugs-To: Bill Zimmerman <billzimmerman@gmail.com>\n"
|
"Report-Msgid-Bugs-To: Bill Zimmerman <billzimmerman@gmail.com>\n"
|
||||||
"POT-Creation-Date: 2017-10-19 08:56+0000\n"
|
"POT-Creation-Date: 2017-10-19 08:56+0000\n"
|
||||||
"PO-Revision-Date: 2025-10-25 12:16\n"
|
"PO-Revision-Date: 2025-11-20 12:19\n"
|
||||||
"Last-Translator: Bill Zimmerman <billzimmerman@gmail.com>\n"
|
"Last-Translator: Bill Zimmerman <billzimmerman@gmail.com>\n"
|
||||||
"Language-Team: Chinese Simplified\n"
|
"Language-Team: Chinese Simplified\n"
|
||||||
"Language: zh_CN\n"
|
"Language: zh_CN\n"
|
||||||
@@ -33,14 +33,14 @@ msgstr "仪表板"
|
|||||||
msgid "WiFi client"
|
msgid "WiFi client"
|
||||||
msgstr "WLAN客户端设置"
|
msgstr "WLAN客户端设置"
|
||||||
|
|
||||||
|
msgid "Status"
|
||||||
|
msgstr "状态"
|
||||||
|
|
||||||
msgid "Hotspot"
|
msgid "Hotspot"
|
||||||
msgstr "WLAN热点设置"
|
msgstr "WLAN热点设置"
|
||||||
|
|
||||||
msgid "Logging"
|
msgid "Logging"
|
||||||
msgstr "日志记录"
|
msgstr "记录"
|
||||||
|
|
||||||
msgid "Status"
|
|
||||||
msgstr "状态"
|
|
||||||
|
|
||||||
msgid "Mem Use"
|
msgid "Mem Use"
|
||||||
msgstr "内存使用"
|
msgstr "内存使用"
|
||||||
@@ -716,7 +716,7 @@ msgid "DHCP configuration for %s updated."
|
|||||||
msgstr "%s 的 DHCP 配置已更新。"
|
msgstr "%s 的 DHCP 配置已更新。"
|
||||||
|
|
||||||
msgid "Interface %s has no default settings."
|
msgid "Interface %s has no default settings."
|
||||||
msgstr "接口 %s 没有默认设置。"
|
msgstr "界面 %s 没有默认设置。"
|
||||||
|
|
||||||
msgid "Configure settings in <strong>DHCP Server</strong> before starting AP."
|
msgid "Configure settings in <strong>DHCP Server</strong> before starting AP."
|
||||||
msgstr "启动 AP 前在<strong>DHCP 服务器</strong>中配置设置。"
|
msgstr "启动 AP 前在<strong>DHCP 服务器</strong>中配置设置。"
|
||||||
@@ -742,6 +742,27 @@ msgstr "开启log"
|
|||||||
msgid "Logfile output"
|
msgid "Logfile output"
|
||||||
msgstr "log信息输出"
|
msgstr "log信息输出"
|
||||||
|
|
||||||
|
msgid "Log level"
|
||||||
|
msgstr "日志级别"
|
||||||
|
|
||||||
|
msgid "Higher levels reduce log verbosity. Informational is recommended."
|
||||||
|
msgstr "级别越高,日志的冗长程度越低。建议使用 \"信息 \"级别。"
|
||||||
|
|
||||||
|
msgid "Verbose debugging"
|
||||||
|
msgstr "详细调试"
|
||||||
|
|
||||||
|
msgid "Debugging"
|
||||||
|
msgstr "调试"
|
||||||
|
|
||||||
|
msgid "Informational"
|
||||||
|
msgstr "信息"
|
||||||
|
|
||||||
|
msgid "Notification"
|
||||||
|
msgstr "通知"
|
||||||
|
|
||||||
|
msgid "Warning"
|
||||||
|
msgstr "警告"
|
||||||
|
|
||||||
msgid "WiFi client AP mode"
|
msgid "WiFi client AP mode"
|
||||||
msgstr "无线网客户端AP模式"
|
msgstr "无线网客户端AP模式"
|
||||||
|
|
||||||
@@ -1357,7 +1378,7 @@ msgid "Automatically close alerts after a specified timeout"
|
|||||||
msgstr "在指定超时后自动关闭警报"
|
msgstr "在指定超时后自动关闭警报"
|
||||||
|
|
||||||
msgid "To <a href=\"%s\" target=\"_blank\">inspect adapters</a> attached to this device, click or tap the button below."
|
msgid "To <a href=\"%s\" target=\"_blank\">inspect adapters</a> attached to this device, click or tap the button below."
|
||||||
msgstr "要<a href=\"%s\" target=\"_blank\">检查连接到此设备的适配器</a>,请单击或点击下面的按钮。"
|
msgstr "要<a href=\"%s\" target=\"_blank\">检查</a>连接到此设备的<a href=\" %s \" target=\"_blank\">适配器</a>,请单击或点击下面的按钮。"
|
||||||
|
|
||||||
msgid "The adapter inspection tool returns details about external WLAN devices including drivers, supported modes and so on."
|
msgid "The adapter inspection tool returns details about external WLAN devices including drivers, supported modes and so on."
|
||||||
msgstr "适配器检查工具返回外部 WLAN 设备的详细信息,包括驱动程序、支持的模式等。"
|
msgstr "适配器检查工具返回外部 WLAN 设备的详细信息,包括驱动程序、支持的模式等。"
|
||||||
|
|||||||
2
plugins
2
plugins
Submodule plugins updated: deb689143e...9236df6139
@@ -28,7 +28,7 @@ class DhcpcdManager
|
|||||||
* @param bool $wifiAPEnable
|
* @param bool $wifiAPEnable
|
||||||
* @param bool $dualAPEnable
|
* @param bool $dualAPEnable
|
||||||
* @param StatusMessage $status
|
* @param StatusMessage $status
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function buildConfig(
|
public function buildConfig(
|
||||||
string $ap_iface,
|
string $ap_iface,
|
||||||
@@ -111,6 +111,8 @@ class DhcpcdManager
|
|||||||
$domain_name_server
|
$domain_name_server
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
$dhcp_cfg = file_get_contents(SELF::CONF_DEFAULT);
|
$dhcp_cfg = file_get_contents(SELF::CONF_DEFAULT);
|
||||||
$skip_dhcp = false;
|
$skip_dhcp = false;
|
||||||
|
|
||||||
@@ -129,11 +131,15 @@ class DhcpcdManager
|
|||||||
$dhcp_cfg = $this->removeIface($dhcp_cfg,'uap0');
|
$dhcp_cfg = $this->removeIface($dhcp_cfg,'uap0');
|
||||||
$dhcp_cfg .= $config;
|
$dhcp_cfg .= $config;
|
||||||
} else {
|
} else {
|
||||||
|
if (strpos($dhcp_cfg, 'interface '.$ap_iface) !== false &&
|
||||||
|
strpos($dhcp_cfg, 'nogateway') !== false) {
|
||||||
|
$config[] = 'nogateway';
|
||||||
|
}
|
||||||
$config = join(PHP_EOL, $config);
|
$config = join(PHP_EOL, $config);
|
||||||
$dhcp_cfg = $this->removeIface($dhcp_cfg,'br0');
|
$dhcp_cfg = $this->removeIface($dhcp_cfg,'br0');
|
||||||
$dhcp_cfg = $this->removeIface($dhcp_cfg,'uap0');
|
$dhcp_cfg = $this->removeIface($dhcp_cfg,'uap0');
|
||||||
if (!strpos($dhcp_cfg, 'metric')) {
|
if (!strpos($dhcp_cfg, 'metric')) {
|
||||||
$dhcp_cfg = preg_replace('/^#\sRaspAP\s'.$ap_iface.'\s.*?(?=(?:\s*^\s*$|\s*nogateway))/ms', $config, $dhcp_cfg, 1);
|
$dhcp_cfg = preg_replace('/^#\sRaspAP\s'.$ap_iface.'\s.*?(?:\s*^\s*$|\s*nogateway)/ms', $config, $dhcp_cfg, 1);
|
||||||
} else {
|
} else {
|
||||||
$metrics = true;
|
$metrics = true;
|
||||||
}
|
}
|
||||||
@@ -193,7 +199,12 @@ class DhcpcdManager
|
|||||||
$status->addMessage('DHCP configuration for '.$iface.' added.', 'success');
|
$status->addMessage('DHCP configuration for '.$iface.' added.', 'success');
|
||||||
} else {
|
} else {
|
||||||
$cfg = join(PHP_EOL, $cfg);
|
$cfg = join(PHP_EOL, $cfg);
|
||||||
$dhcp_cfg = preg_replace('/^#\sRaspAP\s'.$iface.'\s.*?(?=\s*^\s*$)/ms', $cfg, $dhcp_cfg, 1);
|
$dhcp_cfg = preg_replace(
|
||||||
|
'/^#\sRaspAP\s'.$iface.'\s.*?(?=\n*(?:^#\sRaspAP|^interface\s(?!'.$iface.'$)|\z))/ms',
|
||||||
|
$cfg . PHP_EOL,
|
||||||
|
$dhcp_cfg,
|
||||||
|
1
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $dhcp_cfg;
|
return $dhcp_cfg;
|
||||||
@@ -276,8 +287,8 @@ class DhcpcdManager
|
|||||||
*/
|
*/
|
||||||
public function remove(string $iface, StatusMessage $status): bool
|
public function remove(string $iface, StatusMessage $status): bool
|
||||||
{
|
{
|
||||||
$configFile = SELF::CONF_DEFAULT;
|
$configFile = SELF::CONF_DEFAULT;
|
||||||
$tempFile = SELF::CONF_TMP;
|
$tempFile = SELF::CONF_TMP;
|
||||||
|
|
||||||
$dhcp_cfg = file_get_contents($configFile);
|
$dhcp_cfg = file_get_contents($configFile);
|
||||||
$modified_cfg = preg_replace('/^#\sRaspAP\s'.$iface.'\s.*?(?=\s*^\s*$)([\s]+)/ms', '', $dhcp_cfg, 1);
|
$modified_cfg = preg_replace('/^#\sRaspAP\s'.$iface.'\s.*?(?=\s*^\s*$)([\s]+)/ms', '', $dhcp_cfg, 1);
|
||||||
@@ -286,7 +297,7 @@ class DhcpcdManager
|
|||||||
|
|
||||||
$cmd = sprintf('sudo cp %s %s', escapeshellarg($tempFile), escapeshellarg($configFile));
|
$cmd = sprintf('sudo cp %s %s', escapeshellarg($tempFile), escapeshellarg($configFile));
|
||||||
exec($cmd, $output, $result);
|
exec($cmd, $output, $result);
|
||||||
|
|
||||||
if ($result == 0) {
|
if ($result == 0) {
|
||||||
$status->addMessage('DHCP configuration for '.$iface.' removed', 'success');
|
$status->addMessage('DHCP configuration for '.$iface.' removed', 'success');
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -234,9 +234,9 @@ class HostapdManager
|
|||||||
}
|
}
|
||||||
|
|
||||||
// bridge handling
|
// bridge handling
|
||||||
if (!empty($params['bridge'])) {
|
if (!empty($params['bridgeName'])) {
|
||||||
$config[] = 'interface=' . $params['interface'];
|
$config[] = 'interface=' . $params['interface'];
|
||||||
$config[] = 'bridge=' . $params['bridge'];
|
$config[] = 'bridge=' . $params['bridgeName'];
|
||||||
} else {
|
} else {
|
||||||
$config[] = 'interface=' . $params['interface'];
|
$config[] = 'interface=' . $params['interface'];
|
||||||
}
|
}
|
||||||
@@ -250,6 +250,12 @@ class HostapdManager
|
|||||||
$config[] = 'max_num_sta=' . (int)$params['max_num_sta'];
|
$config[] = 'max_num_sta=' . (int)$params['max_num_sta'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add logging configuration if enabled
|
||||||
|
if (!empty($params['log_enable'])) {
|
||||||
|
$config[] = 'logger_syslog=-1';
|
||||||
|
$config[] = 'logger_syslog_level=0';
|
||||||
|
}
|
||||||
|
|
||||||
// optional additional user config
|
// optional additional user config
|
||||||
$config[] = $this->parseUserHostapdCfg();
|
$config[] = $this->parseUserHostapdCfg();
|
||||||
|
|
||||||
@@ -350,17 +356,6 @@ class HostapdManager
|
|||||||
return [$apIface, $cliIface, $sessionIface];
|
return [$apIface, $cliIface, $sessionIface];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Enables or disables hostapd logging
|
|
||||||
*
|
|
||||||
* @param int $logEnable
|
|
||||||
*/
|
|
||||||
private function handleLogState(int $logEnable): void
|
|
||||||
{
|
|
||||||
$script = $logEnable === 1 ? 'enablelog.sh' : 'disablelog.sh';
|
|
||||||
exec('sudo ' . RASPI_CONFIG . '/hostapd/' . $script);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses optional /etc/hostapd/hostapd.conf.users file
|
* Parses optional /etc/hostapd/hostapd.conf.users file
|
||||||
*
|
*
|
||||||
@@ -440,8 +435,6 @@ class HostapdManager
|
|||||||
*/
|
*/
|
||||||
public function persistHostapdIni(array $states, string $apIface, string $cliIface, array $previousIni = []): bool
|
public function persistHostapdIni(array $states, string $apIface, string $cliIface, array $previousIni = []): bool
|
||||||
{
|
{
|
||||||
$this->applyLogState($states['LogEnable']);
|
|
||||||
|
|
||||||
// compose new ini payload
|
// compose new ini payload
|
||||||
$cfg = [
|
$cfg = [
|
||||||
'WifiInterface' => $apIface,
|
'WifiInterface' => $apIface,
|
||||||
@@ -460,17 +453,6 @@ class HostapdManager
|
|||||||
return write_php_ini($cfg, RASPI_CONFIG . '/hostapd.ini');
|
return write_php_ini($cfg, RASPI_CONFIG . '/hostapd.ini');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Enables or disables hostapd logging
|
|
||||||
*
|
|
||||||
* @param int $logEnable 1 = enable, 0 = disable
|
|
||||||
*/
|
|
||||||
private function applyLogState(int $logEnable): void
|
|
||||||
{
|
|
||||||
$script = $logEnable === 1 ? 'enablelog.sh' : 'disablelog.sh';
|
|
||||||
exec('sudo ' . RASPI_CONFIG . '/hostapd/' . $script);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a count of hostapd-<interface>.conf files
|
* Returns a count of hostapd-<interface>.conf files
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -197,6 +197,7 @@ class HotspotService
|
|||||||
try {
|
try {
|
||||||
// normalize state flags
|
// normalize state flags
|
||||||
$validated['interface'] = $apIface;
|
$validated['interface'] = $apIface;
|
||||||
|
$validated["bridgeName"] = !empty($states["BridgedEnable"]) ? "br0" : null;
|
||||||
$validated['bridge'] = !empty($states['BridgedEnable']);
|
$validated['bridge'] = !empty($states['BridgedEnable']);
|
||||||
$validated['apsta'] = !empty($states['WifiAPEnable']);
|
$validated['apsta'] = !empty($states['WifiAPEnable']);
|
||||||
$validated['repeater'] = !empty($states['RepeaterEnable']);
|
$validated['repeater'] = !empty($states['RepeaterEnable']);
|
||||||
@@ -418,6 +419,36 @@ class HotspotService
|
|||||||
return array_values($interfaces);
|
return array_values($interfaces);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves hostapd service logs from systemd journal
|
||||||
|
*
|
||||||
|
* @param int $lines number of log lines to retrieve (default: 100, max: 1000)
|
||||||
|
* @param bool $follow return command for real-time following (tbd)
|
||||||
|
* @return array ['success' => bool, 'logs' => array, 'command' => string]
|
||||||
|
*/
|
||||||
|
public function getHostapdLogs(int $lines = 100, bool $follow = false): array
|
||||||
|
{
|
||||||
|
// sanitize and limit line count
|
||||||
|
$lines = max(1, min(1000, $lines));
|
||||||
|
|
||||||
|
if ($follow) {
|
||||||
|
return [
|
||||||
|
'success' => true,
|
||||||
|
'logs' => [],
|
||||||
|
'command' => 'journalctl -u hostapd.service -f --no-pager'
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
$cmd = sprintf('sudo journalctl -u hostapd.service -n %d --no-pager 2>&1', $lines);
|
||||||
|
exec($cmd, $output, $status);
|
||||||
|
|
||||||
|
return [
|
||||||
|
'success' => $status === 0,
|
||||||
|
'logs' => $output,
|
||||||
|
'line_count' => count($output)
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Starts services for given interface
|
* Starts services for given interface
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -16,16 +16,15 @@ class WiFiManager
|
|||||||
|
|
||||||
private const MIN_RSSI = -100;
|
private const MIN_RSSI = -100;
|
||||||
private const MAX_RSSI = -55;
|
private const MAX_RSSI = -55;
|
||||||
|
const SECURITY_OPEN = 'OPEN';
|
||||||
|
|
||||||
public function knownWifiStations(&$networks)
|
public function knownWifiStations(&$networks)
|
||||||
{
|
{
|
||||||
// find currently configured networks
|
// find currently configured networks
|
||||||
exec(' sudo cat ' . RASPI_WPA_SUPPLICANT_CONFIG, $known_return);
|
exec(' sudo cat ' . RASPI_WPA_SUPPLICANT_CONFIG, $known_return);
|
||||||
$index = 0;
|
|
||||||
foreach ($known_return as $line) {
|
foreach ($known_return as $line) {
|
||||||
if (preg_match('/network\s*=/', $line)) {
|
if (preg_match('/network\s*=/', $line)) {
|
||||||
$network = array('visible' => false, 'configured' => true, 'connected' => false, 'index' => null);
|
$network = array('visible' => false, 'configured' => true, 'connected' => false, 'index' => null);
|
||||||
++$index;
|
|
||||||
} elseif (isset($network) && $network !== null) {
|
} elseif (isset($network) && $network !== null) {
|
||||||
if (preg_match('/^\s*}\s*$/', $line)) {
|
if (preg_match('/^\s*}\s*$/', $line)) {
|
||||||
$networks[$ssid] = $network;
|
$networks[$ssid] = $network;
|
||||||
@@ -37,8 +36,7 @@ class WiFiManager
|
|||||||
$ssid = trim($lineArr[1], '"');
|
$ssid = trim($lineArr[1], '"');
|
||||||
$ssid = str_replace('P"','',$ssid);
|
$ssid = str_replace('P"','',$ssid);
|
||||||
$network['ssid'] = $ssid;
|
$network['ssid'] = $ssid;
|
||||||
$index = $this->getNetworkIdBySSID($ssid);
|
$network['index'] = $this->getNetworkIdBySSID($ssid);
|
||||||
$network['index'] = $index;
|
|
||||||
break;
|
break;
|
||||||
case 'psk':
|
case 'psk':
|
||||||
$network['passkey'] = trim($lineArr[1]);
|
$network['passkey'] = trim($lineArr[1]);
|
||||||
@@ -51,7 +49,7 @@ class WiFiManager
|
|||||||
break;
|
break;
|
||||||
case 'key_mgmt':
|
case 'key_mgmt':
|
||||||
if (! array_key_exists('passphrase', $network) && $lineArr[1] === 'NONE') {
|
if (! array_key_exists('passphrase', $network) && $lineArr[1] === 'NONE') {
|
||||||
$network['protocol'] = 'Open';
|
$network['protocol'] = self::SECURITY_OPEN;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'priority':
|
case 'priority':
|
||||||
@@ -84,24 +82,27 @@ class WiFiManager
|
|||||||
$cacheKey,
|
$cacheKey,
|
||||||
function () use ($iface) {
|
function () use ($iface) {
|
||||||
$stdout = shell_exec("sudo iw dev $iface scan");
|
$stdout = shell_exec("sudo iw dev $iface scan");
|
||||||
|
sleep(1);
|
||||||
|
if ($stdout === null) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
return preg_split("/\n/", $stdout);
|
return preg_split("/\n/", $stdout);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
// exclude the AP from nearby networks
|
// determine the next index that follows the indexes of the known networks
|
||||||
exec('sed -rn "s/ssid=(.*)\s*$/\1/p" ' . escapeshellarg(RASPI_HOSTAPD_CONFIG), $ap_ssid);
|
|
||||||
$ap_ssid = $ap_ssid[0] ?? '';
|
|
||||||
|
|
||||||
$index = 0;
|
$index = 0;
|
||||||
if (!empty($networks)) {
|
if (!empty($networks)) {
|
||||||
$lastnet = end($networks);
|
foreach ($networks as $network) {
|
||||||
if (isset($lastnet['index'])) {
|
if (isset($network['index']) && is_numeric($network['index']) && ($network['index'] > $index)) {
|
||||||
$index = $lastnet['index'] + 1;
|
$index = (int)$network['index'];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
$index++;
|
||||||
|
|
||||||
$current = [];
|
$current = [];
|
||||||
$commitCurrent = function () use (&$current, &$networks, &$index, $ap_ssid) {
|
$commitCurrent = function () use (&$current, &$networks, &$index) {
|
||||||
if (empty($current['ssid'])) {
|
if (empty($current['ssid'])) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -109,7 +110,7 @@ class WiFiManager
|
|||||||
$ssid = $current['ssid'];
|
$ssid = $current['ssid'];
|
||||||
|
|
||||||
// unprintable 7bit ASCII control codes, delete or quotes -> ignore network
|
// unprintable 7bit ASCII control codes, delete or quotes -> ignore network
|
||||||
if ($ssid === $ap_ssid || preg_match('/[\x00-\x1f\x7f\'`\´"]/', $ssid)) {
|
if (preg_match('/[\x00-\x1f\x7f\'`\´"]/', $ssid)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,7 +128,7 @@ class WiFiManager
|
|||||||
$networks[$ssid] = [
|
$networks[$ssid] = [
|
||||||
'ssid' => $ssid,
|
'ssid' => $ssid,
|
||||||
'configured' => false,
|
'configured' => false,
|
||||||
'protocol' => $current['security'] ?? 'OPEN',
|
'protocol' => $current['security'] ?? self::SECURITY_OPEN,
|
||||||
'channel' => $channel,
|
'channel' => $channel,
|
||||||
'passphrase' => '',
|
'passphrase' => '',
|
||||||
'visible' => true,
|
'visible' => true,
|
||||||
@@ -135,9 +136,13 @@ class WiFiManager
|
|||||||
'RSSI' => $rssi,
|
'RSSI' => $rssi,
|
||||||
'index' => $index
|
'index' => $index
|
||||||
];
|
];
|
||||||
++$index;
|
$index++; // increment for next new network
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (is_string($scan_results)) {
|
||||||
|
$scan_results = explode("\n", trim($scan_results));
|
||||||
|
}
|
||||||
|
|
||||||
foreach ($scan_results as $line) {
|
foreach ($scan_results as $line) {
|
||||||
$line = trim($line);
|
$line = trim($line);
|
||||||
@@ -149,7 +154,7 @@ class WiFiManager
|
|||||||
'ssid' => '',
|
'ssid' => '',
|
||||||
'signal' => null,
|
'signal' => null,
|
||||||
'freq' => null,
|
'freq' => null,
|
||||||
'security' => 'OPEN'
|
'security' => self::SECURITY_OPEN
|
||||||
];
|
];
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -172,20 +177,50 @@ class WiFiManager
|
|||||||
}
|
}
|
||||||
$commitCurrent();
|
$commitCurrent();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Check if networks are connected via wpa_cli status
|
||||||
|
* NB: iwconfig shows the last associated SSID even when connection is inactive
|
||||||
*/
|
*/
|
||||||
public function connectedWifiStations(&$networks)
|
public function connectedWifiStations(&$networks)
|
||||||
{
|
{
|
||||||
exec('iwconfig ' .$_SESSION['wifi_client_interface'], $iwconfig_return);
|
$wpa_state = null;
|
||||||
foreach ($iwconfig_return as $line) {
|
$connected_ssid = null;
|
||||||
if (preg_match('/ESSID:\"([^"]+)\"/i', $line, $iwconfig_ssid)) {
|
$iface = $_SESSION['wifi_client_interface'];
|
||||||
$ssid=hexSequence2lower($iwconfig_ssid[1]);
|
|
||||||
$networks[$ssid]['connected'] = true;
|
$cmd = "sudo wpa_cli -i $iface status";
|
||||||
//$check=detectCaptivePortal($_SESSION['wifi_client_interface']);
|
$status_output = shell_exec($cmd);
|
||||||
$networks[$ssid]["portal-url"]=$check["URL"];
|
|
||||||
|
if ($status_output === null || empty($status_output)) {
|
||||||
|
error_log("WiFiManager::connectedWifiStations: wpa_cli command failed or returned no output");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$lines = explode("\n", trim($status_output));
|
||||||
|
|
||||||
|
foreach ($lines as $line) {
|
||||||
|
$line = trim($line);
|
||||||
|
if (preg_match('/^wpa_state=(.+)$/', $line, $matches)) {
|
||||||
|
$wpa_state = trim($matches[1]);
|
||||||
}
|
}
|
||||||
|
if (preg_match('/^ssid=(.+)$/', $line, $matches)) {
|
||||||
|
$connected_ssid = trim($matches[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($wpa_state === 'COMPLETED' && !empty($connected_ssid)) {
|
||||||
|
$ssid = hexSequence2lower($connected_ssid);
|
||||||
|
|
||||||
|
// check if this SSID exists in networks array
|
||||||
|
if (array_key_exists($ssid, $networks)) {
|
||||||
|
$networks[$ssid]['connected'] = true;
|
||||||
|
} else {
|
||||||
|
error_log("WiFiManager::connectedWifiStations: SSID '$ssid' not found. SSIDs: " . implode(', ', array_keys($networks)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// captive portal detection
|
||||||
|
// $check = detectCaptivePortal($iface);
|
||||||
|
// if (isset($check["URL"])) {
|
||||||
|
// $networks[$ssid]["portal-url"] = $check["URL"];
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -250,8 +285,11 @@ class WiFiManager
|
|||||||
{
|
{
|
||||||
$iface = $_SESSION['wifi_client_interface'];
|
$iface = $_SESSION['wifi_client_interface'];
|
||||||
if ($force == true) {
|
if ($force == true) {
|
||||||
$cmd = "sudo /sbin/wpa_supplicant -i $unescapedIface -c /etc/wpa_supplicant/wpa_supplicant.conf -B 2>&1";
|
$cmd = "sudo rm -f /var/run/wpa_supplicant/" . $iface;
|
||||||
$result = shell_exec($cmd);
|
$result = shell_exec($cmd);
|
||||||
|
$cmd = "sudo /sbin/wpa_supplicant -i $iface -c /etc/wpa_supplicant/wpa_supplicant.conf -B 2>&1";
|
||||||
|
$result = shell_exec($cmd);
|
||||||
|
sleep(2);
|
||||||
}
|
}
|
||||||
$cmd = "sudo wpa_cli -i $iface reconfigure";
|
$cmd = "sudo wpa_cli -i $iface reconfigure";
|
||||||
$result = shell_exec($cmd);
|
$result = shell_exec($cmd);
|
||||||
@@ -420,7 +458,7 @@ class WiFiManager
|
|||||||
"sudo wpa_cli -i $iface set_network $netid ssid $ssid",
|
"sudo wpa_cli -i $iface set_network $netid ssid $ssid",
|
||||||
];
|
];
|
||||||
|
|
||||||
if (strtolower($protocol) === 'open') {
|
if ($protocol === self::SECURITY_OPEN) {
|
||||||
$commands[] = "sudo wpa_cli -i $iface set_network $netid key_mgmt NONE";
|
$commands[] = "sudo wpa_cli -i $iface set_network $netid key_mgmt NONE";
|
||||||
} else {
|
} else {
|
||||||
$commands[] = "sudo wpa_cli -i $iface set_network $netid psk $psk";
|
$commands[] = "sudo wpa_cli -i $iface set_network $netid psk $psk";
|
||||||
@@ -442,12 +480,12 @@ class WiFiManager
|
|||||||
error_log("Successfully added network: {$network['ssid']}");
|
error_log("Successfully added network: {$network['ssid']}");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Parses wpa_cli list_networks output and returns the id
|
* Parses wpa_cli list_networks output and returns the id
|
||||||
* of a corresponding network SSID
|
* of a corresponding network SSID
|
||||||
*
|
*
|
||||||
* @param string $ssid
|
* @param string $ssid
|
||||||
* @return integer id
|
* @return integer id or null
|
||||||
*/
|
*/
|
||||||
public function getNetworkIdBySSID($ssid) {
|
public function getNetworkIdBySSID($ssid) {
|
||||||
$iface = escapeshellarg($_SESSION['wifi_client_interface']);
|
$iface = escapeshellarg($_SESSION['wifi_client_interface']);
|
||||||
@@ -455,10 +493,11 @@ class WiFiManager
|
|||||||
$output = [];
|
$output = [];
|
||||||
exec($cmd, $output);
|
exec($cmd, $output);
|
||||||
array_shift($output);
|
array_shift($output);
|
||||||
|
|
||||||
foreach ($output as $line) {
|
foreach ($output as $line) {
|
||||||
$columns = preg_split('/\t/', $line);
|
$columns = preg_split('/\t/', $line);
|
||||||
if (count($columns) >= 4 && trim($columns[1]) === trim($ssid)) {
|
if (count($columns) >= 2 && trim($columns[1]) === trim($ssid)) {
|
||||||
return $columns[0]; // return network ID
|
return (int)$columns[0]; // return network ID
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@@ -513,5 +552,211 @@ CONF;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the operational status of a network interface
|
||||||
|
*
|
||||||
|
* @param string $interface network interface name
|
||||||
|
* @return string returns up, down, or unknown
|
||||||
|
*/
|
||||||
|
public function getInterfaceStatus(string $interface): string
|
||||||
|
{
|
||||||
|
exec('ip a show ' . escapeshellarg($interface), $output);
|
||||||
|
$outputGlued = implode(" ", $output);
|
||||||
|
$outputNormalized = preg_replace('/\s\s+/', ' ', $outputGlued);
|
||||||
|
|
||||||
|
if (preg_match('/state (UP|DOWN)/i', $outputNormalized, $matches)) {
|
||||||
|
return strtolower($matches[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'unknown';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connects to a network using wpa_cli
|
||||||
|
*
|
||||||
|
* @param string $interface network interface name
|
||||||
|
* @param int $netid network ID to connect to
|
||||||
|
* @return bool true on success, false on failure
|
||||||
|
*/
|
||||||
|
public function connectToNetwork(string $interface, int $netid): bool
|
||||||
|
{
|
||||||
|
$iface = escapeshellarg($interface);
|
||||||
|
|
||||||
|
$cmd = "sudo wpa_cli -i $iface select_network $netid";
|
||||||
|
$selectResult = shell_exec($cmd);
|
||||||
|
|
||||||
|
if ($selectResult === null || trim($selectResult) === "FAIL") {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
sleep(3);
|
||||||
|
|
||||||
|
$cmd = "sudo wpa_cli -i $iface reassociate";
|
||||||
|
$reassociateResult = shell_exec($cmd);
|
||||||
|
|
||||||
|
if ($reassociateResult !== null) {
|
||||||
|
$trimmed = trim($reassociateResult);
|
||||||
|
if ($trimmed === "FAIL") {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes a network from wpa_cli
|
||||||
|
*
|
||||||
|
* @param string $interface network interface name
|
||||||
|
* @param int $netid network ID to delete
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function deleteNetwork(string $interface, int $netid): void
|
||||||
|
{
|
||||||
|
$iface = escapeshellarg($interface);
|
||||||
|
|
||||||
|
exec("sudo wpa_cli -i $iface disconnect $netid");
|
||||||
|
exec("sudo wpa_cli -i $iface remove_network $netid");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disconnects from a network using wpa_cli
|
||||||
|
*
|
||||||
|
* @param string $interface network interface name
|
||||||
|
* @param int $netid network ID to disconnect from
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function disconnectNetwork(string $interface, int $netid): void
|
||||||
|
{
|
||||||
|
$iface = escapeshellarg($interface);
|
||||||
|
|
||||||
|
exec("sudo wpa_cli -i $iface disconnect $netid");
|
||||||
|
exec("sudo wpa_cli -i $iface remove_network $netid");
|
||||||
|
sleep(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates/adds a network via wpa_cli
|
||||||
|
*
|
||||||
|
* @param string $interface network interface name
|
||||||
|
* @param string $ssid network SSID
|
||||||
|
* @param string $passphrase network passphrase
|
||||||
|
* @param string $protocol security protocol (OPEN or WPA)
|
||||||
|
* @return int|null network ID on success, null on failure
|
||||||
|
*/
|
||||||
|
public function updateNetwork(string $interface, string $ssid, string $passphrase, string $protocol = 'WPA'): ?int
|
||||||
|
{
|
||||||
|
$iface = escapeshellarg($interface);
|
||||||
|
$escapedSsid = escapeshellarg('"' . $ssid . '"');
|
||||||
|
|
||||||
|
$netid = shell_exec("sudo wpa_cli -i $iface add_network");
|
||||||
|
|
||||||
|
if ($netid === null || !is_numeric(trim($netid))) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$netid = trim($netid);
|
||||||
|
$commands = [
|
||||||
|
"sudo wpa_cli -i $iface set_network $netid ssid $escapedSsid"
|
||||||
|
];
|
||||||
|
|
||||||
|
if ($protocol === self::SECURITY_OPEN) {
|
||||||
|
$commands[] = "sudo wpa_cli -i $iface set_network $netid key_mgmt NONE";
|
||||||
|
} else {
|
||||||
|
$escapedPsk = escapeshellarg('"' . $passphrase . '"');
|
||||||
|
$commands[] = "sudo wpa_cli -i $iface set_network $netid psk $escapedPsk";
|
||||||
|
}
|
||||||
|
|
||||||
|
$commands[] = "sudo wpa_cli -i $iface enable_network $netid";
|
||||||
|
|
||||||
|
foreach ($commands as $cmd) {
|
||||||
|
exec($cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (int)$netid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes a wpa_supplicant configuration and applies it
|
||||||
|
*
|
||||||
|
* @param array $networks array of network configurations
|
||||||
|
* @param string $interface the network interface name
|
||||||
|
* @return array Array with 'success' (bool) and 'message' (string)
|
||||||
|
*/
|
||||||
|
public function writeWpaSupplicant(array $networks, string $interface): array
|
||||||
|
{
|
||||||
|
$wpa_file = fopen('/tmp/wifidata', 'w');
|
||||||
|
if (!$wpa_file) {
|
||||||
|
return ['success' => false, 'message' => 'Failed to update wifi settings'];
|
||||||
|
}
|
||||||
|
|
||||||
|
fwrite($wpa_file, 'ctrl_interface=DIR=' . RASPI_WPA_CTRL_INTERFACE . ' GROUP=netdev' . PHP_EOL);
|
||||||
|
fwrite($wpa_file, 'update_config=1' . PHP_EOL);
|
||||||
|
|
||||||
|
$ok = true;
|
||||||
|
foreach ($networks as $ssid => $network) {
|
||||||
|
if ($network['protocol'] === self::SECURITY_OPEN) {
|
||||||
|
fwrite($wpa_file, "network={".PHP_EOL);
|
||||||
|
fwrite($wpa_file, "\tssid=\"".$ssid."\"".PHP_EOL);
|
||||||
|
fwrite($wpa_file, "\tkey_mgmt=NONE".PHP_EOL);
|
||||||
|
fwrite($wpa_file, "\tscan_ssid=1".PHP_EOL);
|
||||||
|
if (array_key_exists('priority', $network)) {
|
||||||
|
fwrite($wpa_file, "\tpriority=".$network['priority'].PHP_EOL);
|
||||||
|
}
|
||||||
|
fwrite($wpa_file, "}".PHP_EOL);
|
||||||
|
} else {
|
||||||
|
if (strlen($network['passphrase']) >= 8 && strlen($network['passphrase']) <= 63) {
|
||||||
|
unset($wpa_passphrase);
|
||||||
|
unset($line);
|
||||||
|
exec('wpa_passphrase '. $this->ssid2utf8(escapeshellarg($ssid)) . ' ' . escapeshellarg($network['passphrase']), $wpa_passphrase);
|
||||||
|
foreach ($wpa_passphrase as $line) {
|
||||||
|
if (preg_match('/^\s*}\s*$/', $line)) {
|
||||||
|
if (array_key_exists('priority', $network)) {
|
||||||
|
fwrite($wpa_file, "\tpriority=".$network['priority'].PHP_EOL);
|
||||||
|
}
|
||||||
|
fwrite($wpa_file, $line.PHP_EOL);
|
||||||
|
} else {
|
||||||
|
if (preg_match('/\\\\x[0-9A-Fa-f]{2}/', $ssid) && strpos($line, "ssid=\"") !== false) {
|
||||||
|
fwrite($wpa_file, "\tssid=P\"".$ssid."\"".PHP_EOL);
|
||||||
|
} else {
|
||||||
|
fwrite($wpa_file, $line.PHP_EOL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} elseif (strlen($network['passphrase']) == 0 && strlen($network['passkey']) == 64) {
|
||||||
|
$line = "\tpsk=" . $network['passkey'];
|
||||||
|
fwrite($wpa_file, "network={".PHP_EOL);
|
||||||
|
fwrite($wpa_file, "\tssid=\"".$ssid."\"".PHP_EOL);
|
||||||
|
fwrite($wpa_file, $line.PHP_EOL);
|
||||||
|
if (array_key_exists('priority', $network)) {
|
||||||
|
fwrite($wpa_file, "\tpriority=".$network['priority'].PHP_EOL);
|
||||||
|
}
|
||||||
|
fwrite($wpa_file, "}".PHP_EOL);
|
||||||
|
} else {
|
||||||
|
$ok = false;
|
||||||
|
fclose($wpa_file);
|
||||||
|
return ['success' => false, 'message' => 'WPA passphrase must be between 8 and 63 characters'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose($wpa_file);
|
||||||
|
|
||||||
|
if ($ok) {
|
||||||
|
system('sudo cp /tmp/wifidata ' . RASPI_WPA_SUPPLICANT_CONFIG, $returnval);
|
||||||
|
if ($returnval == 0) {
|
||||||
|
exec('sudo wpa_cli -i ' . escapeshellarg($interface) . ' reconfigure', $reconfigure_out, $reconfigure_return);
|
||||||
|
if ($reconfigure_return == 0) {
|
||||||
|
return ['success' => true, 'message' => 'Wifi settings updated successfully'];
|
||||||
|
} else {
|
||||||
|
return ['success' => false, 'message' => 'Wifi settings updated but cannot restart (cannot execute "wpa_cli reconfigure")'];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return ['success' => false, 'message' => 'Wifi settings failed to be updated'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ['success' => false, 'message' => 'Unknown error'];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -107,34 +107,32 @@
|
|||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="mb-3 col-md-6">
|
<div class="mb-3 col-md-6">
|
||||||
<label for="code"><?php echo _("Starting IP Address"); ?></label>
|
<label for="txtrangestart"><?php echo _("Starting IP Address"); ?></label>
|
||||||
<input type="text" class="form-control ip_address" id="txtrangestart" name="RangeStart" maxlength="15" />
|
<input type="text" class="form-control ip_address" id="txtrangestart" name="RangeStart" maxlength="15" />
|
||||||
<div class="invalid-feedback">
|
<div class="invalid-feedback">
|
||||||
<?php echo _("Please provide a valid Starting IP Address."); ?>
|
<?php echo _("Please provide a valid Starting IP Address."); ?>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="mb-3 col-md-6">
|
<div class="mb-3 col-md-6">
|
||||||
<label for="code"><?php echo _("Ending IP Address"); ?></label>
|
<label for="txtrangeend"><?php echo _("Ending IP Address"); ?></label>
|
||||||
<input type="text" class="form-control ip_address" id="txtrangeend" name="RangeEnd" maxlength="15" />
|
<input type="text" class="form-control ip_address" id="txtrangeend" name="RangeEnd" maxlength="15" />
|
||||||
<div class="invalid-feedback">
|
<div class="invalid-feedback">
|
||||||
<?php echo _("Please provide a valid Ending IP Address."); ?>
|
<?php echo _("Please provide a valid Ending IP Address."); ?>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="mb-3 col-xs-3 col-sm-3">
|
<div class="mb-3 col-xs-3 col-sm-3">
|
||||||
<label for="code"><?php echo _("Lease Time"); ?></label>
|
<label for="txtrangeleasetime"><?php echo _("Lease Time"); ?></label>
|
||||||
<input type="text" class="form-control" id="txtrangeleasetime" name="RangeLeaseTime" />
|
<input type="text" class="form-control" id="txtrangeleasetime" name="RangeLeaseTime" />
|
||||||
<div class="invalid-feedback">
|
<div class="invalid-feedback">
|
||||||
<?php echo _("Please provide a valid Lease Time."); ?>
|
<?php echo _("Please provide a valid Lease Time."); ?>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-xs-3 col-sm-3">
|
<div class="col-xs-3 col-sm-3">
|
||||||
<label for="code"><?php echo _("Interval"); ?></label>
|
<label for="cbxrangeleasetimeunits"><?php echo _("Interval"); ?></label>
|
||||||
<select id="cbxrangeleasetimeunits" name="RangeLeaseTimeUnits" class="form-select" >
|
<select id="cbxrangeleasetimeunits" name="RangeLeaseTimeUnits" class="form-select" >
|
||||||
<option value="m"><?php echo _("Minute(s)"); ?></option>
|
<option value="m"><?php echo _("Minute(s)"); ?></option>
|
||||||
<option value="h"><?php echo _("Hour(s)"); ?></option>
|
<option value="h"><?php echo _("Hour(s)"); ?></option>
|
||||||
|
|||||||
@@ -18,9 +18,8 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="mb-3 col-md-6">
|
<div class="mb-3 col-md-6">
|
||||||
<label for="cbxhwmode"><?php echo _("Wireless Mode") ;?></label>
|
<label for="cbxhwmode"><?php echo _("Wireless Mode") ;?></label>
|
||||||
<i class="fas fa-question-circle text-muted" data-bs-toggle="tooltip" data-bs-placement="auto" title="<?php echo _("The 802.11ac 5 GHz option is disabled until a compatible wireless regulatory domain is set."); ?>"></i>
|
|
||||||
<?php SelectorOptions('hw_mode', $arr80211Standard, $arrConfig['selected_hw_mode'], 'cbxhwmode', 'getChannel'); ?>
|
<?php SelectorOptions('hw_mode', $arr80211Standard, $arrConfig['selected_hw_mode'], 'cbxhwmode', 'getChannel'); ?>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="mb-3 col-md-6">
|
<div class="mb-3 col-md-6">
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
<div class="mb-3 col-md-8 mt-2">
|
<div class="mb-3 col-md-8 mt-2">
|
||||||
<?php
|
<?php
|
||||||
if ($arrHostapdConf['LogEnable'] == 1) {
|
if ($arrHostapdConf['LogEnable'] == 1) {
|
||||||
echo '<textarea class="logoutput text-secondary" id="hostapd-log">'.htmlspecialchars($logdata, ENT_QUOTES).'</textarea>';
|
echo '<textarea class="logoutput text-secondary" id="hostapd-log">'.htmlspecialchars(implode("\n", $logOutput), ENT_QUOTES).'</textarea>';
|
||||||
} else {
|
} else {
|
||||||
echo '<textarea class="logoutput my-3"></textarea>';
|
echo '<textarea class="logoutput my-3"></textarea>';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,25 @@
|
|||||||
use RaspAP\Networking\Hotspot\WiFiManager;
|
use RaspAP\Networking\Hotspot\WiFiManager;
|
||||||
$wifi = new WiFiManager();
|
$wifi = new WiFiManager();
|
||||||
|
|
||||||
|
// fix: re-apply locale settings in this template context
|
||||||
|
if (!empty($_SESSION['locale'])) {
|
||||||
|
putenv("LANG=" . $_SESSION['locale']);
|
||||||
|
setlocale(LC_ALL, $_SESSION['locale']);
|
||||||
|
bindtextdomain('messages', realpath(__DIR__ . '/../../locale'));
|
||||||
|
bind_textdomain_codeset('messages', 'UTF-8');
|
||||||
|
textdomain('messages');
|
||||||
|
}
|
||||||
|
|
||||||
|
// set defaults
|
||||||
|
$network = $network ?? [];
|
||||||
|
$network['ssid'] = $network['ssid'] ?? '';
|
||||||
|
$network['ssidutf8'] = $network['ssidutf8'] ?? $network['ssid'];
|
||||||
|
$network['configured'] = $network['configured'] ?? false;
|
||||||
|
$network['connected'] = $network['connected'] ?? false;
|
||||||
|
$network['visible'] = $network['visible'] ?? false;
|
||||||
|
$network['channel'] = $network['channel'] ?? '';
|
||||||
|
$network['protocol'] = $network['protocol'] ?? $wifi::SECURITY_OPEN;
|
||||||
|
$network['passphrase'] = $network['passphrase'] ?? '';
|
||||||
?>
|
?>
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
@@ -10,7 +29,7 @@ $wifi = new WiFiManager();
|
|||||||
<?php if (strlen($network['ssid']) == 0) {
|
<?php if (strlen($network['ssid']) == 0) {
|
||||||
$network['ssid'] = "(unknown)";
|
$network['ssid'] = "(unknown)";
|
||||||
} ?>
|
} ?>
|
||||||
<h5 class="card-title"><i class="fas fa-wifi me-2"></i><?php echo htmlspecialchars($network['ssidutf8'], ENT_QUOTES); ?></h5>
|
<h5 class="card-title"><i class="fas fa-wifi me-2"></i><?php echo htmlspecialchars($network['ssidutf8'], ENT_QUOTES); ?></h5>
|
||||||
<div class="info-item-wifi"><?php echo _("Status"); ?></div>
|
<div class="info-item-wifi"><?php echo _("Status"); ?></div>
|
||||||
<div>
|
<div>
|
||||||
<?php if ($network['configured']) { ?>
|
<?php if ($network['configured']) { ?>
|
||||||
@@ -57,7 +76,7 @@ $wifi = new WiFiManager();
|
|||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<div class="info-item-wifi mb-2"><?php echo _("Passphrase"); ?></div>
|
<div class="info-item-wifi mb-2"><?php echo _("Passphrase"); ?></div>
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<?php if ($network['protocol'] === 'Open') { ?>
|
<?php if ($network['protocol'] === $wifi::SECURITY_OPEN) { ?>
|
||||||
<input type="password" disabled class="form-control" aria-describedby="passphrase" name="passphrase<?php echo $index ?>" value="" />
|
<input type="password" disabled class="form-control" aria-describedby="passphrase" name="passphrase<?php echo $index ?>" value="" />
|
||||||
<?php } else { ?>
|
<?php } else { ?>
|
||||||
<input type="password" class="form-control" aria-describedby="passphrase" name="passphrase<?php echo $index ?>" value="<?php echo htmlspecialchars($network['passphrase']); ?>" data-bs-target="#update<?php echo $index ?>" data-colors="#ffd0d0,#d0ffd0">
|
<input type="password" class="form-control" aria-describedby="passphrase" name="passphrase<?php echo $index ?>" value="<?php echo htmlspecialchars($network['passphrase']); ?>" data-bs-target="#update<?php echo $index ?>" data-colors="#ffd0d0,#d0ffd0">
|
||||||
@@ -66,14 +85,18 @@ $wifi = new WiFiManager();
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="btn-group btn-block d-flex">
|
<div class="btn-group btn-block d-flex">
|
||||||
<?php if ($network['configured']) { ?>
|
<?php if ($network['configured']) { ?>
|
||||||
<input type="submit" class="btn btn-warning" value="<?php echo _("Update"); ?>" id="update<?php echo $index ?>" name="update<?php echo $index ?>"<?php echo ($network['protocol'] === 'Open' ? ' disabled' : '')?> data-bs-toggle="modal" data-bs-target="#configureClientModal" />
|
<input type="submit" class="btn btn-warning" value="<?php echo _("Update"); ?>" id="update<?php echo $index ?>" name="update<?php echo $index ?>"<?php echo ($network['protocol'] === 'Open' ? ' disabled' : '')?> data-bs-toggle="modal" data-bs-target="#configureClientModal" />
|
||||||
<button type="submit" class="btn btn-info" value="<?php echo $index?>" name="connect"><?php echo _("Connect"); ?></button>
|
<?php if ($network['connected']) { ?>
|
||||||
<?php } else { ?>
|
<button type="submit" class="btn btn-info" value="<?php echo $index?>" name="disconnect<?php echo $index ?>"><?php echo _("Disconnect"); ?></button>
|
||||||
<input type="submit" class="btn btn-info" value="<?php echo _("Add"); ?>" id="update<?php echo $index ?>" name="update<?php echo $index ?>" data-bs-toggle="modal" data-bs-target="#configureClientModal" />
|
<?php } else { ?>
|
||||||
<?php } ?>
|
<button type="submit" class="btn btn-info" value="<?php echo $index?>" name="connect"><?php echo _("Connect"); ?></button>
|
||||||
<input type="submit" class="btn btn-danger" value="<?php echo _("Delete"); ?>" name="delete<?php echo $index ?>"<?php echo ($network['configured'] ? '' : ' disabled')?> data-bs-toggle="modal" data-bs-target="#configureClientModal" />
|
<?php } ?>
|
||||||
</div><!-- /.btn-group -->
|
<?php } else { ?>
|
||||||
|
<input type="submit" class="btn btn-info" value="<?php echo _("Add"); ?>" id="update<?php echo $index ?>" name="update<?php echo $index ?>" data-bs-toggle="modal" data-bs-target="#configureClientModal" />
|
||||||
|
<?php } ?>
|
||||||
|
<input type="submit" class="btn btn-danger" value="<?php echo _("Delete"); ?>" name="delete<?php echo $index ?>"<?php echo ($network['configured'] ? '' : ' disabled')?> data-bs-toggle="modal" data-bs-target="#configureClientModal" />
|
||||||
|
</div><!-- /.btn-group -->
|
||||||
</div><!-- /.card-body -->
|
</div><!-- /.card-body -->
|
||||||
</div><!-- /.card -->
|
</div><!-- /.card -->
|
||||||
|
|||||||
Reference in New Issue
Block a user