diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 3303710..0000000 --- a/.travis.yml +++ /dev/null @@ -1,13 +0,0 @@ -language: php -before_script: - - git clone --depth 1 git://github.com/YunoHost/package_linter ../package_linter && cd ../package_linter - - mv ../hotspot_ynh hotspot_ynh -script: - - ./package_linter.py hotspot_ynh -notifications: - email: false - irc: - on_success: always - on_failure: always - channels: - - "irc.geeknode.org#labriqueinter.net-dev" diff --git a/ALL_README.md b/ALL_README.md new file mode 100644 index 0000000..152f2e7 --- /dev/null +++ b/ALL_README.md @@ -0,0 +1,8 @@ +# All available README files by language + +- [Read the README in English](README.md) +- [Lea el README en español](README_es.md) +- [Irakurri README euskaraz](README_eu.md) +- [Lire le README en français](README_fr.md) +- [Le o README en galego](README_gl.md) +- [阅读中文(简体)的 README](README_zh_Hans.md) diff --git a/README.md b/README.md index c945fcb..9b1e364 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ @@ -9,10 +9,10 @@ It shall NOT be edited by hand. [![Install Wifi Hotspot with YunoHost](https://install-app.yunohost.org/install-with-yunohost.svg)](https://install-app.yunohost.org/?app=hotspot) -*[Lire ce readme en français.](./README_fr.md)* +*[Read this README in other languages.](./ALL_README.md)* -> *This package allows you to install Wifi Hotspot quickly and simply on a YunoHost server. -If you don't have YunoHost, please consult [the guide](https://yunohost.org/#/install) to learn how to install it.* +> *This package allows you to install Wifi Hotspot quickly and simply on a YunoHost server.* +> *If you don't have YunoHost, please consult [the guide](https://yunohost.org/install) to learn how to install it.* ## Overview @@ -20,7 +20,7 @@ If you don't have YunoHost, please consult [the guide](https://yunohost.org/#/in * Combine with the [VPN Client app](https://github.com/labriqueinternet/vpnclient_ynh) to obtain a VPN-protected WiFi -**Shipped version:** 2.0~ynh3 +**Shipped version:** 2.3.1~ynh1 ## Screenshots @@ -28,17 +28,17 @@ If you don't have YunoHost, please consult [the guide](https://yunohost.org/#/in ## Documentation and resources -* Official app website: -* YunoHost documentation for this app: -* Report a bug: +- Official app website: +- YunoHost Store: +- Report a bug: ## Developer info -Please send your pull request to the [testing branch](https://github.com/YunoHost-Apps/hotspot_ynh/tree/testing). +Please send your pull request to the [`testing` branch](https://github.com/YunoHost-Apps/hotspot_ynh/tree/testing). -To try the testing branch, please proceed like that. +To try the `testing` branch, please proceed like that: -``` bash +```bash sudo yunohost app install https://github.com/YunoHost-Apps/hotspot_ynh/tree/testing --debug or sudo yunohost app upgrade hotspot -u https://github.com/YunoHost-Apps/hotspot_ynh/tree/testing --debug diff --git a/README_es.md b/README_es.md new file mode 100644 index 0000000..f4260a6 --- /dev/null +++ b/README_es.md @@ -0,0 +1,47 @@ + + +# Wifi Hotspot para Yunohost + +[![Nivel de integración](https://dash.yunohost.org/integration/hotspot.svg)](https://dash.yunohost.org/appci/app/hotspot) ![Estado funcional](https://ci-apps.yunohost.org/ci/badges/hotspot.status.svg) ![Estado En Mantención](https://ci-apps.yunohost.org/ci/badges/hotspot.maintain.svg) + +[![Instalar Wifi Hotspot con Yunhost](https://install-app.yunohost.org/install-with-yunohost.svg)](https://install-app.yunohost.org/?app=hotspot) + +*[Leer este README en otros idiomas.](./ALL_README.md)* + +> *Este paquete le permite instalarWifi Hotspot rapidamente y simplement en un servidor YunoHost.* +> *Si no tiene YunoHost, visita [the guide](https://yunohost.org/install) para aprender como instalarla.* + +## Descripción general + +* Broadcast a Wi-Fi access point from your self-hosted server +* Combine with the [VPN Client app](https://github.com/labriqueinternet/vpnclient_ynh) to obtain a VPN-protected WiFi + + +**Versión actual:** 2.3.1~ynh1 + +## Capturas + +![Captura de Wifi Hotspot](./doc/screenshots/hotspot.png) + +## Documentaciones y recursos + +- Sitio web oficial: +- Catálogo YunoHost: +- Reportar un error: + +## Información para desarrolladores + +Por favor enviar sus correcciones a la [`branch testing`](https://github.com/YunoHost-Apps/hotspot_ynh/tree/testing + +Para probar la rama `testing`, sigue asÍ: + +```bash +sudo yunohost app install https://github.com/YunoHost-Apps/hotspot_ynh/tree/testing --debug +o +sudo yunohost app upgrade hotspot -u https://github.com/YunoHost-Apps/hotspot_ynh/tree/testing --debug +``` + +**Mas informaciones sobre el empaquetado de aplicaciones:** diff --git a/README_eu.md b/README_eu.md new file mode 100644 index 0000000..107765e --- /dev/null +++ b/README_eu.md @@ -0,0 +1,47 @@ + + +# Wifi Hotspot YunoHost-erako + +[![Integrazio maila](https://dash.yunohost.org/integration/hotspot.svg)](https://dash.yunohost.org/appci/app/hotspot) ![Funtzionamendu egoera](https://ci-apps.yunohost.org/ci/badges/hotspot.status.svg) ![Mantentze egoera](https://ci-apps.yunohost.org/ci/badges/hotspot.maintain.svg) + +[![Instalatu Wifi Hotspot YunoHost-ekin](https://install-app.yunohost.org/install-with-yunohost.svg)](https://install-app.yunohost.org/?app=hotspot) + +*[Irakurri README hau beste hizkuntzatan.](./ALL_README.md)* + +> *Pakete honek Wifi Hotspot YunoHost zerbitzari batean azkar eta zailtasunik gabe instalatzea ahalbidetzen dizu.* +> *YunoHost ez baduzu, kontsultatu [gida](https://yunohost.org/install) nola instalatu ikasteko.* + +## Aurreikuspena + +* Broadcast a Wi-Fi access point from your self-hosted server +* Combine with the [VPN Client app](https://github.com/labriqueinternet/vpnclient_ynh) to obtain a VPN-protected WiFi + + +**Paketatutako bertsioa:** 2.3.1~ynh1 + +## Pantaila-argazkiak + +![Wifi Hotspot(r)en pantaila-argazkia](./doc/screenshots/hotspot.png) + +## Dokumentazioa eta baliabideak + +- Aplikazioaren webgune ofiziala: +- YunoHost Denda: +- Eman errore baten berri: + +## Garatzaileentzako informazioa + +Bidali `pull request`a [`testing` abarrera](https://github.com/YunoHost-Apps/hotspot_ynh/tree/testing). + +`testing` abarra probatzeko, ondorengoa egin: + +```bash +sudo yunohost app install https://github.com/YunoHost-Apps/hotspot_ynh/tree/testing --debug +edo +sudo yunohost app upgrade hotspot -u https://github.com/YunoHost-Apps/hotspot_ynh/tree/testing --debug +``` + +**Informazio gehiago aplikazioaren paketatzeari buruz:** diff --git a/README_fr.md b/README_fr.md index 27a6f13..b7b7eae 100644 --- a/README_fr.md +++ b/README_fr.md @@ -1,6 +1,6 @@ # Wifi Hotspot pour YunoHost @@ -9,10 +9,10 @@ It shall NOT be edited by hand. [![Installer Wifi Hotspot avec YunoHost](https://install-app.yunohost.org/install-with-yunohost.svg)](https://install-app.yunohost.org/?app=hotspot) -*[Read this readme in english.](./README.md)* +*[Lire le README dans d'autres langues.](./ALL_README.md)* -> *Ce package vous permet d’installer Wifi Hotspot rapidement et simplement sur un serveur YunoHost. -Si vous n’avez pas YunoHost, regardez [ici](https://yunohost.org/#/install) pour savoir comment l’installer et en profiter.* +> *Ce package vous permet d’installer Wifi Hotspot rapidement et simplement sur un serveur YunoHost.* +> *Si vous n’avez pas YunoHost, consultez [ce guide](https://yunohost.org/install) pour savoir comment l’installer et en profiter.* ## Vue d’ensemble @@ -20,7 +20,7 @@ Si vous n’avez pas YunoHost, regardez [ici](https://yunohost.org/#/install) po * À combiner avec l'[app VPN Client](https://github.com/labriqueinternet/vpnclient_ynh) pour obtenir un accès internet aumatiquement protégé par votre VPN -**Version incluse :** 2.0~ynh3 +**Version incluse :** 2.3.1~ynh1 ## Captures d’écran @@ -28,20 +28,20 @@ Si vous n’avez pas YunoHost, regardez [ici](https://yunohost.org/#/install) po ## Documentations et ressources -* Site officiel de l’app : -* Documentation YunoHost pour cette app : -* Signaler un bug : +- Site officiel de l’app : +- YunoHost Store : +- Signaler un bug : ## Informations pour les développeurs -Merci de faire vos pull request sur la [branche testing](https://github.com/YunoHost-Apps/hotspot_ynh/tree/testing). +Merci de faire vos pull request sur la [branche `testing`](https://github.com/YunoHost-Apps/hotspot_ynh/tree/testing). -Pour essayer la branche testing, procédez comme suit. +Pour essayer la branche `testing`, procédez comme suit : -``` bash +```bash sudo yunohost app install https://github.com/YunoHost-Apps/hotspot_ynh/tree/testing --debug ou sudo yunohost app upgrade hotspot -u https://github.com/YunoHost-Apps/hotspot_ynh/tree/testing --debug ``` -**Plus d’infos sur le packaging d’applications :** \ No newline at end of file +**Plus d’infos sur le packaging d’applications :** diff --git a/README_gl.md b/README_gl.md new file mode 100644 index 0000000..8689b94 --- /dev/null +++ b/README_gl.md @@ -0,0 +1,47 @@ + + +# Wifi Hotspot para YunoHost + +[![Nivel de integración](https://dash.yunohost.org/integration/hotspot.svg)](https://dash.yunohost.org/appci/app/hotspot) ![Estado de funcionamento](https://ci-apps.yunohost.org/ci/badges/hotspot.status.svg) ![Estado de mantemento](https://ci-apps.yunohost.org/ci/badges/hotspot.maintain.svg) + +[![Instalar Wifi Hotspot con YunoHost](https://install-app.yunohost.org/install-with-yunohost.svg)](https://install-app.yunohost.org/?app=hotspot) + +*[Le este README en outros idiomas.](./ALL_README.md)* + +> *Este paquete permíteche instalar Wifi Hotspot de xeito rápido e doado nun servidor YunoHost.* +> *Se non usas YunoHost, le a [documentación](https://yunohost.org/install) para saber como instalalo.* + +## Vista xeral + +* Broadcast a Wi-Fi access point from your self-hosted server +* Combine with the [VPN Client app](https://github.com/labriqueinternet/vpnclient_ynh) to obtain a VPN-protected WiFi + + +**Versión proporcionada:** 2.3.1~ynh1 + +## Capturas de pantalla + +![Captura de pantalla de Wifi Hotspot](./doc/screenshots/hotspot.png) + +## Documentación e recursos + +- Web oficial da app: +- Tenda YunoHost: +- Informar dun problema: + +## Info de desenvolvemento + +Envía a túa colaboración á [rama `testing`](https://github.com/YunoHost-Apps/hotspot_ynh/tree/testing). + +Para probar a rama `testing`, procede deste xeito: + +```bash +sudo yunohost app install https://github.com/YunoHost-Apps/hotspot_ynh/tree/testing --debug +ou +sudo yunohost app upgrade hotspot -u https://github.com/YunoHost-Apps/hotspot_ynh/tree/testing --debug +``` + +**Máis info sobre o empaquetado da app:** diff --git a/README_it.md b/README_it.md new file mode 100644 index 0000000..9c4dee7 --- /dev/null +++ b/README_it.md @@ -0,0 +1,47 @@ + + +# Wifi Hotspot per YunoHost + +[![Livello di integrazione](https://dash.yunohost.org/integration/hotspot.svg)](https://dash.yunohost.org/appci/app/hotspot) ![Stato di funzionamento](https://ci-apps.yunohost.org/ci/badges/hotspot.status.svg) ![Stato di manutenzione](https://ci-apps.yunohost.org/ci/badges/hotspot.maintain.svg) + +[![Installa Wifi Hotspot con YunoHost](https://install-app.yunohost.org/install-with-yunohost.svg)](https://install-app.yunohost.org/?app=hotspot) + +*[Leggi questo README in altre lingue.](./ALL_README.md)* + +> *Questo pacchetto ti permette di installare Wifi Hotspot su un server YunoHost in modo semplice e veloce.* +> *Se non hai YunoHost, consulta [la guida](https://yunohost.org/install) per imparare a installarlo.* + +## Panoramica + +* Broadcast a Wi-Fi access point from your self-hosted server +* Combine with the [VPN Client app](https://github.com/labriqueinternet/vpnclient_ynh) to obtain a VPN-protected WiFi + + +**Versione pubblicata:** 2.3.1~ynh1 + +## Screenshot + +![Screenshot di Wifi Hotspot](./doc/screenshots/hotspot.png) + +## Documentazione e risorse + +- Sito web ufficiale dell’app: +- Store di YunoHost: +- Segnala un problema: + +## Informazioni per sviluppatori + +Si prega di inviare la tua pull request alla [branch di `testing`](https://github.com/YunoHost-Apps/hotspot_ynh/tree/testing). + +Per provare la branch di `testing`, si prega di procedere in questo modo: + +```bash +sudo yunohost app install https://github.com/YunoHost-Apps/hotspot_ynh/tree/testing --debug +o +sudo yunohost app upgrade hotspot -u https://github.com/YunoHost-Apps/hotspot_ynh/tree/testing --debug +``` + +**Maggiori informazioni riguardo il pacchetto di quest’app:** diff --git a/README_zh_Hans.md b/README_zh_Hans.md new file mode 100644 index 0000000..2c93b7d --- /dev/null +++ b/README_zh_Hans.md @@ -0,0 +1,47 @@ + + +# YunoHost 上的 Wifi Hotspot + +[![集成程度](https://dash.yunohost.org/integration/hotspot.svg)](https://dash.yunohost.org/appci/app/hotspot) ![工作状态](https://ci-apps.yunohost.org/ci/badges/hotspot.status.svg) ![维护状态](https://ci-apps.yunohost.org/ci/badges/hotspot.maintain.svg) + +[![使用 YunoHost 安装 Wifi Hotspot](https://install-app.yunohost.org/install-with-yunohost.svg)](https://install-app.yunohost.org/?app=hotspot) + +*[阅读此 README 的其它语言版本。](./ALL_README.md)* + +> *通过此软件包,您可以在 YunoHost 服务器上快速、简单地安装 Wifi Hotspot。* +> *如果您还没有 YunoHost,请参阅[指南](https://yunohost.org/install)了解如何安装它。* + +## 概况 + +* Broadcast a Wi-Fi access point from your self-hosted server +* Combine with the [VPN Client app](https://github.com/labriqueinternet/vpnclient_ynh) to obtain a VPN-protected WiFi + + +**分发版本:** 2.3.1~ynh1 + +## 截图 + +![Wifi Hotspot 的截图](./doc/screenshots/hotspot.png) + +## 文档与资源 + +- 官方应用网站: +- YunoHost 商店: +- 报告 bug: + +## 开发者信息 + +请向 [`testing` 分支](https://github.com/YunoHost-Apps/hotspot_ynh/tree/testing) 发送拉取请求。 + +如要尝试 `testing` 分支,请这样操作: + +```bash +sudo yunohost app install https://github.com/YunoHost-Apps/hotspot_ynh/tree/testing --debug +或 +sudo yunohost app upgrade hotspot -u https://github.com/YunoHost-Apps/hotspot_ynh/tree/testing --debug +``` + +**有关应用打包的更多信息:** diff --git a/check_process b/check_process deleted file mode 100644 index aafd852..0000000 --- a/check_process +++ /dev/null @@ -1,20 +0,0 @@ -;; Test complet - ; Manifest - wifi_ssid="myNeutralNetwork" - wifi_passphrase="VhegT8oev0jZI" - firmware_nonfree="no" - ; Checks - pkg_linter=1 - setup_sub_dir=0 - setup_root=0 - setup_nourl=1 - setup_private=0 - setup_public=0 - upgrade=1 - upgrade=1 from_commit=539a1f26c30ba850455c63746d50ce3d8f33b119 - backup_restore=1 - multi_instance=0 - change_url=0 -;;; Upgrade options - ; commit=539a1f26c30ba850455c63746d50ce3d8f33b119 - name=Pre-2.0 diff --git a/conf/dnsmasq_dhcpdv4.conf.tpl b/conf/dnsmasq_dhcpdv4.conf similarity index 100% rename from conf/dnsmasq_dhcpdv4.conf.tpl rename to conf/dnsmasq_dhcpdv4.conf diff --git a/conf/dnsmasq_dhcpdv6.conf.tpl b/conf/dnsmasq_dhcpdv6.conf similarity index 100% rename from conf/dnsmasq_dhcpdv6.conf.tpl rename to conf/dnsmasq_dhcpdv6.conf diff --git a/conf/hostapd.base.conf b/conf/hostapd.base.conf deleted file mode 100644 index 8ea3d7d..0000000 --- a/conf/hostapd.base.conf +++ /dev/null @@ -1,8 +0,0 @@ -interface=__WIFI_DEVICE__ -hw_mode=g -__N_COMMENT__ieee80211n=1 -__N_COMMENT__wmm_enabled=1 -macaddr_acl=0 -auth_algs=1 -ignore_broadcast_ssid=0 -channel=__WIFI_CHANNEL__ diff --git a/conf/hostapd.accesspoint.conf b/conf/hostapd.conf similarity index 63% rename from conf/hostapd.accesspoint.conf rename to conf/hostapd.conf index a726b1e..64e59eb 100644 --- a/conf/hostapd.accesspoint.conf +++ b/conf/hostapd.conf @@ -1,4 +1,9 @@ -__BSS_COMMENT__bss=__WIFI_INTERFACE__ +interface=__WIFI_DEVICE__ +hw_mode=g +macaddr_acl=0 +auth_algs=1 +ignore_broadcast_ssid=0 +channel=__WIFI_CHANNEL__ ssid=__WIFI_SSID__ __SEC_COMMENT__wpa=2 __SEC_COMMENT__wpa_passphrase=__WIFI_PASSPHRASE__ diff --git a/conf/openvpn_90-hotspot b/conf/openvpn_90-hotspot new file mode 100644 index 0000000..1fc4dd0 --- /dev/null +++ b/conf/openvpn_90-hotspot @@ -0,0 +1,32 @@ +#!/bin/bash + +is_nat_set() { + local gateway_interface=${1} + iptables -w -nvt nat -L POSTROUTING | grep MASQUERADE | grep -q "${gateway_interface}" +} + +unset_nat() { + local gateway_interface=${1} + iptables -w -t nat -D POSTROUTING -o "${gateway_interface}" -j MASQUERADE +} + +set_nat() { + local gateway_interface=${1} + iptables -w -t nat -A POSTROUTING -o "${gateway_interface}" -j MASQUERADE +} + +ynh_hotspot_state=$(systemctl is-active __SERVICE_NAME__) +if [[ "${ynh_hotspot_state}" == "active" || "${ynh_hotspot_state}" == "activating" ]]; then + old_gateway_interface=$(yunohost app setting __APP__ gateway_interface) + new_gateway_interface=$(ip route get 1.2.3.4 | awk '{ print $5; }') + + if [[ -n "$old_gateway_interface" ]] && [[ "$old_gateway_interface" != "$new_gateway_interface" ]] && is_nat_set "$old_gateway_interface"; then + unset_nat "${old_gateway_interface}" + fi + + if [[ -n "$new_gateway_interface" ]] && ! is_nat_set $new_gateway_interface; then + set_nat "${new_gateway_interface}" + fi + + yunohost app setting __APP__ gateway_interface --value "${new_gateway_interface}" +fi diff --git a/conf/systemd.service b/conf/systemd.service index 6268e69..1537aca 100644 --- a/conf/systemd.service +++ b/conf/systemd.service @@ -6,8 +6,8 @@ After=network.target [Service] Type=oneshot User=root -ExecStart=/usr/local/bin/ynh-hotspot start -ExecStop=/usr/local/bin/ynh-hotspot stop +ExecStart=/usr/local/bin/__SERVICE_NAME__ start +ExecStop=/usr/local/bin/__SERVICE_NAME__ stop RemainAfterExit=yes [Install] diff --git a/conf/systemd_hostapd.service b/conf/systemd_hostapd.service new file mode 100644 index 0000000..14ad3eb --- /dev/null +++ b/conf/systemd_hostapd.service @@ -0,0 +1,12 @@ +[Unit] +Description=LSB: Advanced IEEE 802.11 management daemon +After=remote-fs.target +After=network-online.target +Wants=network-online.target + +[Service] +Type=simple +Restart=no +TimeoutSec=5min +ExecStart=/usr/sbin/hostapd /etc/hostapd/__APP__/hostapd.conf +ExecReload=/bin/kill -HEP $MAINPID diff --git a/conf/ynh-hotspot b/conf/ynh-hotspot index 546d283..d55456f 100644 --- a/conf/ynh-hotspot +++ b/conf/ynh-hotspot @@ -17,88 +17,95 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . +source /usr/share/yunohost/helpers + # Functions ## State functions -has_vpnclient_app() { - [ -e /tmp/.ynh-vpnclient-started ] -} - has_ip6delegatedprefix() { - local i=${1} - - [[ -n "${ip6_net[${i}]}" ]] && [[ "${ip6_net[${i}]}" != "none" ]] + [[ -n "${ip6_net}" ]] && [[ "${ip6_net}" != "none" ]] } ip6addrfromdelegatedprefix() { - local i=${1} - - echo "${ip6_net[${i}]}${i}001" + echo "${ip6_net}1" } is_nat_set() { local gateway_interface=${1} - iptables -w -nvt nat -L POSTROUTING | grep MASQUERADE | grep -q "${gateway_interface}" } is_ip4nataddr_set() { - local i=${1} - local dev=$(devfromid "${i}") - - ip address show dev "${dev}" 2>/dev/null | grep -q "${ip4_nat_prefix[${i}]}.1/24" + ip address show dev "${wifi_device}" 2>/dev/null | grep -q "${ip4_nat_prefix}.1/24" } is_ip6addr_set() { - local i=${1} - local dev=$(devfromid "${i}") - - ip address show dev "${dev}" 2>/dev/null | grep -q "$(ip6addrfromdelegatedprefix $i)/64" + ip address show dev "${wifi_device}" 2>/dev/null | grep -q "$(ip6addrfromdelegatedprefix)/64" } is_ip6firewall_set() { - local i=${1} - local dev=$(devfromid "${i}") - - ip6tables -w -nvL FORWARD | grep DROP | grep -q "${dev}" + ip6tables -w -nvL FORWARD | grep DROP | grep -q "${wifi_device}" } is_forwarding_set() { local ip6=$(sysctl net.ipv6.conf.all.forwarding | awk '{ print $NF; }') local ip4=$(sysctl net.ipv4.conf.all.forwarding | awk '{ print $NF; }') - [ "${ip6}" -eq 1 ] && [ "${ip4}" -eq 1 ] + [[ "${ip6}" -eq 1 ]] && [[ "${ip4}" -eq 1 ]] } is_dhcpd6_running() { - local i=${1} - - ps aux | grep "dhcpdv6-ssid${i}" | grep -qv grep + [[ -e "/run/dnsmasq/dnsmasq-dhcpdv6-$app.pid" ]] && ps -p $(cat "/run/dnsmasq/dnsmasq-dhcpdv6-$app.pid") > /dev/null } is_dhcpd4_running() { - local i=${1} - - ps aux | grep "dhcpdv4-ssid${i}" | grep -qv grep + [[ -e "/run/dnsmasq/dnsmasq-dhcpdv4-$app.pid" ]] && ps -p $(cat "/run/dnsmasq/dnsmasq-dhcpdv4-$app.pid") > /dev/null } is_hostapd_running() { - systemctl is-active hostapd &>/dev/null + systemctl is-active "hostapd@${app}" &>/dev/null +} + +is_other_hostapd_running() { + other_hostapd_services=$(systemctl list-units --state=running hostapd@*.service | grep -v "^hostapd@$app.service") + + [[ -n "${other_hostapd_service}" ]] } is_running() { - for i in $(seq 0 $((${multissid} - 1))); do - (has_ip6delegatedprefix ${i} && is_ip6addr_set ${i} \ - && ([ "${ip6_firewall[${i}]}" -eq 1 ] && is_ip6firewall_set ${i} || [ "${ip6_firewall[${i}]}" -eq 0 ]) \ - && is_dhcpd6_running ${i} || ! has_ip6delegatedprefix ${i}) \ - && is_ip4nataddr_set ${i} && is_dhcpd4_running ${i} - - if [ ! $? -eq 0 ]; then + if has_ip6delegatedprefix; then + if ! is_ip6addr_set; then return 1 fi - done + if [[ "${ip6_firewall}" -eq 1 ]] && ! is_ip6firewall_set; then + return 1 + fi + if ! is_dhcpd6_running; then + return 1 + fi + fi - is_hostapd_running && is_forwarding_set && ([ -z "${new_gateway_interface}" ] || is_nat_set "${new_gateway_interface}") + if ! is_ip4nataddr_set; then + return 1 + fi + + if ! is_dhcpd4_running; then + return 1 + fi + + if ! is_hostapd_running; then + return 1 + fi + + if ! is_forwarding_set; then + return 1 + fi + + if [[ -n ${new_gateway_interface} ]] && ! is_nat_set "${new_gateway_interface}"; then + return 1 + fi + + return 0 } ## Setters @@ -110,33 +117,26 @@ set_nat() { } set_ipaddr() { - local i=${1} - local dev=$(devfromid "${i}") - - if ! is_ip4nataddr_set ${i}; then - echo "hotspot${i}: Set IPv4 NAT address" - ip address add "${ip4_nat_prefix[${i}]}.1/24" dev "${dev}" + if ! is_ip4nataddr_set; then + echo "hotspot ${wifi_device}: Set IPv4 NAT address" + ip address add "${ip4_nat_prefix}.1/24" dev "${wifi_device}" fi - if has_ip6delegatedprefix ${i} && ! is_ip6addr_set ${i}; then - echo "hotspot${i}: Set IPv6 address" - ip address delete "$(ip6addrfromdelegatedprefix $i)/64" dev tun0 &>/dev/null - ip address add "$(ip6addrfromdelegatedprefix $i)/64" dev "${dev}" + if has_ip6delegatedprefix && ! is_ip6addr_set; then + echo "hotspot ${wifi_device}: Set IPv6 address" + ip address delete "$(ip6addrfromdelegatedprefix)/64" dev tun0 &>/dev/null + ip address add "$(ip6addrfromdelegatedprefix)/64" dev "${wifi_device}" fi } set_ipfirewall() { - local i=${1} - local dev=$(devfromid "${i}") - # Set ipv6 firewalling - if has_ip6delegatedprefix ${i} && [ "${ip6_firewall[${i}]}" -eq 1 ] && ! is_ip6firewall_set ${i}; then - echo "hotspot${i}: Set IPv6 firewalling" - ip6tables -w -A FORWARD -i "${dev}" -j ACCEPT - ip6tables -w -A FORWARD -o "${dev}" -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT - ip6tables -w -A FORWARD -o "${dev}" -j DROP + if has_ip6delegatedprefix && [[ "${ip6_firewall}" -eq 1 ]] && ! is_ip6firewall_set; then + echo "hotspot ${wifi_device}: Set IPv6 firewalling" + ip6tables -w -A FORWARD -i "${wifi_device}" -j ACCEPT + ip6tables -w -A FORWARD -o "${wifi_device}" -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT + ip6tables -w -A FORWARD -o "${wifi_device}" -j DROP fi - } set_forwarding() { @@ -145,62 +145,22 @@ set_forwarding() { } start_dhcpd() { - local i=${1} - local dev=$(devfromid "${i}") - # Run DHCPv4 server - if ! is_dhcpd4_running ${i}; then - echo "hotspot${i}: Start the DHCPv4 server (dnsmasq)" - - cp /etc/dnsmasq.dhcpd/dhcpdv4{.conf.tpl,-ssid${i}.conf} - - sed "s|__WIFI_DEVICE__|${dev}|g" -i /etc/dnsmasq.dhcpd/dhcpdv4-ssid${i}.conf - sed "s|__IP4_DNS__|${ip4_dns[${i}]}|g" -i /etc/dnsmasq.dhcpd/dhcpdv4-ssid${i}.conf - sed "s|__IP4_NAT_PREFIX__|${ip4_nat_prefix[${i}]}|g" -i /etc/dnsmasq.dhcpd/dhcpdv4-ssid${i}.conf - - dnsmasq -C /etc/dnsmasq.dhcpd/dhcpdv4-ssid${i}.conf -p0 + if ! is_dhcpd4_running; then + echo "hotspot ${wifi_device}: Start the DHCPv4 server (dnsmasq)" + dnsmasq -C /etc/dnsmasq.$app/dhcpdv4.conf -p0 -x /run/dnsmasq/dnsmasq-dhcpdv4-$app.pid fi # Run DHCPv6 server - if has_ip6delegatedprefix ${i} && ! is_dhcpd6_running ${i}; then - echo "hotspot${i}: Start the NDP and DHCPv6 server (dnsmasq)" - - cp /etc/dnsmasq.dhcpd/dhcpdv6{.conf.tpl,-ssid${i}.conf} - - sed "s|__WIFI_DEVICE__|${dev}|g" -i /etc/dnsmasq.dhcpd/dhcpdv6-ssid${i}.conf - sed "s|__IP6_DNS__|${ip6_dns[${i}]}|g" -i /etc/dnsmasq.dhcpd/dhcpdv6-ssid${i}.conf - sed "s|__IP6_NET__|${ip6_net[${i}]}|g" -i /etc/dnsmasq.dhcpd/dhcpdv6-ssid${i}.conf - - dnsmasq -C /etc/dnsmasq.dhcpd/dhcpdv6-ssid${i}.conf -p0 + if has_ip6delegatedprefix && ! is_dhcpd6_running; then + echo "hotspot ${wifi_device}: Start the NDP and DHCPv6 server (dnsmasq)" + dnsmasq -C /etc/dnsmasq.$app/dhcpdv6.conf -p0 -x /run/dnsmasq/dnsmasq-dhcpdv6-$app.pid fi } configure_hostapd() { - local ethaddr=$(ip link show dev "${wifi_device}" | grep link/ether | awk -F: '{ printf "02:%s:%s:%s:%s:00", $2, $3, $4, $5 }') ip link set addr "${ethaddr}" dev "${wifi_device}" - - cp /etc/hostapd/hostapd.base.conf /etc/hostapd/hostapd.conf - sed "s|__WIFI_DEVICE__|${wifi_device}|g" -i /etc/hostapd/hostapd.conf - sed "s|__WIFI_CHANNEL__|${wifi_channel}|g" -i /etc/hostapd/hostapd.conf - sed "s|__N_COMMENT__||g" -i /etc/hostapd/hostapd.conf - - for i in $(seq 0 $((${multissid} - 1))); do - - [ "${wifi_secure[${i}]}" -eq 1 ] && local sec_comment="" || local sec_comment="#" - [ "${i}" -eq 0 ] && local bss_comment="#" || local bss_comment="" - - cp /etc/hostapd/hostapd.accesspoint.conf /etc/hostapd/hostapd.conf.tmp - - sed "s|__WIFI_INTERFACE__|hotspot${i}|g" -i /etc/hostapd/hostapd.conf.tmp - sed "s|__WIFI_SSID__|${wifi_ssid[${i}]}|g" -i /etc/hostapd/hostapd.conf.tmp - sed "s|__WIFI_PASSPHRASE__|${wifi_passphrase[${i}]}|g" -i /etc/hostapd/hostapd.conf.tmp - sed "s|__SEC_COMMENT__|${sec_comment}|g" -i /etc/hostapd/hostapd.conf.tmp - sed "s|__BSS_COMMENT__|${bss_comment}|g" -i /etc/hostapd/hostapd.conf.tmp - - cat /etc/hostapd/hostapd.conf.tmp >>/etc/hostapd/hostapd.conf - rm /etc/hostapd/hostapd.conf.tmp - done } ## Unsetters @@ -212,29 +172,23 @@ unset_nat() { } unset_ipaddr() { - local i=${1} - local dev=$(devfromid "${i}") - - if is_ip4nataddr_set ${i}; then - echo "hotspot${i}: Unset IPv4 NAT address" - ip address delete "${ip4_nat_prefix[${i}]}.1/24" dev "${dev}" + if is_ip4nataddr_set; then + echo "hotspot ${wifi_device}: Unset IPv4 NAT address" + ip address delete "${ip4_nat_prefix}.1/24" dev "${wifi_device}" fi - if has_ip6delegatedprefix ${i} && is_ip6addr_set ${i}; then - echo "hotspot${i}: Unset IPv6 address" - ip address delete "$(ip6addrfromdelegatedprefix $i)/64" dev "${dev}" + if has_ip6delegatedprefix && is_ip6addr_set; then + echo "hotspot ${wifi_device}: Unset IPv6 address" + ip address delete "$(ip6addrfromdelegatedprefix)/64" dev "${wifi_device}" fi } unset_ipfirewall() { - local i=${1} - local dev=$(devfromid "${i}") - - if has_ip6delegatedprefix ${i} && [ "${ip6_firewall[${i}]}" -eq 1 ] && is_ip6firewall_set ${i}; then - echo "hotspot${i}: Unset IPv6 firewalling" - ip6tables -w -D FORWARD -i "${dev}" -j ACCEPT - ip6tables -w -D FORWARD -o "${dev}" -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT - ip6tables -w -D FORWARD -o "${dev}" -j DROP + if has_ip6delegatedprefix && [[ "${ip6_firewall}" -eq 1 ]] && is_ip6firewall_set; then + echo "hotspot ${wifi_device}: Unset IPv6 firewalling" + ip6tables -w -D FORWARD -i "${wifi_device}" -j ACCEPT + ip6tables -w -D FORWARD -o "${wifi_device}" -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT + ip6tables -w -D FORWARD -o "${wifi_device}" -j DROP fi } @@ -244,77 +198,21 @@ unset_forwarding() { } stop_dhcpd() { - local i=${1} - - if is_dhcpd6_running ${i}; then - echo "hotspot${i}: Stop the NDP and DHCPv6 server (dnsmasq)" - kill $(ps aux | grep 'dhcpdv6-ssid' | grep -v grep | awk '{ print $2 }') - rm -f /etc/dnsmasq.d/dhcpdv6-ssid*.conf + if is_dhcpd6_running; then + echo "hotspot ${wifi_device}: Stop the NDP and DHCPv6 server (dnsmasq)" + kill $(cat /run/dnsmasq/dnsmasq-dhcpdv6-$app.pid) + rm -f /run/dnsmasq/dnsmasq-dhcpdv6-$app.pid fi - if is_dhcpd4_running ${i}; then - echo "hotspot${i}: Stop the DHCPv4 server (dnsmasq)" - kill $(ps aux | grep 'dhcpdv4-ssid' | grep -v grep | awk '{ print $2 }') - rm -f /etc/dnsmasq.d/dhcpdv4-ssid*.conf + if is_dhcpd4_running; then + echo "hotspot ${wifi_device}: Stop the DHCPv4 server (dnsmasq)" + kill $(cat /run/dnsmasq/dnsmasq-dhcpdv4-$app.pid) + rm -f /run/dnsmasq/dnsmasq-dhcpdv4-$app.pid fi } -stop_dhcpd4() { - : -} - stop_hostapd() { - systemctl stop hostapd -} - -## Tools - -ynh_setting_get() { - - APP="$1" KEY="$2" python3 - </dev/null - if [ "$?" -eq 0 ]; then - new_gateway_interface=tun0 - fi + # The awk syntax is to accomodate to the fact that the ip route output may look like: + # 1.2.3.4 via 192.168.1.254 dev end0 src 192.168.1.35 uid 0 + # 1.2.3.4 dev vpn_iloth table 51820 src 5.6.7.8 uid 0 + new_gateway_interface=$(ip route get 1.2.3.4 | awk '$2 ~ /^dev$/ { print $3; } $4 ~ /^dev$/ { print $5; }') echo "OK" fi @@ -369,27 +252,26 @@ start) if is_running; then echo "Already started" exit 0 - elif [ "${service_enabled}" != "enabled" ]; then - echo "Not starting because hotspod service is disabled" + elif [[ "${service_enabled}" -eq 0 ]]; then + echo "Not starting because hotspot service is disabled" exit 1 fi - if [ -z "${wifi_device}" ]; then + if [[ -z "${wifi_device}" ]]; then echo "[FAIL] No wifi device selected. Make sure your wifi antenna is plugged-in / available and select it in the Hotspot admin" exit 1 fi - echo "[hotspot] Starting..." - touch /tmp/.ynh-hotspot-started + echo "[$app] Starting..." + touch /tmp/.${service_name}-started # Check old state of the ipv4 NAT settings - if [ -n "${old_gateway_interface}" ] && [ "${new_gateway_interface}" != "${old_gateway_interface}" ] && is_nat_set "${old_gateway_interface}"; then - + if [[ -n "${old_gateway_interface}" ]] && [[ "${new_gateway_interface}" != "${old_gateway_interface}" ]] && is_nat_set "${old_gateway_interface}"; then unset_nat "${old_gateway_interface}" fi # Set ipv4 NAT - if [ -n "${new_gateway_interface}" ] && ! is_nat_set "${new_gateway_interface}"; then + if [[ -n "${new_gateway_interface}" ]] && ! is_nat_set "${new_gateway_interface}"; then echo "Set NAT" set_nat "${new_gateway_interface}" fi @@ -404,66 +286,49 @@ start) configure_hostapd echo "Starting hostapd..." - if ! systemctl start hostapd; then + if ! systemctl start "hostapd@${app}"; then journalctl -u hostapd -n 100 --no-hostname --no-pager exit 1 fi sleep 1 - - # On single SSID, the hotspot interface will be wlan0 (or similar) - # in multissid, we additionally want to make sure that at least hotspot1 started - if [ "${multissid}" -gt 1 ]; then - i=0 - while ! ip link show dev "hotspot1" &>/dev/null; do - sleep 1 - if [ ${i} -gt 20 ]; then - echo "Failed to see hotspot interface showing up in 'ip a'" - stop_hostapd - exit 1 - fi - i=$(($i + 1)) - done - fi fi - # For each registred ssid - for i in $(seq 0 $((${multissid} - 1))); do - set_ipaddr ${i} - set_ipfirewall ${i} - start_dhcpd ${i} - done + set_ipaddr + set_ipfirewall + start_dhcpd # Update dynamic settings - ynh_setting_set hotspot gateway_interface "${new_gateway_interface}" + ynh_app_setting_set --app=$app --key=gateway_interface --value="${new_gateway_interface}" + + # Regen-conf dnsmasq to enable dns resolution on dnsmasq for the new interface + yunohost tools regen-conf dnsmasq ;; stop) - echo "[hotspot] Stopping..." - rm -f /tmp/.ynh-hotspot-started + echo "[$app] Stopping..." + rm -f /tmp/.${service_name}-started - if [ -n "${old_gateway_interface}" ] && is_nat_set "${old_gateway_interface}"; then - echo "Unset NAT" - unset_nat "${old_gateway_interface}" + if ! is_other_hostapd_running; then + if [[ -n "${old_gateway_interface}" ]] && is_nat_set "${old_gateway_interface}"; then + echo "Unset NAT" + unset_nat "${old_gateway_interface}" + fi + + echo "Unset forwarding" + unset_forwarding fi - echo "Unset forwarding" - unset_forwarding - - for i in $(seq 0 $((${multissid} - 1))); do - unset_ipaddr ${i} - unset_ipfirewall ${i} - stop_dhcpd ${i} - done + unset_ipaddr + unset_ipfirewall + stop_dhcpd if is_hostapd_running; then echo "Stop hostapd" stop_hostapd fi - # Fix configuration - if has_vpnclient_app; then - ynh-vpnclient start - fi + # Regen-conf dnsmasq to disable dns resolution on dnsmasq for the previous interface + yunohost tools regen-conf dnsmasq ;; restart) $0 stop @@ -472,12 +337,12 @@ restart) status) exitcode=0 - if [ "${service_enabled}" != "enabled" ]; then + if [[ "${service_enabled}" -eq 0 ]]; then echo "[FAIL] Hotspot Service disabled" exit 1 fi - if [ -z "${wifi_device}" ]; then + if [[ -z "${wifi_device}" ]]; then echo "[FAIL] No wifi device selected. Make sure your wifi antenna is plugged-in / available and select it in the Hotspot admin" exit 1 fi @@ -487,7 +352,7 @@ status) if is_nat_set "${new_gateway_interface}"; then echo "[ OK ] IPv4 NAT set" else - if [ -z "${new_gateway_interface}" ]; then + if [[ -z "${new_gateway_interface}" ]]; then echo "[INFO] No IPv4 NAT set (no internet interface)" else echo "[FAIL] No IPv4 NAT set" @@ -509,53 +374,51 @@ status) exitcode=1 fi - for i in $(seq 0 $((${multissid} - 1))); do - if has_ip6delegatedprefix ${i}; then - echo "[INFO] hotspot${i}: IPv6 delegated prefix found" - echo "[INFO] hotspot${i}: IPv6 address computed from the delegated prefix: $(ip6addrfromdelegatedprefix $i)" + if has_ip6delegatedprefix; then + echo "[INFO] hotspot ${wifi_device}: IPv6 delegated prefix found" + echo "[INFO] hotspot ${wifi_device}: IPv6 address computed from the delegated prefix: $(ip6addrfromdelegatedprefix)" - if is_ip6addr_set ${i}; then - echo "[ OK ] hotspot${i}: IPv6 address set" - else - echo "[FAIL] hotspot${i}: No IPv6 address set" - exitcode=1 - fi - - if is_ip6firewall_set ${i}; then - echo "[ OK ] hotspot${i}: IPv6 firewalling set" - else - if [ "${ip6_firewall[${i}]}" -eq 1 ]; then - echo "[FAIL] hotspot${i}: No IPv6 firewalling set" - else - echo "[INFO] hotspot${i}: No IPv6 firewalling set" - fi - exitcode=1 - fi - - if is_dhcpd6_running ${i}; then - echo "[ OK ] hotspot${i}: NDP and DHCPv6 server (dnsmasq) are running" - else - echo "[FAIL] hotspot${i}: NDP and DHCPv6 server (dnsmasq) are not running" - exitcode=1 - fi + if is_ip6addr_set; then + echo "[ OK ] hotspot ${wifi_device}: IPv6 address set" else - echo "[INFO] hotspot${i}: No IPv6 delegated prefix found" - fi - - if is_dhcpd4_running ${i}; then - echo "[ OK ] hotspot${i}: DHCPv4 server (dnsmasq) is running" - else - echo "[FAIL] hotspot${i}: DHCPv4 (dnsmasq) is not running" + echo "[FAIL] hotspot ${wifi_device}: No IPv6 address set" exitcode=1 fi - if is_ip4nataddr_set ${i}; then - echo "[ OK ] hotspot${i}: IPv4 NAT address set" + if is_ip6firewall_set; then + echo "[ OK ] hotspot ${wifi_device}: IPv6 firewalling set" else - echo "[FAIL] hotspot${i}: No IPv4 NAT address set" + if [[ "${ip6_firewall}" -eq 1 ]]; then + echo "[FAIL] hotspot ${wifi_device}: No IPv6 firewalling set" + else + echo "[INFO] hotspot ${wifi_device}: No IPv6 firewalling set" + fi exitcode=1 fi - done + + if is_dhcpd6_running; then + echo "[ OK ] hotspot ${wifi_device}: NDP and DHCPv6 server (dnsmasq) are running" + else + echo "[FAIL] hotspot ${wifi_device}: NDP and DHCPv6 server (dnsmasq) are not running" + exitcode=1 + fi + else + echo "[INFO] hotspot ${wifi_device}: No IPv6 delegated prefix found" + fi + + if is_dhcpd4_running; then + echo "[ OK ] hotspot ${wifi_device}: DHCPv4 server (dnsmasq) is running" + else + echo "[FAIL] hotspot ${zifi_device}: DHCPv4 (dnsmasq) is not running" + exitcode=1 + fi + + if is_ip4nataddr_set; then + echo "[ OK ] hotspot ${wifi_device}: IPv4 NAT address set" + else + echo "[FAIL] hotspot ${wifi_device}: No IPv4 NAT address set" + exitcode=1 + fi exit ${exitcode} ;; diff --git a/config_panel.toml b/config_panel.toml index 54eb774..1326b1c 100644 --- a/config_panel.toml +++ b/config_panel.toml @@ -19,7 +19,7 @@ name = "Configuration" visible = "no_antenna" [main.service.status] - ask = "The status of your VPN is unknown." + ask = "The status of your Hotspot is unknown." type = "alert" style = "info" visible = "! no_antenna" @@ -52,236 +52,73 @@ name = "Configuration" visible = "! no_antenna" help = "Changing the channel may help with signal strength depending on neighbour WiFis" - [main.service.multissid] - ask = "Number of hotspots to broadcast" - type = "select" - choices.1 = "1" - choices.2 = "2" - choices.3 = "3" - visible = "! no_antenna" - - [main.hotspot1] - name = "Hotspot 1" + [main.hotspot] + name = "Hotspot" optional = false visible = "! no_antenna" - [main.hotspot1.wifi_ssid__1] + [main.hotspot.wifi_ssid] ask = "Name (SSID)" type = "string" - bind = "array_settings()" pattern.regexp = '^[\w \-]{1,32}$' pattern.error = "SSID in this app are limited to letter, number space, dash and underscores." - [main.hotspot1.wifi_secure__1] + [main.hotspot.wifi_secure] ask = "Secure" type = "boolean" - bind = "array_settings()" - [main.hotspot1.wifi_passphrase__1] + [main.hotspot.wifi_passphrase] ask = "Password (WPA2)" type = "string" - bind = "array_settings()" redact = true optional = true - visible = "wifi_secure__1" + visible = "wifi_secure" pattern.regexp = '^[a-zA-Z0-9]{8,63}$' pattern.error = "Only printable alphanumeric characters are permitted in your password. Maximal size 63 chars" - [main.hotspot1.advanced__1] + [main.hotspot.advanced] ask = "Advanced settings" type = "boolean" - bind = "array_settings()" - [main.hotspot1.ip4_nat_prefix__1] + [main.hotspot.ip4_nat_prefix] ask = "IPv4 NAT prefix (/24)" type = "string" - bind = "array_settings()" - visible = "advanced__1" + visible = "advanced" pattern.regexp = '^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$' pattern.error = "Please provide a private /24 range in the format xxx.xxx.xxx" - [main.hotspot1.ip6_net__1] + [main.hotspot.ip6_net] ask = "IPv6 delegated prefix" type = "string" - bind = "array_settings()" optional = true - visible = "advanced__1" + visible = "advanced" pattern.regexp = '^[0-9a-fA-F:]+$' pattern.error = "Please provide a valid IPv6 Prefix" - [main.hotspot1.ip6_firewall__1] + [main.hotspot.ip6_firewall] ask = "IPv6 firewall" type = "boolean" - bind = "array_settings()" - visible = "advanced__1" + visible = "advanced" - [main.hotspot1.dns__1] + [main.hotspot.dns] ask = "DNS resolvers" type = "tags" - bind = "array_settings()" - visible = "advanced__1" + optional = true + visible = "advanced" pattern.regexp = '^([0-9.]{7,15}|[0-9a-fA-F:]+)$' pattern.error = "Not an ip" - [main.hotspot1.captive_portal__1] - ask = "Captive portal" - type = "boolean" - bind = "array_settings()" - visible = "advanced__1" - help = "Activate the captive portal mode" - - [main.hotspot1.captive_portal_url__1] - ask = "Local captive portal URL" - type = "string" - bind = "array_settings()" - visible = "advanced__1 && captive_portal__1" - help = "Local URL on which redirect onto when the user mac address is not yet allowed" - - [main.hotspot2] - name = "Hotspot 2" - visible = "! no_antenna && multissid >= 2" - - [main.hotspot2.wifi_ssid__2] - ask = "Name (SSID)" - type = "string" - bind = "array_settings()" - pattern.regexp = '^[\w \-]{1,32}$' - pattern.error = "SSID in this app are limited to letter, number space, dash and underscores." - - [main.hotspot2.wifi_secure__2] - ask = "Secure" - type = "boolean" - bind = "array_settings()" - - [main.hotspot2.wifi_passphrase__2] - ask = "Password (WPA2)" - type = "string" - bind = "array_settings()" - redact = true - visible = "wifi_secure__2" - pattern.regexp = '^[a-zA-Z0-9]{8,63}$' - pattern.error = "Only printable alphanumeric characters are permitted in your password. Maximal size 63 chars" - - [main.hotspot2.advanced__2] - ask = "Advanced settings" - type = "boolean" - bind = "array_settings()" - - [main.hotspot2.ip4_nat_prefix__2] - ask = "IPv4 NAT prefix (/24)" - type = "string" - bind = "array_settings()" - visible = "advanced__2" - pattern.regexp = '^[0-9.]{7,15}$' - pattern.error = "Please provide a valid IP" - - [main.hotspot2.ip6_net__2] - ask = "IPv6 delegated prefix" - type = "string" - bind = "array_settings()" - visible = "advanced__2" - pattern.regexp = '^[0-9a-fA-F:]+$' - pattern.error = "Please provide a valid IPv6 Prefix" - - [main.hotspot2.ip6_firewall__2] - ask = "IPv6 firewall" - type = "boolean" - bind = "array_settings()" - visible = "advanced__2" - - [main.hotspot2.dns__2] - ask = "DNS resolvers" - type = "tags" - bind = "array_settings()" - visible = "advanced__2" - pattern.regexp = '^([0-9.]{7,15}|[0-9a-fA-F:]+)$' - pattern.error = "Not an ip" - - [main.hotspot2.captive_portal__2] - ask = "Captive portal" - type = "boolean" - bind = "array_settings()" - visible = "advanced__2" - help = "Activate the captive portal mode" - - [main.hotspot2.captive_portal_url__2] - ask = "Local captive portal URL" - type = "string" - bind = "array_settings()" - visible = "advanced__2 && captive_portal__2" - help = "Local URL on which redirect onto when the user mac address is not yet allowed" - - [main.hotspot3] - name = "Hotspot 3" - visible = "! no_antenna && multissid >= 3" - - [main.hotspot3.wifi_ssid__3] - ask = "Name (SSID)" - type = "string" - bind = "array_settings()" - pattern.regexp = '^[\w \-]{1,32}$' - pattern.error = "SSID in this app are limited to letter, number space, dash and underscores." - - [main.hotspot3.wifi_secure__3] - ask = "Secure" - type = "boolean" - bind = "array_settings()" - - [main.hotspot3.wifi_passphrase__3] - ask = "Password (WPA2)" - type = "string" - bind = "array_settings()" - redact = true - visible = "wifi_secure__3" - pattern.regexp = '^[a-zA-Z0-9]{8,63}$' - pattern.error = "Only printable alphanumeric characters are permitted in your password. Maximal size 63 chars" - - [main.hotspot3.advanced__3] - ask = "Advanced settings" - type = "boolean" - bind = "array_settings()" - - [main.hotspot3.ip4_nat_prefix__3] - ask = "IPv4 NAT prefix (/24)" - type = "string" - bind = "array_settings()" - visible = "advanced__3" - pattern.regexp = '^[0-9.]{7,15}$' - pattern.error = "Please provide a valid IP" - - [main.hotspot3.ip6_net__3] - ask = "IPv6 delegated prefix" - type = "string" - bind = "array_settings()" - visible = "advanced__3" - pattern.regexp = '^[0-9a-fA-F:]+$' - pattern.error = "Please provide a valid IPv6 Prefix" - - [main.hotspot3.ip6_firewall__3] - ask = "IPv6 firewall" - type = "boolean" - bind = "array_settings()" - visible = "advanced__3" - - [main.hotspot3.dns__3] - ask = "DNS resolvers" - type = "tags" - bind = "array_settings()" - visible = "advanced__3" - pattern.regexp = '^([0-9.]{7,15}|[0-9a-fA-F:]+)$' - pattern.error = "Not an ip" - - [main.hotspot3.captive_portal__3] + [main.hotspot.captive_portal] ask = "Captive portal" type = "boolean" bind = "array_settings()" visible = "advanced__3" help = "Activate the captive portal mode" - [main.hotspot3.captive_portal_url__3] + [main.hotspot.captive_portal_url] ask = "Local captive portal URL" type = "string" bind = "array_settings()" - visible = "advanced__3 && captive_portal__3" + visible = "advanced && captive_portal" help = "Local URL on which redirect onto when the user mac address is not yet allowed" diff --git a/doc/PRE_INSTALL.md b/doc/PRE_INSTALL.md new file mode 100644 index 0000000..1b77a3b --- /dev/null +++ b/doc/PRE_INSTALL.md @@ -0,0 +1 @@ +After the installation, you will be able to configure the application from YunoHost's webadmin in Applications > Hotspot > Configuration. diff --git a/doc/PRE_INSTALL_fr.md b/doc/PRE_INSTALL_fr.md new file mode 100644 index 0000000..e210e68 --- /dev/null +++ b/doc/PRE_INSTALL_fr.md @@ -0,0 +1 @@ +Après l'application, vous pourrez configurer l'application depuis la webadmin de YunoHost dans Applications > Hotspot > Configuration. diff --git a/manifest.json b/manifest.json deleted file mode 100644 index c609848..0000000 --- a/manifest.json +++ /dev/null @@ -1,66 +0,0 @@ -{ - "name": "Wifi Hotspot", - "id": "hotspot", - "packaging_format": 1, - "description": { - "en": "Create and manager wifi networks, share Internet access and use YunoHost apps accross wifi", - "fr": "Créer et configurer des réseaux wifi, partager l'accès a Internet et utiliser les applications YunoHost via wifi" - }, - "version": "2.0~ynh3", - "url": "https://github.com/labriqueinternet/hotspot_ynh", - "license": "AGPL-3.0", - "maintainer": { - "name": "Julien Vaubourg", - "email": "julien@vaubourg.com", - "url": "http://julien.vaubourg.com" - }, - "upstream": { - "license": "AGPL-3.0", - "website": "https://internetcu.be/" - }, - "requirements": { - "yunohost": ">= 4.3.2" - }, - "multi_instance": false, - "services": [], - "arguments": { - "install" : [ - { - "name": "disclaimer", - "type": "display_text", - "style": "info", - "ask": { - "en": "After installation, you will be able to configure the application from YunoHost's webadmin in Applications > Hotspot > Configuration.", - "fr": "Après l'application, vous pourrez configurer l'application depuis la webadmin de YunoHost dans Applications > Hotspot > Configuration." - } - }, - { - "name": "wifi_ssid", - "type": "string", - "ask": { - "en": "Choose a wifi name (SSID)", - "fr": "Choisissez un nom pour le wifi (SSID)" - }, - "example": "myNeutralNetwork", - "default": "myNeutralNetwork" - }, - { - "name": "wifi_passphrase", - "type": "password", - "ask": { - "en": "Choose a wifi password (at least 8 characters for WPA2)", - "fr": "Choisissez un mot de passe wifi (au minimum 8 caractères pour le WPA2)" - } - }, - { - "name": "firmware_nonfree", - "type": "boolean", - "ask": { - "en": "Install non-free WiFi firmwares? (Only needed if you're using a proprietary WiFi antenna/dongle)", - "fr": "Installer des firmwares WiFi non-libres ? (Nécessaire seulement si vous utilisez une antenne/clé WiFi propriétaire)" - }, - "default": false - } - ] - } -} diff --git a/manifest.toml b/manifest.toml new file mode 100644 index 0000000..678f54f --- /dev/null +++ b/manifest.toml @@ -0,0 +1,70 @@ +#:schema https://raw.githubusercontent.com/YunoHost/apps/master/schemas/manifest.v2.schema.json + +packaging_format = 2 + +id = "hotspot" +name = "Wifi Hotspot" +description.en = "Create and configure a WiFi hotspot" +description.fr = "Créez et gérez un point d'accès WiFi" + +version = "2.3.1~ynh1" + +maintainers = [] + +[upstream] +license = "AGPL-3.0" +website = "https://internetcu.be/" + +[integration] +yunohost = ">= 11.2.7" +architectures = "all" +multi_instance = true +ldap = "not_relevant" +sso = "not_relevant" +disk = "50M" +ram.build = "50M" +ram.runtime = "50M" + +[install] + [install.wifi_ssid] + ask.en = "Choose a wifi name (SSID)" + ask.fr = "Choisissez un nom pour le wifi (SSID)" + type = "string" + example = "myNeutralNetwork" + default = "myNeutralNetwork" + + [install.wifi_passphrase] + ask.en = "Choose a wifi password (at least 8 characters for WPA2)" + ask.fr = "Choisissez un mot de passe wifi (au minimum 8 caractères pour le WPA2)" + type = "password" + + [install.firmware_nonfree] + ask.en = "Install non-free WiFi firmwares? (Only needed if you're using a proprietary WiFi antenna/dongle)" + ask.fr = "Installer des firmwares WiFi non-libres ? (Nécessaire seulement si vous utilisez une antenne/clé WiFi propriétaire)" + type = "boolean" + default = false + +[resources] + [resources.system_user] + + [resources.permissions] + + [resources.apt] + packages = "sipcalc, hostapd, iw, kmod" + packages_from_raw_bash = '[[ "$firmware_nonfree" -eq 0 ]] && echo "firmware-ath9k-htc" || true' + + [resources.apt.extras.nonfree] + repo = "deb http://deb.debian.org/debian bullseye non-free" + key = "https://ftp-master.debian.org/keys/archive-key-11.asc" + packages_from_raw_bash = """ + # Proprietary USB Wireless Device firmwares, based on https://wiki.debian.org/WiFi#USB_Devices + if [[ "$firmware_nonfree" -eq 1 ]]; then + # if armbian-firmware is detected, we dont include ra-link which is known to conflict.... + if dpkg --list | grep -q armbian-firmware; then + echo "firmware-atheros firmware-realtek firmware-libertas atmel-firmware firmware-zd1211" + else + echo "firmware-atheros firmware-realtek firmware-ralink firmware-libertas atmel-firmware firmware-zd1211" + fi + else + echo " " + fi""" diff --git a/screenshot.png b/screenshot.png deleted file mode 100644 index d8b4cdf..0000000 Binary files a/screenshot.png and /dev/null differ diff --git a/scripts/_common.sh b/scripts/_common.sh index 0687a14..6d440ed 100644 --- a/scripts/_common.sh +++ b/scripts/_common.sh @@ -1,57 +1,67 @@ #!/bin/bash -#================================================= -# COMMON VARIABLES -#================================================= - -pkg_dependencies="sipcalc hostapd iw kmod" -nonfree_firmware_packages="firmware-atheros firmware-realtek firmware-ralink firmware-libertas atmel-firmware firmware-zd1211" -free_firmware_packages="firmware-ath9k-htc" - -#================================================= -# PERSONAL HELPERS -#================================================= +function other_hotspot_apps() +{ + local app_shortname="${app%%__*}" + local hotspot_apps=$(yunohost app list --output-as json | jq -r .apps[].id | grep -F $app_shortname) + # Remove this app from hotspot apps list + grep -F -x -v $app <<< ${hotspot_apps} +} function iw_devices() { - echo -n $(/sbin/iw dev | grep Interface | grep -v 'mon\.' | grep -v hotspot | awk '{ print $NF }') | tr ' ' '|' + /sbin/iw dev | grep Interface | grep -v 'mon\.' | grep -v hotspot | awk '{ print $NF }' } -function check_armbian_nonfree_conflict() +function used_iw_devices() { + for hotspot_app in $(other_hotspot_apps); do + hotspot_wifi_device=$(ynh_app_setting_get --app=$hotspot_app --key=wifi_device) + if [[ -n "${hotspot_wifi_device}" ]]; then + echo "${hotspot_wifi_device}" + fi + done +} - # If we're on armbian, force $firmware_nonfree - # because armbian-firmware conflicts with firmware-misc-nonfree package - if dpkg --list | grep -q armbian-firmware; then - echo "You are running Armbian and firmware-misc-nonfree are known to conflict with armbian-firwmare. " >&2 - echo "The package firmware-misc-nonfree is a dependency of firmware-ralink, so firmware-ralink will NOT be installed" >&2 - echo "You can manually install firmware-ralink with 'apt -o Dpkg::Options::=\"--force-overwrite\" firmware-ralink'" >&2 - nonfree_firmware_packages=$(echo $nonfree_firmware_packages | sed 's/ firmware-ralink//') - fi - +function unused_iw_devices() +{ + # Only prints devices that are not in the list of used devices + iw_devices | grep -F -v -f <(used_iw_devices) } function hot_reload_usb_wifi_cards() { - modulesList="acx-mac80211 ar5523 ar9170usb at76c50x-usb at76_usb ath9k_htc carl9170 orinoco_usb p54usb prism2_usb r8712u r8192s_usb r8192u_usb rndis_wlan rt2500usb rt2800usb rt2870sta rt73usb rtl8187 rtl8192cu usb8xxx vt6656_stage zd1201 zd1211rw" - modprobe --quiet --remove $modulesList || true - possibleUsbDevicesNeedingReload=$(dmesg | grep -Pio '(?<=usb )[0-9-]+(?=:.*firmware)' | sort | uniq) - for usbPath in $possibleUsbDevicesNeedingReload; do - if [[ -f "/sys/bus/usb/devices/$usbPath/authorized" ]]; then - echo "Try to reload driver for usb $usbPath" >&2 - echo 0 > /sys/bus/usb/devices/$usbPath/authorized - echo 1 > /sys/bus/usb/devices/$usbPath/authorized - # Wait for driver reloading - sleep 2 - fi - done + modulesList="acx-mac80211 ar5523 ar9170usb at76c50x-usb at76_usb ath9k_htc carl9170 orinoco_usb p54usb prism2_usb r8712u r8192s_usb r8192u_usb rndis_wlan rt2500usb rt2800usb rt2870sta rt73usb rtl8187 rtl8192cu usb8xxx vt6656_stage zd1201 zd1211rw" + modprobe --quiet --remove $modulesList || true + possibleUsbDevicesNeedingReload=$(dmesg | grep -Pio '(?<=usb )[0-9-]+(?=:.*firmware)' | sort | uniq) + for usbPath in $possibleUsbDevicesNeedingReload; do + if [[ -f "/sys/bus/usb/devices/$usbPath/authorized" ]]; then + echo "Try to reload driver for usb $usbPath" >&2 + echo 0 > /sys/bus/usb/devices/$usbPath/authorized + echo 1 > /sys/bus/usb/devices/$usbPath/authorized + # Wait for driver reloading + sleep 2 + fi + done } -#================================================= -# EXPERIMENTAL HELPERS -#================================================= +function configure_hostapd() +{ + if [[ "${wifi_secure}" -eq 1 ]]; then + sec_comment="" + else + sec_comment="#" + fi -#================================================= -# FUTURE OFFICIAL HELPERS -#================================================= + ynh_add_config --template="../conf/hostapd.conf" --destination="/etc/hostapd/$app/hostapd.conf" +} + +function configure_dhcp() +{ + ynh_add_config --template="../conf/dnsmasq_dhcpdv4.conf" --destination="/etc/dnsmasq.$app/dhcpdv4.conf" + + if [[ -n "${ip6_net}" ]] && [[ "${ip6_net}" != "none" ]]; then + ynh_add_config --template="../conf/dnsmasq_dhcpdv6.conf" --destination="/etc/dnsmasq.$app/dhcpdv6.conf" + fi +} diff --git a/scripts/backup b/scripts/backup index 7251006..27f8b14 100644 --- a/scripts/backup +++ b/scripts/backup @@ -10,27 +10,6 @@ source ../settings/scripts/_common.sh source /usr/share/yunohost/helpers -#================================================= -# MANAGE SCRIPT FAILURE -#================================================= - -ynh_clean_setup () { - ynh_clean_check_starting -} -# Exit if an error occurs during the execution of the script -ynh_abort_if_errors - -#================================================= -# LOAD SETTINGS -#================================================= -ynh_print_info --message="Loading installation settings..." - -app=$YNH_APP_INSTANCE_NAME - -final_path=$(ynh_app_setting_get --app=$app --key=final_path) -firmware_nonfree=$(ynh_app_setting_get --app=$app --key=firmware_nonfree) -service_name=$(ynh_app_setting_get --app=$app --key=service_name) - #================================================= # DECLARE DATA AND CONF FILES TO BACKUP #================================================= @@ -40,27 +19,19 @@ ynh_print_info --message="Declaring files to be backed up..." # BACKUP THE APP MAIN DIR #================================================= -for FILE in $(ls /etc/hostapd/hostapd.*.conf 2>/dev/null) -do - ynh_backup --src_path="$FILE" -done - -ynh_backup --src_path="/etc/dnsmasq.dhcpd/dhcpdv6.conf.tpl" -ynh_backup --src_path="/etc/dnsmasq.dhcpd/dhcpdv4.conf.tpl" +ynh_backup --src_path="/etc/hostapd/$app/hostapd.conf" --not_mandatory +ynh_backup --src_path="/etc/dnsmasq.$app/dhcpdv6.conf" --not_mandatory +ynh_backup --src_path="/etc/dnsmasq.$app/dhcpdv4.conf" --not_mandatory ynh_backup --src_path="/usr/local/bin/$service_name" ynh_backup --src_path="/usr/local/bin/captiveportal_fakedns" ynh_backup --src_path="/usr/local/bin/captiveportal_allow" -ynh_backup --src_path="/etc/init.d/hostapd" - -#================================================= -# SPECIFIC BACKUP -#================================================= -# BACKUP SYSTEMD -#================================================= +ynh_backup --src_path="/etc/openvpn/scripts/route-up.d/90-$service_name" +ynh_backup --src_path="/etc/openvpn/scripts/route-down.d/90-$service_name" ynh_backup --src_path="/etc/systemd/system/$service_name.service" +ynh_backup --src_path="/etc/systemd/system/hostapd@$app.service" ynh_backup --src_path="/etc/systemd/system/captiveportal_fakedns.service" #================================================= diff --git a/scripts/config b/scripts/config index 190f4bd..b62af3e 100644 --- a/scripts/config +++ b/scripts/config @@ -16,18 +16,12 @@ source /usr/share/yunohost/helpers # Exit if an error occurs during the execution of the script ynh_abort_if_errors -#================================================= -# RETRIEVE ARGUMENTS -#================================================= - -final_path=$(ynh_app_setting_get $app final_path) - #================================================= # SPECIFIC GETTERS FOR TOML SHORT KEY #================================================= get__no_antenna() { - if [[ $(iw_devices) == "" ]] + if [[ "$(unused_iw_devices)" == "" ]] then echo "value: true" else @@ -37,9 +31,9 @@ get__no_antenna() { get__status() { local service_enabled=$(ynh_app_setting_get $app service_enabled) - if systemctl is-active hostapd -q + if systemctl is-active hostapd@$app -q then - if [ $service_enabled -eq 1 ] + if [[ "$service_enabled" -eq 1 ]] then cat << EOF style: success @@ -54,7 +48,7 @@ ask: en: Your Hotspot is running, but it shouldn't ! EOF fi - elif [ $service_enabled -eq 1 ] + elif [[ "$service_enabled" -eq 1 ]] then cat << EOF style: danger @@ -62,7 +56,7 @@ ask: en: |- Your Hotspot is down ! Here are errors logged in the last 5 minutes \`\`\` -$(journalctl -u hostapd -n10 -o cat | sed 's/^/ /g') +$(journalctl -u hostapd@$app -n10 -o cat | sed 's/^/ /g') \`\`\` EOF else @@ -76,14 +70,15 @@ EOF } get__wifi_device() { - if [[ $(iw_devices) == "" ]] + local unused_wifi_devices=$(unused_iw_devices) + if [[ -z "${unused_wifi_devices}" ]] then echo "choices: []" else cat << EOF choices: EOF - for device in $(iw_devices | sed "s/|/ /g") + for device in $unused_wifi_devices do echo " $device: $device" done @@ -92,154 +87,130 @@ EOF echo "value: '$(ynh_app_setting_get $app wifi_device)'" } -get__array_settings() { - local short_setting="${1%%__*}" - local index="${1#*__}" - IFS='|' read -a values <<< "$(ynh_app_setting_get $app $short_setting)" - echo "value: \"${values[$(($index - 1))]:-}\"" +get__dns() { + ip6_net=$(ynh_app_setting_get --app=$app --key=ip6_net) + ip6_dns=$(ynh_app_setting_get --app=$app --key=ip6_dns | tr -d '[]') + ip4_nat_prefix=$(ynh_app_setting_get --app=$app --key=ip4_nat_prefix) + ip4_dns=$(ynh_app_setting_get --app=$app --key=ip4_dns) + + if [[ -n "${ip6_net}" ]] && [[ -z "${ip6_dns}" ]]; then + ip6_dns="${ip6_net}1" + fi + + if [[ -n "${ip4_nat_prefix}" ]] && [[ -z "${ip4_dns}" ]]; then + ip4_dns="${ip4_nat_prefix}.1" + fi + + echo "value: ${ip4_dns},${ip6_dns}" } #================================================= # SPECIFIC VALIDATORS FOR TOML SHORT KEYS #================================================= -is_unique() { - local short_setting="$1" - local short_setting__1="$1__1" - local short_setting__2="$1__2" - local short_setting__3="$1__3" - if [[ "${!short_setting__1}" == "${!short_setting__2}" ]] - then - return 1 - elif [ "$multissid" -ge "3" ] && [[ "${!short_setting__1}" == "${!short_setting__3}" ]] - then - return 1 - elif [ "$multissid" -ge "3" ] && [[ "${!short_setting__2}" == "${!short_setting__3}" ]] - then - return 1 - fi - return 0 -} + validate__wifi_ssid() { - local wifi_ssid_var="wifi_ssid__$1" - if [ "$multissid" -ge "$1" ] && [[ -z "${!wifi_ssid_var}" ]] + if [[ -z "${wifi_ssid}" ]] then echo 'SSID required' fi - if ! is_unique wifi_ssid - then - echo 'All Wifi names must be unique' - fi } validate__wifi_passphrase() { - local wifi_secure_var="wifi_secure__$1" - local wifi_passphrase_var="wifi_passphrase__$1" - if [ "$multissid" -ge "$1" ] && [[ "${!wifi_secure_var}" == "1" ]] && [[ -z "${!wifi_passphrase_var}" ]] + if [[ "${wifi_secure}" == "1" ]] && [[ -z "${wifi_passphrase}" ]] then echo 'In WPA2 secure mode, you need to provide a passphrase' fi } validate__ip4_nat_prefix() { - local ip4_nat_prefix_var="ip4_nat_prefix__$1" - if [ "$multissid" -ge "$1" ] && [[ -z "${!ip4_nat_prefix_var}" ]] + if [[ -z "${ip4_nat_prefix}" ]] then echo 'Private IPv4 nat prefix required' fi - if ! is_unique ip4_nat_prefix - then - echo 'All IPv4 prefix must be unique' - fi } validate__dns() { - local dns_var="dns__$1" - local ip6_net_var="dns__$1" - if [ "$multissid" -ge "$1" ] && ! echo "${!dns_var}" | grep -q "\." + if [[ -z "$ip4_dns" ]] then echo 'IPv4 DNS required' fi - if [ "$multissid" -ge "$1" ] && [[ -n "${!ip6_net_var}" ]] && ! echo "${!dns_var}" | grep -q ":" + if [[ -n "${ip6_net}" ]] && [[ -z "$ip6_dns" ]] then echo 'IPv6 DNS required' fi } -validate__array_settings() { - local short_setting="${1%%__*}" - local index="${1#*__}" - if type -t validate__$short_setting | grep -q '^function$' 2>/dev/null; - then - validate__$short_setting $index +ynh_app_config_validate() { + if [[ "${advanced}" -eq 0 ]]; then + # When we aren't in advanced mode, these variables must be manually declared + dns="${old[dns]}" + ip6_net="${old[ip6_net]}" + ip4_nat_prefix="${old[ip4_nat_prefix]}" fi + + ip6_dns="" + ip4_dns="" + for ip in $(echo "${dns}" | tr ',' ' '); do + if [[ "$ip" == *":"* ]]; then + ip6_dns+="[$ip]," + else + ip4_dns+="$ip," + fi + done + # Remove trailing , + ip6_dns="${ip6_dns%%,}" + ip4_dns="${ip4_dns%%,}" + + if [[ -n "${ip6_net}" ]] && [[ -z "${ip6_dns}" ]]; then + ip6_dns="${ip6_net}1" + fi + + if [[ -n "${ip4_nat_prefix}" ]] && [[ -z "${ip4_dns}" ]]; then + ip4_dns="${ip4_nat_prefix}.1" + fi + + _ynh_app_config_validate } #================================================= # SPECIFIC SETTERS FOR TOML SHORT KEYS #================================================= -set__array_settings() { - local short_setting="${1%%__*}" - local index="${1#*__}" - local type="${types[$1]}" - local value="${!1}" - if [[ "$type" == "string" ]] && [ "$multissid" -lt "$index" ] - then - value="" - fi - local values="$(ynh_app_setting_get $app $short_setting | awk 'BEGIN{FS=OFS="|"} {$'$index'="'${!1}'"}'1)" - ynh_app_setting_set --app=$app --key=$short_setting --value="$values" - ynh_print_info --message="Configuration key '$short_setting' edited in app settings" -} +set__dns() { + ynh_app_setting_set $app ip6_dns "${ip6_dns}" + ynh_app_setting_set $app ip4_dns "${ip4_dns}" +} #================================================= # OVERWRITING VALIDATE STEP #================================================= -ynh_app_config_validate() { - _ynh_app_config_validate -} #================================================= # OVERWRITING APPLY STEP #================================================= ynh_app_config_apply() { - + service_name=$(ynh_app_setting_get --app=$app --key=service_name) + # Stop vpn client ynh_print_info --message="Stopping hotspot in order to edit files" - /usr/local/bin/ynh-hotspot stop + yunohost service stop $service_name _ynh_app_config_apply # Activate captive portal or not captive_portal=$(ynh_app_setting_get --app=$app --key=captive_portal) - if [[ "$captive_portal" =~ 1 ]] + if [[ "$captive_portal" == '1' ]] then echo "location / {" > /etc/nginx/conf.d/default.d/redirect_to_admin.conf - if [[ "$captive_portal__1" == "1" ]] - then - echo " if (\$remote_addr ~ "^$ip4_nat_prefix__1.\d+$") {" >> /etc/nginx/conf.d/default.d/redirect_to_admin.conf + + echo " if (\$remote_addr ~ "^$ip4_nat_prefix.\d+$") {" >> /etc/nginx/conf.d/default.d/redirect_to_admin.conf - echo " return 302 $captive_portal_url__1;" >> /etc/nginx/conf.d/default.d/redirect_to_admin.conf + echo " return 302 $captive_portal_url;" >> /etc/nginx/conf.d/default.d/redirect_to_admin.conf - echo " }" > /etc/nginx/conf.d/default.d/redirect_to_admin.conf - fi - if [[ "$captive_portal__2" == "1" ]] - then - echo " if (\$remote_addr ~ "^$ip4_nat_prefix__2.\d+$") {" >> /etc/nginx/conf.d/default.d/redirect_to_admin.conf - - echo " return 302 $captive_portal_url__2;" >> /etc/nginx/conf.d/default.d/redirect_to_admin.conf - - echo " }" >> /etc/nginx/conf.d/default.d/redirect_to_admin.conf - fi - if [[ "$captive_portal__3" == "1" ]] - then - echo " if (\$remote_addr ~ "^$ip4_nat_prefix__3.\d+$") {" >> /etc/nginx/conf.d/default.d/redirect_to_admin.conf - - echo " return 302 $captive_portal_url__3;" >> /etc/nginx/conf.d/default.d/redirect_to_admin.conf - - echo " }" >> /etc/nginx/conf.d/default.d/redirect_to_admin.conf - fi + echo " }" > /etc/nginx/conf.d/default.d/redirect_to_admin.conf + echo " return 302 https://\$http_host/yunohost/admin;" >> /etc/nginx/conf.d/default.d/redirect_to_admin.conf + echo "}" >> /etc/nginx/conf.d/default.d/redirect_to_admin.conf systemctl reload nginx ynh_systemd_action --service_name=captiveportal_fakedns --action="start" --log_path=systemd @@ -251,6 +222,23 @@ ynh_app_config_apply() { ynh_print_info --message="Starting hotspot service if needed" /usr/local/bin/ynh-hotspot start + if [[ "${service_enabled}" -eq 1 ]]; then + configure_hostapd + configure_dhcp + + # Start hotspot + ynh_print_info --message="Starting hotspot service if needed" + yunohost service start $service_name + else + ynh_print_info --message="Cleanup hotspot config files" + ynh_secure_remove --file="/etc/hostapd/$app/hostapd.conf" + ynh_secure_remove --file="/etc/dnsmasq.$app/dhcpdv4.conf" + ynh_secure_remove --file="/etc/dnsmasq.$app/dhcpdv6.conf" + + systemctl restart dnsmasq + fi + + yunohost tools regen-conf dnsmasq } ynh_app_config_run $1 diff --git a/scripts/install b/scripts/install index 9e7798a..957fc61 100644 --- a/scripts/install +++ b/scripts/install @@ -9,32 +9,14 @@ source _common.sh source /usr/share/yunohost/helpers -#================================================= -# MANAGE SCRIPT FAILURE -#================================================= - -ynh_clean_setup () { - ynh_clean_check_starting -} -# Exit if an error occurs during the execution of the script -ynh_abort_if_errors - -#================================================= -# RETRIEVE ARGUMENTS FROM THE MANIFEST -#================================================= - -wifi_ssid=$YNH_APP_ARG_WIFI_SSID -wifi_passphrase=$YNH_APP_ARG_WIFI_PASSPHRASE -firmware_nonfree=$YNH_APP_ARG_FIRMWARE_NONFREE - -app=$YNH_APP_INSTANCE_NAME - -# the service name must match the service template files -service_name='ynh-hotspot' +service_name=ynh-$app +ynh_app_setting_set --app=$app --key=service_name --value=$service_name #================================================= # CHECK IF THE APP CAN BE INSTALLED WITH THESE ARGS #================================================= + +# FIXME : we could probably implement all these checks in manifest.toml directly ? ynh_script_progression --message="Validating installation parameters..." # Check arguments @@ -45,7 +27,7 @@ fi # Check passphrase length wifi_passphrase_length="$(wc -c <<< "${wifi_passphrase}")" if [[ $wifi_passphrase_length -lt 8 ]] || [[ $wifi_passphrase_length -gt 63 ]]; then - ynh_die --message="Your password must from 8 to 63 characters (WPA2 passphrase)" + ynh_die --message="Your password must have between 8 and 63 characters (WPA2 passphrase)" fi # Check no special characters are present in the passphrase @@ -53,16 +35,6 @@ if [[ $wifi_passphrase =~ [^[:print:]] ]]; then ynh_die --message="Only printable ASCII characters are permitted in your password (WPA2 passphrase)" fi -#================================================= -# STORE SETTINGS FROM MANIFEST -#================================================= -ynh_script_progression --message="Storing installation settings..." - -ynh_app_setting_set --app=$app --key=wifi_ssid --value="$wifi_ssid" -ynh_app_setting_set --app=$app --key=wifi_passphrase --value="$wifi_passphrase" -ynh_app_setting_set --app=$app --key=firmware_nonfree --value="$firmware_nonfree" -ynh_app_setting_set --app=$app --key=service_name --value=$service_name - #================================================= # STANDARD MODIFICATIONS #================================================= @@ -71,6 +43,7 @@ ynh_app_setting_set --app=$app --key=service_name --value=$service_name ynh_script_progression --message="Configuring firewall..." # Update firewall for DHCP +# FIXME : move to manifest.toml ynh_exec_warn_less yunohost firewall allow --no-upnp --ipv6 UDP 547 ynh_exec_warn_less yunohost firewall allow --no-upnp UDP 67 @@ -81,145 +54,119 @@ then /usr/sbin/rfkill unblock wlan fi -#================================================= -# INSTALL NONFREE FIRWARE IF REQUESTED -#================================================= -ynh_script_progression --message="Installing firmware..." - -export DEBIAN_FRONTEND=noninteractive - -# Packaged USB Wireless Device firmwares -# Based on https://wiki.debian.org/WiFi#USB_Devices -if [[ $firmware_nonfree -eq 1 ]]; then - check_armbian_nonfree_conflict - ynh_install_extra_app_dependencies --repo="deb http://deb.debian.org/debian $(ynh_get_debian_release) non-free" --package="$nonfree_firmware_packages" -else - pkg_dependencies="$pkg_dependencies $free_firmware_packages" -fi - -#================================================= -# INSTALL DEPENDENCIES -#================================================= -ynh_script_progression --message="Installing dependencies..." - -ynh_install_app_dependencies $pkg_dependencies - -#================================================= -# CREATE DEDICATED USER -#================================================= -ynh_script_progression --message="Configuring system user..." - -# Create a system user -ynh_system_user_create --username=$app - #================================================= # SPECIFIC SETTINGS #================================================= ynh_script_progression --message="Configuring hotspot..." -if [[ ! -v ip6_net ]]; then # if ip6_net not set - ip6_net="" +ip6_net="" +ip6_dns="" - if [[ -e /tmp/.ynh-vpnclient-started ]]; then - vpnclient_ip6_net=$(ynh_app_setting_get vpnclient ip6_net 2>&1) - - if [[ $vpnclient_ip6_net =~ :: ]]; then - ip6_net=${vpnclient_ip6_net} - fi - fi +ip4_nat_prefix_index=${app##*__} +if [[ "${ip4_nat_prefix_index}" == "${app}" ]]; then + ip4_nat_prefix_index=0 fi +ip4_nat_prefix="10.${ip4_nat_prefix_index}.242" +ip4_dns="${ip4_nat_prefix}.1" hot_reload_usb_wifi_cards -wifi_device=$(iw_devices | awk -F\| '{ print $1 }') +wifi_device=$(unused_iw_devices | head -n 1) +wifi_secure=1 +wifi_channel=6 -ynh_app_setting_set --app=$app --key=multissid --value=1 -ynh_app_setting_set --app=$app --key=ssid_nb --value=1 -ynh_app_setting_set --app=$app --key=wifi_ssid --value="${wifi_ssid}" -ynh_app_setting_set --app=$app --key=wifi_secure --value=1 -ynh_app_setting_set --app=$app --key=wifi_passphrase --value="${wifi_passphrase}" +ynh_app_setting_set --app=$app --key=wifi_secure --value="${wifi_secure}" ynh_app_setting_set --app=$app --key=wifi_device --value="${wifi_device}" -ynh_app_setting_set --app=$app --key=wifi_channel --value=6 +ynh_app_setting_set --app=$app --key=wifi_channel --value="${wifi_channel}" +ynh_app_setting_set --app=$app --key=advanced --value=0 ynh_app_setting_set --app=$app --key=ip6_firewall --value=1 ynh_app_setting_set --app=$app --key=ip6_net --value="${ip6_net}" -ynh_app_setting_set --app=$app --key=dns --value="10.0.242.1" -ynh_app_setting_set --app=$app --key=ip4_nat_prefix --value=10.0.242 +ynh_app_setting_set --app=$app --key=ip6_dns --value="${ip6_dns}" +ynh_app_setting_set --app=$app --key=ip4_dns --value="${ip4_dns}" +ynh_app_setting_set --app=$app --key=ip4_nat_prefix --value="${ip4_nat_prefix}" ynh_app_setting_set --app=$app --key=captive_portal --value=0 ynh_app_setting_set --app=$app --key=captive_portal_url --value="" -if [[ -z $wifi_device ]]; then +if [[ -z "$wifi_device" ]]; then ynh_app_setting_set --app=$app --key=service_enabled --value=0 else ynh_app_setting_set --app=$app --key=service_enabled --value=1 fi +# We must explicitly save the wifi passphrase despite being in the install question +# because password-type questions are not saved automatically +ynh_app_setting_set --app=$app --key=wifi_passphrase --value="$wifi_passphrase" + #================================================= # COPY CONFIGS #================================================= ynh_script_progression --message="Copying configuration files..." -mkdir -pm 0755 /etc/dnsmasq.dhcpd/ -chown root: /etc/dnsmasq.dhcpd/ -mkdir -pm 0755 /etc/hotspot/ -touch /etc/hotspot/allowed.csv -chown -R root: /etc/hotspot/ +mkdir -pm 0755 /etc/hostapd/$app/ +chown root: /etc/hostapd/$app/ -install -b -o root -g root -m 0644 ../conf/hostapd.*.conf /etc/hostapd/ -install -b -o root -g root -m 0644 ../conf/dnsmasq_dhcpdv6.conf.tpl /etc/dnsmasq.dhcpd/dhcpdv6.conf.tpl -install -b -o root -g root -m 0644 ../conf/dnsmasq_dhcpdv4.conf.tpl /etc/dnsmasq.dhcpd/dhcpdv4.conf.tpl +mkdir -pm 0755 /etc/dnsmasq.$app/ +chown root: /etc/dnsmasq.$app/ + +touch /etc/hotspot/allowed.csv # Copy init script -install -o root -g root -m 0755 ../conf/$service_name /usr/local/bin/ -install -o root -g root -m 0755 ../conf/captiveportal_fakedns /usr/local/bin/ -install -o root -g root -m 0755 ../conf/captiveportal_allow /usr/local/bin/ +ynh_add_config --template="../conf/ynh-hotspot" --destination="/usr/local/bin/$service_name" +chmod 0755 "/usr/local/bin/$service_name" + +ynh_add_config --template="../conf/captiveportal_fakedns" --destination="/usr/local/bin/captiveportal_fakedns" +chmod 0755 "/usr/local/bin/captiveportal_fakedns" +ynh_add_config --template="../conf/captiveportal_allow" --destination="/usr/local/bin/captiveportal_allow" +chmod 0755 "/usr/local/bin/captiveportal_allow" + +# Copy openvpn scripts +mkdir -pm 0755 /etc/openvpn/scripts +mkdir -pm 0755 /etc/openvpn/scripts/route-up.d +mkdir -pm 0755 /etc/openvpn/scripts/route-down.d +ynh_add_config --template="../conf/openvpn_90-hotspot" --destination="/etc/openvpn/scripts/route-up.d/90-$service_name" +ynh_add_config --template="../conf/openvpn_90-hotspot" --destination="/etc/openvpn/scripts/route-down.d/90-$service_name" +chmod 0755 "/etc/openvpn/scripts/route-up.d/90-${service_name}" +chmod 0755 "/etc/openvpn/scripts/route-down.d/90-${service_name}" #================================================= # CONFIGURE HOSTAPD #================================================= ynh_script_progression --message="Configuring hostapd..." -## hostapd -ynh_replace_string --match_string="^DAEMON_CONF=$" --replace_string="&/etc/hostapd/hostapd.conf" --target_file=/etc/init.d/hostapd -ynh_store_file_checksum --file="/etc/init.d/hostapd" - -# We also need to put this in /etc/default/hostapd because on some setup -# like RPi, the version of hostapd is different and /etc/init.d/hostapd -# isnt used ... instead the service is "pure systemd" ... -echo "DAEMON_CONF=/etc/hostapd/hostapd.conf" > /etc/default/hostapd - -# Set default inits -# The boot order of these services are important, so they are disabled by default -# and the ynh-hotspot service handles them. +# Disable hostapd, we'll use hostapd@$app instead (for multissid support etc) systemctl disable hostapd --quiet 2>&1 systemctl stop hostapd 2>&1 -systemctl unmask hostapd 2>&1 # On some system e.g. RPi, for some reason hostapd is masked after install ... +systemctl mask hostapd 2>&1 + +if [[ -n "${wifi_device}" ]]; then + configure_hostapd + configure_dhcp +fi #================================================= # SETUP SYSTEMD #================================================= -ynh_script_progression --message="Configuring a systemd service..." +ynh_script_progression --message="Configuring systemd service..." # Create a dedicated systemd config ynh_add_systemd_config --service=$service_name -ynh_add_systemd_config --service=captiveportal_fakedns --template=captiveportal_fakedns -#================================================= -# INTEGRATE SERVICE IN YUNOHOST -#================================================= -ynh_script_progression --message="Integrating service in YunoHost..." +# Create custom systemd config for hostapd to handle multiple wifi devices +ynh_add_systemd_config --service="hostapd@$app" --template="../conf/systemd_hostapd.service" +yunohost service add $service_name --description "Creates a Wi-Fi access point" --test_status "systemctl is-active hostapd@$app" --need_lock -yunohost service add $service_name --description "Creates a Wi-Fi access point" --test_status "systemctl is-active hostapd" +ynh_add_systemd_config --service="captiveportal_fakedns" --template="captiveportal_fakedns" yunohost service add captiveportal_fakedns --description "Captive portal dns service" --test_status "systemctl is-active captiveportal_fakedns" #================================================= # START SYSTEMD SERVICE #================================================= -ynh_script_progression --message="Starting a systemd service..." +ynh_script_progression --message="Starting the hotspot..." # Start a systemd service if device is present if [[ $wifi_device == "" ]]; then - echo "WARNING: Wifi Hotspot is not started because no wifi device was found (please, check the web admin)" >&2 + echo "WARNING: Wifi Hotspot is not started because no wifi device was found (check the Hotspot configuration in the webadmin > Applications > Hotspot > the config panel)" >&2 else - ynh_systemd_action --service_name=$service_name --action="start" --log_path=systemd #--line_match="Started YunoHost Wifi Hotspot" + yunohost service start $service_name fi #================================================= diff --git a/scripts/remove b/scripts/remove index f62daa1..3680307 100644 --- a/scripts/remove +++ b/scripts/remove @@ -9,16 +9,6 @@ source _common.sh source /usr/share/yunohost/helpers -#================================================= -# LOAD SETTINGS -#================================================= -ynh_script_progression --message="Loading installation settings..." - -app=$YNH_APP_INSTANCE_NAME - -firmware_nonfree=$(ynh_app_setting_get --app=$app --key=firmware_nonfree) -service_name=$(ynh_app_setting_get --app=$app --key=service_name) - #================================================= # STANDARD REMOVE #================================================= @@ -26,89 +16,53 @@ service_name=$(ynh_app_setting_get --app=$app --key=service_name) #================================================= # Remove the service from the list of services known by Yunohost (added from `yunohost service add`) -if yunohost service status $service_name >/dev/null 2>&1 -then - ynh_script_progression --message="Removing $app service" - yunohost service stop $service_name - yunohost service remove $service_name -fi -if yunohost service status captiveportal_fakedns >/dev/null 2>&1 -then - ynh_script_progression --message="Removing $app captiveportal_fakedns service" - yunohost service stop captiveportal_fakedns - yunohost service remove captiveportal_fakedns -fi +ynh_script_progression --message="Removing $app service" +yunohost service stop $service_name +yunohost service remove $service_name -#================================================= -# STOP AND REMOVE SERVICE -#================================================= -ynh_script_progression --message="Stopping and removing the systemd service..." +ynh_script_progression --message="Removing $app captiveportal_fakedns service" +yunohost service stop captiveportal_fakedns +yunohost service remove captiveportal_fakedns -# Remove the dedicated systemd config ynh_remove_systemd_config --service=$service_name +ynh_remove_systemd_config --service="hostapd@$app" ynh_remove_systemd_config --service=captiveportal_fakedns -#================================================= -# REMOVE DEPENDENCIES -#================================================= -ynh_script_progression --message="Removing dependencies..." - -# Remove metapackage and its dependencies -ynh_remove_app_dependencies - #================================================= # REMOVE APP MAIN DIR #================================================= -ynh_script_progression --message="Removing app main directory..." +ynh_script_progression --message="Removing $app configurations..." -# Remove the app directory securely +ynh_secure_remove --file="/etc/openvpn/scripts/route-up.d/90-${service_name}" +ynh_secure_remove --file="/etc/openvpn/scripts/route-down.d/90-${service_name}" ynh_secure_remove --file="/usr/local/bin/$service_name" ynh_secure_remove --file="/usr/local/bin/captiveportal_fakedns" ynh_secure_remove --file="/usr/local/bin/captiveportal_allow" ynh_secure_remove --file="/etc/hotspot" -for FILE in $(ls /tmp/.ynh-hotspot-* 2>/dev/null) -do +for FILE in $(ls /tmp/.${service_name}-* 2>/dev/null); do ynh_secure_remove --file="$FILE" done # Remove confs -ynh_secure_remove --file="/etc/dnsmasq.dhcpd/dhcpdv6.conf.tpl" -ynh_secure_remove --file="/etc/dnsmasq.dhcpd/dhcpdv4.conf.tpl" -for FILE in $(ls /etc/hostapd/hostapd.*.conf 2>/dev/null) -do - ynh_secure_remove --file="$FILE" -done +ynh_secure_remove --file="/etc/dnsmasq.d/$app.conf" +systemctl restart dnsmasq + +ynh_secure_remove --file="/etc/dnsmasq.$app/" +ynh_secure_remove --file="/etc/hostapd/$app/" #================================================= # CLOSE A PORT #================================================= -if yunohost firewall list | grep -q "\- 547$" -then - ynh_script_progression --message="Closing port 547" - ynh_exec_warn_less yunohost firewall disallow TCP 547 +if [[ -z "$(other_hotspot_apps)" ]]; then + if yunohost firewall list | grep -q "\- 547$"; then + ynh_script_progression --message="Closing port 547" + ynh_exec_warn_less yunohost firewall disallow TCP 547 + fi + + if yunohost firewall list | grep -q "\- 67$"; then + ynh_script_progression --message="Closing port 67" + ynh_exec_warn_less yunohost firewall disallow TCP 67 + fi fi - - -if yunohost firewall list | grep -q "\- 67$" -then - ynh_script_progression --message="Closing port 67" - ynh_exec_warn_less yunohost firewall disallow TCP 67 -fi - -#================================================= -# GENERIC FINALIZATION -#================================================= -# REMOVE DEDICATED USER -#================================================= -ynh_script_progression --message="Removing the dedicated system user..." - -# Delete a system user -ynh_system_user_delete --username=$app - -#================================================= -# END OF SCRIPT -#================================================= - -ynh_script_progression --message="Removal of $app completed" diff --git a/scripts/restore b/scripts/restore index fb047d1..6a60840 100644 --- a/scripts/restore +++ b/scripts/restore @@ -10,30 +10,22 @@ source ../settings/scripts/_common.sh source /usr/share/yunohost/helpers -#================================================= -# MANAGE SCRIPT FAILURE -#================================================= - -ynh_clean_setup () { - ynh_clean_check_starting -} -# Exit if an error occurs during the execution of the script -ynh_abort_if_errors +if systemctl -q is-enabled hostapd +then + # Disable hostapd, we'll use hostapd@$app instead (for multissid support etc) + systemctl disable hostapd --quiet 2>&1 + systemctl stop hostapd 2>&1 + systemctl mask hostapd 2>&1 +fi #================================================= -# LOAD SETTINGS +# FIND AND OPEN A PORT #================================================= -ynh_script_progression --message="Loading installation settings..." +ynh_script_progression --message="Configuring firewall..." -app=$YNH_APP_INSTANCE_NAME - -firmware_nonfree=$(ynh_app_setting_get --app=$app --key=firmware_nonfree) -service_name=$(ynh_app_setting_get --app=$app --key=service_name) - -#================================================= -# CHECK IF THE APP CAN BE RESTORED -#================================================= -ynh_script_progression --message="Validating restoration parameters..." +# Update firewall for DHCP +ynh_exec_warn_less yunohost firewall allow --no-upnp --ipv6 UDP 547 +ynh_exec_warn_less yunohost firewall allow --no-upnp UDP 67 # Meh idk where to put this ... On RPi, by default wlan is blocked if test -e /usr/sbin/rfkill && rfkill | grep wlan | grep -q -w 'blocked' @@ -45,77 +37,35 @@ fi #================================================= # STANDARD RESTORATION STEPS #================================================= -#================================================= -# RECREATE THE DEDICATED USER -#================================================= -ynh_script_progression --message="Recreating the dedicated system user..." -# Create the dedicated user (if not existing) -ynh_system_user_create --username=$app +ynh_script_progression --message="Restoring configurations ..." +ynh_restore -if [[ $firmware_nonfree -eq 1 ]]; then - check_armbian_nonfree_conflict - ynh_install_extra_app_dependencies --repo="deb http://deb.debian.org/debian $(ynh_get_debian_release) non-free" --package="$nonfree_firmware_packages" -else - pkg_dependencies="$pkg_dependencies $free_firmware_packages" -fi - -for FILE in $(ls /etc/hostapd/hostapd.conf{.tpl?,} 2>/dev/null) -do - ynh_restore_file --origin_path="$FILE" -done -ynh_restore_file --origin_path="/etc/dnsmasq.dhcpd/dhcpdv6.conf.tpl" -ynh_restore_file --origin_path="/etc/dnsmasq.dhcpd/dhcpdv4.conf.tpl" - -ynh_restore_file --origin_path="/usr/local/bin/$service_name" - -ynh_restore_file --origin_path="/etc/init.d/hostapd" - -#================================================= -# SPECIFIC RESTORATION -#================================================= -# REINSTALL DEPENDENCIES -#================================================= -ynh_script_progression --message="Reinstalling dependencies..." - -# Define and install dependencies -ynh_install_app_dependencies $pkg_dependencies - -#================================================= -# RESTORE SYSTEMD -#================================================= -ynh_script_progression --message="Restoring the systemd configuration..." - -ynh_restore_file --origin_path="/etc/systemd/system/$service_name.service" -systemctl enable $service_name.service --quiet - -#================================================= -# INTEGRATE SERVICE IN YUNOHOST -#================================================= -ynh_script_progression --message="Integrating service in YunoHost..." - -yunohost service add $service_name --description "Creates a Wi-Fi access point" --test_status "systemctl is-active hostapd" +yunohost service add "$service_name" --description "Creates a Wi-Fi access point" --test_status "systemctl is-active hostapd@$app" --need_lock #================================================= # START SYSTEMD SERVICE #================================================= -ynh_script_progression --message="Starting a systemd service..." +ynh_script_progression --message="Starting the hotspot service..." hot_reload_usb_wifi_cards -wifi_device=$(iw_devices | awk -F\| '{ print $1 }') +if [[ -z "${wifi_device:-}" ]] || ! grep -q -F "$wifi_device" <(unused_iw_devices); then + wifi_device=$(unused_iw_devices | head -n 1) + ynh_app_setting_set --app=$app --key=wifi_device --value="${wifi_device}" +fi -if [[ -z $wifi_device ]]; then +if [[ -z "${wifi_device:-}" ]]; then ynh_app_setting_set --app=$app --key=service_enabled --value=0 else ynh_app_setting_set --app=$app --key=service_enabled --value=1 fi # Start a systemd service if device is present -if [[ $wifi_device == "" ]]; then +if [[ "${wifi_device:-}" == "" ]]; then echo "WARNING: Wifi Hotspot is not started because no wifi device was found (please, check the web admin)" >&2 else - ynh_systemd_action --service_name=$service_name --action="start" --log_path=systemd #--line_match="Started YunoHost Wifi Hotspot" + yunohost service start $service_name fi #================================================= diff --git a/scripts/upgrade b/scripts/upgrade index 519721e..fb92cc1 100644 --- a/scripts/upgrade +++ b/scripts/upgrade @@ -9,45 +9,15 @@ source _common.sh source /usr/share/yunohost/helpers -#================================================= -# LOAD SETTINGS -#================================================= -ynh_script_progression --message="Loading installation settings..." - -app=$YNH_APP_INSTANCE_NAME - -firmware_nonfree=$(ynh_app_setting_get --app=$app --key=firmware_nonfree) -service_name=$(ynh_app_setting_get --app=$app --key=service_name) - -#================================================= -# CHECK VERSION -#================================================= -ynh_script_progression --message="Checking version..." - upgrade_type=$(ynh_check_app_version_changed) -#================================================= -# BACKUP BEFORE UPGRADE THEN ACTIVE TRAP -#================================================= -ynh_script_progression --message="Backing up the app before upgrading (may take a while)..." - -# Backup the current version of the app -ynh_backup_before_upgrade -ynh_clean_setup () { - # Restore it if the upgrade fails - ynh_restore_upgradebackup -} -# Exit if an error occurs during the execution of the script -ynh_abort_if_errors - #================================================= # STANDARD UPGRADE STEPS #================================================= # STOP SYSTEMD SERVICE #================================================= ynh_script_progression --message="Stopping the hotspot service ... (this may take some time)" - -ynh_systemd_action --service_name=$service_name --action="stop" --log_path=systemd #--line_match="Started YunoHost Wifi Hotspot" +yunohost service stop $service_name #================================================= # ENSURE DOWNWARD COMPATIBILITY @@ -58,24 +28,81 @@ if [ -d /var/www/wifiadmin/ ]; then ynh_secure_remove /var/www/wifiadmin/ fi +if [ -e /etc/dnsmasq.d/$app.conf ]; then + ynh_secure_remove /etc/dnsmasq.d/$app.conf +fi -if [ $firmware_nonfree = "yes" ]; then +if [ ${firmware_nonfree:-} = "yes" ]; then firmware_nonfree=1 ynh_app_setting_set --app=$app --key=firmware_nonfree --value=$firmware_nonfree -elif [ $firmware_nonfree = "no" ]; then +elif [ ${firmware_nonfree:-} = "no" ]; then firmware_nonfree=0 ynh_app_setting_set --app=$app --key=firmware_nonfree --value=$firmware_nonfree fi -if [ -z $service_name ]; then - service_name="ynh-hotspot" +if [ -z ${service_name:-} ]; then + service_name="ynh-$app" ynh_app_setting_set --app=$app --key=service_name --value=$service_name fi +if [[ -n "${multissid:-}" ]] && [[ "${multissid}" -gt 1 ]]; then + wifi_ssid=$(cut -d'|' -f 1 <<< ${wifi_ssid}) + wifi_secure=$(cut -d'|' -f 1 <<< ${wifi_secure}) + wifi_passphrase=$(cut -d'|' -f 1 <<< ${wifi_passphrase}) + advanced=$(cut -d'|' -f 1 <<< ${advanced}) + ip4_nat_prefix=$(cut -d'|' -f 1 <<< ${ip4_nat_prefix}) + ip6_net=$(cut -d'|' -f 1 <<< ${ip6_net}) + ip6_firewall=$(cut -d'|' -f 1 <<< ${ip6_firewall}) + dns=$(cut -d'|' -f 1 <<< ${dns}) + + ynh_app_setting_set --app=$app --key=wifi_ssid --value="${wifi_ssid}" + ynh_app_setting_set --app=$app --key=wifi_secure --value="${wifi_secure}" + ynh_app_setting_set --app=$app --key=wifi_passphrase --value="${wifi_passphrase}" + ynh_app_setting_set --app=$app --key=ip4_nat_prefix --value="${ip4_nat_prefix}" + ynh_app_setting_set --app=$app --key=ip6_net --value="${ip6_net}" + ynh_app_setting_set --app=$app --key=ip6_firewall --value="${ip6_firewall}" +fi + +if [[ -n "${dns:-}" ]]; then + ip6_dns="" + ip4_dns="" + for ip in $(echo "${dns}" | tr ',' ' '); do + if [[ "$ip" == *":"* ]]; then + ip6_dns+="[$ip]," + else + ip4_dns+="$ip," + fi + done + # Remove trailing , + ip6_dns="${ip6_dns%%,}" + ip4_dns="${ip4_dns%%,}" + + if [[ -z "$(ynh_app_setting_get --app=$app --key=ip6_dns)" ]]; then + ynh_app_setting_set --app=$app --key=ip6_dns --value="${ip6_dns}" + fi + if [[ -z "$(ynh_app_setting_get --app=$app --key=ip4_dns)" ]]; then + ynh_app_setting_set --app=$app --key=ip4_dns --value="${ip4_dns}" + fi + + ynh_app_setting_delete $app dns +fi + +if [[ -n "${multissid:-}" ]]; then + ynh_app_setting_delete --app=$app --key=multissid + + ynh_secure_remove --file="/etc/hostapd/hostapd.conf" + ynh_secure_remove --file="/etc/hostapd/hostapd.base.conf" + ynh_secure_remove --file="/etc/hostapd/hostapd.accesspoint.conf" + ynh_secure_remove --file="/etc/dnsmasq.dhcpd/" +fi + +if [[ -z "${advanced:-}" ]]; then + ynh_app_setting_set --app=$app --key=advanced --value=0 +fi + # Old stuff prior to 2.x -ip6_net=$(ynh_app_setting_get --app=$app --key=ip6_net) -if [ "$ip6_net" == "none" ] +if [ "${ip6_net:-}" == "none" ] then ip6_net="" ynh_app_setting_set --app=$app --key=ip6_net --value="$ip6_net" @@ -94,36 +121,22 @@ if [ -d /var/www/$app ]; then ynh_secure_remove /var/www/$app fi -[ -z "$(ynh_app_setting_get $app domain)" ] || ynh_app_setting_delete $app domain -[ -z "$(ynh_app_setting_get $app path)" ] || ynh_app_setting_delete $app path -[ -z "$(ynh_app_setting_get $app final_path)" ] || ynh_app_setting_delete $app final_path +[ -z "${domain:-}" ] || ynh_app_setting_delete $app domain +[ -z "${path:-}" ] || ynh_app_setting_delete $app path +[ -z "${install_dir:-}" ] || ynh_app_setting_delete $app install_dir if [ -e "/etc/sudoers.d/${app}_ynh" ]; then ynh_secure_remove "/etc/sudoers.d/${app}_ynh" fi -#================================================= -# CREATE DEDICATED USER -#================================================= -ynh_script_progression --message="Making sure dedicated system user exists..." - -# Create a dedicated user (if not existing) -ynh_system_user_create --username=$app - -#================================================= -# UPGRADE DEPENDENCIES -#================================================= -ynh_script_progression --message="Upgrading dependencies..." - -if [[ $firmware_nonfree -eq 1 ]]; then - check_armbian_nonfree_conflict - ynh_install_extra_app_dependencies --repo="deb http://deb.debian.org/debian $(ynh_get_debian_release) non-free" --package="$nonfree_firmware_packages" -else - pkg_dependencies="$pkg_dependencies $free_firmware_packages" +if systemctl -q is-enabled hostapd +then + # Disable hostapd, we'll use hostapd@$app instead (for multissid support etc) + systemctl disable hostapd --quiet 2>&1 + systemctl stop hostapd 2>&1 + systemctl mask hostapd 2>&1 fi -ynh_install_app_dependencies $pkg_dependencies - #================================================= # SPECIFIC UPGRADE #================================================= @@ -131,15 +144,40 @@ ynh_install_app_dependencies $pkg_dependencies #================================================= ynh_script_progression --message="Copying configuration..." -mkdir -pm 0755 /etc/dnsmasq.dhcpd/ -chown root: /etc/dnsmasq.dhcpd/ +hot_reload_usb_wifi_cards -install -b -o root -g root -m 0644 ../conf/hostapd.*.conf /etc/hostapd/ -install -b -o root -g root -m 0644 ../conf/dnsmasq_dhcpdv6.conf.tpl /etc/dnsmasq.dhcpd/dhcpdv6.conf.tpl -install -b -o root -g root -m 0644 ../conf/dnsmasq_dhcpdv4.conf.tpl /etc/dnsmasq.dhcpd/dhcpdv4.conf.tpl +if [[ -z "$wifi_device" ]] || ! grep -q -F "$wifi_device" <(unused_iw_devices); then + wifi_device="$(unused_iw_devices | head -n 1)" + ynh_app_setting_set --app=$app --key=wifi_device --value="${wifi_device}" +fi + +mkdir -pm 0755 /etc/hostapd/$app/ +chown root: /etc/hostapd/$app/ + +mkdir -pm 0755 /etc/dnsmasq.$app/ +chown root: /etc/dnsmasq.$app/ + +if [[ -n "${wifi_device:-}" ]]; then + configure_hostapd + configure_dhcp + ynh_app_setting_set --app=$app --key=service_enabled --value=1 +else + ynh_app_setting_set --app=$app --key=service_enabled --value=0 + wifi_device="" +fi # Copy init script -install -o root -g root -m 0755 ../conf/$service_name /usr/local/bin/ +ynh_add_config --template="../conf/ynh-hotspot" --destination="/usr/local/bin/$service_name" +chmod 0755 "/usr/local/bin/$service_name" + +# Copy openvpn scripts +mkdir -pm 0755 /etc/openvpn/scripts +mkdir -pm 0755 /etc/openvpn/scripts/route-up.d +mkdir -pm 0755 /etc/openvpn/scripts/route-down.d +ynh_add_config --template="../conf/openvpn_90-hotspot" --destination="/etc/openvpn/scripts/route-up.d/90-$service_name" +ynh_add_config --template="../conf/openvpn_90-hotspot" --destination="/etc/openvpn/scripts/route-down.d/90-$service_name" +chmod 0755 "/etc/openvpn/scripts/route-up.d/90-${service_name}" +chmod 0755 "/etc/openvpn/scripts/route-down.d/90-${service_name}" #================================================= # SETUP SYSTEMD @@ -148,36 +186,21 @@ ynh_script_progression --message="Upgrading systemd configuration..." # Create a dedicated systemd config ynh_add_systemd_config --service=$service_name +# Create custom systemd config for hostapd to handle multiple wifi devices +ynh_add_systemd_config --service="hostapd@$app" --template="../conf/systemd_hostapd.service" -#================================================= -# GENERIC FINALIZATION -#================================================= -# INTEGRATE SERVICE IN YUNOHOST -#================================================= -ynh_script_progression --message="Integrating service in YunoHost..." - -yunohost service add $service_name --description "Creates a Wi-Fi access point" --test_status "systemctl is-active hostapd" +yunohost service add $service_name --description "Creates a Wi-Fi access point" --test_status "systemctl is-active hostapd@$app" --need_lock #================================================= # START SYSTEMD SERVICE #================================================= ynh_script_progression --message="Starting the hotspot service..." -hot_reload_usb_wifi_cards -wifi_device=$(iw_devices | awk -F\| '{ print $1 }') - -if [[ -z $wifi_device ]]; then - ynh_app_setting_set --app=$app --key=service_enabled --value=0 - wifi_device="" -else - ynh_app_setting_set --app=$app --key=service_enabled --value=1 -fi - # Start a systemd service if device is present if [[ $wifi_device == "" ]]; then - echo "WARNING: Wifi Hotspot is not started because no wifi device was found (please, check the web admin)" >&2 + echo "WARNING: Wifi Hotspot is not started because no wifi device was found (check the Hotspot configuration in the webadmin > Applications > Hotspot > the config panel)" >&2 else - ynh_systemd_action --service_name=$service_name --action="start" --log_path=systemd #--line_match="Started YunoHost Wifi Hotspot" + yunohost service start $service_name fi #================================================= diff --git a/tests.toml b/tests.toml new file mode 100644 index 0000000..f8716c5 --- /dev/null +++ b/tests.toml @@ -0,0 +1,16 @@ +test_format = 1.0 + +[default] + + args.wifi_passphrase = "!abcDEF01234" + args.firmware_nonfree = "no" + + test_upgrade_from.539a1f26.name = "Pre 2.0" + test_upgrade_from.539a1f26.args.domain = "domain.tld" + test_upgrade_from.539a1f26.args.wifi_passphrase = "!abcDEF01234" + +[with_nonfree] + + args.wifi_passphrase = "!abcDEF01234" + args.firmware_nonfree = "yes" + only = ["install.nourl"]