mirror of
https://github.com/lucaspalomodevelop/opnsense-core.git
synced 2026-03-13 00:07:27 +00:00
Compare commits
104 Commits
c48353cdc1
...
3c2ad5d6b3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3c2ad5d6b3 | ||
|
|
a4124d7e99 | ||
|
|
2a935b7afa | ||
|
|
727967ed6d | ||
|
|
3280916191 | ||
|
|
35f46bbb11 | ||
|
|
1c4a9830f9 | ||
|
|
39d5ff1a26 | ||
|
|
e3003959bc | ||
|
|
f5e0735d94 | ||
|
|
b2a6288437 | ||
|
|
bc9f73a562 | ||
|
|
b1a84fc5b9 | ||
|
|
17134aef77 | ||
|
|
2d1c1fcebe | ||
|
|
30343809e9 | ||
|
|
54629f459d | ||
|
|
51dcbcc39e | ||
|
|
5aa8d206e6 | ||
|
|
4ce4450537 | ||
|
|
f31d7a8aa6 | ||
|
|
f30f0f05a0 | ||
|
|
f5352f841e | ||
|
|
0deba9c9de | ||
|
|
f9ea24113a | ||
|
|
a819b91049 | ||
|
|
08a86fdae9 | ||
|
|
bdb3f73315 | ||
|
|
b83cc529eb | ||
|
|
bf14a0a2e3 | ||
|
|
9c50cbfcb8 | ||
|
|
25e5341dd4 | ||
|
|
7beec43db9 | ||
|
|
5636079c16 | ||
|
|
302ed6b037 | ||
|
|
e09112ab45 | ||
|
|
c53dc21190 | ||
|
|
5d0007a023 | ||
|
|
4d20b54aa5 | ||
|
|
1e37f6a7fc | ||
|
|
27fdbd950f | ||
|
|
e72077c376 | ||
|
|
045dec233a | ||
|
|
927bda891f | ||
|
|
4f3db31351 | ||
|
|
6d579db491 | ||
|
|
b87eba3085 | ||
|
|
f30c28ca79 | ||
|
|
25585eb6b9 | ||
|
|
6a89c8968b | ||
|
|
d0f745a70e | ||
|
|
5ad41a236c | ||
|
|
0d6aa56527 | ||
|
|
413f49c3ef | ||
|
|
02e511091d | ||
|
|
4567021437 | ||
|
|
d81b2eec9d | ||
|
|
5a2e399586 | ||
|
|
54fed30cf1 | ||
|
|
d4ddc8def6 | ||
|
|
fb87f688f6 | ||
|
|
25b2716325 | ||
|
|
7e838c6d92 | ||
|
|
6d507b1dd9 | ||
|
|
86ffbd88ad | ||
|
|
0e5a5c3ba2 | ||
|
|
da6fab5bff | ||
|
|
7446f8cbbf | ||
|
|
d0b1c8d369 | ||
|
|
9f7a1fa062 | ||
|
|
8d3d392ae6 | ||
|
|
817e7fb11d | ||
|
|
7b2ad791ee | ||
|
|
983a0663b0 | ||
|
|
09bd2d96cc | ||
|
|
5629911558 | ||
|
|
d240c8b0fa | ||
|
|
c1b1af2ac2 | ||
|
|
0a33697a90 | ||
|
|
ce2abde150 | ||
|
|
d3c5aa22a0 | ||
|
|
e6a4bde0bf | ||
|
|
868a74e058 | ||
|
|
7210f016eb | ||
|
|
905b990dea | ||
|
|
207bddcad5 | ||
|
|
368598eafc | ||
|
|
f90e5445db | ||
|
|
63b9f2e1aa | ||
|
|
dbf37413b9 | ||
|
|
732a393fb7 | ||
|
|
7ec7e1d174 | ||
|
|
97da2221d7 | ||
|
|
ef1c4e07c8 | ||
|
|
adf95bc108 | ||
|
|
25d629fcd3 | ||
|
|
557b793a4e | ||
|
|
04b5749010 | ||
|
|
b55023315c | ||
|
|
4de4bd2774 | ||
|
|
8c609298f3 | ||
|
|
d8adc429f7 | ||
|
|
f698e25cbb | ||
|
|
3f1ed2dff5 |
@ -1,3 +1,25 @@
|
||||
PW=/usr/sbin/pw
|
||||
USER=wwwonly
|
||||
UID=789
|
||||
GROUP=${USER}
|
||||
GID=${UID}
|
||||
|
||||
PW_ARG=add
|
||||
if ${PW} groupshow ${GROUP} >/dev/null 2>&1; then
|
||||
PW_ARG=mod
|
||||
fi
|
||||
|
||||
echo "Creating group '${GROUP}' with gid '${GID}'"
|
||||
${PW} group${PW_ARG} ${GROUP} -g ${GID}
|
||||
|
||||
PW_ARG=add
|
||||
if ${PW} usershow ${USER} >/dev/null 2>&1; then
|
||||
PW_ARG=mod
|
||||
fi
|
||||
|
||||
echo "Creating user '${USER}' with uid '${UID}'"
|
||||
${PW} user${PW_ARG} ${USER} -u ${UID} -g ${GID} -c "World Wide Web Only" -d /nonexistent -s /usr/sbin/nologin
|
||||
|
||||
echo "Updating /etc/shells"
|
||||
cp /etc/shells /etc/shells.bak
|
||||
(grep -v /usr/local/sbin/opnsense-shell /etc/shells.bak; \
|
||||
|
||||
2
LICENSE
2
LICENSE
@ -3,7 +3,7 @@ Copyright (c) 2017 Alexander Shursha <kekek2@ya.ru>
|
||||
Copyright (c) 2004 Bachman Kharazmi
|
||||
Copyright (c) 2005-2008 Bill Marquette <bill.marquette@gmail.com>
|
||||
Copyright (c) 2012 Carlos Cesario <carloscesario@gmail.com>
|
||||
Copyright (c) 2024 Cedrik Pischem
|
||||
Copyright (c) 2024-2025 Cedrik Pischem
|
||||
Copyright (c) 2005-2006 Colin Smith <ethethlay@gmail.com>
|
||||
Copyright (c) 2013 Dagorlad
|
||||
Copyright (c) 2006 Daniel S. Haischt
|
||||
|
||||
86
Scripts/unused-functions.sh
Executable file
86
Scripts/unused-functions.sh
Executable file
@ -0,0 +1,86 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Copyright (c) 2025 Franco Fichtner <franco@opnsense.org>
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
#
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
# SUCH DAMAGE.
|
||||
|
||||
PLUGINS="configure cron devices firewall interfaces run services syslog xmlrpc_sync"
|
||||
|
||||
if [ -n "${1}" ]; then
|
||||
cd "${1}"
|
||||
fi
|
||||
|
||||
TESTDIR=src
|
||||
|
||||
DIRS=${TESTDIR}
|
||||
NOTE="(did not check plugins)"
|
||||
|
||||
if [ -d ../plugins ]; then
|
||||
DIRS="${DIRS} ../plugins"
|
||||
NOTE="(cross-checked plugins)"
|
||||
fi
|
||||
|
||||
grep -Eor '^function &?[^( ]+' ${TESTDIR} | tr ':' ' ' | tr -d '&' | while read FILE X FUNC; do
|
||||
BASEDIR=$(dirname ${FILE})
|
||||
BASEDIR=$(basename ${BASEDIR})
|
||||
MODULE=$(basename ${FILE})
|
||||
MODULE=${MODULE%.inc}
|
||||
|
||||
# exclude indirect plugin calls not otherwise referenced
|
||||
if [ "${BASEDIR}" = "plugins.inc.d" ]; then
|
||||
for PLUGIN in ${PLUGINS}; do
|
||||
if [ "${FUNC}" = "${MODULE}_${PLUGIN}" ]; then
|
||||
continue 2
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# exclude xmlrpc magic
|
||||
if [ "${BASEDIR}" = "xmlrpc" ]; then
|
||||
if [ "${FUNC}" = "xmlrpc_publishable_${MODULE}" ]; then
|
||||
continue 2
|
||||
fi
|
||||
fi
|
||||
|
||||
# exclude obvious and non-obvious ways to call a function
|
||||
USED=$(grep -Fr "${FUNC}" ${DIRS} | grep -F \
|
||||
-e "${FUNC}(" \
|
||||
-e "'${FUNC}'" \
|
||||
-e "'${FUNC}:" \
|
||||
-e "${FUNC}.bind" \
|
||||
-e "${FUNC}.call" \
|
||||
-e ".keyup(${FUNC})" \
|
||||
-e "= ${FUNC};" \
|
||||
| wc -l | awk '{ print $1 }')
|
||||
if [ ${USED} -le 1 ]; then
|
||||
echo "${FUNC}() appears unused" ${NOTE}
|
||||
elif [ ${USED} -eq 2 ]; then
|
||||
# XXX if a match happens in the same file it's probably already considered ;)
|
||||
#echo "${FUNC}() only used once, consider refactor"
|
||||
:
|
||||
else
|
||||
USED=$((USED - 1))
|
||||
#echo "${FUNC}() used ${USED} times"
|
||||
fi
|
||||
done
|
||||
@ -3,17 +3,22 @@
|
||||
# This file is in the public domain, so clarified as of
|
||||
# 2009-05-17 by Arthur David Olson.
|
||||
#
|
||||
# From Paul Eggert (2015-05-02):
|
||||
# From Paul Eggert (2023-09-06):
|
||||
# This file contains a table of two-letter country codes. Columns are
|
||||
# separated by a single tab. Lines beginning with '#' are comments.
|
||||
# All text uses UTF-8 encoding. The columns of the table are as follows:
|
||||
#
|
||||
# 1. ISO 3166-1 alpha-2 country code, current as of
|
||||
# ISO 3166-1 N905 (2016-11-15). See: Updates on ISO 3166-1
|
||||
# http://isotc.iso.org/livelink/livelink/Open/16944257
|
||||
# 2. The usual English name for the coded region,
|
||||
# chosen so that alphabetic sorting of subsets produces helpful lists.
|
||||
# This is not the same as the English name in the ISO 3166 tables.
|
||||
# ISO/TC 46 N1108 (2023-04-05). See: ISO/TC 46 Documents
|
||||
# https://www.iso.org/committee/48750.html?view=documents
|
||||
# 2. The usual English name for the coded region. This sometimes
|
||||
# departs from ISO-listed names, sometimes so that sorted subsets
|
||||
# of names are useful (e.g., "Samoa (American)" and "Samoa
|
||||
# (western)" rather than "American Samoa" and "Samoa"),
|
||||
# sometimes to avoid confusion among non-experts (e.g.,
|
||||
# "Czech Republic" and "Turkey" rather than "Czechia" and "Türkiye"),
|
||||
# and sometimes to omit needless detail or churn (e.g., "Netherlands"
|
||||
# rather than "Netherlands (the)" or "Netherlands (Kingdom of the)").
|
||||
#
|
||||
# The table is sorted by country code.
|
||||
#
|
||||
@ -166,7 +171,7 @@ ME Montenegro
|
||||
MF St Martin (French)
|
||||
MG Madagascar
|
||||
MH Marshall Islands
|
||||
MK Macedonia
|
||||
MK North Macedonia
|
||||
ML Mali
|
||||
MM Myanmar (Burma)
|
||||
MN Mongolia
|
||||
@ -235,10 +240,10 @@ ST Sao Tome & Principe
|
||||
SV El Salvador
|
||||
SX St Maarten (Dutch)
|
||||
SY Syria
|
||||
SZ Swaziland
|
||||
SZ Eswatini (Swaziland)
|
||||
TC Turks & Caicos Is
|
||||
TD Chad
|
||||
TF French Southern & Antarctic Lands
|
||||
TF French S. Terr.
|
||||
TG Togo
|
||||
TH Thailand
|
||||
TJ Tajikistan
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
# This file is in the public domain, so clarified as of
|
||||
# 2009-05-17 by Arthur David Olson.
|
||||
#
|
||||
# From Paul Eggert (2018-06-27):
|
||||
# From Paul Eggert (2021-09-20):
|
||||
# This file is intended as a backward-compatibility aid for older programs.
|
||||
# New programs should use zone1970.tab. This file is like zone1970.tab (see
|
||||
# zone1970.tab's comments), but with the following additional restrictions:
|
||||
@ -16,6 +16,9 @@
|
||||
# clocks have agreed since 1970; this is a narrower definition than
|
||||
# that of zone1970.tab.
|
||||
#
|
||||
# Unlike zone1970.tab, a row's third column can be a Link from
|
||||
# 'backward' instead of a Zone.
|
||||
#
|
||||
# This table is intended as an aid for users, to help them select timezones
|
||||
# appropriate for their practical needs. It is not intended to take or
|
||||
# endorse any position on legal or territorial claims.
|
||||
@ -45,7 +48,7 @@ AR -3124-06411 America/Argentina/Cordoba Argentina (most areas: CB, CC, CN, ER,
|
||||
AR -2447-06525 America/Argentina/Salta Salta (SA, LP, NQ, RN)
|
||||
AR -2411-06518 America/Argentina/Jujuy Jujuy (JY)
|
||||
AR -2649-06513 America/Argentina/Tucuman Tucuman (TM)
|
||||
AR -2828-06547 America/Argentina/Catamarca Catamarca (CT); Chubut (CH)
|
||||
AR -2828-06547 America/Argentina/Catamarca Catamarca (CT), Chubut (CH)
|
||||
AR -2926-06651 America/Argentina/La_Rioja La Rioja (LR)
|
||||
AR -3132-06831 America/Argentina/San_Juan San Juan (SJ)
|
||||
AR -3253-06849 America/Argentina/Mendoza Mendoza (MZ)
|
||||
@ -56,8 +59,7 @@ AS -1416-17042 Pacific/Pago_Pago
|
||||
AT +4813+01620 Europe/Vienna
|
||||
AU -3133+15905 Australia/Lord_Howe Lord Howe Island
|
||||
AU -5430+15857 Antarctica/Macquarie Macquarie Island
|
||||
AU -4253+14719 Australia/Hobart Tasmania (most areas)
|
||||
AU -3956+14352 Australia/Currie Tasmania (King Island)
|
||||
AU -4253+14719 Australia/Hobart Tasmania
|
||||
AU -3749+14458 Australia/Melbourne Victoria
|
||||
AU -3352+15113 Australia/Sydney New South Wales (most areas)
|
||||
AU -3157+14127 Australia/Broken_Hill New South Wales (Yancowinna)
|
||||
@ -85,7 +87,7 @@ BN +0456+11455 Asia/Brunei
|
||||
BO -1630-06809 America/La_Paz
|
||||
BQ +120903-0681636 America/Kralendijk
|
||||
BR -0351-03225 America/Noronha Atlantic islands
|
||||
BR -0127-04829 America/Belem Para (east); Amapa
|
||||
BR -0127-04829 America/Belem Para (east), Amapa
|
||||
BR -0343-03830 America/Fortaleza Brazil (northeast: MA, PI, CE, RN, PB)
|
||||
BR -0803-03454 America/Recife Pernambuco
|
||||
BR -0712-04812 America/Araguaina Tocantins
|
||||
@ -105,34 +107,29 @@ BT +2728+08939 Asia/Thimphu
|
||||
BW -2439+02555 Africa/Gaborone
|
||||
BY +5354+02734 Europe/Minsk
|
||||
BZ +1730-08812 America/Belize
|
||||
CA +4734-05243 America/St_Johns Newfoundland; Labrador (southeast)
|
||||
CA +4439-06336 America/Halifax Atlantic - NS (most areas); PE
|
||||
CA +4734-05243 America/St_Johns Newfoundland, Labrador (SE)
|
||||
CA +4439-06336 America/Halifax Atlantic - NS (most areas), PE
|
||||
CA +4612-05957 America/Glace_Bay Atlantic - NS (Cape Breton)
|
||||
CA +4606-06447 America/Moncton Atlantic - New Brunswick
|
||||
CA +5320-06025 America/Goose_Bay Atlantic - Labrador (most areas)
|
||||
CA +5125-05707 America/Blanc-Sablon AST - QC (Lower North Shore)
|
||||
CA +4339-07923 America/Toronto Eastern - ON, QC (most areas)
|
||||
CA +4901-08816 America/Nipigon Eastern - ON, QC (no DST 1967-73)
|
||||
CA +4823-08915 America/Thunder_Bay Eastern - ON (Thunder Bay)
|
||||
CA +6344-06828 America/Iqaluit Eastern - NU (most east areas)
|
||||
CA +6608-06544 America/Pangnirtung Eastern - NU (Pangnirtung)
|
||||
CA +484531-0913718 America/Atikokan EST - ON (Atikokan); NU (Coral H)
|
||||
CA +4953-09709 America/Winnipeg Central - ON (west); Manitoba
|
||||
CA +4843-09434 America/Rainy_River Central - ON (Rainy R, Ft Frances)
|
||||
CA +4339-07923 America/Toronto Eastern - ON & QC (most areas)
|
||||
CA +6344-06828 America/Iqaluit Eastern - NU (most areas)
|
||||
CA +484531-0913718 America/Atikokan EST - ON (Atikokan), NU (Coral H)
|
||||
CA +4953-09709 America/Winnipeg Central - ON (west), Manitoba
|
||||
CA +744144-0944945 America/Resolute Central - NU (Resolute)
|
||||
CA +624900-0920459 America/Rankin_Inlet Central - NU (central)
|
||||
CA +5024-10439 America/Regina CST - SK (most areas)
|
||||
CA +5017-10750 America/Swift_Current CST - SK (midwest)
|
||||
CA +5333-11328 America/Edmonton Mountain - AB; BC (E); SK (W)
|
||||
CA +5333-11328 America/Edmonton Mountain - AB, BC(E), NT(E), SK(W)
|
||||
CA +690650-1050310 America/Cambridge_Bay Mountain - NU (west)
|
||||
CA +6227-11421 America/Yellowknife Mountain - NT (central)
|
||||
CA +682059-1334300 America/Inuvik Mountain - NT (west)
|
||||
CA +4906-11631 America/Creston MST - BC (Creston)
|
||||
CA +5946-12014 America/Dawson_Creek MST - BC (Dawson Cr, Ft St John)
|
||||
CA +5546-12014 America/Dawson_Creek MST - BC (Dawson Cr, Ft St John)
|
||||
CA +5848-12242 America/Fort_Nelson MST - BC (Ft Nelson)
|
||||
CA +6043-13503 America/Whitehorse MST - Yukon (east)
|
||||
CA +6404-13925 America/Dawson MST - Yukon (west)
|
||||
CA +4916-12307 America/Vancouver Pacific - BC (most areas)
|
||||
CA +6043-13503 America/Whitehorse Pacific - Yukon (south)
|
||||
CA +6404-13925 America/Dawson Pacific - Yukon (north)
|
||||
CC -1210+09655 Indian/Cocos
|
||||
CD -0418+01518 Africa/Kinshasa Dem. Rep. of Congo (west)
|
||||
CD -1140+02728 Africa/Lubumbashi Dem. Rep. of Congo (east)
|
||||
@ -141,7 +138,7 @@ CG -0416+01517 Africa/Brazzaville
|
||||
CH +4723+00832 Europe/Zurich
|
||||
CI +0519-00402 Africa/Abidjan
|
||||
CK -2114-15946 Pacific/Rarotonga
|
||||
CL -3327-07040 America/Santiago Chile (most areas)
|
||||
CL -3327-07040 America/Santiago most of Chile
|
||||
CL -5309-07055 America/Punta_Arenas Region of Magallanes
|
||||
CL -2709-10926 Pacific/Easter Easter Island
|
||||
CM +0403+00942 Africa/Douala
|
||||
@ -153,10 +150,10 @@ CU +2308-08222 America/Havana
|
||||
CV +1455-02331 Atlantic/Cape_Verde
|
||||
CW +1211-06900 America/Curacao
|
||||
CX -1025+10543 Indian/Christmas
|
||||
CY +3510+03322 Asia/Nicosia Cyprus (most areas)
|
||||
CY +3510+03322 Asia/Nicosia most of Cyprus
|
||||
CY +3507+03357 Asia/Famagusta Northern Cyprus
|
||||
CZ +5005+01426 Europe/Prague
|
||||
DE +5230+01322 Europe/Berlin Germany (most areas)
|
||||
DE +5230+01322 Europe/Berlin most of Germany
|
||||
DE +4742+00841 Europe/Busingen Busingen
|
||||
DJ +1136+04309 Africa/Djibouti
|
||||
DK +5540+01235 Europe/Copenhagen
|
||||
@ -189,7 +186,7 @@ GF +0456-05220 America/Cayenne
|
||||
GG +492717-0023210 Europe/Guernsey
|
||||
GH +0533-00013 Africa/Accra
|
||||
GI +3608-00521 Europe/Gibraltar
|
||||
GL +6411-05144 America/Godthab Greenland (most areas)
|
||||
GL +6411-05144 America/Nuuk most of Greenland
|
||||
GL +7646-01840 America/Danmarkshavn National Park (east coast)
|
||||
GL +7029-02158 America/Scoresbysund Scoresbysund/Ittoqqortoormiit
|
||||
GL +7634-06847 America/Thule Thule/Pituffik
|
||||
@ -210,8 +207,8 @@ HT +1832-07220 America/Port-au-Prince
|
||||
HU +4730+01905 Europe/Budapest
|
||||
ID -0610+10648 Asia/Jakarta Java, Sumatra
|
||||
ID -0002+10920 Asia/Pontianak Borneo (west, central)
|
||||
ID -0507+11924 Asia/Makassar Borneo (east, south); Sulawesi/Celebes, Bali, Nusa Tengarra; Timor (west)
|
||||
ID -0232+14042 Asia/Jayapura New Guinea (West Papua / Irian Jaya); Malukus/Moluccas
|
||||
ID -0507+11924 Asia/Makassar Borneo (east, south), Sulawesi/Celebes, Bali, Nusa Tengarra, Timor (west)
|
||||
ID -0232+14042 Asia/Jayapura New Guinea (West Papua / Irian Jaya), Malukus/Moluccas
|
||||
IE +5320-00615 Europe/Dublin
|
||||
IL +314650+0351326 Asia/Jerusalem
|
||||
IM +5409-00428 Europe/Isle_of_Man
|
||||
@ -229,7 +226,7 @@ KE -0117+03649 Africa/Nairobi
|
||||
KG +4254+07436 Asia/Bishkek
|
||||
KH +1133+10455 Asia/Phnom_Penh
|
||||
KI +0125+17300 Pacific/Tarawa Gilbert Islands
|
||||
KI -0308-17105 Pacific/Enderbury Phoenix Islands
|
||||
KI -0247-17143 Pacific/Kanton Phoenix Islands
|
||||
KI +0152-15720 Pacific/Kiritimati Line Islands
|
||||
KM -1141+04316 Indian/Comoro
|
||||
KN +1718-06243 America/St_Kitts
|
||||
@ -237,7 +234,7 @@ KP +3901+12545 Asia/Pyongyang
|
||||
KR +3733+12658 Asia/Seoul
|
||||
KW +2920+04759 Asia/Kuwait
|
||||
KY +1918-08123 America/Cayman
|
||||
KZ +4315+07657 Asia/Almaty Kazakhstan (most areas)
|
||||
KZ +4315+07657 Asia/Almaty most of Kazakhstan
|
||||
KZ +4448+06528 Asia/Qyzylorda Qyzylorda/Kyzylorda/Kzyl-Orda
|
||||
KZ +5312+06337 Asia/Qostanay Qostanay/Kostanay/Kustanay
|
||||
KZ +5017+05710 Asia/Aqtobe Aqtobe/Aktobe
|
||||
@ -261,14 +258,13 @@ MD +4700+02850 Europe/Chisinau
|
||||
ME +4226+01916 Europe/Podgorica
|
||||
MF +1804-06305 America/Marigot
|
||||
MG -1855+04731 Indian/Antananarivo
|
||||
MH +0709+17112 Pacific/Majuro Marshall Islands (most areas)
|
||||
MH +0709+17112 Pacific/Majuro most of Marshall Islands
|
||||
MH +0905+16720 Pacific/Kwajalein Kwajalein
|
||||
MK +4159+02126 Europe/Skopje
|
||||
ML +1239-00800 Africa/Bamako
|
||||
MM +1647+09610 Asia/Yangon
|
||||
MN +4755+10653 Asia/Ulaanbaatar Mongolia (most areas)
|
||||
MN +4801+09139 Asia/Hovd Bayan-Olgiy, Govi-Altai, Hovd, Uvs, Zavkhan
|
||||
MN +4804+11430 Asia/Choibalsan Dornod, Sukhbaatar
|
||||
MN +4755+10653 Asia/Ulaanbaatar most of Mongolia
|
||||
MN +4801+09139 Asia/Hovd Bayan-Olgii, Hovd, Uvs
|
||||
MO +221150+1133230 Asia/Macau
|
||||
MP +1512+14545 Pacific/Saipan
|
||||
MQ +1436-06105 America/Martinique
|
||||
@ -278,17 +274,18 @@ MT +3554+01431 Europe/Malta
|
||||
MU -2010+05730 Indian/Mauritius
|
||||
MV +0410+07330 Indian/Maldives
|
||||
MW -1547+03500 Africa/Blantyre
|
||||
MX +1924-09909 America/Mexico_City Central Time
|
||||
MX +2105-08646 America/Cancun Eastern Standard Time - Quintana Roo
|
||||
MX +2058-08937 America/Merida Central Time - Campeche, Yucatan
|
||||
MX +2540-10019 America/Monterrey Central Time - Durango; Coahuila, Nuevo Leon, Tamaulipas (most areas)
|
||||
MX +2550-09730 America/Matamoros Central Time US - Coahuila, Nuevo Leon, Tamaulipas (US border)
|
||||
MX +2313-10625 America/Mazatlan Mountain Time - Baja California Sur, Nayarit, Sinaloa
|
||||
MX +2838-10605 America/Chihuahua Mountain Time - Chihuahua (most areas)
|
||||
MX +2934-10425 America/Ojinaga Mountain Time US - Chihuahua (US border)
|
||||
MX +2904-11058 America/Hermosillo Mountain Standard Time - Sonora
|
||||
MX +3232-11701 America/Tijuana Pacific Time US - Baja California
|
||||
MX +2048-10515 America/Bahia_Banderas Central Time - Bahia de Banderas
|
||||
MX +1924-09909 America/Mexico_City Central Mexico
|
||||
MX +2105-08646 America/Cancun Quintana Roo
|
||||
MX +2058-08937 America/Merida Campeche, Yucatan
|
||||
MX +2540-10019 America/Monterrey Durango; Coahuila, Nuevo Leon, Tamaulipas (most areas)
|
||||
MX +2550-09730 America/Matamoros Coahuila, Nuevo Leon, Tamaulipas (US border)
|
||||
MX +2838-10605 America/Chihuahua Chihuahua (most areas)
|
||||
MX +3144-10629 America/Ciudad_Juarez Chihuahua (US border - west)
|
||||
MX +2934-10425 America/Ojinaga Chihuahua (US border - east)
|
||||
MX +2313-10625 America/Mazatlan Baja California Sur, Nayarit (most areas), Sinaloa
|
||||
MX +2048-10515 America/Bahia_Banderas Bahia de Banderas
|
||||
MX +2904-11058 America/Hermosillo Sonora
|
||||
MX +3232-11701 America/Tijuana Baja California
|
||||
MY +0310+10142 Asia/Kuala_Lumpur Malaysia (peninsula)
|
||||
MY +0133+11020 Asia/Kuching Sabah, Sarawak
|
||||
MZ -2558+03235 Africa/Maputo
|
||||
@ -303,7 +300,7 @@ NO +5955+01045 Europe/Oslo
|
||||
NP +2743+08519 Asia/Kathmandu
|
||||
NR -0031+16655 Pacific/Nauru
|
||||
NU -1901-16955 Pacific/Niue
|
||||
NZ -3652+17446 Pacific/Auckland New Zealand (most areas)
|
||||
NZ -3652+17446 Pacific/Auckland most of New Zealand
|
||||
NZ -4357-17633 Pacific/Chatham Chatham Islands
|
||||
OM +2336+05835 Asia/Muscat
|
||||
PA +0858-07932 America/Panama
|
||||
@ -311,9 +308,9 @@ PE -1203-07703 America/Lima
|
||||
PF -1732-14934 Pacific/Tahiti Society Islands
|
||||
PF -0900-13930 Pacific/Marquesas Marquesas Islands
|
||||
PF -2308-13457 Pacific/Gambier Gambier Islands
|
||||
PG -0930+14710 Pacific/Port_Moresby Papua New Guinea (most areas)
|
||||
PG -0930+14710 Pacific/Port_Moresby most of Papua New Guinea
|
||||
PG -0613+15534 Pacific/Bougainville Bougainville
|
||||
PH +1435+12100 Asia/Manila
|
||||
PH +143512+1205804 Asia/Manila
|
||||
PK +2452+06703 Asia/Karachi
|
||||
PL +5215+02100 Europe/Warsaw
|
||||
PM +4703-05620 America/Miquelon
|
||||
@ -332,10 +329,13 @@ RO +4426+02606 Europe/Bucharest
|
||||
RS +4450+02030 Europe/Belgrade
|
||||
RU +5443+02030 Europe/Kaliningrad MSK-01 - Kaliningrad
|
||||
RU +554521+0373704 Europe/Moscow MSK+00 - Moscow area
|
||||
RU +4457+03406 Europe/Simferopol MSK+00 - Crimea
|
||||
# The obsolescent zone.tab format cannot represent Europe/Simferopol well.
|
||||
# Put it in RU section and list as UA. See "territorial claims" above.
|
||||
# Programs should use zone1970.tab instead; see above.
|
||||
UA +4457+03406 Europe/Simferopol Crimea
|
||||
RU +5836+04939 Europe/Kirov MSK+00 - Kirov
|
||||
RU +4844+04425 Europe/Volgograd MSK+00 - Volgograd
|
||||
RU +4621+04803 Europe/Astrakhan MSK+01 - Astrakhan
|
||||
RU +4844+04425 Europe/Volgograd MSK+01 - Volgograd
|
||||
RU +5134+04602 Europe/Saratov MSK+01 - Saratov
|
||||
RU +5420+04824 Europe/Ulyanovsk MSK+01 - Ulyanovsk
|
||||
RU +5312+05009 Europe/Samara MSK+01 - Samara, Udmurtia
|
||||
@ -354,7 +354,7 @@ RU +4310+13156 Asia/Vladivostok MSK+07 - Amur River
|
||||
RU +643337+1431336 Asia/Ust-Nera MSK+07 - Oymyakonsky
|
||||
RU +5934+15048 Asia/Magadan MSK+08 - Magadan
|
||||
RU +4658+14242 Asia/Sakhalin MSK+08 - Sakhalin Island
|
||||
RU +6728+15343 Asia/Srednekolymsk MSK+08 - Sakha (E); North Kuril Is
|
||||
RU +6728+15343 Asia/Srednekolymsk MSK+08 - Sakha (E), N Kuril Is
|
||||
RU +5301+15839 Asia/Kamchatka MSK+09 - Kamchatka
|
||||
RU +6445+17729 Asia/Anadyr MSK+09 - Bering Sea
|
||||
RW -0157+03004 Africa/Kigali
|
||||
@ -389,15 +389,13 @@ TK -0922-17114 Pacific/Fakaofo
|
||||
TL -0833+12535 Asia/Dili
|
||||
TM +3757+05823 Asia/Ashgabat
|
||||
TN +3648+01011 Africa/Tunis
|
||||
TO -2110-17510 Pacific/Tongatapu
|
||||
TO -210800-1751200 Pacific/Tongatapu
|
||||
TR +4101+02858 Europe/Istanbul
|
||||
TT +1039-06131 America/Port_of_Spain
|
||||
TV -0831+17913 Pacific/Funafuti
|
||||
TW +2503+12130 Asia/Taipei
|
||||
TZ -0648+03917 Africa/Dar_es_Salaam
|
||||
UA +5026+03031 Europe/Kiev Ukraine (most areas)
|
||||
UA +4837+02218 Europe/Uzhgorod Ruthenia
|
||||
UA +4750+03510 Europe/Zaporozhye Zaporozh'ye/Zaporizhia; Lugansk/Luhansk (east)
|
||||
UA +5026+03031 Europe/Kyiv most of Ukraine
|
||||
UG +0019+03225 Africa/Kampala
|
||||
UM +2813-17722 Pacific/Midway Midway Islands
|
||||
UM +1917+16637 Pacific/Wake Wake Island
|
||||
@ -419,8 +417,8 @@ US +470659-1011757 America/North_Dakota/Center Central - ND (Oliver)
|
||||
US +465042-1012439 America/North_Dakota/New_Salem Central - ND (Morton rural)
|
||||
US +471551-1014640 America/North_Dakota/Beulah Central - ND (Mercer)
|
||||
US +394421-1045903 America/Denver Mountain (most areas)
|
||||
US +433649-1161209 America/Boise Mountain - ID (south); OR (east)
|
||||
US +332654-1120424 America/Phoenix MST - Arizona (except Navajo)
|
||||
US +433649-1161209 America/Boise Mountain - ID (south), OR (east)
|
||||
US +332654-1120424 America/Phoenix MST - AZ (except Navajo)
|
||||
US +340308-1181434 America/Los_Angeles Pacific
|
||||
US +611305-1495401 America/Anchorage Alaska (most areas)
|
||||
US +581807-1342511 America/Juneau Alaska - Juneau area
|
||||
@ -428,7 +426,7 @@ US +571035-1351807 America/Sitka Alaska - Sitka area
|
||||
US +550737-1313435 America/Metlakatla Alaska - Annette Island
|
||||
US +593249-1394338 America/Yakutat Alaska - Yakutat
|
||||
US +643004-1652423 America/Nome Alaska (west)
|
||||
US +515248-1763929 America/Adak Aleutian Islands
|
||||
US +515248-1763929 America/Adak Alaska - western Aleutians
|
||||
US +211825-1575130 Pacific/Honolulu Hawaii
|
||||
UY -345433-0561245 America/Montevideo
|
||||
UZ +3940+06648 Asia/Samarkand Uzbekistan (west)
|
||||
|
||||
22
plist
22
plist
@ -155,6 +155,7 @@
|
||||
/usr/local/etc/rc.syshook.d/upgrade/20-unbound-duckdb.py
|
||||
/usr/local/etc/rc.syshook.d/upgrade/90-cleanup.sh
|
||||
/usr/local/etc/ssh/sshd_config.d/README
|
||||
/usr/local/etc/ssl/ext_sources/README
|
||||
/usr/local/etc/ssl/opnsense.cnf
|
||||
/usr/local/etc/strongswan.opnsense.d/README
|
||||
/usr/local/etc/unbound.opnsense.d/README
|
||||
@ -285,7 +286,6 @@
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/Dnsmasq/LeasesController.php
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/Dnsmasq/SettingsController.php
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/Dnsmasq/forms/dialogDHCPboot.xml
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/Dnsmasq/forms/dialogDHCPmatch.xml
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/Dnsmasq/forms/dialogDHCPoption.xml
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/Dnsmasq/forms/dialogDHCPrange.xml
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/Dnsmasq/forms/dialogDHCPtag.xml
|
||||
@ -360,6 +360,7 @@
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/IPsec/forms/dialogSPD.xml
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/IPsec/forms/dialogVTI.xml
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/IPsec/forms/settings.xml
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/Interfaces/Api/BridgeSettingsController.php
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/Interfaces/Api/GifSettingsController.php
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/Interfaces/Api/GreSettingsController.php
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/Interfaces/Api/LaggSettingsController.php
|
||||
@ -369,6 +370,7 @@
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/Interfaces/Api/VipSettingsController.php
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/Interfaces/Api/VlanSettingsController.php
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/Interfaces/Api/VxlanSettingsController.php
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/Interfaces/BridgeController.php
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/Interfaces/GifController.php
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/Interfaces/GreController.php
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/Interfaces/LaggController.php
|
||||
@ -378,6 +380,7 @@
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/Interfaces/VipController.php
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/Interfaces/VlanController.php
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/Interfaces/VxlanController.php
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/Interfaces/forms/dialogBridge.xml
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/Interfaces/forms/dialogGif.xml
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/Interfaces/forms/dialogGre.xml
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/Interfaces/forms/dialogLagg.xml
|
||||
@ -388,14 +391,20 @@
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/Interfaces/forms/dialogVxlan.xml
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/Kea/Api/CtrlAgentController.php
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/Kea/Api/Dhcpv4Controller.php
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/Kea/Api/Dhcpv6Controller.php
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/Kea/Api/Leases4Controller.php
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/Kea/Api/ServiceController.php
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/Kea/DhcpController.php
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/Kea/forms/agentSettings.xml
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/Kea/forms/dialogPDPool6.xml
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/Kea/forms/dialogPeer4.xml
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/Kea/forms/dialogPeer6.xml
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/Kea/forms/dialogReservation4.xml
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/Kea/forms/dialogReservation6.xml
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/Kea/forms/dialogSubnet4.xml
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/Kea/forms/dialogSubnet6.xml
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/Kea/forms/generalSettings4.xml
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/Kea/forms/generalSettings6.xml
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/Monit/Api/ServiceController.php
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/Monit/Api/SettingsController.php
|
||||
/usr/local/opnsense/mvc/app/controllers/OPNsense/Monit/Api/StatusController.php
|
||||
@ -752,6 +761,9 @@
|
||||
/usr/local/opnsense/mvc/app/models/OPNsense/IPsec/Swanctl.php
|
||||
/usr/local/opnsense/mvc/app/models/OPNsense/IPsec/Swanctl.xml
|
||||
/usr/local/opnsense/mvc/app/models/OPNsense/Interfaces/ACL/ACL.xml
|
||||
/usr/local/opnsense/mvc/app/models/OPNsense/Interfaces/Bridge.php
|
||||
/usr/local/opnsense/mvc/app/models/OPNsense/Interfaces/Bridge.xml
|
||||
/usr/local/opnsense/mvc/app/models/OPNsense/Interfaces/FieldTypes/BridgeMemberField.php
|
||||
/usr/local/opnsense/mvc/app/models/OPNsense/Interfaces/FieldTypes/LaggInterfaceField.php
|
||||
/usr/local/opnsense/mvc/app/models/OPNsense/Interfaces/FieldTypes/LinkAddressField.php
|
||||
/usr/local/opnsense/mvc/app/models/OPNsense/Interfaces/FieldTypes/NeighborField.php
|
||||
@ -783,6 +795,8 @@
|
||||
/usr/local/opnsense/mvc/app/models/OPNsense/Kea/KeaCtrlAgent.xml
|
||||
/usr/local/opnsense/mvc/app/models/OPNsense/Kea/KeaDhcpv4.php
|
||||
/usr/local/opnsense/mvc/app/models/OPNsense/Kea/KeaDhcpv4.xml
|
||||
/usr/local/opnsense/mvc/app/models/OPNsense/Kea/KeaDhcpv6.php
|
||||
/usr/local/opnsense/mvc/app/models/OPNsense/Kea/KeaDhcpv6.xml
|
||||
/usr/local/opnsense/mvc/app/models/OPNsense/Kea/Menu/Menu.xml
|
||||
/usr/local/opnsense/mvc/app/models/OPNsense/Monit/ACL/ACL.xml
|
||||
/usr/local/opnsense/mvc/app/models/OPNsense/Monit/Menu/Menu.xml
|
||||
@ -915,6 +929,7 @@
|
||||
/usr/local/opnsense/mvc/app/views/OPNsense/IPsec/spd.volt
|
||||
/usr/local/opnsense/mvc/app/views/OPNsense/IPsec/tunnels.volt
|
||||
/usr/local/opnsense/mvc/app/views/OPNsense/IPsec/vti.volt
|
||||
/usr/local/opnsense/mvc/app/views/OPNsense/Interface/bridge.volt
|
||||
/usr/local/opnsense/mvc/app/views/OPNsense/Interface/gif.volt
|
||||
/usr/local/opnsense/mvc/app/views/OPNsense/Interface/gre.volt
|
||||
/usr/local/opnsense/mvc/app/views/OPNsense/Interface/lagg.volt
|
||||
@ -926,6 +941,7 @@
|
||||
/usr/local/opnsense/mvc/app/views/OPNsense/Interface/vxlan.volt
|
||||
/usr/local/opnsense/mvc/app/views/OPNsense/Kea/ctrl_agent.volt
|
||||
/usr/local/opnsense/mvc/app/views/OPNsense/Kea/dhcpv4.volt
|
||||
/usr/local/opnsense/mvc/app/views/OPNsense/Kea/dhcpv6.volt
|
||||
/usr/local/opnsense/mvc/app/views/OPNsense/Kea/leases4.volt
|
||||
/usr/local/opnsense/mvc/app/views/OPNsense/Monit/index.volt
|
||||
/usr/local/opnsense/mvc/app/views/OPNsense/Monit/status.volt
|
||||
@ -1175,6 +1191,7 @@
|
||||
/usr/local/opnsense/scripts/interfaces/ppp-linkup.sh
|
||||
/usr/local/opnsense/scripts/interfaces/ppp-rename.sh
|
||||
/usr/local/opnsense/scripts/interfaces/ppp-uptime.sh
|
||||
/usr/local/opnsense/scripts/interfaces/reconfigure_bridges.php
|
||||
/usr/local/opnsense/scripts/interfaces/reconfigure_gifs.php
|
||||
/usr/local/opnsense/scripts/interfaces/reconfigure_gres.php
|
||||
/usr/local/opnsense/scripts/interfaces/reconfigure_laggs.php
|
||||
@ -1270,6 +1287,7 @@
|
||||
/usr/local/opnsense/scripts/syslog/streamLog.py
|
||||
/usr/local/opnsense/scripts/system/activity.py
|
||||
/usr/local/opnsense/scripts/system/bectl.py
|
||||
/usr/local/opnsense/scripts/system/cert_fetch_local.py
|
||||
/usr/local/opnsense/scripts/system/certctl.py
|
||||
/usr/local/opnsense/scripts/system/cpu.py
|
||||
/usr/local/opnsense/scripts/system/crl_fetch.py
|
||||
@ -2403,8 +2421,6 @@
|
||||
/usr/local/www/index.php
|
||||
/usr/local/www/interfaces.php
|
||||
/usr/local/www/interfaces_assign.php
|
||||
/usr/local/www/interfaces_bridge.php
|
||||
/usr/local/www/interfaces_bridge_edit.php
|
||||
/usr/local/www/interfaces_ppps.php
|
||||
/usr/local/www/interfaces_ppps_edit.php
|
||||
/usr/local/www/interfaces_wireless.php
|
||||
|
||||
@ -81,9 +81,6 @@
|
||||
<track6-prefix-id>0</track6-prefix-id>
|
||||
</lan>
|
||||
</interfaces>
|
||||
<unbound>
|
||||
<enable>1</enable>
|
||||
</unbound>
|
||||
<dnsmasq>
|
||||
<enable>1</enable>
|
||||
<port>0</port>
|
||||
@ -94,6 +91,9 @@
|
||||
<end_addr>192.168.1.199</end_addr>
|
||||
</dhcp_ranges>
|
||||
</dnsmasq>
|
||||
<unbound>
|
||||
<enable>1</enable>
|
||||
</unbound>
|
||||
<snmpd>
|
||||
<syslocation/>
|
||||
<syscontact/>
|
||||
|
||||
@ -49,15 +49,11 @@ $userindex = index_users();
|
||||
*/
|
||||
function isAuthLocalIP($http_host)
|
||||
{
|
||||
global $config;
|
||||
|
||||
if (isset($config['virtualip']['vip'])) {
|
||||
foreach ($config['virtualip']['vip'] as $vip) {
|
||||
foreach (config_read_array('virtualip', 'vip') as $vip) {
|
||||
if ($vip['subnet'] == $http_host) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$address_in_list = function ($interface_list_ips, $http_host) {
|
||||
foreach ($interface_list_ips as $ilips => $ifname) {
|
||||
|
||||
@ -107,6 +107,9 @@ function ca_chain_array(&$cert)
|
||||
$crt = false;
|
||||
}
|
||||
if ($crt) {
|
||||
if (in_array($crt, $chain)) {
|
||||
break; /* exit endless loop */
|
||||
}
|
||||
$chain[] = $crt;
|
||||
}
|
||||
}
|
||||
@ -192,25 +195,6 @@ function cert_get_subject($str_crt, $decode = true)
|
||||
return certs_build_name($components);
|
||||
}
|
||||
|
||||
function cert_get_subject_array($crt)
|
||||
{
|
||||
$str_crt = base64_decode($crt);
|
||||
$inf_crt = openssl_x509_parse($str_crt);
|
||||
$components = $inf_crt['subject'];
|
||||
|
||||
if (!is_array($components)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$subject_array = array();
|
||||
|
||||
foreach ($components as $a => $v) {
|
||||
$subject_array[] = array('a' => $a, 'v' => $v);
|
||||
}
|
||||
|
||||
return $subject_array;
|
||||
}
|
||||
|
||||
function cert_get_issuer($str_crt, $decode = true)
|
||||
{
|
||||
if ($decode) {
|
||||
|
||||
@ -256,25 +256,6 @@ function write_config($desc = '', $backup = true)
|
||||
return $config;
|
||||
}
|
||||
|
||||
function config_restore($conffile)
|
||||
{
|
||||
global $config;
|
||||
|
||||
if (!file_exists($conffile)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
$cnf = OPNsense\Core\Config::getInstance();
|
||||
$cnf->backup();
|
||||
$cnf->restoreBackup($conffile);
|
||||
|
||||
$config = parse_config();
|
||||
|
||||
write_config(sprintf('Reverted to %s', array_pop(explode('/', $conffile))), false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
function &config_read_array()
|
||||
{
|
||||
global $config;
|
||||
|
||||
@ -205,122 +205,106 @@ function interfaces_bridge_configure($device)
|
||||
return null;
|
||||
}
|
||||
|
||||
function _interfaces_bridge_configure($bridge)
|
||||
function _interfaces_bridge_configure($bridge, $ifconfig_details = null)
|
||||
{
|
||||
$ret = $bridge['bridgeif'];
|
||||
$bridgeif = $bridge['bridgeif'];
|
||||
|
||||
/* XXX avoid destroy/create */
|
||||
legacy_interface_destroy($bridge['bridgeif']);
|
||||
legacy_interface_create($bridge['bridgeif']);
|
||||
if (empty($ifconfig_details)) {
|
||||
$ifconfig_details = legacy_interfaces_details();
|
||||
}
|
||||
$this_if = !empty($ifconfig_details[$bridgeif]) ? $ifconfig_details[$bridgeif] : [];
|
||||
|
||||
$checklist = get_configured_interface_with_descr();
|
||||
$members = [];
|
||||
if (empty($ifconfig_details[$bridgeif]) && empty(legacy_interface_create($bridgeif))) {
|
||||
/* not found, unable to create. errors are logged inside legacy_interface_create() */
|
||||
return null;
|
||||
}
|
||||
|
||||
/* find all required members */
|
||||
$members = [];
|
||||
foreach (explode(',', $bridge['members'] ?? '') as $member) {
|
||||
if (empty($checklist[$member])) {
|
||||
/* ignores disabled ones */
|
||||
continue;
|
||||
}
|
||||
|
||||
$device = get_real_interface($member);
|
||||
if (!does_interface_exist($device)) {
|
||||
log_msg("Device {$bridge['bridgeif']} cannot attach non-existent member {$device}, skipping now.");
|
||||
/* continue but mark this as failed for caller so they could retry */
|
||||
$ret = null;
|
||||
if (empty($ifconfig_details[$device])) {
|
||||
log_msg("Device {$bridgeif} cannot attach non-existent member {$device}, skipping now.");
|
||||
continue;
|
||||
}
|
||||
|
||||
$members[$member] = $device;
|
||||
}
|
||||
|
||||
/* calculate smaller mtu and enforce it */
|
||||
$mtu = null;
|
||||
foreach ($members as $member => $device) {
|
||||
$opts = legacy_interface_stats($device);
|
||||
if (!empty($opts['mtu']) && ($mtu == null || $opts['mtu'] < $mtu)) {
|
||||
$mtu = $opts['mtu'];
|
||||
if (
|
||||
empty($this_if) || empty($this_if['nd6']) ||
|
||||
in_array('AUTO_LINKLOCAL', $this_if['nd6']['flags']) != !empty($bridge['linklocal'])
|
||||
) {
|
||||
mwexecf('/sbin/ifconfig %s inet6 %sauto_linklocal', [$bridgeif, !empty($bridge['linklocal']) ? '' : '-']);
|
||||
}
|
||||
}
|
||||
|
||||
mwexecf('/sbin/ifconfig %s inet6 %sauto_linklocal', [$bridge['bridgeif'], isset($bridge['linklocal']) ? '' : '-']);
|
||||
|
||||
/* add member interfaces to bridge */
|
||||
$current_members = !empty($this_if['members']) ? $this_if['members'] : [];
|
||||
foreach ($members as $member => $device) {
|
||||
configure_interface_hardware($device);
|
||||
legacy_interface_mtu($device, $mtu);
|
||||
if (empty($current_members[$device])) {
|
||||
configure_interface_hardware($device, $ifconfig_details);
|
||||
legacy_interface_flags($device, 'up');
|
||||
legacy_bridge_member($bridge['bridgeif'], $device);
|
||||
}
|
||||
|
||||
if (isset($bridge['enablestp'])) {
|
||||
mwexecf('/sbin/ifconfig %s proto %s', [$bridge['bridgeif'], $bridge['proto']]);
|
||||
if (!empty($bridge['stp'])) {
|
||||
foreach (explode(',', $bridge['stp']) as $stpif) {
|
||||
mwexecf('/sbin/ifconfig %s stp %s', [$bridge['bridgeif'], get_real_interface($stpif)]);
|
||||
}
|
||||
}
|
||||
if (!empty($bridge['maxage'])) {
|
||||
mwexec("/sbin/ifconfig {$bridge['bridgeif']} maxage " . escapeshellarg($bridge['maxage']));
|
||||
}
|
||||
if (!empty($bridge['fwdelay'])) {
|
||||
mwexec("/sbin/ifconfig {$bridge['bridgeif']} fwddelay " . escapeshellarg($bridge['fwdelay']));
|
||||
}
|
||||
if (!empty($bridge['holdcnt'])) {
|
||||
mwexec("/sbin/ifconfig {$bridge['bridgeif']} holdcnt " . escapeshellarg($bridge['holdcnt']));
|
||||
legacy_bridge_member($bridgeif, $device);
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($bridge['maxaddr'])) {
|
||||
mwexec("/sbin/ifconfig {$bridge['bridgeif']} maxaddr " . escapeshellarg($bridge['maxaddr']));
|
||||
}
|
||||
if (!empty($bridge['timeout'])) {
|
||||
mwexec("/sbin/ifconfig {$bridge['bridgeif']} timeout " . escapeshellarg($bridge['timeout']));
|
||||
}
|
||||
if (!empty($bridge['span'])) {
|
||||
$realif = get_real_interface($bridge['span']);
|
||||
mwexec("/sbin/ifconfig {$bridge['bridgeif']} span {$realif}");
|
||||
}
|
||||
if (!empty($bridge['edge'])) {
|
||||
foreach (explode(',', $bridge['edge']) as $edgeif) {
|
||||
$realif = get_real_interface($edgeif);
|
||||
mwexec("/sbin/ifconfig {$bridge['bridgeif']} edge {$realif}");
|
||||
}
|
||||
}
|
||||
if (!empty($bridge['autoedge'])) {
|
||||
foreach (explode(',', $bridge['autoedge']) as $edgeif) {
|
||||
$realif = get_real_interface($edgeif);
|
||||
mwexec("/sbin/ifconfig {$bridge['bridgeif']} -autoedge {$realif}");
|
||||
}
|
||||
}
|
||||
if (!empty($bridge['ptp'])) {
|
||||
foreach (explode(',', $bridge['ptp']) as $ptpif) {
|
||||
$realif = get_real_interface($ptpif);
|
||||
mwexec("/sbin/ifconfig {$bridge['bridgeif']} ptp {$realif}");
|
||||
}
|
||||
}
|
||||
if (!empty($bridge['autoptp'])) {
|
||||
foreach (explode(',', $bridge['autoptp']) as $ptpif) {
|
||||
$realif = get_real_interface($ptpif);
|
||||
mwexec("/sbin/ifconfig {$bridge['bridgeif']} -autoptp {$realif}");
|
||||
}
|
||||
}
|
||||
if (!empty($bridge['static'])) {
|
||||
foreach (explode(',', $bridge['static']) as $stickyif) {
|
||||
$realif = get_real_interface($stickyif);
|
||||
mwexec("/sbin/ifconfig {$bridge['bridgeif']} sticky {$realif}");
|
||||
}
|
||||
}
|
||||
if (!empty($bridge['private'])) {
|
||||
foreach (explode(',', $bridge['private']) as $privateif) {
|
||||
$realif = get_real_interface($privateif);
|
||||
mwexec("/sbin/ifconfig {$bridge['bridgeif']} private {$realif}");
|
||||
/* remove unassigned members */
|
||||
foreach (array_keys($current_members) as $device) {
|
||||
if (!in_array($device, $members)) {
|
||||
mwexecf('/sbin/ifconfig %s deletem %s', [$bridgeif, $device]);
|
||||
}
|
||||
}
|
||||
|
||||
legacy_interface_flags($bridge['bridgeif'], 'up');
|
||||
/* compare and apply requested flags */
|
||||
foreach (['stp', 'edge', 'autoedge', 'ptp', 'autoptp', 'static', 'private', 'span'] as $section) {
|
||||
$section_members = explode(',', $bridge[$section] ?? '');
|
||||
foreach ($members as $member => $device) {
|
||||
$flag = $section == 'static' ? 'sticky' : $section;
|
||||
if (
|
||||
str_starts_with($section, 'auto') && (
|
||||
!isset($current_members[$device]) ||
|
||||
in_array($flag, $current_members[$device]['flags']) == in_array($member, $section_members)
|
||||
)
|
||||
) {
|
||||
/* in list equals off for tags starting with "auto" */
|
||||
mwexecf(sprintf(
|
||||
"/sbin/ifconfig %s %s %s",
|
||||
$bridgeif,
|
||||
(in_array($member, $section_members) ? '-' : '') . $flag,
|
||||
$device
|
||||
));
|
||||
} elseif (
|
||||
!str_starts_with($section, 'auto') && (
|
||||
!isset($current_members[$device]) ||
|
||||
in_array($flag, $current_members[$device]['flags']) != in_array($member, $section_members)
|
||||
)
|
||||
) {
|
||||
mwexecf(sprintf(
|
||||
"/sbin/ifconfig %s %s %s",
|
||||
$bridgeif,
|
||||
(!in_array($member, $section_members) ? '-' : '') . $flag,
|
||||
$device
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $ret;
|
||||
/* update changed bridge properties */
|
||||
foreach (['maxage', 'fwddelay', 'holdcnt', 'maxaddr', 'timeout', 'proto'] as $prop) {
|
||||
if (!empty($bridge[$prop]) && (empty($this_if[$prop]) || $this_if[$prop] != $bridge[$prop])) {
|
||||
mwexecf(sprintf(
|
||||
"/sbin/ifconfig %s %s %s",
|
||||
$bridgeif,
|
||||
$prop,
|
||||
$bridge[$prop]
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($this_if['flags']) || !in_array('up', $this_if['flags'])) {
|
||||
legacy_interface_flags($bridgeif, 'up');
|
||||
}
|
||||
|
||||
return $bridgeif;
|
||||
}
|
||||
|
||||
function interfaces_lagg_configure($verbose = false)
|
||||
@ -3325,9 +3309,9 @@ function DHCP_Config_File_Advanced($interface, $wancfg, $wanif)
|
||||
|
||||
$option_modifiers = "";
|
||||
if ($wancfg['adv_dhcp_option_modifiers'] != '') {
|
||||
$modifiers = preg_split('/\s*,\s*(?=(?:[^"]*"[^"]*")*[^"]*$)/', $wancfg['adv_dhcp_option_modifiers']);
|
||||
$modifiers = preg_split('/\s*(?<!\\\),\s*(?=(?:[^"]*"[^"]*")*[^"]*$)/', $wancfg['adv_dhcp_option_modifiers']);
|
||||
foreach ($modifiers as $modifier) {
|
||||
$option_modifiers .= "\t" . $modifier . ";\n";
|
||||
$option_modifiers .= "\t" . str_replace('\,', ',', $modifier) . ";\n";
|
||||
}
|
||||
}
|
||||
|
||||
@ -3679,18 +3663,14 @@ function link_interface_to_bridge($interface, $attach_device = null, $ifconfig_d
|
||||
|
||||
function link_interface_to_gre($interface, $update = false, $family = null)
|
||||
{
|
||||
global $config;
|
||||
|
||||
$aliaslist = get_configured_ip_aliases_list();
|
||||
$result = [];
|
||||
|
||||
if (isset($config['gres']['gre'])) {
|
||||
foreach ($config['gres']['gre'] as $gre) {
|
||||
foreach (config_read_array('gres', 'gre') as $gre) {
|
||||
$parent = explode('_vip', $gre['if'])[0];
|
||||
if (is_ipaddr($parent)) {
|
||||
foreach ($aliaslist as $ip => $int) {
|
||||
if ($ip == $parent) {
|
||||
$parent = $int;
|
||||
foreach (config_read_array('virtualip', 'vip') as $vip) {
|
||||
if ($vip['mode'] == 'ipalias' && $vip['subnet'] == $parent) {
|
||||
$parent = $vip['interface'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -3712,19 +3692,15 @@ function link_interface_to_gre($interface, $update = false, $family = null)
|
||||
/* callers are only concerned with the resulting device names */
|
||||
$result[] = $gre['greif'];
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
function link_interface_to_gif($interface, $update = false, $family = null)
|
||||
{
|
||||
global $config;
|
||||
|
||||
$result = [];
|
||||
|
||||
if (isset($config['gifs']['gif'])) {
|
||||
foreach ($config['gifs']['gif'] as $gif) {
|
||||
foreach (config_read_array('gifs', 'gif') as $gif) {
|
||||
if (explode('_vip', $gif['if'])[0] != $interface) {
|
||||
continue;
|
||||
} elseif ($family == 4 && !is_ipaddrv4($gif['remote-addr'])) {
|
||||
@ -3741,7 +3717,6 @@ function link_interface_to_gif($interface, $update = false, $family = null)
|
||||
/* callers are only concerned with the resulting device names */
|
||||
$result[] = $gif['gifif'];
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
@ -3838,19 +3813,6 @@ function get_interface_mac($interface, $ifconfig_details = null)
|
||||
return $intf_details['macaddr'];
|
||||
}
|
||||
|
||||
function get_vip_descr($ipaddress)
|
||||
{
|
||||
global $config;
|
||||
|
||||
foreach ($config['virtualip']['vip'] as $vip) {
|
||||
if ($vip['subnet'] == $ipaddress) {
|
||||
return ($vip['descr'] ?? '');
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
function interfaces_staticarp_configure($if, $ifconfig_details = null)
|
||||
{
|
||||
global $config;
|
||||
|
||||
@ -501,6 +501,27 @@ function legacy_interfaces_details($intf = null)
|
||||
$result[$current_interface]['vxlan']['group'] = null;
|
||||
$result[$current_interface]["vxlan"]["remote"] = $line_parts[6];
|
||||
}
|
||||
} elseif (preg_match("/member: (.*)\Wflags=\w+<(.*)>.*/", $line, $matches)) {
|
||||
if (empty($result[$current_interface]["members"])) {
|
||||
$result[$current_interface]["members"] = [];
|
||||
}
|
||||
$result[$current_interface]["members"][$matches[1]] = [
|
||||
"flags" => explode(",", strtolower($matches[2]))
|
||||
];
|
||||
} elseif (preg_match("/\tnd6 options=\w+<(.*)>/", $line, $matches)) {
|
||||
$result[$current_interface]["nd6"] = [
|
||||
"flags" => explode(",", strtolower($matches[1]))
|
||||
];
|
||||
} elseif (preg_match("/\tid ([\w\:]+) priority (\d+) hellotime (\d+) fwddelay (\d+).*/", $line, $matches)) {
|
||||
$result[$current_interface]["priority"] = $matches[2];
|
||||
$result[$current_interface]["hellotime"] = $matches[3];
|
||||
$result[$current_interface]["fwddelay"] = $matches[4];
|
||||
} elseif (preg_match("/\tmaxage (\d+) holdcnt (\d+) proto (\w+) maxaddr (\d+) timeout (\d+).*/", $line, $matches)) {
|
||||
$result[$current_interface]["maxage"] = $matches[1];
|
||||
$result[$current_interface]["holdcnt"] = $matches[2];
|
||||
$result[$current_interface]["proto"] = $matches[3];
|
||||
$result[$current_interface]["maxaddr"] = $matches[4];
|
||||
$result[$current_interface]["timeout"] = $matches[5];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -120,10 +120,12 @@ function captiveportal_firewall($fw)
|
||||
'protocol' => 'tcp',
|
||||
'from' => "<__captiveportal_zone_{$zoneid}>",
|
||||
'from_not' => true,
|
||||
'to' => 'any',
|
||||
'to' => "<__captiveportal_zone_{$zoneid}>",
|
||||
'to_not' => true,
|
||||
'to_port' => $to_port,
|
||||
'target' => '127.0.0.1',
|
||||
'localport' => $rdr_port,
|
||||
'natreflection' => 'disable',
|
||||
'descr' => "Redirect to Captive Portal (zone {$zoneid})",
|
||||
'#ref' => "ui/captiveportal#edit={$uuid}"
|
||||
]
|
||||
@ -157,7 +159,8 @@ function captiveportal_firewall($fw)
|
||||
'direction' => 'in',
|
||||
'from' => "<__captiveportal_zone_{$zoneid}>",
|
||||
'from_not' => true,
|
||||
'to' => 'any',
|
||||
'to' => "<__captiveportal_zone_{$zoneid}>",
|
||||
'to_not' => true,
|
||||
'descr' => "Default Captive Portal block rule (zone {$zoneid})",
|
||||
'log' => !isset($config['syslog']['nologdefaultblock']),
|
||||
'#ref' => "ui/captiveportal#edit={$uuid}",
|
||||
|
||||
@ -47,16 +47,23 @@ function dhcpd_run()
|
||||
function dhcpd_dhcpv6_enabled()
|
||||
{
|
||||
global $config;
|
||||
$explicit_off = [];
|
||||
|
||||
/* handle manually configured DHCP6 server settings first */
|
||||
foreach (config_read_array('dhcpdv6') as $dhcpv6if => $dhcpv6ifconf) {
|
||||
if (isset($config['interfaces'][$dhcpv6if]['enable']) && isset($dhcpv6ifconf['enable'])) {
|
||||
if ($dhcpv6ifconf['enable'] == '-1') {
|
||||
$explicit_off[] = $dhcpv6if;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/* handle DHCP-PD prefixes and 6RD dynamic interfaces */
|
||||
foreach (legacy_config_get_interfaces(array('virtual' => false)) as $ifcfg) {
|
||||
foreach (legacy_config_get_interfaces(array('virtual' => false)) as $ifnm => $ifcfg) {
|
||||
if (in_array($ifnm, $explicit_off)) {
|
||||
continue;
|
||||
}
|
||||
if (isset($ifcfg['enable']) && !empty($ifcfg['track6-interface']) && !isset($ifcfg['dhcpd6track6allowoverride'])) {
|
||||
return true;
|
||||
}
|
||||
@ -864,8 +871,12 @@ function dhcpd_dhcp6_configure($verbose = false, $blacklist = [])
|
||||
|
||||
if (!isset($config['interfaces'][$ifname]['dhcpd6track6allowoverride'])) {
|
||||
/* mock a real server */
|
||||
$dhcpdv6cfg[$ifname] = array();
|
||||
$dhcpdv6cfg[$ifname]['enable'] = true;
|
||||
if (!empty($dhcpdv6cfg[$ifname]) && $dhcpdv6cfg[$ifname]['enable'] == '-1') {
|
||||
/* tracking, but dhcpv6 disabled */
|
||||
$dhcpdv6cfg[$ifname] = [];
|
||||
} else {
|
||||
$dhcpdv6cfg[$ifname] = ['enable' => true];
|
||||
}
|
||||
|
||||
/* fixed range */
|
||||
$ifcfgipv6arr[7] = '1000';
|
||||
|
||||
@ -311,6 +311,9 @@ function dpinger_status()
|
||||
'monitor' => !empty($gwitem['monitor']) ? $gwitem['monitor'] : '~',
|
||||
'gateway' => $gwitem['gateway'] ?? '',
|
||||
'monitor_killstates' => $gwitem['monitor_killstates'] ?? '0',
|
||||
'monitor_killstates_priority' => $gwitem['monitor_killstates_priority'] ?? '0',
|
||||
'priority' => $gwitem['priority'] ?? '255',
|
||||
'ipprotocol' => $gwitem['ipprotocol'],
|
||||
'name' => $gwname,
|
||||
'stddev' => '~',
|
||||
'delay' => '~',
|
||||
|
||||
@ -583,52 +583,6 @@ function ipsec_idinfo_to_cidr(&$idinfo, $addrbits = false, $mode = '')
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Return phase1 association for phase2
|
||||
*/
|
||||
function ipsec_lookup_phase1(&$ph2ent, &$ph1ent)
|
||||
{
|
||||
global $config;
|
||||
|
||||
if (!isset($config['ipsec']) || !is_array($config['ipsec'])) {
|
||||
return false;
|
||||
}
|
||||
if (!is_array($config['ipsec']['phase1'])) {
|
||||
return false;
|
||||
}
|
||||
if (empty($config['ipsec']['phase1'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ($config['ipsec']['phase1'] as $ph1tmp) {
|
||||
if ($ph1tmp['ikeid'] == $ph2ent['ikeid']) {
|
||||
$ph1ent = $ph1tmp;
|
||||
return $ph1ent;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check phase1 communications status
|
||||
*/
|
||||
function ipsec_phase1_status($ipsec_status, $ikeid)
|
||||
{
|
||||
foreach ($ipsec_status as $ike) {
|
||||
if ($ike['id'] != $ikeid) {
|
||||
continue;
|
||||
}
|
||||
if ($ike['status'] == 'established') {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
function ipsec_resolve($hostname, $ipproto = 'inet')
|
||||
{
|
||||
if (!is_ipaddr($hostname)) {
|
||||
@ -686,7 +640,7 @@ function ipsec_find_id(&$ph1ent, $side = 'local')
|
||||
$thisid_data = $id_data;
|
||||
}
|
||||
|
||||
return trim($thisid_data);
|
||||
return is_string($thisid_data) ? trim($thisid_data) : $thisid_data;
|
||||
}
|
||||
|
||||
/* include all configuration functions */
|
||||
|
||||
@ -42,6 +42,23 @@ function kea_services()
|
||||
'name' => 'kea-dhcpv4',
|
||||
];
|
||||
}
|
||||
if (!empty((string)(new \OPNsense\Kea\KeaDhcpv6())->general->enabled)) {
|
||||
/**
|
||||
* Although kea's backend operation is a single package, various services do offer their own pid files.
|
||||
* Ideally we should have a list of pids to check for the services and only return a single item,
|
||||
* but showing both with the same action below is the second best we can achieve.
|
||||
*/
|
||||
$services[] = [
|
||||
'description' => gettext('KEA DHCPv6 server'),
|
||||
'pidfile' => '/var/run/kea/kea-dhcp6.kea-dhcp6.pid',
|
||||
'configd' => [
|
||||
'restart' => ['kea restart'],
|
||||
'start' => ['kea start'],
|
||||
'stop' => ['kea stop'],
|
||||
],
|
||||
'name' => 'kea-dhcpv6',
|
||||
];
|
||||
}
|
||||
return $services;
|
||||
}
|
||||
|
||||
@ -55,14 +72,18 @@ function kea_run()
|
||||
function kea_staticmap($proto = null, $valid_addresses = true, $ifconfig_details = null)
|
||||
{
|
||||
$staticmap = [];
|
||||
$keav4 = new \OPNsense\Kea\KeaDhcpv4();
|
||||
if ($proto == 6) {
|
||||
$keamdl = new \OPNsense\Kea\KeaDhcpv6();
|
||||
} else {
|
||||
$keamdl = new \OPNsense\Kea\KeaDhcpv4();
|
||||
}
|
||||
|
||||
if ($proto == 6 || empty((string)$keav4->general->enabled)) {
|
||||
/* unsupported protocol or not enabled */
|
||||
if (empty((string)$keamdl->general->enabled)) {
|
||||
/* not enabled */
|
||||
return $staticmap;
|
||||
}
|
||||
|
||||
foreach ($keav4->reservations->reservation->iterateItems() as $reservation) {
|
||||
foreach ($keamdl->reservations->reservation->iterateItems() as $reservation) {
|
||||
$hostname = !empty((string)$reservation->hostname) ? (string)$reservation->hostname : null;
|
||||
$ip_address = (string)$reservation->ip_address;
|
||||
if ($valid_addresses) {
|
||||
@ -81,13 +102,15 @@ function kea_staticmap($proto = null, $valid_addresses = true, $ifconfig_details
|
||||
|
||||
$description = !empty((string)$reservation->description) ? (string)$reservation->description : null;
|
||||
|
||||
$subnet_node = $keav4->getNodeByReference("subnets.subnet4.{$reservation->subnet}");
|
||||
$domain = null;
|
||||
if ($proto == 4) {
|
||||
$subnet_node = $keamdl->getNodeByReference("subnets.subnet4.{$reservation->subnet}");
|
||||
if ($subnet_node) {
|
||||
if (!empty((string)$subnet_node->option_data->domain_name)) {
|
||||
$domain = (string)$subnet_node->option_data->domain_name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$entry = [
|
||||
'descr' => $description,
|
||||
@ -113,9 +136,17 @@ function kea_configure()
|
||||
function kea_configure_do($verbose = false)
|
||||
{
|
||||
$keaDhcpv4 = new \OPNsense\Kea\KeaDhcpv4();
|
||||
if ($keaDhcpv4->isEnabled()) {
|
||||
$keaDhcpv6 = new \OPNsense\Kea\KeaDhcpv6();
|
||||
if ($keaDhcpv4->isEnabled() || $keaDhcpv6->isEnabled()) {
|
||||
service_log('Sync KEA DHCP config...', $verbose);
|
||||
if ($keaDhcpv4->isEnabled() && $keaDhcpv4->general->manual_config->isEmpty()) {
|
||||
/* skip kea-dhcp4.conf when configured manually */
|
||||
$keaDhcpv4->generateConfig();
|
||||
}
|
||||
if ($keaDhcpv6->isEnabled() && $keaDhcpv6->general->manual_config->isEmpty()) {
|
||||
/* skip kea-dhcp6.conf when configured manually */
|
||||
$keaDhcpv6->generateConfig();
|
||||
}
|
||||
(new \OPNsense\Kea\KeaCtrlAgent())->generateConfig();
|
||||
service_log("done.\n", $verbose);
|
||||
}
|
||||
@ -133,6 +164,7 @@ function kea_firewall($fw)
|
||||
{
|
||||
global $config;
|
||||
$keav4 = new \OPNsense\Kea\KeaDhcpv4();
|
||||
$keav6 = new \OPNsense\Kea\KeaDhcpv6();
|
||||
if ($keav4->fwrulesEnabled()) {
|
||||
// automatic (IPv4) rules enabled
|
||||
foreach (explode(',', $keav4->general->interfaces) as $intf) {
|
||||
@ -166,6 +198,65 @@ function kea_firewall($fw)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if ($keav6->fwrulesEnabled()) {
|
||||
foreach (explode(',', $keav6->general->interfaces) as $intf) {
|
||||
$default_opts = [
|
||||
'protocol' => 'udp',
|
||||
'ipprotocol' => 'inet6',
|
||||
'interface' => $intf,
|
||||
'#ref' => 'ui/kea/dhcp/v6',
|
||||
'descr' => 'allow access to DHCPv6 server',
|
||||
'log' => !isset($config['syslog']['nologdefaultpass'])
|
||||
];
|
||||
$fw->registerFilterRule(
|
||||
1,
|
||||
[
|
||||
'from' => 'fe80::/10',
|
||||
'to' => 'fe80::/10,ff02::/16',
|
||||
'to_port' => 546
|
||||
],
|
||||
$default_opts
|
||||
);
|
||||
$fw->registerFilterRule(
|
||||
1,
|
||||
[
|
||||
'from' => 'fe80::/10',
|
||||
'to' => 'ff02::/16',
|
||||
'to_port' => 547
|
||||
],
|
||||
$default_opts
|
||||
);
|
||||
$fw->registerFilterRule(
|
||||
1,
|
||||
[
|
||||
'from' => 'ff02::/16',
|
||||
'to' => 'fe80::/10',
|
||||
'to_port' => 547
|
||||
],
|
||||
$default_opts
|
||||
);
|
||||
$fw->registerFilterRule(
|
||||
1,
|
||||
[
|
||||
'from' => 'fe80::/10',
|
||||
'to' => '(self)',
|
||||
'to_port' => 546
|
||||
],
|
||||
$default_opts
|
||||
);
|
||||
$fw->registerFilterRule(
|
||||
1,
|
||||
[
|
||||
'from' => '(self)',
|
||||
'to' => 'fe80::/10',
|
||||
'from_port' => 547,
|
||||
'direction' => 'out'
|
||||
],
|
||||
$default_opts
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function kea_xmlrpc_sync()
|
||||
@ -176,7 +267,7 @@ function kea_xmlrpc_sync()
|
||||
'description' => gettext('Kea DHCP'),
|
||||
'section' => 'OPNsense.Kea',
|
||||
'id' => 'kea',
|
||||
'services' => ["kea-dhcpv4"],
|
||||
'services' => ["kea-dhcpv4", "kea-dhcpv6"],
|
||||
];
|
||||
|
||||
return $result;
|
||||
|
||||
@ -40,16 +40,21 @@ function radvd_configure()
|
||||
function radvd_enabled()
|
||||
{
|
||||
global $config;
|
||||
$explicit_off = [];
|
||||
|
||||
/* handle manually configured DHCP6 server settings first */
|
||||
foreach (config_read_array('dhcpdv6') as $dhcpv6if => $dhcpv6ifconf) {
|
||||
if (isset($config['interfaces'][$dhcpv6if]['enable']) && isset($dhcpv6ifconf['ramode']) && $dhcpv6ifconf['ramode'] != 'disabled') {
|
||||
return true;
|
||||
} elseif (isset($dhcpv6ifconf['ramode']) && $dhcpv6ifconf['ramode'] == 'disabled') {
|
||||
$explicit_off[] = $dhcpv6if;
|
||||
}
|
||||
}
|
||||
|
||||
/* handle DHCP-PD prefixes and 6RD dynamic interfaces */
|
||||
foreach (legacy_config_get_interfaces(array('virtual' => false)) as $ifcfg) {
|
||||
foreach (legacy_config_get_interfaces(array('virtual' => false)) as $ifnm => $ifcfg) {
|
||||
if (in_array($ifnm, $explicit_off)) {
|
||||
continue;
|
||||
}
|
||||
if (isset($ifcfg['enable']) && !empty($ifcfg['track6-interface']) && !isset($ifcfg['dhcpd6track6allowoverride'])) {
|
||||
return true;
|
||||
}
|
||||
@ -349,6 +354,9 @@ function radvd_configure_do($verbose = false, $blacklist = [])
|
||||
} elseif (isset($blacklist[$if])) {
|
||||
$radvdconf .= "# Skipping blacklisted interface {$if}\n";
|
||||
continue;
|
||||
} elseif (!empty($config['dhcpdv6'][$if]) && !empty($config['dhcpdv6'][$if]['ramode']) && $config['dhcpdv6'][$if]['ramode'] == 'disabled') {
|
||||
$radvdconf .= "# Skipping explicit disabled interface {$if}\n";
|
||||
continue;
|
||||
}
|
||||
|
||||
$trackif = $config['interfaces'][$if]['track6-interface'];
|
||||
|
||||
@ -285,22 +285,6 @@ function get_locale_list()
|
||||
return $locales;
|
||||
}
|
||||
|
||||
function get_country_codes()
|
||||
{
|
||||
$dn_cc = array();
|
||||
|
||||
$iso3166_tab = '/usr/local/opnsense/contrib/tzdata/iso3166.tab';
|
||||
if (file_exists($iso3166_tab)) {
|
||||
$dn_cc_file = file($iso3166_tab);
|
||||
foreach ($dn_cc_file as $line) {
|
||||
if (preg_match('/^([A-Z][A-Z])\t(.*)$/', $line, $matches)) {
|
||||
$dn_cc[$matches[1]] = trim($matches[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $dn_cc;
|
||||
}
|
||||
|
||||
function get_zoneinfo()
|
||||
{
|
||||
$zones = timezone_identifiers_list(DateTimeZone::ALL ^ DateTimeZone::UTC);
|
||||
@ -326,13 +310,17 @@ function get_searchdomains()
|
||||
}
|
||||
|
||||
if (!empty($syscfg['dnssearchdomain'])) {
|
||||
if ($syscfg['dnssearchdomain'] == '.') {
|
||||
/* pass root only */
|
||||
return [$syscfg['dnssearchdomain']];
|
||||
$dnssds = array_unique(explode(',', $syscfg['dnssearchdomain']));
|
||||
|
||||
foreach ($dnssds as $dnssd) {
|
||||
if ($dnssd == '.') {
|
||||
/* pass root only but including other manually set domains as is */
|
||||
return $dnssds;
|
||||
}
|
||||
|
||||
/* add custom search entries after default domain before potential provider entries */
|
||||
$master_list[] = $syscfg['dnssearchdomain'];
|
||||
$master_list[] = $dnssd;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($syscfg['dnsallowoverride'])) {
|
||||
|
||||
@ -32,7 +32,6 @@
|
||||
|
||||
require_once 'IPv6.inc';
|
||||
|
||||
/* XXX only two callers left, better remove this unreliable function */
|
||||
function killbyname($procname, $sig = 'TERM', $waitforit = true)
|
||||
{
|
||||
/* pgrep -n only kills the newest matching process */
|
||||
@ -636,41 +635,6 @@ function is_uniquelocal($ipaddr)
|
||||
return !!preg_match('/^fd[0-9a-f][0-9a-f]:/i', $ipaddr ?? '');
|
||||
}
|
||||
|
||||
/* returns true if $ipaddr is a valid literal IPv6 address */
|
||||
function is_literalipaddrv6($ipaddr)
|
||||
{
|
||||
if (preg_match('/\[([0-9a-f:]+)\]/i', $ipaddr, $match)) {
|
||||
$ipaddr = $match[1];
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return is_ipaddrv6($ipaddr);
|
||||
}
|
||||
|
||||
function is_ipaddrwithport($ipport)
|
||||
{
|
||||
$parts = explode(":", $ipport);
|
||||
$port = array_pop($parts);
|
||||
if (count($parts) == 1) {
|
||||
return is_ipaddrv4($parts[0]) && is_port($port);
|
||||
} elseif (count($parts) > 1) {
|
||||
return is_literalipaddrv6(implode(":", $parts)) && is_port($port);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function is_hostnamewithport($hostport)
|
||||
{
|
||||
$parts = explode(":", $hostport);
|
||||
$port = array_pop($parts);
|
||||
if (count($parts) == 1) {
|
||||
return is_hostname($parts[0]) && is_port($port);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* returns true if $ipaddr is a valid dotted IPv4 address or an alias thereof */
|
||||
function is_ipaddroralias($ipaddr)
|
||||
{
|
||||
@ -802,32 +766,6 @@ function is_inrange($test, $start, $end)
|
||||
return is_ipaddrv6($test) ? is_inrange_v6($test, $start, $end) : is_inrange_v4($test, $start, $end);
|
||||
}
|
||||
|
||||
function get_configured_carp_interface_list()
|
||||
{
|
||||
$carp_list = [];
|
||||
|
||||
foreach (config_read_array('virtualip', 'vip') as $vip) {
|
||||
if ($vip['mode'] == 'carp') {
|
||||
$carp_list["{$vip['interface']}_vip{$vip['vhid']}"] = $vip['subnet'];
|
||||
}
|
||||
}
|
||||
|
||||
return $carp_list;
|
||||
}
|
||||
|
||||
function get_configured_ip_aliases_list()
|
||||
{
|
||||
$alias_list = [];
|
||||
|
||||
foreach (config_read_array('virtualip', 'vip') as $vip) {
|
||||
if ($vip['mode'] == 'ipalias') {
|
||||
$alias_list[$vip['subnet']] = $vip['interface'];
|
||||
}
|
||||
}
|
||||
|
||||
return $alias_list;
|
||||
}
|
||||
|
||||
function get_configured_interface_with_descr()
|
||||
{
|
||||
$iflist = [];
|
||||
@ -1011,41 +949,6 @@ function is_alias($name)
|
||||
return \OPNsense\Firewall\Util::isAlias($name);
|
||||
}
|
||||
|
||||
function subnet_size($subnet)
|
||||
{
|
||||
if (is_subnetv4($subnet)) {
|
||||
list ($ip, $bits) = explode("/", $subnet);
|
||||
return round(exp(log(2) * (32 - $bits)));
|
||||
} elseif (is_subnetv6($subnet)) {
|
||||
list ($ip, $bits) = explode("/", $subnet);
|
||||
return round(exp(log(2) * (128 - $bits)));
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* find out whether two subnets overlap */
|
||||
function check_subnets_overlap($subnet1, $bits1, $subnet2, $bits2)
|
||||
{
|
||||
if (!is_numeric($bits1)) {
|
||||
$bits1 = 32;
|
||||
}
|
||||
if (!is_numeric($bits2)) {
|
||||
$bits2 = 32;
|
||||
}
|
||||
|
||||
if ($bits1 < $bits2) {
|
||||
$relbits = $bits1;
|
||||
} else {
|
||||
$relbits = $bits2;
|
||||
}
|
||||
|
||||
$sn1 = gen_subnet_mask_long($relbits) & ip2long($subnet1);
|
||||
$sn2 = gen_subnet_mask_long($relbits) & ip2long($subnet2);
|
||||
|
||||
return ($sn1 == $sn2);
|
||||
}
|
||||
|
||||
/* compare two IP addresses */
|
||||
function ipcmp($a, $b)
|
||||
{
|
||||
@ -1087,23 +990,6 @@ function is_private_ip($iptocheck)
|
||||
return false;
|
||||
}
|
||||
|
||||
function format_bytes($bytes)
|
||||
{
|
||||
if ($bytes >= 1024 ** 5) {
|
||||
return sprintf("%.2f PB", $bytes / (1024 ** 5));
|
||||
} elseif ($bytes >= 1024 ** 4) {
|
||||
return sprintf("%.2f TB", $bytes / (1024 ** 4));
|
||||
} elseif ($bytes >= 1024 ** 3) {
|
||||
return sprintf("%.2f GB", $bytes / (1024 ** 3));
|
||||
} elseif ($bytes >= 1024 ** 2) {
|
||||
return sprintf("%.2f MB", $bytes / (1024 ** 2));
|
||||
} elseif ($bytes >= 1024) {
|
||||
return sprintf("%.0f KB", $bytes / 1024);
|
||||
} else {
|
||||
return sprintf("%d bytes", $bytes);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* get_sysctl($names)
|
||||
* Get values of sysctl OID's listed in $names (accepts an array or a single
|
||||
@ -1329,27 +1215,3 @@ function dhcp6c_duid_clear()
|
||||
/* clear the backup so that it will not be restored: */
|
||||
@unlink('/conf/dhcp6c_duid');
|
||||
}
|
||||
|
||||
/**
|
||||
* check if interface is assigned
|
||||
* @param $interface technical interface name
|
||||
* @return string interface name (lan, wan, optX)
|
||||
*/
|
||||
function is_interface_assigned($interface)
|
||||
{
|
||||
global $config;
|
||||
|
||||
foreach (legacy_config_get_interfaces() as $if => $intf) {
|
||||
if (isset($intf['if']) && $intf['if'] == $interface) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (isset($config['vlans']['vlan'])) {
|
||||
foreach ($config['vlans']['vlan'] as $vlan) {
|
||||
if ($vlan['if'] == $interface) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2017-2024 Franco Fichtner <franco@opnsense.org>
|
||||
* Copyright (C) 2017-2025 Franco Fichtner <franco@opnsense.org>
|
||||
* Copyright (C) 2006 Scott Ullrich <sullrich@gmail.com>
|
||||
* Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>
|
||||
* All rights reserved.
|
||||
@ -38,6 +38,8 @@ require_once("interfaces.inc");
|
||||
|
||||
$argument = isset($argv[1]) ? trim($argv[1]) : '';
|
||||
$force = !empty($argv[2]) ? 'yes' : 'no';
|
||||
$family = 'inet';
|
||||
$family_int = 4;
|
||||
|
||||
exit_on_bootup(function ($argument) {
|
||||
log_msg("IP renewal deferred during boot on '{$argument}'");
|
||||
@ -66,7 +68,7 @@ if (!is_ipaddr($ip)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$gw = OPNsense\Interface\Autoconf::getRouter($device, 'inet');
|
||||
$gw = OPNsense\Interface\Autoconf::getRouter($device, $family);
|
||||
|
||||
$cacheip_file = "/tmp/{$device}_oldip";
|
||||
$cacheip = trim(@file_get_contents($cacheip_file));
|
||||
@ -81,10 +83,17 @@ if ($force == 'no' && $ip == $cacheip) {
|
||||
|
||||
log_msg("IP renewal starting (new: {$ip}, old: {$cacheip}, interface: {$interface}, device: {$device}, force: {$force})");
|
||||
|
||||
interfaces_vips_configure($interface, 4);
|
||||
interfaces_vips_configure($interface, $family_int);
|
||||
|
||||
$greifs = link_interface_to_gre($interface, true, 4);
|
||||
$gififs = link_interface_to_gif($interface, true, 4);
|
||||
$auxdevs = [];
|
||||
|
||||
/* find and reconfigure all linked devices */
|
||||
foreach (link_interface_to_gre($interface, true, $family_int) as $linked) {
|
||||
$auxdevs[] = $linked;
|
||||
}
|
||||
foreach (link_interface_to_gif($interface, true, $family_int) as $linked) {
|
||||
$auxdevs[] = $linked;
|
||||
}
|
||||
|
||||
switch (isset($config['system']['ipv6allow']) ? ($config['interfaces'][$interface]['ipaddrv6'] ?? 'none') : 'none') {
|
||||
case '6to4':
|
||||
@ -99,7 +108,8 @@ switch (isset($config['system']['ipv6allow']) ? ($config['interfaces'][$interfac
|
||||
break;
|
||||
}
|
||||
|
||||
interfaces_restart_by_device(false, array_merge($greifs, $gififs));
|
||||
/* linked devices that are assigned need to be reconfigured now */
|
||||
interfaces_restart_by_device(false, $auxdevs);
|
||||
|
||||
/*
|
||||
* Interface reconfigure finished here so sync
|
||||
@ -107,7 +117,10 @@ interfaces_restart_by_device(false, array_merge($greifs, $gififs));
|
||||
*/
|
||||
ifgroup_setup();
|
||||
|
||||
system_routing_configure(false, $interface, true, 'inet');
|
||||
$interfaces = [/* empty for v6 compat */];
|
||||
array_unshift($interfaces, $interface);
|
||||
|
||||
system_routing_configure(false, $interfaces, true, $family);
|
||||
|
||||
filter_configure_sync();
|
||||
|
||||
@ -126,5 +139,5 @@ if (is_ipaddr($cachegw) && is_ipaddr($gw) && $gw != $cachegw) {
|
||||
|
||||
@file_put_contents($cachegw_file, $gw . PHP_EOL);
|
||||
|
||||
plugins_configure('vpn', false, [[$interface], 'inet']);
|
||||
plugins_configure('newwanip', false, [[$interface], 'inet']);
|
||||
plugins_configure('vpn', false, [$interfaces, $family]);
|
||||
plugins_configure('newwanip', false, [$interfaces, $family]);
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2017-2024 Franco Fichtner <franco@opnsense.org>
|
||||
* Copyright (C) 2017-2025 Franco Fichtner <franco@opnsense.org>
|
||||
* Copyright (C) 2006 Scott Ullrich <sullrich@gmail.com>
|
||||
* Copyright (C) 2003-2005 Manuel Kasper <mk@neon1.net>
|
||||
* All rights reserved.
|
||||
@ -38,6 +38,8 @@ require_once("interfaces.inc");
|
||||
|
||||
$argument = isset($argv[1]) ? trim($argv[1]) : '';
|
||||
$force = !empty($argv[2]) ? 'yes' : 'no';
|
||||
$family = 'inet6';
|
||||
$family_int = 6;
|
||||
|
||||
exit_on_bootup(function ($argument) {
|
||||
log_msg("IP renewal deferred during boot on '{$argument}'");
|
||||
@ -46,7 +48,7 @@ exit_on_bootup(function ($argument) {
|
||||
|
||||
if (empty($argument)) {
|
||||
$interface = 'wan';
|
||||
$device = get_real_interface($interface, 'inet6');
|
||||
$device = get_real_interface($interface, $family);
|
||||
} else {
|
||||
$interface = convert_real_interface_to_friendly_interface_name($argument);
|
||||
$device = $argument;
|
||||
@ -89,15 +91,24 @@ if (!is_ipaddr($ip)) {
|
||||
|
||||
log_msg("IP renewal starting (address: {$ip}, interface: {$interface}, device: {$device})");
|
||||
|
||||
interfaces_vips_configure($interface, 6);
|
||||
interfaces_vips_configure($interface, $family_int);
|
||||
|
||||
$greifs = link_interface_to_gre($interface, true, 6);
|
||||
$gififs = link_interface_to_gif($interface, true, 6);
|
||||
$auxdevs = [];
|
||||
|
||||
/* find and reconfigure all linked devices which includes looking up tracked interfaces */
|
||||
foreach (array_merge([$interface], array_keys(link_interface_to_track6($interface))) as $allif) {
|
||||
foreach (link_interface_to_gre($allif, true, $family_int) as $linked) {
|
||||
$auxdevs[] = $linked;
|
||||
}
|
||||
foreach (link_interface_to_gif($allif, true, $family_int) as $linked) {
|
||||
$auxdevs[] = $linked;
|
||||
}
|
||||
}
|
||||
|
||||
switch (isset($config['system']['ipv6allow']) ? ($config['interfaces'][$interface]['ipaddrv6'] ?? 'none') : 'none') {
|
||||
case 'slaac':
|
||||
/* require immediate reconfiguration before reconfiguring clients */
|
||||
plugins_configure('dhcp', false, ['inet6']);
|
||||
plugins_configure('dhcp', false, [$family]);
|
||||
break;
|
||||
default:
|
||||
/*
|
||||
@ -111,14 +122,21 @@ switch (isset($config['system']['ipv6allow']) ? ($config['interfaces'][$interfac
|
||||
break;
|
||||
}
|
||||
|
||||
interfaces_restart_by_device(false, array_merge($greifs, $gififs));
|
||||
/* linked devices that are assigned need to be reconfigured now */
|
||||
interfaces_restart_by_device(false, $auxdevs);
|
||||
|
||||
/*
|
||||
* Interface reconfigure finished here so sync
|
||||
* firewall groups in case of destroy/create use.
|
||||
*/
|
||||
ifgroup_setup();
|
||||
|
||||
$interfaces = array_keys(link_interface_to_track6($interface, true));
|
||||
array_unshift($interfaces, $interface);
|
||||
|
||||
system_routing_configure(false, $interfaces, true, 'inet6');
|
||||
system_routing_configure(false, $interfaces, true, $family);
|
||||
|
||||
filter_configure_sync();
|
||||
|
||||
plugins_configure('vpn', false, [$interfaces, 'inet6']);
|
||||
plugins_configure('newwanip', false, [$interfaces, 'inet6']);
|
||||
plugins_configure('vpn', false, [$interfaces, $family]);
|
||||
plugins_configure('newwanip', false, [$interfaces, $family]);
|
||||
|
||||
@ -35,12 +35,34 @@ require_once 'interfaces.inc';
|
||||
$gwnames = [];
|
||||
$affected_gateways = !empty($argv[1]) ? explode(',', $argv[1]) : [];
|
||||
|
||||
$metered_found_prios = ['inet' => 256, 'inet6' => 256];
|
||||
$metered_gws = ['inet' => [], 'inet6' => []];
|
||||
|
||||
foreach (return_gateways_status() as $status) {
|
||||
if ($status['status'] == 'down') {
|
||||
/* try to recover monitors stuck in down state ignoring "force_down" */
|
||||
/* recover monitors stuck in down state ignoring "force_down" */
|
||||
$gwnames[] = $status['name'];
|
||||
if (!empty($status['monitor_killstates']) && in_array($status['name'], $affected_gateways)) {
|
||||
configdp_run('filter kill gateway_states', [$status['gateway']], true);
|
||||
$uuid = trim(configdp_run('filter kill gateway_states', [$status['gateway']], true));
|
||||
log_msg("ROUTING: killing states for unreachable gateway {$status['name']} [$uuid]", LOG_NOTICE);
|
||||
}
|
||||
} elseif ($status['status'] != 'force_down') {
|
||||
/* collect "metered" gateways for all non-down status reports */
|
||||
if (!empty($status['monitor_killstates_priority'])) {
|
||||
$metered_gws[$status['ipprotocol']][] = $status;
|
||||
/* only consider currently affected gateways as priority candidates */
|
||||
} elseif (in_array($status['name'], $affected_gateways)) {
|
||||
$metered_found_prios[$status['ipprotocol']] = min($status['priority'], $metered_found_prios[$status['ipprotocol']]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($metered_found_prios as $ipproto => $metered_found_prio) {
|
||||
/* kill states for "metered" gateways */
|
||||
foreach ($metered_gws[$ipproto] as $status) {
|
||||
if ($status['priority'] > $metered_found_prio) {
|
||||
$uuid = trim(configdp_run('filter kill gateway_states', [$status['gateway']], true));
|
||||
log_msg("ROUTING: killing states for deferred gateway {$status['name']} [$uuid]", LOG_NOTICE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
14
src/etc/ssl/ext_sources/README
Normal file
14
src/etc/ssl/ext_sources/README
Normal file
@ -0,0 +1,14 @@
|
||||
OPNsense certificates used by external applications and registered in the gui for viewing purposes only.
|
||||
|
||||
In this directory you can create files with a .conf extension (e.g. myapp.conf) with the following (sample) config:
|
||||
|
||||
[location]
|
||||
base=/usr/local/md/domains
|
||||
pattern=pubcert.pem
|
||||
description=OPNWAF
|
||||
|
||||
|
||||
"base" is the directory to recursively iterate, "pattern" is a regex matcher and each item returned will have a description
|
||||
attached to it for the frontend.
|
||||
|
||||
Files found can be identified by their id, which is an md5 hash of the contents.
|
||||
@ -36,6 +36,7 @@ return new OPNsense\Core\AppConfig([
|
||||
'pluginsDir' => __DIR__ . '/../../app/plugins/',
|
||||
'libraryDir' => __DIR__ . '/../../app/library/',
|
||||
'cacheDir' => __DIR__ . '/../../app/cache/',
|
||||
'contribDir' => __DIR__ . '/../../../contrib/',
|
||||
'baseUri' => '/opnsense_gui/',
|
||||
],
|
||||
'globals' => [
|
||||
|
||||
@ -33,6 +33,7 @@ class GroupController extends \OPNsense\Base\IndexController
|
||||
public function indexAction()
|
||||
{
|
||||
$this->view->formDialogEditGroup = $this->getForm("dialogGroup");
|
||||
$this->view->formGridGroup = $this->getFormGrid("dialogGroup");
|
||||
$this->view->pick('OPNsense/Auth/group');
|
||||
}
|
||||
}
|
||||
|
||||
@ -33,6 +33,7 @@ class PrivController extends \OPNsense\Base\IndexController
|
||||
public function indexAction()
|
||||
{
|
||||
$this->view->formDialogEditPriv = $this->getForm("dialogPriv");
|
||||
$this->view->formGridPriv = $this->getFormGrid("dialogPriv");
|
||||
$this->view->pick('OPNsense/Auth/priv');
|
||||
}
|
||||
}
|
||||
|
||||
@ -51,6 +51,7 @@ class UserController extends \OPNsense\Base\IndexController
|
||||
public function indexAction()
|
||||
{
|
||||
$this->view->formDialogEditUser = $this->getForm("dialogUser");
|
||||
$this->view->formGridUser = $this->getFormGrid("dialogUser");
|
||||
$this->view->pick('OPNsense/Auth/user');
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,32 +3,50 @@
|
||||
<id>group.scope</id>
|
||||
<label>Defined By</label>
|
||||
<type>info</type>
|
||||
<grid_view>
|
||||
<visible>false</visible>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>group.gid</id>
|
||||
<label>gid</label>
|
||||
<type>info</type>
|
||||
<grid_view>
|
||||
<visible>false</visible>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>group.name</id>
|
||||
<label>Group name</label>
|
||||
<type>text</type>
|
||||
<grid_view>
|
||||
<sequence>10</sequence>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>group.description</id>
|
||||
<label>Description</label>
|
||||
<type>text</type>
|
||||
<help>You may enter a description here for your reference (not parsed).</help>
|
||||
<grid_view>
|
||||
<sequence>40</sequence>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>group.priv</id>
|
||||
<label>Privileges</label>
|
||||
<type>select_multiple</type>
|
||||
<grid_view>
|
||||
<sequence>20</sequence>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>group.member</id>
|
||||
<label>Members</label>
|
||||
<type>select_multiple</type>
|
||||
<help>List of users that are a member of this group</help>
|
||||
<grid_view>
|
||||
<sequence>30</sequence>
|
||||
</grid_view>
|
||||
</field>
|
||||
</form>
|
||||
|
||||
@ -4,14 +4,33 @@
|
||||
<label>Id</label>
|
||||
<type>info</type>
|
||||
</field>
|
||||
<field>
|
||||
<id>priv.name</id>
|
||||
<label>Name</label>
|
||||
<type>ignore</type>
|
||||
<grid_view>
|
||||
<formatter>lines</formatter>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>priv.match</id>
|
||||
<label>Match</label>
|
||||
<type>ignore</type>
|
||||
</field>
|
||||
<field>
|
||||
<id>priv.users</id>
|
||||
<label>Users</label>
|
||||
<type>select_multiple</type>
|
||||
<grid_view>
|
||||
<formatter>count</formatter>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>priv.groups</id>
|
||||
<label>Groups</label>
|
||||
<type>select_multiple</type>
|
||||
<grid_view>
|
||||
<formatter>count</formatter>
|
||||
</grid_view>
|
||||
</field>
|
||||
</form>
|
||||
|
||||
@ -3,93 +3,149 @@
|
||||
<id>user.scope</id>
|
||||
<label>Defined By</label>
|
||||
<type>info</type>
|
||||
<grid_view>
|
||||
<visible>false</visible>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>user.uid</id>
|
||||
<label>uid</label>
|
||||
<type>info</type>
|
||||
<grid_view>
|
||||
<visible>false</visible>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>user.disabled</id>
|
||||
<label>Disabled</label>
|
||||
<type>checkbox</type>
|
||||
<help>Deny authentication, only applicable for local users</help>
|
||||
<grid_view>
|
||||
<visible>false</visible>
|
||||
<type>boolean</type>
|
||||
<formatter>boolean</formatter>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>user.name</id>
|
||||
<label>Username</label>
|
||||
<type>text</type>
|
||||
<grid_view>
|
||||
<formatter>username</formatter>
|
||||
<sequence>10</sequence>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>user.password</id>
|
||||
<label>Password</label>
|
||||
<type>password</type>
|
||||
<grid_view>
|
||||
<ignore>true</ignore>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>user.scrambled_password</id>
|
||||
<label>Scrambled Password</label>
|
||||
<type>checkbox</type>
|
||||
<help>Generate a scrambled password to prevent local database logins for this user.</help>
|
||||
<grid_view>
|
||||
<visible>false</visible>
|
||||
<type>boolean</type>
|
||||
<formatter>boolean</formatter>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>user.descr</id>
|
||||
<label>Full name</label>
|
||||
<type>text</type>
|
||||
<help>User's full name, for your own information only</help>
|
||||
<grid_view>
|
||||
<sequence>30</sequence>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>user.email</id>
|
||||
<label>E-mail</label>
|
||||
<type>text</type>
|
||||
<help>User's e-mail address, for your own information only</help>
|
||||
<grid_view>
|
||||
<visible>false</visible>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>user.comment</id>
|
||||
<label>Comment</label>
|
||||
<type>textbox</type>
|
||||
<help>User comment, for your own information only</help>
|
||||
<grid_view>
|
||||
<visible>false</visible>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>user.landing_page</id>
|
||||
<label>Preferred landing page</label>
|
||||
<type>text</type>
|
||||
<help>Preferred landing page after login or authentication failure</help>
|
||||
<grid_view>
|
||||
<visible>false</visible>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>user.language</id>
|
||||
<label>Language</label>
|
||||
<type>dropdown</type>
|
||||
<grid_view>
|
||||
<visible>false</visible>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>user.shell</id>
|
||||
<label>Login shell</label>
|
||||
<type>dropdown</type>
|
||||
<grid_view>
|
||||
<visible>false</visible>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>user.expires</id>
|
||||
<label>Expiration date</label>
|
||||
<type>text</type>
|
||||
<style>datepicker</style>
|
||||
<grid_view>
|
||||
<visible>false</visible>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>user.group_memberships</id>
|
||||
<label>Group membership</label>
|
||||
<type>select_multiple</type>
|
||||
<grid_view>
|
||||
<sequence>20</sequence>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>user.priv</id>
|
||||
<label>Privileges</label>
|
||||
<type>select_multiple</type>
|
||||
<grid_view>
|
||||
<visible>false</visible>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>user.otp_seed</id>
|
||||
<label>OTP seed</label>
|
||||
<type>text</type>
|
||||
<style>otp_seed otp_default_hidden</style>
|
||||
<grid_view>
|
||||
<ignore>true</ignore>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>user.authorizedkeys</id>
|
||||
<label>Authorized Keys</label>
|
||||
<type>textbox</type>
|
||||
<grid_view>
|
||||
<ignore>true</ignore>
|
||||
</grid_view>
|
||||
</field>
|
||||
</form>
|
||||
|
||||
@ -17,15 +17,6 @@
|
||||
<type>select_multiple</type>
|
||||
<help><![CDATA[Select interface(s) to enable for captive portal.]]></help>
|
||||
</field>
|
||||
<field>
|
||||
<id>zone.interfaces_inbound</id>
|
||||
<label>Allow inbound</label>
|
||||
<type>select_multiple</type>
|
||||
<help><![CDATA[
|
||||
Select interfaces from which to allow inbound (stateful) traffic. This can be convenient if the zone in question
|
||||
contains machines/servers which should be accessible from other networks attached to this firewall.
|
||||
]]></help>
|
||||
</field>
|
||||
<field>
|
||||
<id>zone.authservers</id>
|
||||
<label>Authenticate using</label>
|
||||
|
||||
@ -145,6 +145,7 @@ class SystemController extends ApiControllerBase
|
||||
$response = [
|
||||
'uptime' => $this->formatUptime(time() - $matches[1]),
|
||||
'datetime' => date("D M j G:i:s T Y"),
|
||||
'boottime' => date("D M j G:i:s T Y", $matches[1]),
|
||||
'config' => $last_change,
|
||||
'loadavg' => $loadavg,
|
||||
];
|
||||
|
||||
@ -256,32 +256,6 @@ class SettingsController extends ApiMutableModelControllerBase
|
||||
return $this->delBase('dhcp_options', $uuid);
|
||||
}
|
||||
|
||||
/* dhcp match options */
|
||||
public function searchMatchAction()
|
||||
{
|
||||
return $this->searchBase('dhcp_options_match', null, null, $this->buildFilterFunction());
|
||||
}
|
||||
|
||||
public function getMatchAction($uuid = null)
|
||||
{
|
||||
return $this->getBase('match', 'dhcp_options_match', $uuid);
|
||||
}
|
||||
|
||||
public function setMatchAction($uuid)
|
||||
{
|
||||
return $this->setBase('match', 'dhcp_options_match', $uuid);
|
||||
}
|
||||
|
||||
public function addMatchAction()
|
||||
{
|
||||
return $this->addBase('match', 'dhcp_options_match');
|
||||
}
|
||||
|
||||
public function delMatchAction($uuid)
|
||||
{
|
||||
return $this->delBase('dhcp_options_match', $uuid);
|
||||
}
|
||||
|
||||
/* dhcp boot options */
|
||||
public function searchBootAction()
|
||||
{
|
||||
|
||||
@ -43,8 +43,6 @@ class SettingsController extends \OPNsense\Base\IndexController
|
||||
$this->view->formGridDHCPrange = $this->getFormGrid("dialogDHCPrange", "range");
|
||||
$this->view->formDialogEditDHCPoption = $this->getForm("dialogDHCPoption");
|
||||
$this->view->formGridDHCPoption = $this->getFormGrid("dialogDHCPoption", "option");
|
||||
$this->view->formDialogEditDHCPmatch = $this->getForm("dialogDHCPmatch");
|
||||
$this->view->formGridDHCPmatch = $this->getFormGrid("dialogDHCPmatch", "match");
|
||||
$this->view->formDialogEditDHCPboot = $this->getForm("dialogDHCPboot");
|
||||
$this->view->formGridDHCPboot = $this->getFormGrid("dialogDHCPboot", "boot");
|
||||
|
||||
|
||||
@ -1,32 +0,0 @@
|
||||
<form>
|
||||
<field>
|
||||
<id>match.option</id>
|
||||
<label>Option</label>
|
||||
<type>dropdown</type>
|
||||
<help>DHCPv4 option to offer to the client.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>match.option6</id>
|
||||
<label>Option6</label>
|
||||
<type>dropdown</type>
|
||||
<help>DHCPv6 option to offer to the client.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>match.set_tag</id>
|
||||
<label>Tag [set]</label>
|
||||
<type>dropdown</type>
|
||||
<help>Tag to set for requests matching this range which can be used to selectively match dhcp options</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>match.value</id>
|
||||
<label>Value</label>
|
||||
<type>text</type>
|
||||
<help>Value to match, leave empty to match on the option only</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>match.description</id>
|
||||
<label>Description</label>
|
||||
<type>text</type>
|
||||
<help>You may enter a description here for your reference (not parsed).</help>
|
||||
</field>
|
||||
</form>
|
||||
@ -1,4 +1,10 @@
|
||||
<form>
|
||||
<field>
|
||||
<id>option.type</id>
|
||||
<label>Type</label>
|
||||
<type>dropdown</type>
|
||||
<help>"Set" option to send it to a client in a DHCP offer or "Match" option to dynamically tag clients that send it in the initial DHCP request.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>option.option</id>
|
||||
<label>Option</label>
|
||||
@ -15,6 +21,7 @@
|
||||
<id>option.interface</id>
|
||||
<label>Interface</label>
|
||||
<type>dropdown</type>
|
||||
<style>selectpicker style_set</style>
|
||||
<help>This adds a single interface as tag so this DHCP option can match the interface of a DHCP range.</help>
|
||||
</field>
|
||||
<field>
|
||||
@ -22,18 +29,27 @@
|
||||
<label>Tag</label>
|
||||
<type>select_multiple</type>
|
||||
<help>If the optional tags are given then this option is only sent when all the tags are matched. Can be optionally combined with an interface tag.</help>
|
||||
<style>selectpicker style_set</style>
|
||||
</field>
|
||||
<field>
|
||||
<id>option.set_tag</id>
|
||||
<label>Tag [set]</label>
|
||||
<type>dropdown</type>
|
||||
<help>Tag to set for requests matching this range which can be used to selectively match dhcp options</help>
|
||||
<style>selectpicker style_match</style>
|
||||
</field>
|
||||
<field>
|
||||
<id>option.value</id>
|
||||
<label>Value</label>
|
||||
<type>text</type>
|
||||
<help>Value (or values) to send to the client. The special address 0.0.0.0 is taken to mean "the address of the machine running dnsmasq"</help>
|
||||
<help>Value (or values) to send to the client. The special address 0.0.0.0 or [::] is taken to mean "the address of the machine running dnsmasq". When using "Match", leave empty to match on the option only.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>option.force</id>
|
||||
<label>Force</label>
|
||||
<type>checkbox</type>
|
||||
<help>Always send the option, also when the client does not ask for it in the parameter request list.</help>
|
||||
<style>style_set</style>
|
||||
<grid_view>
|
||||
<type>boolean</type>
|
||||
<formatter>boolean</formatter>
|
||||
|
||||
@ -32,6 +32,7 @@ namespace OPNsense\Firewall\Api;
|
||||
|
||||
use OPNsense\Base\ApiMutableModelControllerBase;
|
||||
use OPNsense\Base\UserException;
|
||||
use OPNsense\Core\AppConfig;
|
||||
use OPNsense\Core\Backend;
|
||||
use OPNsense\Core\Config;
|
||||
use OPNsense\Firewall\Category;
|
||||
@ -256,7 +257,8 @@ class AliasController extends ApiMutableModelControllerBase
|
||||
]
|
||||
];
|
||||
|
||||
foreach (explode("\n", file_get_contents('/usr/local/opnsense/contrib/tzdata/iso3166.tab')) as $line) {
|
||||
$contribDir = (new AppConfig())->application->contribDir;
|
||||
foreach (explode("\n", file_get_contents($contribDir . '/tzdata/iso3166.tab')) as $line) {
|
||||
$line = trim($line);
|
||||
if (strlen($line) > 3 && substr($line, 0, 1) != '#') {
|
||||
$result[substr($line, 0, 2)] = array(
|
||||
@ -265,7 +267,7 @@ class AliasController extends ApiMutableModelControllerBase
|
||||
);
|
||||
}
|
||||
}
|
||||
foreach (explode("\n", file_get_contents('/usr/local/opnsense/contrib/tzdata/zone.tab')) as $line) {
|
||||
foreach (explode("\n", file_get_contents($contribDir . '/tzdata/zone.tab')) as $line) {
|
||||
if (strlen($line) > 0 && substr($line, 0, 1) == '#') {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -168,6 +168,16 @@
|
||||
<sortable>false</sortable>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>rule.icmptype</id>
|
||||
<label>ICMP type</label>
|
||||
<type>select_multiple</type>
|
||||
<hint>Any</hint>
|
||||
<advanced>true</advanced>
|
||||
<grid_view>
|
||||
<ignore>true</ignore>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>rule.source_not</id>
|
||||
<label>Invert Source</label>
|
||||
|
||||
@ -0,0 +1,138 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2025 Deciso B.V.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
namespace OPNsense\Interfaces\Api;
|
||||
|
||||
use OPNsense\Base\ApiMutableModelControllerBase;
|
||||
use OPNsense\Base\UserException;
|
||||
use OPNsense\Core\Backend;
|
||||
use OPNsense\Core\Config;
|
||||
|
||||
/**
|
||||
* @package OPNsense\Interfaces
|
||||
*/
|
||||
class BridgeSettingsController extends ApiMutableModelControllerBase
|
||||
{
|
||||
protected static $internalModelName = 'bridge';
|
||||
protected static $internalModelClass = 'OPNsense\Interfaces\Bridge';
|
||||
|
||||
/**
|
||||
* search bridges
|
||||
* @return array search results
|
||||
*/
|
||||
public function searchItemAction()
|
||||
{
|
||||
return $this->searchBase("bridged", null, "descr");
|
||||
}
|
||||
|
||||
/**
|
||||
* Update bridge with given properties
|
||||
* @param string $uuid internal id
|
||||
* @return array save result + validation output
|
||||
*/
|
||||
public function setItemAction($uuid)
|
||||
{
|
||||
Config::getInstance()->lock();
|
||||
$node = $this->getModel()->getNodeByReference('bridged.' . $uuid);
|
||||
$overlay = null;
|
||||
if (!empty($node)) {
|
||||
// not allowed to change bridge interface name
|
||||
$overlay['bridgeif'] = (string)$node->bridgeif;
|
||||
}
|
||||
return $this->setBase("bridge", "bridged", $uuid, $overlay);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add new bridge and set with attributes from post
|
||||
* @return array save result + validation output
|
||||
*/
|
||||
public function addItemAction()
|
||||
{
|
||||
Config::getInstance()->lock();
|
||||
$overlay = [];
|
||||
$ifnames = [];
|
||||
foreach ($this->getModel()->bridged->iterateItems() as $node) {
|
||||
$ifnames[] = (string)$node->bridgeif;
|
||||
}
|
||||
for ($i = 0; true; ++$i) {
|
||||
$gifif = sprintf('bridge%d', $i);
|
||||
if (!in_array($gifif, $ifnames)) {
|
||||
$overlay['bridgeif'] = $gifif;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->addBase("bridge", "bridged", $overlay);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve bridge settings or return defaults for new one
|
||||
* @param $uuid item unique id
|
||||
* @return array bridge content
|
||||
*/
|
||||
public function getItemAction($uuid = null)
|
||||
{
|
||||
return $this->getBase("bridge", "bridged", $uuid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete bridge by uuid
|
||||
* @param string $uuid internal id
|
||||
* @return array save status
|
||||
*/
|
||||
public function delItemAction($uuid)
|
||||
{
|
||||
Config::getInstance()->lock();
|
||||
$node = $this->getModel()->getNodeByReference('bridged.' . $uuid);
|
||||
if ($node != null) {
|
||||
$cfg = Config::getInstance()->object();
|
||||
foreach ($cfg->interfaces->children() as $key => $value) {
|
||||
if ((string)$value->if == (string)$node->bridgeif) {
|
||||
throw new \OPNsense\Base\UserException(
|
||||
sprintf(gettext("Cannot delete bridge. Currently in use by [%s] %s"), $key, $value),
|
||||
gettext("bridge in use")
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $this->delBase("bridged", $uuid);
|
||||
}
|
||||
|
||||
/**
|
||||
* reconfigure bridges
|
||||
*/
|
||||
public function reconfigureAction()
|
||||
{
|
||||
if ($this->request->isPost()) {
|
||||
(new Backend())->configdRun("interface bridge configure");
|
||||
return ["status" => "ok"];
|
||||
} else {
|
||||
return ["status" => "failed"];
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2025 Deciso B.V.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
namespace OPNsense\Interfaces;
|
||||
|
||||
class BridgeController extends \OPNsense\Base\IndexController
|
||||
{
|
||||
public function indexAction()
|
||||
{
|
||||
$this->view->pick('OPNsense/Interface/bridge');
|
||||
|
||||
$this->view->formDialogBridge = $this->getForm("dialogBridge");
|
||||
$this->view->formGridBridge = $this->getFormGrid("dialogBridge");
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,194 @@
|
||||
<form>
|
||||
<field>
|
||||
<id>bridge.bridgeif</id>
|
||||
<label>Device</label>
|
||||
<type>info</type>
|
||||
<grid_view>
|
||||
<width>12em</width>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>bridge.members</id>
|
||||
<label>Member interfaces</label>
|
||||
<type>select_multiple</type>
|
||||
<help>Interfaces participating in the bridge.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>bridge.descr</id>
|
||||
<label>Description</label>
|
||||
<type>text</type>
|
||||
<help>You may enter a description here for your reference (not parsed).</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>bridge.linklocal</id>
|
||||
<label>Enable link-local address</label>
|
||||
<type>checkbox</type>
|
||||
<help>By default, link-local addresses for bridges are disabled. You can enable them manually using this option. However, when a bridge interface has IPv6 addresses, IPv6 addresses on a member interface will be automatically removed before the interface is added.</help>
|
||||
<grid_view>
|
||||
<type>boolean</type>
|
||||
<formatter>boolean</formatter>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<type>header</type>
|
||||
<label>Spanning Tree Protocol (RSTP/STP)</label>
|
||||
<advanced>true</advanced>
|
||||
</field>
|
||||
<field>
|
||||
<id>bridge.enablestp</id>
|
||||
<label>Enable</label>
|
||||
<type>checkbox</type>
|
||||
<help>Enable spanning tree options for this bridge.</help>
|
||||
<advanced>true</advanced>
|
||||
<grid_view>
|
||||
<type>boolean</type>
|
||||
<formatter>boolean</formatter>
|
||||
<visible>false</visible>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>bridge.proto</id>
|
||||
<label>Protocol</label>
|
||||
<type>dropdown</type>
|
||||
<help>Protocol used for spanning tree.</help>
|
||||
<advanced>true</advanced>
|
||||
<grid_view>
|
||||
<visible>false</visible>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>bridge.stp</id>
|
||||
<label>STP interfaces</label>
|
||||
<type>select_multiple</type>
|
||||
<help>Enable Spanning Tree Protocol on interface. The if_bridge(4) driver has support for the IEEE 802.1D Spanning Tree Protocol (STP). STP is used to detect and remove loops in a network topology.</help>
|
||||
<advanced>true</advanced>
|
||||
<grid_view>
|
||||
<visible>false</visible>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>bridge.maxage</id>
|
||||
<label>Valid time</label>
|
||||
<type>text</type>
|
||||
<help>Set the time that a Spanning Tree Protocol configuration is valid. The default is 20 seconds. The minimum is 6 seconds and the maximum is 40 seconds.</help>
|
||||
<advanced>true</advanced>
|
||||
<grid_view>
|
||||
<visible>false</visible>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>bridge.fwdelay</id>
|
||||
<label>Forward time</label>
|
||||
<type>text</type>
|
||||
<help>Set the time that must pass before an interface begins forwarding packets when Spanning Tree is enabled. The default is 15 seconds. The minimum is 4 seconds and the maximum is 30 seconds.</help>
|
||||
<advanced>true</advanced>
|
||||
<grid_view>
|
||||
<visible>false</visible>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>bridge.holdcnt</id>
|
||||
<label>Hold count</label>
|
||||
<type>text</type>
|
||||
<help>Set the transmit hold count for Spanning Tree. This is the number of packets transmitted before being rate limited. The default is 6. The minimum is 1 and the maximum is 10.</help>
|
||||
<advanced>true</advanced>
|
||||
<grid_view>
|
||||
<visible>false</visible>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<type>header</type>
|
||||
<label>Advanced</label>
|
||||
<advanced>true</advanced>
|
||||
</field>
|
||||
<field>
|
||||
<id>bridge.maxaddr</id>
|
||||
<label>Cache size</label>
|
||||
<type>text</type>
|
||||
<help>Set the size of the bridge address cache to size. The default is 2000 entries.</help>
|
||||
<advanced>true</advanced>
|
||||
<grid_view>
|
||||
<visible>false</visible>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>bridge.timeout</id>
|
||||
<label>Cache entry expire time (s)</label>
|
||||
<type>text</type>
|
||||
<help>Set the timeout of address cache entries to this number of seconds. If seconds is zero, then address cache entries will not be expired. The default is 1200 seconds.</help>
|
||||
<advanced>true</advanced>
|
||||
<grid_view>
|
||||
<visible>false</visible>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>bridge.span</id>
|
||||
<label>Span port</label>
|
||||
<type>dropdown</type>
|
||||
<help>Add the interface named by interface as a span port on the bridge. Span ports transmit a copy of every frame received by the bridge. This is most useful for snooping a bridged network passively on another host connected to one of the span ports of the bridge.</help>
|
||||
<advanced>true</advanced>
|
||||
<grid_view>
|
||||
<visible>false</visible>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>bridge.edge</id>
|
||||
<label>Edge ports</label>
|
||||
<type>select_multiple</type>
|
||||
<help>Set interface as an edge port. An edge port connects directly to end stations and cannot create bridging loops in the network; this allows it to transition straight to forwarding.</help>
|
||||
<advanced>true</advanced>
|
||||
<grid_view>
|
||||
<visible>false</visible>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>bridge.autoedge</id>
|
||||
<label>Auto Edge ports</label>
|
||||
<type>select_multiple</type>
|
||||
<help>Allow interface to automatically detect edge status. This is the default for all interfaces added to a bridge. (This will disable the autoedge status of interfaces.)</help>
|
||||
<advanced>true</advanced>
|
||||
<grid_view>
|
||||
<visible>false</visible>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>bridge.ptp</id>
|
||||
<label>PTP ports</label>
|
||||
<type>select_multiple</type>
|
||||
<help>Set the interface as a point-to-point link. This is required for straight transitions to forwarding and should be enabled on a direct link to another RSTP-capable switch.</help>
|
||||
<advanced>true</advanced>
|
||||
<grid_view>
|
||||
<visible>false</visible>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>bridge.autoptp</id>
|
||||
<label>Auto PTP ports</label>
|
||||
<type>select_multiple</type>
|
||||
<help>Automatically detect the point-to-point status on interface by checking the full duplex link status. This is the default for interfaces added to the bridge. (The interfaces selected here will be removed from default autoedge status.)</help>
|
||||
<advanced>true</advanced>
|
||||
<grid_view>
|
||||
<visible>false</visible>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>bridge.static</id>
|
||||
<label>Sticky ports</label>
|
||||
<type>select_multiple</type>
|
||||
<help>Mark an interface as a "sticky" interface. Dynamically learned address entries are treated as static once entered into the cache. Sticky entries are never aged out of the cache or replaced, even if the address is seen on a different interface.</help>
|
||||
<advanced>true</advanced>
|
||||
<grid_view>
|
||||
<visible>false</visible>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>bridge.private</id>
|
||||
<label>Private ports</label>
|
||||
<type>select_multiple</type>
|
||||
<help>Mark an interface as a "private" interface. A private interface does not forward any traffic to any other port that is also a private interface.</help>
|
||||
<advanced>true</advanced>
|
||||
<grid_view>
|
||||
<visible>false</visible>
|
||||
</grid_view>
|
||||
</field>
|
||||
</form>
|
||||
@ -0,0 +1,188 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2025 Deciso B.V.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
namespace OPNsense\Kea\Api;
|
||||
|
||||
use OPNsense\Base\ApiMutableModelControllerBase;
|
||||
use OPNsense\Core\Config;
|
||||
use OPNsense\Firewall\Util;
|
||||
|
||||
class Dhcpv6Controller extends ApiMutableModelControllerBase
|
||||
{
|
||||
protected static $internalModelName = 'dhcpv6';
|
||||
protected static $internalModelClass = 'OPNsense\Kea\KeaDhcpv6';
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getAction()
|
||||
{
|
||||
$data = parent::getAction();
|
||||
return [
|
||||
self::$internalModelName => [
|
||||
'general' => $data[self::$internalModelName]['general'],
|
||||
'ha' => $data[self::$internalModelName]['ha'],
|
||||
'this_hostname' => (string)Config::getInstance()->object()->system->hostname
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public function searchSubnetAction()
|
||||
{
|
||||
return $this->searchBase("subnets.subnet6", null, "subnet");
|
||||
}
|
||||
|
||||
public function setSubnetAction($uuid)
|
||||
{
|
||||
return $this->setBase("subnet6", "subnets.subnet6", $uuid);
|
||||
}
|
||||
|
||||
public function addSubnetAction()
|
||||
{
|
||||
return $this->addBase("subnet6", "subnets.subnet6");
|
||||
}
|
||||
|
||||
public function getSubnetAction($uuid = null)
|
||||
{
|
||||
return $this->getBase("subnet6", "subnets.subnet6", $uuid);
|
||||
}
|
||||
|
||||
public function delSubnetAction($uuid)
|
||||
{
|
||||
return $this->delBase("subnets.subnet6", $uuid);
|
||||
}
|
||||
|
||||
public function searchReservationAction()
|
||||
{
|
||||
return $this->searchBase("reservations.reservation", null, "duid");
|
||||
}
|
||||
|
||||
public function setReservationAction($uuid)
|
||||
{
|
||||
return $this->setBase("reservation", "reservations.reservation", $uuid);
|
||||
}
|
||||
|
||||
public function addReservationAction()
|
||||
{
|
||||
return $this->addBase("reservation", "reservations.reservation");
|
||||
}
|
||||
|
||||
public function getReservationAction($uuid = null)
|
||||
{
|
||||
return $this->getBase("reservation", "reservations.reservation", $uuid);
|
||||
}
|
||||
|
||||
public function delReservationAction($uuid)
|
||||
{
|
||||
return $this->delBase("reservations.reservation", $uuid);
|
||||
}
|
||||
|
||||
public function downloadReservationsAction()
|
||||
{
|
||||
if ($this->request->isGet()) {
|
||||
$this->exportCsv($this->getModel()->reservations->reservation->asRecordSet(false, ['subnet']));
|
||||
}
|
||||
}
|
||||
|
||||
public function uploadReservationsAction()
|
||||
{
|
||||
if ($this->request->isPost() && $this->request->hasPost('payload')) {
|
||||
$subnets = [];
|
||||
foreach ($this->getModel()->subnets->subnet6->iterateItems() as $key => $node) {
|
||||
$subnets[(string)$node->subnet] = $key;
|
||||
}
|
||||
return $this->importCsv(
|
||||
'reservations.reservation',
|
||||
$this->request->getPost('payload'),
|
||||
['duid', 'subnet'],
|
||||
function (&$record) use ($subnets) {
|
||||
/* seek matching subnet */
|
||||
if (!empty($record['ip_address'])) {
|
||||
foreach ($subnets as $subnet => $uuid) {
|
||||
if (Util::isIPInCIDR($record['ip_address'], $subnet)) {
|
||||
$record['subnet'] = $uuid;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
} else {
|
||||
return ['status' => 'failed'];
|
||||
}
|
||||
}
|
||||
|
||||
public function searchPdPoolAction()
|
||||
{
|
||||
return $this->searchBase("pd_pools.pd_pool");
|
||||
}
|
||||
|
||||
public function setPdPoolAction($uuid)
|
||||
{
|
||||
return $this->setBase("pd_pool", "pd_pools.pd_pool", $uuid);
|
||||
}
|
||||
|
||||
public function addPdPoolAction()
|
||||
{
|
||||
return $this->addBase("pd_pool", "pd_pools.pd_pool");
|
||||
}
|
||||
|
||||
public function getPdPoolAction($uuid = null)
|
||||
{
|
||||
return $this->getBase("pd_pool", "pd_pools.pd_pool", $uuid);
|
||||
}
|
||||
|
||||
public function delPdPoolAction($uuid)
|
||||
{
|
||||
return $this->delBase("pd_pools.pd_pool", $uuid);
|
||||
}
|
||||
|
||||
public function searchPeerAction()
|
||||
{
|
||||
return $this->searchBase("ha_peers.peer", null, "name");
|
||||
}
|
||||
|
||||
public function setPeerAction($uuid)
|
||||
{
|
||||
return $this->setBase("peer", "ha_peers.peer", $uuid);
|
||||
}
|
||||
|
||||
public function addPeerAction()
|
||||
{
|
||||
return $this->addBase("peer", "ha_peers.peer");
|
||||
}
|
||||
|
||||
public function getPeerAction($uuid = null)
|
||||
{
|
||||
return $this->getBase("peer", "ha_peers.peer", $uuid);
|
||||
}
|
||||
|
||||
public function delPeerAction($uuid)
|
||||
{
|
||||
return $this->delBase("ha_peers.peer", $uuid);
|
||||
}
|
||||
}
|
||||
@ -30,6 +30,8 @@ namespace OPNsense\Kea\Api;
|
||||
|
||||
use OPNsense\Base\ApiMutableServiceControllerBase;
|
||||
use OPNsense\Core\Backend;
|
||||
use OPNsense\Kea\KeaDhcpv4;
|
||||
use OPNsense\Kea\KeaDhcpv6;
|
||||
|
||||
class ServiceController extends ApiMutableServiceControllerBase
|
||||
{
|
||||
@ -38,8 +40,8 @@ class ServiceController extends ApiMutableServiceControllerBase
|
||||
protected static $internalServiceEnabled = 'general.enabled';
|
||||
protected static $internalServiceName = 'kea';
|
||||
|
||||
/**
|
||||
* TODO: overwrite when implementing KeaDhcpv6 as well. Both services share the same rc script
|
||||
* protected function serviceEnabled() {}
|
||||
*/
|
||||
protected function serviceEnabled()
|
||||
{
|
||||
return (new KeaDhcpv4())->general->enabled == '1' || (new KeaDhcpv6())->general->enabled == '1';
|
||||
}
|
||||
}
|
||||
|
||||
@ -61,6 +61,24 @@ class DhcpController extends \OPNsense\Base\IndexController
|
||||
$this->view->formGridPeer = $this->getFormGrid("dialogPeer4");
|
||||
}
|
||||
|
||||
public function v6Action()
|
||||
{
|
||||
$this->view->pick('OPNsense/Kea/dhcpv6');
|
||||
$this->view->formGeneralSettings = $this->getForm("generalSettings6");
|
||||
|
||||
$this->view->formDialogSubnet = $this->getForm("dialogSubnet6");
|
||||
$this->view->formGridSubnet = $this->getFormGrid("dialogSubnet6");
|
||||
|
||||
$this->view->formDialogReservation = $this->getForm("dialogReservation6");
|
||||
$this->view->formGridReservation = $this->getFormGrid("dialogReservation6");
|
||||
|
||||
$this->view->formDialogPDPool = $this->getForm("dialogPDPool6");
|
||||
$this->view->formGridPDPool = $this->getFormGrid("dialogPDPool6");
|
||||
|
||||
$this->view->formDialogPeer = $this->getForm("dialogPeer6");
|
||||
$this->view->formGridPeer = $this->getFormGrid("dialogPeer6");
|
||||
}
|
||||
|
||||
public function leases4Action()
|
||||
{
|
||||
$this->view->pick('OPNsense/Kea/leases4');
|
||||
|
||||
@ -0,0 +1,32 @@
|
||||
<form>
|
||||
<field>
|
||||
<id>pd_pool.subnet</id>
|
||||
<label>Subnet</label>
|
||||
<type>dropdown</type>
|
||||
<help>Subnet this reservation belongs to</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>pd_pool.prefix</id>
|
||||
<label>Prefix</label>
|
||||
<type>text</type>
|
||||
<help></help>
|
||||
</field>
|
||||
<field>
|
||||
<id>pd_pool.prefix_len</id>
|
||||
<label>Prefix length</label>
|
||||
<type>text</type>
|
||||
<help></help>
|
||||
</field>
|
||||
<field>
|
||||
<id>pd_pool.delegated_len</id>
|
||||
<label>Delegated Length</label>
|
||||
<type>text</type>
|
||||
<help></help>
|
||||
</field>
|
||||
<field>
|
||||
<id>pd_pool.description</id>
|
||||
<label>Description</label>
|
||||
<type>text</type>
|
||||
<help>You may enter a description here for your reference (not parsed).</help>
|
||||
</field>
|
||||
</form>
|
||||
@ -0,0 +1,21 @@
|
||||
<form>
|
||||
<field>
|
||||
<id>peer.name</id>
|
||||
<label>Name</label>
|
||||
<type>text</type>
|
||||
<help>Peer name, there should be one entry matching this machines "This server name"</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>peer.role</id>
|
||||
<label>Role</label>
|
||||
<type>dropdown</type>
|
||||
<help>This peers role</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>peer.url</id>
|
||||
<label>Url</label>
|
||||
<type>text</type>
|
||||
<help>This specifies the URL of our server instance, which should use a different port than the control agent.
|
||||
For example http://my.host:8001/</help>
|
||||
</field>
|
||||
</form>
|
||||
@ -0,0 +1,44 @@
|
||||
<form>
|
||||
<field>
|
||||
<id>reservation.subnet</id>
|
||||
<label>Subnet</label>
|
||||
<type>dropdown</type>
|
||||
<help>Subnet this reservation belongs to</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>reservation.ip_address</id>
|
||||
<label>IP address</label>
|
||||
<type>text</type>
|
||||
<help>IP address to offer to the client</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>reservation.duid</id>
|
||||
<label>DUID</label>
|
||||
<type>text</type>
|
||||
<help>duid of the client in question</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>reservation.hostname</id>
|
||||
<label>Hostname</label>
|
||||
<type>text</type>
|
||||
<help>Offer a hostname to the client</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>reservation.domain_search</id>
|
||||
<label>Domain search</label>
|
||||
<type>select_multiple</type>
|
||||
<style>tokenize</style>
|
||||
<allownew>true</allownew>
|
||||
<separator>,</separator>
|
||||
<help>Specifies a ´search list´ of Domain Names to be used by the client to locate not-fully-qualified domain names.</help>
|
||||
<grid_view>
|
||||
<visible>false</visible>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>reservation.description</id>
|
||||
<label>Description</label>
|
||||
<type>text</type>
|
||||
<help>You may enter a description here for your reference (not parsed).</help>
|
||||
</field>
|
||||
</form>
|
||||
@ -0,0 +1,47 @@
|
||||
<form>
|
||||
<field>
|
||||
<id>subnet6.subnet</id>
|
||||
<label>Subnet</label>
|
||||
<type>text</type>
|
||||
<help>Subnet to use, should be large enough to hold the specified pools and reservations</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>subnet6.description</id>
|
||||
<label>Description</label>
|
||||
<type>text</type>
|
||||
<help>You may enter a description here for your reference (not parsed).</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>subnet6.pools</id>
|
||||
<label>Pools</label>
|
||||
<type>textbox</type>
|
||||
<help>List of pools, one per line in range or subnet format (e.g. 2001:db8:1::-2001:db8:1::100, 2001:db8:1::/80</help>
|
||||
</field>
|
||||
<field>
|
||||
<type>header</type>
|
||||
<label>DHCP option data</label>
|
||||
</field>
|
||||
<field>
|
||||
<id>subnet6.option_data.dns_servers</id>
|
||||
<label>DNS servers</label>
|
||||
<type>select_multiple</type>
|
||||
<style>tokenize</style>
|
||||
<allownew>true</allownew>
|
||||
<help>DNS servers to offer to the clients</help>
|
||||
<grid_view>
|
||||
<visible>false</visible>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>subnet6.option_data.domain_search</id>
|
||||
<label>Domain search</label>
|
||||
<type>select_multiple</type>
|
||||
<style>tokenize</style>
|
||||
<allownew>true</allownew>
|
||||
<separator>,</separator>
|
||||
<help>Specifies a ´search list´ of Domain Names to be used by the client to locate not-fully-qualified domain names.</help>
|
||||
<grid_view>
|
||||
<visible>false</visible>
|
||||
</grid_view>
|
||||
</field>
|
||||
</form>
|
||||
@ -1,7 +1,7 @@
|
||||
<form>
|
||||
<field>
|
||||
<type>header</type>
|
||||
<label>General settings</label>
|
||||
<label>Service</label>
|
||||
</field>
|
||||
<field>
|
||||
<id>dhcpv4.general.enabled</id>
|
||||
@ -9,6 +9,17 @@
|
||||
<type>checkbox</type>
|
||||
<help>Enable DHCPv4 server.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>dhcpv4.general.manual_config</id>
|
||||
<label>Manual config</label>
|
||||
<type>checkbox</type>
|
||||
<advanced>true</advanced>
|
||||
<help>Disable configuration file generation and manage the file (/usr/local/etc/kea/kea-dhcp4.conf) manually.</help>
|
||||
</field>
|
||||
<field>
|
||||
<type>header</type>
|
||||
<label>General settings</label>
|
||||
</field>
|
||||
<field>
|
||||
<id>dhcpv4.general.interfaces</id>
|
||||
<label>Interfaces</label>
|
||||
|
||||
@ -0,0 +1,69 @@
|
||||
<form>
|
||||
<field>
|
||||
<type>header</type>
|
||||
<label>Service</label>
|
||||
</field>
|
||||
<field>
|
||||
<id>dhcpv6.general.enabled</id>
|
||||
<label>Enabled</label>
|
||||
<type>checkbox</type>
|
||||
<help>Enable DHCPv6 server.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>dhcpv6.general.manual_config</id>
|
||||
<label>Manual config</label>
|
||||
<type>checkbox</type>
|
||||
<advanced>true</advanced>
|
||||
<help>Disable configuration file generation and manage the file (/usr/local/etc/kea/kea-dhcp4.conf) manually.</help>
|
||||
</field>
|
||||
<field>
|
||||
<type>header</type>
|
||||
<label>General settings</label>
|
||||
</field>
|
||||
<field>
|
||||
<id>dhcpv6.general.interfaces</id>
|
||||
<label>Interfaces</label>
|
||||
<type>select_multiple</type>
|
||||
<help>Select interfaces to listen on.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>dhcpv6.general.valid_lifetime</id>
|
||||
<label>Valid lifetime</label>
|
||||
<type>text</type>
|
||||
<help>Defines how long the addresses (leases) given out by the server are valid (in seconds)</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>dhcpv6.general.fwrules</id>
|
||||
<label>Firewall rules</label>
|
||||
<type>checkbox</type>
|
||||
<help>Automatically add a basic set of firewall rules to allow dhcp traffic, more fine grained controls can be offered manually when disabling this option.</help>
|
||||
</field>
|
||||
<field>
|
||||
<type>header</type>
|
||||
<label>High Availability</label>
|
||||
</field>
|
||||
<field>
|
||||
<id>dhcpv6.ha.enabled</id>
|
||||
<label>Enabled</label>
|
||||
<type>checkbox</type>
|
||||
<help>Enable High availability hook, requires the Control Agent to be enabled as well.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>dhcpv6.ha.this_server_name</id>
|
||||
<label>This server name</label>
|
||||
<type>text</type>
|
||||
<help>The name of this server, should match with one of the entries in the HA peers.
|
||||
Leave empty to use this machines hostname
|
||||
</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>dhcpv6.ha.max_unacked_clients</id>
|
||||
<label>Max Unacked clients</label>
|
||||
<type>text</type>
|
||||
<help>
|
||||
This specifies the number of clients which send messages to the partner but appear to not receive any response.
|
||||
A higher value needs a busier environment in order to consider a member down, when set to 0,
|
||||
any network disruption will cause a failover to happen.
|
||||
</help>
|
||||
</field>
|
||||
</form>
|
||||
@ -57,6 +57,13 @@
|
||||
<style>export_option</style>
|
||||
<help>Sets auth-nocache in the exported configuration when password authentication is used. This prevents OpenVPN from caching passwords in memory.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>openvpn_export.static_challenge</id>
|
||||
<label>Enable static challenge (OTP)</label>
|
||||
<type>checkbox</type>
|
||||
<style>export_option</style>
|
||||
<help>Ask the user for its one time password token separately (instead of as part the password).</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>openvpn_export.plain_config</id>
|
||||
<label>Custom config</label>
|
||||
|
||||
@ -58,10 +58,17 @@
|
||||
</field>
|
||||
<field>
|
||||
<id>gateway_item.monitor_killstates</id>
|
||||
<label>Kill states when down</label>
|
||||
<label>Failover States</label>
|
||||
<type>checkbox</type>
|
||||
<style>monitor_opt</style>
|
||||
<help>When a monitor down event is triggered, kill all states to this gateway.</help>
|
||||
<help>If this gateway goes down, force clients to reconnect over a different online gateway by killing states associated with this gateway. This option requires "default gateway switching" to be enabled, or this gateway assigned as part of a gateway group to trigger.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>gateway_item.monitor_killstates_priority</id>
|
||||
<label>Failback States</label>
|
||||
<type>checkbox</type>
|
||||
<style>monitor_opt</style>
|
||||
<help>If another gateway comes up with a higher priority than this gateway, force clients to reconnect by killing states associated with this gateway. This option requires "default gateway switching" to be enabled, or this gateway assigned as part of a gateway group to trigger. The common use case for this option are metered connections over LTE that should only be used when no other gateway is online.</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>gateway_item.monitor</id>
|
||||
|
||||
@ -114,11 +114,7 @@ class SettingsController extends ApiMutableModelControllerBase
|
||||
*/
|
||||
public function searchPipesAction()
|
||||
{
|
||||
return $this->searchBase(
|
||||
"pipes.pipe",
|
||||
array("enabled","number", "bandwidth","bandwidthMetric","description","mask","origin"),
|
||||
"number"
|
||||
);
|
||||
return $this->searchBase("pipes.pipe", null, "number");
|
||||
}
|
||||
|
||||
|
||||
@ -129,11 +125,7 @@ class SettingsController extends ApiMutableModelControllerBase
|
||||
*/
|
||||
public function searchQueuesAction()
|
||||
{
|
||||
return $this->searchBase(
|
||||
"queues.queue",
|
||||
array("enabled","number", "pipe","weight","description","mask","origin"),
|
||||
"number"
|
||||
);
|
||||
return $this->searchBase("queues.queue", null, "number");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -204,12 +196,7 @@ class SettingsController extends ApiMutableModelControllerBase
|
||||
*/
|
||||
public function searchRulesAction()
|
||||
{
|
||||
return $this->searchBase(
|
||||
"rules.rule",
|
||||
array("enabled", "interface", "proto", "source_not","source", "destination_not",
|
||||
"destination", "description", "origin", "sequence", "target"),
|
||||
"sequence"
|
||||
);
|
||||
return $this->searchBase("rules.rule", null, "sequence");
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -44,8 +44,14 @@ class IndexController extends \OPNsense\Base\IndexController
|
||||
{
|
||||
// include dialog form definitions
|
||||
$this->view->formDialogPipe = $this->getForm("dialogPipe");
|
||||
$this->view->formGridPipe = $this->getFormGrid("dialogPipe");
|
||||
|
||||
$this->view->formDialogQueue = $this->getForm("dialogQueue");
|
||||
$this->view->formGridQueue = $this->getFormGrid("dialogQueue");
|
||||
|
||||
$this->view->formDialogRule = $this->getForm("dialogRule");
|
||||
$this->view->formGridRule = $this->getFormGrid("dialogRule");
|
||||
|
||||
// choose template
|
||||
$this->view->pick('OPNsense/TrafficShaper/index');
|
||||
}
|
||||
|
||||
@ -4,6 +4,11 @@
|
||||
<label>Enabled</label>
|
||||
<type>checkbox</type>
|
||||
<help>Enable this pipe and its related queues and rules</help>
|
||||
<grid_view>
|
||||
<width>6em</width>
|
||||
<type>boolean</type>
|
||||
<formatter>rowtoggle</formatter>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>pipe.bandwidth</id>
|
||||
@ -22,6 +27,9 @@
|
||||
<type>text</type>
|
||||
<help>number of dynamic queues, leave empty for default</help>
|
||||
<advanced>true</advanced>
|
||||
<grid_view>
|
||||
<visible>false</visible>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>pipe.mask</id>
|
||||
@ -39,6 +47,9 @@
|
||||
<type>text</type>
|
||||
<help>Specifies the size of the hash table used for storing the various dynamic pipes configured with the mask setting</help>
|
||||
<advanced>true</advanced>
|
||||
<grid_view>
|
||||
<visible>false</visible>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>pipe.scheduler</id>
|
||||
@ -46,12 +57,20 @@
|
||||
<type>dropdown</type>
|
||||
<advanced>true</advanced>
|
||||
<help>Specify the scheduling algorithm to use</help>
|
||||
<grid_view>
|
||||
<visible>false</visible>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>pipe.codel_enable</id>
|
||||
<label>Enable CoDel</label>
|
||||
<type>checkbox</type>
|
||||
<help>Enable CoDel active queue management</help>
|
||||
<grid_view>
|
||||
<visible>false</visible>
|
||||
<type>boolean</type>
|
||||
<formatter>boolean</formatter>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>pipe.codel_target</id>
|
||||
@ -59,6 +78,9 @@
|
||||
<type>text</type>
|
||||
<advanced>true</advanced>
|
||||
<help>Minimum acceptable persistent queue delay (in ms), leave empty for default</help>
|
||||
<grid_view>
|
||||
<visible>false</visible>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>pipe.codel_interval</id>
|
||||
@ -66,6 +88,9 @@
|
||||
<type>text</type>
|
||||
<advanced>true</advanced>
|
||||
<help>Interval before dropping packets (in ms), leave empty for default</help>
|
||||
<grid_view>
|
||||
<visible>false</visible>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>pipe.codel_ecn_enable</id>
|
||||
@ -73,6 +98,11 @@
|
||||
<type>checkbox</type>
|
||||
<advanced>true</advanced>
|
||||
<help>Explicit Congestion Notification</help>
|
||||
<grid_view>
|
||||
<visible>false</visible>
|
||||
<type>boolean</type>
|
||||
<formatter>boolean</formatter>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>pipe.fqcodel_quantum</id>
|
||||
@ -80,6 +110,9 @@
|
||||
<type>text</type>
|
||||
<advanced>true</advanced>
|
||||
<help>The number of bytes a queue can serve before being moved to the tail of old queues list (bytes), leave empty for defaults</help>
|
||||
<grid_view>
|
||||
<visible>false</visible>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>pipe.fqcodel_limit</id>
|
||||
@ -87,6 +120,9 @@
|
||||
<type>text</type>
|
||||
<advanced>true</advanced>
|
||||
<help>The hard size limit of all queues managed by this instance, leave empty for defaults</help>
|
||||
<grid_view>
|
||||
<visible>false</visible>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>pipe.fqcodel_flows</id>
|
||||
@ -94,12 +130,20 @@
|
||||
<type>text</type>
|
||||
<advanced>true</advanced>
|
||||
<help>The number of flow queues that are created and managed, leave empty for defaults</help>
|
||||
<grid_view>
|
||||
<visible>false</visible>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>pipe.pie_enable</id>
|
||||
<label>Enable PIE</label>
|
||||
<type>checkbox</type>
|
||||
<help>Enable PIE active queue management</help>
|
||||
<grid_view>
|
||||
<visible>false</visible>
|
||||
<type>boolean</type>
|
||||
<formatter>boolean</formatter>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>pipe.delay</id>
|
||||
@ -107,6 +151,9 @@
|
||||
<type>text</type>
|
||||
<advanced>true</advanced>
|
||||
<help>Add delay in ms to this pipe.</help>
|
||||
<grid_view>
|
||||
<visible>false</visible>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>pipe.description</id>
|
||||
|
||||
@ -4,6 +4,11 @@
|
||||
<label>Enabled</label>
|
||||
<type>checkbox</type>
|
||||
<help>Enable this queue and its related rules</help>
|
||||
<grid_view>
|
||||
<width>6em</width>
|
||||
<type>boolean</type>
|
||||
<formatter>rowtoggle</formatter>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>queue.pipe</id>
|
||||
@ -26,6 +31,9 @@
|
||||
<li>Choose source to evenly share every IP in the source field of rules the specified bandwidth. Normally this is used for upload queues.</li>
|
||||
<li>Leave this value empty if you want to specify multiple queues with different weights.</li>
|
||||
]]></help>
|
||||
<grid_view>
|
||||
<visible>false</visible>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>queue.buckets</id>
|
||||
@ -33,12 +41,20 @@
|
||||
<type>text</type>
|
||||
<help>Specifies the size of the hash table used for storing the various dynamic queues configured with the mask setting</help>
|
||||
<advanced>true</advanced>
|
||||
<grid_view>
|
||||
<visible>false</visible>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>queue.codel_enable</id>
|
||||
<label>Enable CoDel</label>
|
||||
<type>checkbox</type>
|
||||
<help>Enable CoDel active queue management</help>
|
||||
<grid_view>
|
||||
<visible>false</visible>
|
||||
<type>boolean</type>
|
||||
<formatter>boolean</formatter>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>queue.codel_target</id>
|
||||
@ -46,6 +62,9 @@
|
||||
<type>text</type>
|
||||
<advanced>true</advanced>
|
||||
<help>Minimum acceptable persistent queue delay (in ms), leave empty for default</help>
|
||||
<grid_view>
|
||||
<visible>false</visible>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>queue.codel_interval</id>
|
||||
@ -53,6 +72,9 @@
|
||||
<type>text</type>
|
||||
<advanced>true</advanced>
|
||||
<help>Interval before dropping packets (in ms), leave empty for default</help>
|
||||
<grid_view>
|
||||
<visible>false</visible>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>queue.codel_ecn_enable</id>
|
||||
@ -60,12 +82,22 @@
|
||||
<type>checkbox</type>
|
||||
<advanced>true</advanced>
|
||||
<help>Explicit Congestion Notification</help>
|
||||
<grid_view>
|
||||
<visible>false</visible>
|
||||
<type>boolean</type>
|
||||
<formatter>boolean</formatter>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>queue.pie_enable</id>
|
||||
<label>Enable PIE</label>
|
||||
<type>checkbox</type>
|
||||
<help>Enable PIE active queue management</help>
|
||||
<grid_view>
|
||||
<visible>false</visible>
|
||||
<type>boolean</type>
|
||||
<formatter>boolean</formatter>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>queue.description</id>
|
||||
|
||||
@ -4,6 +4,11 @@
|
||||
<label>Enabled</label>
|
||||
<type>checkbox</type>
|
||||
<help>enable this rule</help>
|
||||
<grid_view>
|
||||
<width>6em</width>
|
||||
<type>boolean</type>
|
||||
<formatter>rowtoggle</formatter>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>rule.sequence</id>
|
||||
@ -22,6 +27,9 @@
|
||||
<type>dropdown</type>
|
||||
<advanced>true</advanced>
|
||||
<help>secondary interface, matches packets traveling to/from interface (1) to/from interface (2). can be combined with direction.</help>
|
||||
<grid_view>
|
||||
<visible>false</visible>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>rule.proto</id>
|
||||
@ -35,6 +43,9 @@
|
||||
<advanced>true</advanced>
|
||||
<type>text</type>
|
||||
<help>Specifies the maximum size of packets to match in bytes</help>
|
||||
<grid_view>
|
||||
<visible>false</visible>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>rule.source</id>
|
||||
@ -49,12 +60,18 @@
|
||||
<label>Invert source</label>
|
||||
<type>checkbox</type>
|
||||
<help>invert source (not)</help>
|
||||
<grid_view>
|
||||
<ignore>true</ignore>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>rule.src_port</id>
|
||||
<label>Src-port</label>
|
||||
<type>text</type>
|
||||
<help>Source port number or well known name (imap, imaps, http, https, ...), for ranges use a dash</help>
|
||||
<grid_view>
|
||||
<visible>false</visible>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>rule.destination</id>
|
||||
@ -69,12 +86,18 @@
|
||||
<label>Invert destination</label>
|
||||
<type>checkbox</type>
|
||||
<help>invert destination (not)</help>
|
||||
<grid_view>
|
||||
<ignore>true</ignore>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>rule.dst_port</id>
|
||||
<label>Dst-port</label>
|
||||
<type>text</type>
|
||||
<help>Destination port number or well known name (imap, imaps, http, https, ...), for ranges use a dash</help>
|
||||
<grid_view>
|
||||
<visible>false</visible>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>rule.dscp</id>
|
||||
@ -82,6 +105,9 @@
|
||||
<type>select_multiple</type>
|
||||
<advanced>true</advanced>
|
||||
<help>Match against one or multiple DSCP values.</help>
|
||||
<grid_view>
|
||||
<visible>false</visible>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>rule.direction</id>
|
||||
@ -89,6 +115,9 @@
|
||||
<type>dropdown</type>
|
||||
<advanced>true</advanced>
|
||||
<help>matches incoming or outgoing packets or both (default)</help>
|
||||
<grid_view>
|
||||
<visible>false</visible>
|
||||
</grid_view>
|
||||
</field>
|
||||
<field>
|
||||
<id>rule.target</id>
|
||||
|
||||
@ -352,7 +352,7 @@ class FilterRule extends Rule
|
||||
}
|
||||
public function isUIFromNot()
|
||||
{
|
||||
return isset($this->rule['source']) && isset($this->rule['source']['not']);
|
||||
return (isset($this->rule['source']) && isset($this->rule['source']['not'])) || !empty($this->rule['from_not']);
|
||||
}
|
||||
public function getUIFromPort()
|
||||
{
|
||||
@ -378,7 +378,7 @@ class FilterRule extends Rule
|
||||
}
|
||||
public function isUIToNot()
|
||||
{
|
||||
return isset($this->rule['destination']) && isset($this->rule['destination']['not']);
|
||||
return isset($this->rule['destination']) && isset($this->rule['destination']['not']) || !empty($this->rule['to_not']);
|
||||
}
|
||||
public function getUIToPort()
|
||||
{
|
||||
|
||||
@ -48,7 +48,7 @@ class ArchiveOpenVPN extends PlainOpenVPN
|
||||
*/
|
||||
public function supportedOptions()
|
||||
{
|
||||
return array("plain_config", "p12_password", "random_local_port", "auth_nocache", "cryptoapi");
|
||||
return ["plain_config", "p12_password", "random_local_port", "auth_nocache", "cryptoapi", "static_challenge"];
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -48,7 +48,7 @@ class PlainOpenVPN extends BaseExporter implements IExportProvider
|
||||
*/
|
||||
public function supportedOptions()
|
||||
{
|
||||
return array("plain_config", "random_local_port", "auth_nocache", "cryptoapi");
|
||||
return ["plain_config", "random_local_port", "auth_nocache", "cryptoapi", "static_challenge"];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -143,6 +143,10 @@ class PlainOpenVPN extends BaseExporter implements IExportProvider
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($this->config['static_challenge'])) {
|
||||
$conf[] = sprintf('static-challenge "%s" 1', addslashes(gettext('Enter OTP token:')));
|
||||
}
|
||||
|
||||
if (!empty($this->config['compression'])) {
|
||||
switch ($this->config['compression']) {
|
||||
case 'no':
|
||||
|
||||
@ -48,7 +48,7 @@ class ViscosityVisz extends PlainOpenVPN
|
||||
*/
|
||||
public function supportedOptions()
|
||||
{
|
||||
return array("plain_config", "p12_password", "random_local_port", "auth_nocache", "cryptoapi");
|
||||
return ["plain_config", "p12_password", "random_local_port", "auth_nocache", "cryptoapi", "static_challenge"];
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -596,7 +596,11 @@ class Store
|
||||
{
|
||||
$chain = [];
|
||||
while (($item = self::getCA(!isset($item) ? $caref : $item->caref)) != null) {
|
||||
$chain[] = base64_decode((string)$item->crt);
|
||||
$data = base64_decode((string)$item->crt);
|
||||
if (in_array($data, $chain)) {
|
||||
break; /* exit endless loop */
|
||||
}
|
||||
$chain[] = $data;
|
||||
}
|
||||
return implode("\n", $chain);
|
||||
}
|
||||
|
||||
@ -28,6 +28,8 @@
|
||||
|
||||
namespace OPNsense\Base\FieldTypes;
|
||||
|
||||
use OPNsense\Core\AppConfig;
|
||||
|
||||
/**
|
||||
* Class CountryField field type to select iso3166 countries
|
||||
* @package OPNsense\Base\FieldTypes
|
||||
@ -62,7 +64,8 @@ class CountryField extends BaseListField
|
||||
self::$internalCacheOptionList[$setid] = [];
|
||||
}
|
||||
if (empty(self::$internalCacheOptionList[$setid])) {
|
||||
$filename = '/usr/local/opnsense/contrib/tzdata/iso3166.tab';
|
||||
$contribDir = (new AppConfig())->application->contribDir;
|
||||
$filename = $contribDir . '/tzdata/iso3166.tab';
|
||||
$data = file_get_contents($filename);
|
||||
foreach (explode("\n", $data) as $line) {
|
||||
$line = trim($line);
|
||||
|
||||
@ -169,6 +169,27 @@ class MenuSystem
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* temporary legacy glue to remove isc dhcp4 settings when not enabled and Dnsmasq is configured as dhcp
|
||||
* @return boolean
|
||||
*/
|
||||
|
||||
private function isc_v4_enabled($if)
|
||||
{
|
||||
$config = Config::getInstance()->object();
|
||||
if (isset($config->dhcpd) && isset($config->dhcpd->$if) && !empty((string)$config->dhcpd->$if->enable)) {
|
||||
/* still configured on interface */
|
||||
return true;
|
||||
} elseif (isset($config->dnsmasq) && empty((string)$config->dnsmasq->enable)) {
|
||||
/* dnsmasq not configured at all */
|
||||
return true;
|
||||
} elseif (isset($config->dnsmasq) && !empty((string)$config->dnsmasq->interface)) {
|
||||
/* dnsmasq configured, but only on selected interfaces */
|
||||
return !in_array($if, explode(',', $config->dnsmasq->interface));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* construct a new menu
|
||||
* @throws MenuInitException
|
||||
@ -238,10 +259,13 @@ class MenuSystem
|
||||
}
|
||||
// "Services: DHCPv[46]" menu tab:
|
||||
if (empty($node->virtual) && isset($node->enable)) {
|
||||
if (!empty(filter_var($node->ipaddr, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4))) {
|
||||
if (
|
||||
$this->isc_v4_enabled($key) &&
|
||||
!empty(filter_var($node->ipaddr, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4))
|
||||
) {
|
||||
$iftargets['dhcp4'][$key] = !empty($node->descr) ? (string)$node->descr : strtoupper($key);
|
||||
}
|
||||
if (!empty(filter_var($node->ipaddrv6, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) || !empty($node->dhcpd6track6allowoverride)) {
|
||||
if (!empty(filter_var($node->ipaddrv6, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) || !empty($node->{'track6-interface'})) {
|
||||
$iftargets['dhcp6'][$key] = !empty($node->descr) ? (string)$node->descr : strtoupper($key);
|
||||
}
|
||||
}
|
||||
|
||||
@ -31,7 +31,6 @@
|
||||
namespace OPNsense\CaptivePortal;
|
||||
|
||||
use OPNsense\Base\BaseModel;
|
||||
use OPNsense\Base\Messages\Message;
|
||||
|
||||
/**
|
||||
* Class CaptivePortal
|
||||
@ -85,35 +84,4 @@ class CaptivePortal extends BaseModel
|
||||
$newItem->fileid = uniqid();
|
||||
return $newItem;
|
||||
}
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function performValidation($validateFullModel = false)
|
||||
{
|
||||
$messages = parent::performValidation($validateFullModel);
|
||||
// validate changed instances
|
||||
foreach ($this->zones->zone->iterateItems() as $zone) {
|
||||
if (!$validateFullModel && !$zone->isFieldChanged()) {
|
||||
continue;
|
||||
}
|
||||
$key = $zone->__reference;
|
||||
if (!empty((string)$zone->interfaces_inbound) && !empty((string)$zone->interfaces)) {
|
||||
$ifs_inbound = array_filter(explode(',', $zone->interfaces_inbound));
|
||||
$ifs = array_filter(explode(',', $zone->interfaces));
|
||||
$overlap = array_intersect($ifs_inbound, $ifs);
|
||||
if (!empty($overlap)) {
|
||||
$messages->appendMessage(
|
||||
new Message(
|
||||
sprintf(
|
||||
gettext("Inbound interfaces may not overlap with zone interfaces (%s)"),
|
||||
implode(',', $overlap)
|
||||
),
|
||||
$key . ".interfaces_inbound"
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $messages;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<model>
|
||||
<mount>//OPNsense/captiveportal</mount>
|
||||
<version>1.0.2</version>
|
||||
<version>1.0.3</version>
|
||||
<description>Captive portal application model</description>
|
||||
<items>
|
||||
<zones>
|
||||
@ -25,12 +25,6 @@
|
||||
</filters>
|
||||
<ValidationMessage>At least one interface must be selected</ValidationMessage>
|
||||
</interfaces>
|
||||
<interfaces_inbound type="InterfaceField">
|
||||
<Multiple>Y</Multiple>
|
||||
<filters>
|
||||
<enable>/^(?!0).*$/</enable>
|
||||
</filters>
|
||||
</interfaces_inbound>
|
||||
<authservers type="AuthenticationServerField">
|
||||
<Multiple>Y</Multiple>
|
||||
</authservers>
|
||||
|
||||
@ -366,7 +366,7 @@ class ACL
|
||||
return "ui/user_portal";
|
||||
} elseif (!empty($this->userDatabase[$username]['landing_page'])) {
|
||||
// remove leading slash, which would result in redirection to //page (without host) after login or auth failure.
|
||||
$page = ltrim($this->userDatabase[$username]['landing_page'], '/');
|
||||
return ltrim($this->userDatabase[$username]['landing_page'], '/');
|
||||
} elseif (!empty($this->userDatabase[$username])) {
|
||||
// default behaviour, find first accessible location from configured privileges, but prefer /
|
||||
if ($this->isPageAccessible($username, '/')) {
|
||||
|
||||
@ -299,17 +299,12 @@
|
||||
</patterns>
|
||||
</page-interfaces-assignnetworkports>
|
||||
<page-interfaces-bridge-edit>
|
||||
<name>Interfaces: Bridge edit</name>
|
||||
<patterns>
|
||||
<pattern>interfaces_bridge_edit.php*</pattern>
|
||||
</patterns>
|
||||
</page-interfaces-bridge-edit>
|
||||
<page-interfaces-bridge>
|
||||
<name>Interfaces: Bridge</name>
|
||||
<patterns>
|
||||
<pattern>interfaces_bridge.php*</pattern>
|
||||
<pattern>ui/interfaces/bridge</pattern>
|
||||
<pattern>api/interfaces/bridge_settings/*</pattern>
|
||||
</patterns>
|
||||
</page-interfaces-bridge>
|
||||
</page-interfaces-bridge-edit>
|
||||
<page-interfaces-gif-edit>
|
||||
<name>Interfaces: GIF</name>
|
||||
<patterns>
|
||||
|
||||
@ -16,10 +16,6 @@
|
||||
<url>https://opnsense-update.deciso.com</url>
|
||||
<description>Deciso (HTTPS, NL, Commercial)</description>
|
||||
</mirror>
|
||||
<mirror>
|
||||
<url>https://mirror.dns-root.de/opnsense</url>
|
||||
<description>dns-root.de (HTTPS, Cloudflare CDN)</description>
|
||||
</mirror>
|
||||
<mirror>
|
||||
<url>https://opnsense.c0urier.net</url>
|
||||
<description>c0urier.net (HTTPS, Horsens, DK)</description>
|
||||
|
||||
@ -31,6 +31,7 @@ namespace OPNsense\Dnsmasq;
|
||||
use OPNsense\Base\BaseModel;
|
||||
use OPNsense\Base\Messages\Message;
|
||||
use OPNsense\Core\Backend;
|
||||
use OPNsense\Firewall\Util;
|
||||
|
||||
/**
|
||||
* Class Dnsmasq
|
||||
@ -174,7 +175,16 @@ class Dnsmasq extends BaseModel
|
||||
);
|
||||
}
|
||||
|
||||
if (in_array('static', explode(',', $range->mode)) && $start_inet == 'inet6') {
|
||||
$is_static = in_array('static', explode(',', $range->mode));
|
||||
if (!$range->end_addr->isEmpty() && $is_static) {
|
||||
$messages->appendMessage(
|
||||
new Message(
|
||||
gettext("Static only accepts a starting address."),
|
||||
$key . ".end_addr"
|
||||
)
|
||||
);
|
||||
}
|
||||
if ($is_static && $start_inet == 'inet6') {
|
||||
$messages->appendMessage(
|
||||
new Message(
|
||||
gettext("Static is only available IPv4."),
|
||||
@ -250,32 +260,36 @@ class Dnsmasq extends BaseModel
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->dhcp_options_match->iterateItems() as $match) {
|
||||
if (!$validateFullModel && !$match->isFieldChanged()) {
|
||||
continue;
|
||||
}
|
||||
$key = $match->__reference;
|
||||
|
||||
if (!$match->option->isEmpty() && !$match->option6->isEmpty()) {
|
||||
if ($option->type == 'match' && $option->set_tag->isEmpty()) {
|
||||
$messages->appendMessage(
|
||||
new Message(
|
||||
gettext("'Option' and 'Option6' cannot be selected at the same time."),
|
||||
$key . ".option"
|
||||
gettext("When type is 'Match', a tag must be set."),
|
||||
$key . ".set_tag"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if ($match->option->isEmpty() && $match->option6->isEmpty()) {
|
||||
if (
|
||||
!$option->value->isEmpty() &&
|
||||
!$option->option6->isEmpty()
|
||||
) {
|
||||
$values = array_map('trim', explode(',', (string)$option->value));
|
||||
foreach ($values as $value) {
|
||||
if (
|
||||
Util::isIpv6Address(trim($value, '[]')) &&
|
||||
!(str_starts_with($value, '[') && str_ends_with($value, ']'))
|
||||
) {
|
||||
$messages->appendMessage(
|
||||
new Message(
|
||||
gettext("Either 'Option' or 'Option6' is required."),
|
||||
$key . ".option"
|
||||
gettext("Each IPv6 address must be wrapped inside square brackets '[fe80::]'."),
|
||||
$key . ".value"
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
($validateFullModel || $this->enable->isFieldChanged() || $this->port->isFieldChanged()) &&
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<model>
|
||||
<mount>/dnsmasq</mount>
|
||||
<version>1.0.4</version>
|
||||
<version>1.0.5</version>
|
||||
<items>
|
||||
<enable type="BooleanField"/>
|
||||
<regdhcp type="BooleanField"/>
|
||||
@ -219,6 +219,14 @@
|
||||
<description type="DescriptionField"/>
|
||||
</dhcp_ranges>
|
||||
<dhcp_options type="ArrayField">
|
||||
<type type="OptionField">
|
||||
<OptionValues>
|
||||
<set>Set</set>
|
||||
<match>Match</match>
|
||||
</OptionValues>
|
||||
<Default>set</Default>
|
||||
<Required>Y</Required>
|
||||
</type>
|
||||
<option type="JsonKeyValueStoreField">
|
||||
<ConfigdPopulateAct>dnsmasq list dhcp_options</ConfigdPopulateAct>
|
||||
</option>
|
||||
@ -243,17 +251,6 @@
|
||||
</Model>
|
||||
<Multiple>Y</Multiple>
|
||||
</tag>
|
||||
<value type="TextField"/>
|
||||
<force type="BooleanField"/>
|
||||
<description type="DescriptionField"/>
|
||||
</dhcp_options>
|
||||
<dhcp_options_match type="ArrayField">
|
||||
<option type="JsonKeyValueStoreField">
|
||||
<ConfigdPopulateAct>dnsmasq list dhcp_options</ConfigdPopulateAct>
|
||||
</option>
|
||||
<option6 type="JsonKeyValueStoreField">
|
||||
<ConfigdPopulateAct>dnsmasq list dhcp_options6</ConfigdPopulateAct>
|
||||
</option6>
|
||||
<set_tag type="ModelRelationField">
|
||||
<Model>
|
||||
<tag>
|
||||
@ -262,11 +259,11 @@
|
||||
<display>tag</display>
|
||||
</tag>
|
||||
</Model>
|
||||
<Required>Y</Required>
|
||||
</set_tag>
|
||||
<value type="TextField"/>
|
||||
<force type="BooleanField"/>
|
||||
<description type="DescriptionField"/>
|
||||
</dhcp_options_match>
|
||||
</dhcp_options>
|
||||
<dhcp_boot type="ArrayField">
|
||||
<tag type="ModelRelationField">
|
||||
<Model>
|
||||
|
||||
@ -7,7 +7,6 @@
|
||||
<Dhcpranges VisibleName="DHCP ranges" order="50" url="/ui/dnsmasq/settings#dhcpranges"/>
|
||||
<Dhcpoptions VisibleName="DHCP options" order="60" url="/ui/dnsmasq/settings#dhcpoptions"/>
|
||||
<Dhcptags VisibleName="DHCP tags" order="65" url="/ui/dnsmasq/settings#dhcptags"/>
|
||||
<Dhcpmatches VisibleName="DHCP matches" order="70" url="/ui/dnsmasq/settings#dhcpmatches"/>
|
||||
<Leases order="80" url="/ui/dnsmasq/leases"/>
|
||||
<LogFile VisibleName="Log File" order="90" url="/ui/diagnostics/log/core/dnsmasq"/>
|
||||
</Dnsmasq>
|
||||
|
||||
@ -31,6 +31,7 @@ namespace OPNsense\Firewall\FieldTypes;
|
||||
use OPNsense\Base\FieldTypes\BaseField;
|
||||
use OPNsense\Base\Messages\Message;
|
||||
use OPNsense\Base\Validators\CallbackValidator;
|
||||
use OPNsense\Core\AppConfig;
|
||||
use OPNsense\Core\Config;
|
||||
use OPNsense\Firewall\Util;
|
||||
|
||||
@ -105,7 +106,8 @@ class AliasContentField extends BaseField
|
||||
if (empty(self::$internalCountryCodes)) {
|
||||
// Maxmind's country code 6255148 (EU Unclassified)
|
||||
self::$internalCountryCodes[] = 'EU';
|
||||
foreach (explode("\n", file_get_contents('/usr/local/opnsense/contrib/tzdata/iso3166.tab')) as $line) {
|
||||
$contribDir = (new AppConfig())->application->contribDir;
|
||||
foreach (explode("\n", file_get_contents($contribDir . '/tzdata/iso3166.tab')) as $line) {
|
||||
$line = trim($line);
|
||||
if (strlen($line) > 3 && substr($line, 0, 1) != '#') {
|
||||
self::$internalCountryCodes[] = substr($line, 0, 2);
|
||||
|
||||
@ -1,8 +1,7 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
/*
|
||||
* Copyright (C) 2023 Deciso B.V.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -25,7 +24,6 @@
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OPNsense\Firewall\FieldTypes;
|
||||
@ -46,17 +44,17 @@ class GroupField extends ArrayField
|
||||
'openvpn' => [
|
||||
'sequence' => 10,
|
||||
'ifname' => 'openvpn',
|
||||
'descr' => gettext('All OpenVPN interfaces')
|
||||
'descr' => gettext('All OpenVPN interfaces'),
|
||||
],
|
||||
'enc0' => [
|
||||
'sequence' => 10,
|
||||
'ifname' => 'enc0',
|
||||
'descr' => gettext('IPsec')
|
||||
'descr' => gettext('IPsec'),
|
||||
],
|
||||
'wireguard' => [
|
||||
'sequence' => 10,
|
||||
'ifname' => 'wireguard',
|
||||
'descr' => gettext('WireGuard')
|
||||
'descr' => gettext('WireGuard'),
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
@ -92,6 +92,26 @@ class Filter extends BaseModel
|
||||
}
|
||||
}
|
||||
|
||||
if (!$rule->icmptype->isEmpty() && !in_array($rule->protocol, ['ICMP'])) {
|
||||
$messages->appendMessage(new Message(
|
||||
gettext("Option only applies to ICMP packets"),
|
||||
$rule->icmptype->__reference
|
||||
));
|
||||
}
|
||||
|
||||
if (strpos($rule->source_net, ',') !== false && $rule->source_not == '1') {
|
||||
$messages->appendMessage(new Message(
|
||||
gettext("Inverting sources is only allowed for single targets to avoid mis-interpretations"),
|
||||
$rule->source_not->__reference
|
||||
));
|
||||
}
|
||||
if (strpos($rule->destination_net, ',') !== false && $rule->destination_not == '1') {
|
||||
$messages->appendMessage(new Message(
|
||||
gettext("Inverting destinations is only allowed for single targets to avoid mis-interpretations"),
|
||||
$rule->destination_net->__reference
|
||||
));
|
||||
}
|
||||
|
||||
// Additional source nat validations
|
||||
if ($rule->target !== null) {
|
||||
$target_is_addr = Util::isSubnet($rule->target) || Util::isIpAddress($rule->target);
|
||||
|
||||
@ -85,6 +85,27 @@
|
||||
<opt1 value='TCP/UDP'>TCP/UDP</opt1>
|
||||
</AddOptions>
|
||||
</protocol>
|
||||
<icmptype type="OptionField">
|
||||
<Multiple>Y</Multiple>
|
||||
<OptionValues>
|
||||
<echoreq>Echo Request</echoreq>
|
||||
<echorep>Echo Reply</echorep>
|
||||
<unreach>Destination Unreachable</unreach>
|
||||
<squench>Source Quench (Deprecated)</squench>
|
||||
<redir>Redirect</redir>
|
||||
<althost>Alternate Host Address (Deprecated)</althost>
|
||||
<routeradv>Router Advertisement</routeradv>
|
||||
<routersol>Router Solicitation</routersol>
|
||||
<timex>Time Exceeded</timex>
|
||||
<paramprob>Parameter Problem</paramprob>
|
||||
<timereq>Timestamp</timereq>
|
||||
<timerep>Timestamp Reply</timerep>
|
||||
<inforeq>Information Request (Deprecated)</inforeq>
|
||||
<inforep>Information Reply (Deprecated)</inforep>
|
||||
<maskreq>Address Mask Request (Deprecated)</maskreq>
|
||||
<maskrep>Address Mask Reply (Deprecated)</maskrep>
|
||||
</OptionValues>
|
||||
</icmptype>
|
||||
<!-- XXX: should map internally to 'source' => array('network' => $source_net, "not" => true|false) -->
|
||||
<source_net type="NetworkAliasField">
|
||||
<Default>any</Default>
|
||||
|
||||
@ -6,11 +6,11 @@
|
||||
<patterns>
|
||||
<pattern>ui/ipsec/key_pairs/*</pattern>
|
||||
<pattern>api/ipsec/key_pairs/*</pattern>
|
||||
<pattern>api/ipsec/legacy_subsystem/*</pattern>
|
||||
<pattern>api/ipsec/service/*</pattern>
|
||||
</patterns>
|
||||
</page-vpn-ipsec-keypairs>
|
||||
<page-vpn-ipsec>
|
||||
<name>VPN: IPsec: Tunnels Settings [legacy]</name>
|
||||
<name>VPN: IPsec: Tunnels [legacy]</name>
|
||||
<patterns>
|
||||
<pattern>ui/ipsec/tunnels</pattern>
|
||||
<pattern>api/ipsec/tunnel/*</pattern>
|
||||
@ -21,11 +21,12 @@
|
||||
<name>VPN: IPsec: Connections</name>
|
||||
<patterns>
|
||||
<pattern>ui/ipsec/connections</pattern>
|
||||
<pattern>ui/ipsec/connections/settings</pattern>
|
||||
<pattern>ui/ipsec/vti</pattern>
|
||||
<pattern>api/ipsec/connections/*</pattern>
|
||||
<pattern>api/ipsec/pools/*</pattern>
|
||||
<pattern>api/ipsec/service/*</pattern>
|
||||
<pattern>api/ipsec/vti/*</pattern>
|
||||
<pattern>api/ipsec/legacy_subsystem/*</pattern>
|
||||
</patterns>
|
||||
</page-vpn-ipsec-connections>
|
||||
|
||||
@ -47,10 +48,11 @@
|
||||
<patterns>
|
||||
<pattern>ui/ipsec/pre_shared_keys</pattern>
|
||||
<pattern>api/ipsec/pre_shared_keys/*</pattern>
|
||||
<pattern>api/ipsec/service/*</pattern>
|
||||
</patterns>
|
||||
</page-vpn-ipsec-editkeys>
|
||||
<page-vpn-ipsec-mobile>
|
||||
<name>VPN: IPsec: Mobile</name>
|
||||
<name>VPN: IPsec: Mobile [legacy]</name>
|
||||
<patterns>
|
||||
<pattern>vpn_ipsec_mobile.php*</pattern>
|
||||
</patterns>
|
||||
@ -82,6 +84,7 @@
|
||||
<pattern>ui/ipsec/spd</pattern>
|
||||
<pattern>api/ipsec/spd/*</pattern>
|
||||
<pattern>api/ipsec/manual_spd/*</pattern>
|
||||
<pattern>api/ipsec/service/*</pattern>
|
||||
</patterns>
|
||||
</page-status-ipsec-spd>
|
||||
<page-status-systemlogs-ipsecvpn>
|
||||
|
||||
@ -122,6 +122,7 @@ class IPsecProposalField extends BaseListField
|
||||
'aes128-sha1-modp2048' => 'aes128-sha1-modp2048 [DH14]',
|
||||
'aes256-sha1-modp4096' => 'aes256-sha1-modp4096 [DH16]',
|
||||
'aes256-sha1-ecp521' => 'aes256-sha1-ecp521 [DH21, NIST EC]',
|
||||
'aes256-sha256-modp1024' => 'aes256-sha256-modp1024 [DH2]',
|
||||
'aes256-sha512-modp1024' => 'aes256-sha512-modp1024 [DH2]',
|
||||
'aes256-sha256' => 'aes256-sha256',
|
||||
'null' => gettext('null (testing only, no encryption and no integrity checking!)')
|
||||
|
||||
@ -203,8 +203,8 @@ class IPsec extends BaseModel
|
||||
foreach (explode(',', (string)$item) as $item) {
|
||||
$idx = 'server' . (string)(count($servers) + 1);
|
||||
$mapping = [];
|
||||
if (isset($cnf->authserver)) {
|
||||
foreach ($cnf->authserver as $authserver) {
|
||||
if (isset($cnf->system->authserver)) {
|
||||
foreach ($cnf->system->authserver as $authserver) {
|
||||
if ($authserver->name == $item) {
|
||||
$servers[$idx] = [
|
||||
'address' => (string)$authserver->host,
|
||||
@ -223,6 +223,10 @@ class IPsec extends BaseModel
|
||||
if ($target_key == '28672') {
|
||||
/* Unity login banner, needs to be wrapped? */
|
||||
$result[$target_key] = '"' . str_replace(['\\', '"'], '', (string)$item) . '"';
|
||||
} elseif ($target_key == '28675') {
|
||||
/* 28675 (splitdns name) is equal/similar to 25 (INTERNAL_DNS_DOMAIN) */
|
||||
$result['25'] = (string)$item;
|
||||
$result[$target_key] = (string)$item;
|
||||
} else {
|
||||
$result[$target_key] = (string)$item;
|
||||
}
|
||||
|
||||
@ -113,7 +113,6 @@
|
||||
<!-- UNITY_DEF_DOMAIN -->
|
||||
<x_28674 type="TextField"/>
|
||||
<x_28675 type="TextField"/>
|
||||
<x_25 type="TextField"/>
|
||||
<x_28672 type="TextField"/>
|
||||
<x_28673 type="BooleanField"/>
|
||||
<x_28679 type="OptionField">
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
<Phase1 url="/vpn_ipsec_phase1.php*" visibility="hidden"/>
|
||||
<Phase2 url="/vpn_ipsec_phase2.php*" visibility="hidden"/>
|
||||
</Tunnels>
|
||||
<Mobile order="20" VisibleName="Mobile Clients (legacy)" url="/vpn_ipsec_mobile.php">
|
||||
<Mobile order="20" VisibleName="Mobile Clients [legacy]" url="/vpn_ipsec_mobile.php">
|
||||
<Act url="/vpn_ipsec_mobile.php*" visibility="hidden"/>
|
||||
</Mobile>
|
||||
<Keys order="30" VisibleName="Pre-Shared Keys" url="/ui/ipsec/pre_shared_keys"/>
|
||||
|
||||
76
src/opnsense/mvc/app/models/OPNsense/Interfaces/Bridge.php
Normal file
76
src/opnsense/mvc/app/models/OPNsense/Interfaces/Bridge.php
Normal file
@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2025 Deciso B.V.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
namespace OPNsense\Interfaces;
|
||||
|
||||
use OPNsense\Base\Messages\Message;
|
||||
use OPNsense\Base\BaseModel;
|
||||
use OPNsense\Firewall\Util;
|
||||
|
||||
class Bridge extends BaseModel
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function performValidation($validateFullModel = false)
|
||||
{
|
||||
$messages = parent::performValidation($validateFullModel);
|
||||
foreach ($this->bridged->iterateItems() as $bridge) {
|
||||
if (!$validateFullModel && !$bridge->isFieldChanged()) {
|
||||
continue;
|
||||
}
|
||||
$key = $bridge->__reference;
|
||||
$members = explode(',', $bridge->members->getCurrentValue());
|
||||
if (!$bridge->span->isEmpty() && in_array($bridge->span->getCurrentValue(), $members)) {
|
||||
$messages->appendMessage(
|
||||
new Message(
|
||||
gettext("Span interface cannot be part of the bridge."),
|
||||
$key . ".span"
|
||||
)
|
||||
);
|
||||
}
|
||||
foreach (['stp', 'edge', 'autoedge', 'ptp', 'autoptp', 'static', 'private'] as $section) {
|
||||
if ($bridge->$section->isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
foreach (explode(',', $bridge->$section->getCurrentValue()) as $if) {
|
||||
if (!in_array($if, $members)) {
|
||||
$messages->appendMessage(
|
||||
new Message(
|
||||
gettext("Contains non bridge members."),
|
||||
$key . "." . $section
|
||||
)
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $messages;
|
||||
}
|
||||
}
|
||||
74
src/opnsense/mvc/app/models/OPNsense/Interfaces/Bridge.xml
Normal file
74
src/opnsense/mvc/app/models/OPNsense/Interfaces/Bridge.xml
Normal file
@ -0,0 +1,74 @@
|
||||
<model>
|
||||
<mount>/bridges</mount>
|
||||
<version>1.0.0</version>
|
||||
<description>Bridge interfaces</description>
|
||||
<items>
|
||||
<bridged type="ArrayField">
|
||||
<bridgeif type="TextField">
|
||||
<Required>Y</Required>
|
||||
<Constraints>
|
||||
<check001>
|
||||
<ValidationMessage>Bridge already exists!</ValidationMessage>
|
||||
<type>UniqueConstraint</type>
|
||||
</check001>
|
||||
</Constraints>
|
||||
<Mask>/^bridge[\d]+$/</Mask>
|
||||
</bridgeif>
|
||||
<members type=".\BridgeMemberField">
|
||||
<Required>Y</Required>
|
||||
<Multiple>Y</Multiple>
|
||||
</members>
|
||||
<linklocal type="BooleanField"/>
|
||||
<enablestp type="BooleanField"/>
|
||||
<proto type="OptionField">
|
||||
<Required>Y</Required>
|
||||
<Default>rstp</Default>
|
||||
<OptionValues>
|
||||
<rstp>RSTP</rstp>
|
||||
<stp>STP</stp>
|
||||
</OptionValues>
|
||||
</proto>
|
||||
<stp type=".\BridgeMemberField">
|
||||
<Multiple>Y</Multiple>
|
||||
</stp>
|
||||
<maxage type="IntegerField">
|
||||
<MinimumValue>6</MinimumValue>
|
||||
<MaximumValue>40</MaximumValue>
|
||||
</maxage>
|
||||
<fwdelay type="IntegerField">
|
||||
<MinimumValue>4</MinimumValue>
|
||||
<MaximumValue>30</MaximumValue>
|
||||
</fwdelay>
|
||||
<holdcnt type="IntegerField">
|
||||
<MinimumValue>1</MinimumValue>
|
||||
<MaximumValue>10</MaximumValue>
|
||||
</holdcnt>
|
||||
<maxaddr type="IntegerField">
|
||||
<MinimumValue>1</MinimumValue>
|
||||
</maxaddr>
|
||||
<timeout type="IntegerField">
|
||||
<MinimumValue>0</MinimumValue>
|
||||
</timeout>
|
||||
<span type=".\BridgeMemberField"/>
|
||||
<edge type=".\BridgeMemberField">
|
||||
<Multiple>Y</Multiple>
|
||||
</edge>
|
||||
<autoedge type=".\BridgeMemberField">
|
||||
<Multiple>Y</Multiple>
|
||||
</autoedge>
|
||||
<ptp type=".\BridgeMemberField">
|
||||
<Multiple>Y</Multiple>
|
||||
</ptp>
|
||||
<autoptp type=".\BridgeMemberField">
|
||||
<Multiple>Y</Multiple>
|
||||
</autoptp>
|
||||
<static type=".\BridgeMemberField">
|
||||
<Multiple>Y</Multiple>
|
||||
</static>
|
||||
<private type=".\BridgeMemberField">
|
||||
<Multiple>Y</Multiple>
|
||||
</private>
|
||||
<descr type="DescriptionField"/>
|
||||
</bridged>
|
||||
</items>
|
||||
</model>
|
||||
@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2025 Deciso B.V.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
namespace OPNsense\Interfaces\FieldTypes;
|
||||
|
||||
use OPNsense\Base\FieldTypes\BaseListField;
|
||||
use OPNsense\Core\Config;
|
||||
|
||||
class BridgeMemberField extends BaseListField
|
||||
{
|
||||
private static $interfaces = [];
|
||||
protected function actionPostLoadingEvent()
|
||||
{
|
||||
if (empty(self::$interfaces)) {
|
||||
$configHandle = Config::getInstance()->object();
|
||||
if (!empty($configHandle->interfaces)) {
|
||||
foreach ($configHandle->interfaces->children() as $ifname => $node) {
|
||||
if (!empty((string)$node->virtual)) {
|
||||
continue;
|
||||
} elseif (!empty((string)$node->if) && str_starts_with('gre', $node->if)) {
|
||||
continue;
|
||||
} elseif (!empty((string)$node->if) && str_starts_with('lo', $node->if)) {
|
||||
continue;
|
||||
}
|
||||
$descr = !empty((string)$node->descr) ? (string)$node->descr : strtoupper($ifname);
|
||||
self::$interfaces[$ifname] = $descr;
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->internalOptionList = self::$interfaces;
|
||||
return parent::actionPostLoadingEvent();
|
||||
}
|
||||
}
|
||||
@ -53,7 +53,7 @@ class LinkAddressField extends BaseField
|
||||
self::$option_groups['ipalias'] = ['items' => [], 'title' => gettext('IP Alias')];
|
||||
foreach ($cfg->interfaces->children() as $ifname => $node) {
|
||||
$descr = !empty((string)$node->descr) ? (string)$node->descr : strtoupper($ifname);
|
||||
if (!empty((string)$node->virtual) || empty((string)$node->enable)) {
|
||||
if (!empty((string)$node->virtual)) {
|
||||
continue;
|
||||
}
|
||||
self::$known_addresses[$ifname] = $descr;
|
||||
|
||||
@ -2,9 +2,7 @@
|
||||
<Interfaces>
|
||||
<Assignments order="200" url="/interfaces_assign.php" cssClass="fa fa-pencil fa-fw"/>
|
||||
<Devices order="210" cssClass="fa fa-archive fa-fw">
|
||||
<Bridge url="/interfaces_bridge.php">
|
||||
<Edit url="/interfaces_bridge_edit.php*" visibility="hidden"/>
|
||||
</Bridge>
|
||||
<Bridge url="/ui/interfaces/bridge"/>
|
||||
<GIF url="/ui/interfaces/gif"/>
|
||||
<GRE url="/ui/interfaces/gre"/>
|
||||
<LAGG url="/ui/interfaces/lagg"/>
|
||||
|
||||
@ -4,9 +4,38 @@
|
||||
<description>Allow access to the KEA dhcp4 server</description>
|
||||
<patterns>
|
||||
<pattern>ui/kea/dhcp/v4</pattern>
|
||||
<pattern>ui/kea/dhcp/leases4</pattern>
|
||||
<pattern>api/kea/dhcpv4/*</pattern>
|
||||
<pattern>api/kea/leases4/*</pattern>
|
||||
<pattern>api/kea/service/*</pattern>
|
||||
</patterns>
|
||||
</page-dhcp-kea-v4>
|
||||
<page-dhcp-kea-v6>
|
||||
<name>Services: DHCP: Kea(v6)</name>
|
||||
<description>Allow access to the KEA dhcp6 server</description>
|
||||
<patterns>
|
||||
<pattern>ui/kea/dhcp/v6</pattern>
|
||||
<pattern>ui/kea/dhcp/leases6</pattern>
|
||||
<pattern>api/kea/dhcpv6/*</pattern>
|
||||
<pattern>api/kea/leases6/*</pattern>
|
||||
<pattern>api/kea/service/*</pattern>
|
||||
</patterns>
|
||||
</page-dhcp-kea-v6>
|
||||
<page-dhcp-kea-ctrl-agent>
|
||||
<name>Services: DHCP: Kea Ctrl Agent</name>
|
||||
<description>Allow access to the KEA Ctrl Agent</description>
|
||||
<patterns>
|
||||
<pattern>ui/kea/dhcp/ctrl_agent</pattern>
|
||||
<pattern>api/kea/ctrl_agent/*</pattern>
|
||||
<pattern>api/kea/service/*</pattern>
|
||||
</patterns>
|
||||
</page-dhcp-kea-ctrl-agent>
|
||||
<page-diagnostics-logs-kea>
|
||||
<name>Services: DHCP: Kea Log File</name>
|
||||
<description>Allow access to the KEA Log File</description>
|
||||
<patterns>
|
||||
<pattern>ui/diagnostics/log/core/kea/*</pattern>
|
||||
<pattern>api/diagnostics/log/core/kea/*</pattern>
|
||||
</patterns>
|
||||
</page-diagnostics-logs-kea>
|
||||
</acl>
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
<Default>0</Default>
|
||||
<Required>Y</Required>
|
||||
</enabled>
|
||||
<manual_config type="BooleanField"/>
|
||||
<interfaces type="InterfaceField">
|
||||
<Multiple>Y</Multiple>
|
||||
</interfaces>
|
||||
|
||||
239
src/opnsense/mvc/app/models/OPNsense/Kea/KeaDhcpv6.php
Normal file
239
src/opnsense/mvc/app/models/OPNsense/Kea/KeaDhcpv6.php
Normal file
@ -0,0 +1,239 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright (C) 2025 Deciso B.V.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
namespace OPNsense\Kea;
|
||||
|
||||
use OPNsense\Base\Messages\Message;
|
||||
use OPNsense\Base\BaseModel;
|
||||
use OPNsense\Core\Config;
|
||||
use OPNsense\Core\Backend;
|
||||
use OPNsense\Core\File;
|
||||
use OPNsense\Firewall\Util;
|
||||
|
||||
class KeaDhcpv6 extends BaseModel
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function performValidation($validateFullModel = false)
|
||||
{
|
||||
$messages = parent::performValidation($validateFullModel);
|
||||
// validate changed reservations
|
||||
foreach ($this->reservations->reservation->iterateItems() as $reservation) {
|
||||
if (!$validateFullModel && !$reservation->isFieldChanged()) {
|
||||
continue;
|
||||
}
|
||||
$key = $reservation->__reference;
|
||||
$subnet = "";
|
||||
$subnet_node = $this->getNodeByReference("subnets.subnet6.{$reservation->subnet}");
|
||||
if ($subnet_node) {
|
||||
$subnet = (string)$subnet_node->subnet;
|
||||
}
|
||||
if (!Util::isIPInCIDR((string)$reservation->ip_address, $subnet)) {
|
||||
$messages->appendMessage(new Message(gettext("Address not in specified subnet"), $key . ".ip_address"));
|
||||
}
|
||||
}
|
||||
|
||||
return $messages;
|
||||
}
|
||||
|
||||
public function isEnabled()
|
||||
{
|
||||
return (string)$this->general->enabled == '1' && !empty((string)(string)$this->general->interfaces);
|
||||
}
|
||||
|
||||
/**
|
||||
* should filter rules be enabled
|
||||
* @return bool
|
||||
*/
|
||||
public function fwrulesEnabled()
|
||||
{
|
||||
return (string)$this->general->enabled == '1' &&
|
||||
(string)$this->general->fwrules == '1' &&
|
||||
!empty((string)$this->general->interfaces);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private function getConfigPhysicalInterfaces()
|
||||
{
|
||||
$result = [];
|
||||
$cfg = Config::getInstance()->object();
|
||||
foreach (explode(',', $this->general->interfaces) as $if) {
|
||||
if (isset($cfg->interfaces->$if) && !empty($cfg->interfaces->$if->if)) {
|
||||
$result[] = (string)$cfg->interfaces->$if->if;
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function getConfigThisServerHostname()
|
||||
{
|
||||
$hostname = (string)$this->ha->this_server_name;
|
||||
if (empty($hostname)) {
|
||||
$hostname = (string)Config::getInstance()->object()->system->hostname;
|
||||
}
|
||||
return $hostname;
|
||||
}
|
||||
|
||||
private function getConfigSubnets()
|
||||
{
|
||||
$result = [];
|
||||
$subnet_id = 1;
|
||||
foreach ($this->subnets->subnet6->iterateItems() as $subnet_uuid => $subnet) {
|
||||
$record = [
|
||||
'id' => $subnet_id++,
|
||||
'subnet' => (string)$subnet->subnet,
|
||||
'option-data' => [],
|
||||
'pools' => [],
|
||||
'pd-pools' => [],
|
||||
'reservations' => []
|
||||
];
|
||||
/* standard option-data elements */
|
||||
foreach ($subnet->option_data->iterateItems() as $key => $value) {
|
||||
$target_fieldname = str_replace('_', '-', $key);
|
||||
if ((string)$value != '') {
|
||||
$record['option-data'][] = [
|
||||
'name' => $target_fieldname,
|
||||
'data' => (string)$value
|
||||
];
|
||||
} elseif ($key == 'domain_name') {
|
||||
$record['option-data'][] = [
|
||||
'name' => $target_fieldname,
|
||||
'data' => (string)Config::getInstance()->object()->system->domain
|
||||
];
|
||||
}
|
||||
}
|
||||
/* add pools */
|
||||
foreach (array_filter(explode("\n", $subnet->pools)) as $pool) {
|
||||
$record['pools'][] = ['pool' => $pool];
|
||||
}
|
||||
/* add pd-pools */
|
||||
foreach ($this->pd_pools->pd_pool->iterateItems() as $key => $pdpool) {
|
||||
if ($pdpool->subnet != $subnet_uuid) {
|
||||
continue;
|
||||
}
|
||||
$record['pd-pools'][] = [
|
||||
'prefix' => (string)$pdpool->prefix,
|
||||
'prefix-len' => (int)$pdpool->prefix_len->getCurrentValue(),
|
||||
'delegated-len' => (int)$pdpool->delegated_len->getCurrentValue()
|
||||
];
|
||||
}
|
||||
/* static reservations */
|
||||
foreach ($this->reservations->reservation->iterateItems() as $key => $reservation) {
|
||||
if ($reservation->subnet != $subnet_uuid) {
|
||||
continue;
|
||||
}
|
||||
$res = ['option-data' => []];
|
||||
foreach (['duid', 'hostname'] as $key) {
|
||||
if (!empty((string)$reservation->$key)) {
|
||||
$res[str_replace('_', '-', $key)] = (string)$reservation->$key;
|
||||
}
|
||||
}
|
||||
$res['ip-addresses'] = explode(',', (string)$reservation->ip_address);
|
||||
if (!$reservation->domain_search->isEmpty()) {
|
||||
$res['option-data'][] = [
|
||||
'name' => 'domain-search',
|
||||
'data' => (string)$reservation->domain_search
|
||||
];
|
||||
}
|
||||
$record['reservations'][] = $res;
|
||||
}
|
||||
$result[] = $record;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function generateConfig($target = '/usr/local/etc/kea/kea-dhcp6.conf')
|
||||
{
|
||||
$cnf = [
|
||||
'Dhcp6' => [
|
||||
'valid-lifetime' => (int)$this->general->valid_lifetime->__toString(),
|
||||
'interfaces-config' => [
|
||||
'interfaces' => $this->getConfigPhysicalInterfaces()
|
||||
],
|
||||
'lease-database' => [
|
||||
'type' => 'memfile',
|
||||
'persist' => true,
|
||||
],
|
||||
'control-socket' => [
|
||||
'socket-type' => 'unix',
|
||||
'socket-name' => '/var/run/kea6-ctrl-socket'
|
||||
],
|
||||
'loggers' => [
|
||||
[
|
||||
'name' => 'kea-dhcp6',
|
||||
'output_options' => [
|
||||
[
|
||||
'output' => 'syslog'
|
||||
]
|
||||
],
|
||||
'severity' => 'INFO',
|
||||
]
|
||||
],
|
||||
'subnet6' => $this->getConfigSubnets(),
|
||||
]
|
||||
];
|
||||
if (!empty((string)(new KeaCtrlAgent())->general->enabled)) {
|
||||
$cnf['Dhcp6']['hooks-libraries'] = [];
|
||||
$cnf['Dhcp6']['hooks-libraries'][] = [
|
||||
'library' => '/usr/local/lib/kea/hooks/libdhcp_lease_cmds.so'
|
||||
];
|
||||
if (!empty((string)$this->ha->enabled)) {
|
||||
$record = [
|
||||
'library' => '/usr/local/lib/kea/hooks/libdhcp_ha.so',
|
||||
'parameters' => [
|
||||
'high-availability' => [
|
||||
[
|
||||
'this-server-name' => $this->getConfigThisServerHostname(),
|
||||
'mode' => 'hot-standby',
|
||||
'heartbeat-delay' => 10000,
|
||||
'max-response-delay' => 60000,
|
||||
'max-ack-delay' => 5000,
|
||||
'max-unacked-clients' => (int)((string)$this->ha->max_unacked_clients),
|
||||
'sync-timeout' => 60000,
|
||||
]
|
||||
]
|
||||
]
|
||||
];
|
||||
foreach ($this->ha_peers->peer->iterateItems() as $peer) {
|
||||
if (!isset($record['parameters']['high-availability'][0]['peers'])) {
|
||||
$record['parameters']['high-availability'][0]['peers'] = [];
|
||||
}
|
||||
$record['parameters']['high-availability'][0]['peers'][] = array_map(
|
||||
fn($x) => (string)$x,
|
||||
iterator_to_array($peer->iterateItems())
|
||||
);
|
||||
}
|
||||
$cnf['Dhcp6']['hooks-libraries'][] = $record;
|
||||
}
|
||||
}
|
||||
File::file_put_contents($target, json_encode($cnf, JSON_PRETTY_PRINT), 0600);
|
||||
}
|
||||
}
|
||||
181
src/opnsense/mvc/app/models/OPNsense/Kea/KeaDhcpv6.xml
Normal file
181
src/opnsense/mvc/app/models/OPNsense/Kea/KeaDhcpv6.xml
Normal file
@ -0,0 +1,181 @@
|
||||
<model>
|
||||
<mount>//OPNsense/Kea/dhcp6</mount>
|
||||
<version>1.0.0</version>
|
||||
<description>Kea DHCPv6 configuration</description>
|
||||
<items>
|
||||
<general>
|
||||
<enabled type="BooleanField">
|
||||
<Default>0</Default>
|
||||
<Required>Y</Required>
|
||||
</enabled>
|
||||
<manual_config type="BooleanField"/>
|
||||
<interfaces type="InterfaceField">
|
||||
<Multiple>Y</Multiple>
|
||||
</interfaces>
|
||||
<valid_lifetime type="IntegerField">
|
||||
<Default>4000</Default>
|
||||
<Required>Y</Required>
|
||||
</valid_lifetime>
|
||||
<fwrules type="BooleanField">
|
||||
<Required>Y</Required>
|
||||
<Default>1</Default>
|
||||
</fwrules>
|
||||
</general>
|
||||
<ha>
|
||||
<enabled type="BooleanField">
|
||||
<Default>0</Default>
|
||||
<Required>Y</Required>
|
||||
</enabled>
|
||||
<this_server_name type="TextField">
|
||||
<Mask>/^([0-9a-zA-Z.\:\-,_]){0,1024}$/u</Mask>
|
||||
</this_server_name>
|
||||
<max_unacked_clients type="IntegerField">
|
||||
<MinimumValue>0</MinimumValue>
|
||||
<MaximumValue>65535</MaximumValue>
|
||||
<Default>2</Default>
|
||||
<Required>Y</Required>
|
||||
</max_unacked_clients>
|
||||
</ha>
|
||||
<subnets>
|
||||
<subnet6 type="ArrayField">
|
||||
<subnet type="NetworkField">
|
||||
<NetMaskRequired>Y</NetMaskRequired>
|
||||
<AddressFamily>ipv6</AddressFamily>
|
||||
<Required>Y</Required>
|
||||
</subnet>
|
||||
<option_data>
|
||||
<dns_servers type="NetworkField">
|
||||
<NetMaskAllowed>N</NetMaskAllowed>
|
||||
<AddressFamily>ipv6</AddressFamily>
|
||||
<AsList>Y</AsList>
|
||||
<FieldSeparator>,</FieldSeparator>
|
||||
</dns_servers>
|
||||
<domain_search type="HostnameField">
|
||||
<IpAllowed>N</IpAllowed>
|
||||
<FieldSeparator>,</FieldSeparator>
|
||||
<AsList>Y</AsList>
|
||||
<ValidationMessage>Please specify a valid list of domains</ValidationMessage>
|
||||
</domain_search>
|
||||
</option_data>
|
||||
<pools type=".\KeaPoolsField">
|
||||
</pools>
|
||||
<description type="DescriptionField"/>
|
||||
</subnet6>
|
||||
</subnets>
|
||||
<reservations>
|
||||
<reservation type="ArrayField">
|
||||
<subnet type="ModelRelationField">
|
||||
<Model>
|
||||
<subnets>
|
||||
<source>OPNsense.Kea.KeaDhcpv6</source>
|
||||
<items>subnets.subnet6</items>
|
||||
<display>subnet</display>
|
||||
</subnets>
|
||||
</Model>
|
||||
<ValidationMessage>Related subnet not found</ValidationMessage>
|
||||
<Constraints>
|
||||
<check001>
|
||||
<reference>duid.check001</reference>
|
||||
</check001>
|
||||
</Constraints>
|
||||
<Required>Y</Required>
|
||||
</subnet>
|
||||
<ip_address type="NetworkField">
|
||||
<NetMaskAllowed>N</NetMaskAllowed>
|
||||
<AddressFamily>ipv6</AddressFamily>
|
||||
<Constraints>
|
||||
<check001>
|
||||
<ValidationMessage>Duplicate entry exists</ValidationMessage>
|
||||
<type>UniqueConstraint</type>
|
||||
</check001>
|
||||
</Constraints>
|
||||
</ip_address>
|
||||
<duid type="TextField">
|
||||
<Required>Y</Required>
|
||||
<Mask>/^(?:[0-9A-Fa-f]{2}(?::[0-9A-Fa-f]{2})+)$/</Mask>
|
||||
<ValidationMessage>Value must be a colon-separated hexadecimal sequence (e.g., 01:02:f3).</ValidationMessage>
|
||||
<Constraints>
|
||||
<check001>
|
||||
<ValidationMessage>Duplicate entry exists</ValidationMessage>
|
||||
<type>UniqueConstraint</type>
|
||||
<addFields>
|
||||
<field1>subnet</field1>
|
||||
</addFields>
|
||||
</check001>
|
||||
</Constraints>
|
||||
</duid>
|
||||
<hostname type="HostnameField">
|
||||
<IsDNSName>Y</IsDNSName>
|
||||
</hostname>
|
||||
<domain_search type="HostnameField">
|
||||
<IpAllowed>N</IpAllowed>
|
||||
<FieldSeparator>,</FieldSeparator>
|
||||
<AsList>Y</AsList>
|
||||
<ValidationMessage>Please specify a valid list of domains</ValidationMessage>
|
||||
</domain_search>
|
||||
<description type="DescriptionField"/>
|
||||
</reservation>
|
||||
</reservations>
|
||||
<pd_pools>
|
||||
<pd_pool type="ArrayField">
|
||||
<subnet type="ModelRelationField">
|
||||
<Model>
|
||||
<subnets>
|
||||
<source>OPNsense.Kea.KeaDhcpv6</source>
|
||||
<items>subnets.subnet6</items>
|
||||
<display>subnet</display>
|
||||
</subnets>
|
||||
</Model>
|
||||
<ValidationMessage>Related subnet not found</ValidationMessage>
|
||||
<Required>Y</Required>
|
||||
</subnet>
|
||||
<prefix type="NetworkField">
|
||||
<AddressFamily>ipv6</AddressFamily>
|
||||
</prefix>
|
||||
<prefix_len type="IntegerField">
|
||||
<MinimumValue>1</MinimumValue>
|
||||
<MaximumValue>128</MaximumValue>
|
||||
<Default>56</Default>
|
||||
<Required>Y</Required>
|
||||
</prefix_len>
|
||||
<delegated_len type="IntegerField">
|
||||
<MinimumValue>1</MinimumValue>
|
||||
<MaximumValue>128</MaximumValue>
|
||||
<Required>Y</Required>
|
||||
<Default>64</Default>
|
||||
</delegated_len>
|
||||
<description type="DescriptionField"/>
|
||||
</pd_pool>
|
||||
</pd_pools>
|
||||
<ha_peers>
|
||||
<peer type="ArrayField">
|
||||
<name type="TextField">
|
||||
<Required>Y</Required>
|
||||
<Constraints>
|
||||
<check001>
|
||||
<ValidationMessage>Duplicate entry exists</ValidationMessage>
|
||||
<type>UniqueConstraint</type>
|
||||
</check001>
|
||||
</Constraints>
|
||||
</name>
|
||||
<role type="OptionField">
|
||||
<Default>primary</Default>
|
||||
<Required>Y</Required>
|
||||
<OptionValues>
|
||||
<primary>primary</primary>
|
||||
<standby>standby</standby>
|
||||
</OptionValues>
|
||||
</role>
|
||||
<url type="UrlField">
|
||||
<Required>Y</Required>
|
||||
<Constraints>
|
||||
<check001>
|
||||
<ValidationMessage>Duplicate entry exists</ValidationMessage>
|
||||
<type>UniqueConstraint</type>
|
||||
</check001>
|
||||
</Constraints>
|
||||
</url>
|
||||
</peer>
|
||||
</ha_peers>
|
||||
</items>
|
||||
</model>
|
||||
@ -3,6 +3,7 @@
|
||||
<KeaDHCP VisibleName="Kea DHCP" cssClass="fa fa-bullseye fa-fw">
|
||||
<ControlAgent order="5" VisibleName="Control Agent" url="/ui/kea/dhcp/ctrl_agent"/>
|
||||
<Keav4 order="10" VisibleName="Kea DHCPv4" url="/ui/kea/dhcp/v4"/>
|
||||
<Keav6 order="20" VisibleName="Kea DHCPv6" url="/ui/kea/dhcp/v6"/>
|
||||
<Leases4 order="50" VisibleName="Leases DHCPv4" url="/ui/kea/dhcp/leases4"/>
|
||||
<LogFile order="100" VisibleName="Log File" url="/ui/diagnostics/log/core/kea"/>
|
||||
</KeaDHCP>
|
||||
|
||||
@ -29,6 +29,7 @@
|
||||
</validate_server_cn>
|
||||
<cryptoapi type="BooleanField"/>
|
||||
<auth_nocache type="BooleanField"/>
|
||||
<static_challenge type="BooleanField"/>
|
||||
<plain_config type="TextField"/>
|
||||
</server>
|
||||
</servers>
|
||||
|
||||
@ -56,6 +56,7 @@
|
||||
</monitor_disable>
|
||||
<monitor_noroute type="BooleanField"/>
|
||||
<monitor_killstates type="BooleanField"/>
|
||||
<monitor_killstates_priority type="BooleanField"/>
|
||||
<monitor type="TextField">
|
||||
<Constraints>
|
||||
<check001>
|
||||
|
||||
@ -28,6 +28,7 @@
|
||||
|
||||
namespace OPNsense\Trust\FieldTypes;
|
||||
|
||||
use OPNsense\Core\Backend;
|
||||
use OPNsense\Core\Config;
|
||||
use OPNsense\Base\FieldTypes\ArrayField;
|
||||
use OPNsense\Base\FieldTypes\ContainerField;
|
||||
@ -94,6 +95,11 @@ class CertificateContainerField extends ContainerField
|
||||
*/
|
||||
class CertificatesField extends ArrayField
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $internalStaticChildren = [];
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@ -105,6 +111,26 @@ class CertificatesField extends ArrayField
|
||||
return $container_node;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array of externally managed certificates
|
||||
*/
|
||||
protected static function getStaticChildren()
|
||||
{
|
||||
$result = [];
|
||||
$ext_data = json_decode((new Backend())->configdRun('system trust ext_sources') ?? '', true);
|
||||
if (is_array($ext_data)) {
|
||||
foreach ($ext_data as $data) {
|
||||
$payload = \OPNsense\Trust\Store::parseX509($data['cert'] ?? '');
|
||||
if ($payload !== false && !empty($data['id'])) {
|
||||
$payload['crt_payload'] = $data['cert'];
|
||||
$payload['descr'] = $data['descr'] ?? '';
|
||||
$result[$data['id']] = $payload;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
protected function actionPostLoadingEvent()
|
||||
{
|
||||
$usernames = [];
|
||||
|
||||
@ -28,7 +28,7 @@
|
||||
'use strict';
|
||||
|
||||
$( document ).ready(function () {
|
||||
let grid_group = $("#grid-group").UIBootgrid({
|
||||
let grid_group = $("#{{formGridGroup['table_id']}}").UIBootgrid({
|
||||
search:'/api/auth/group/search/',
|
||||
get:'/api/auth/group/get/',
|
||||
add:'/api/auth/group/add/',
|
||||
@ -56,32 +56,8 @@
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
<div class="tab-content content-box">
|
||||
<div id="group" class="tab-pane fade in active">
|
||||
<table id="grid-group" class="table table-condensed table-hover table-striped table-responsive" data-editDialog="DialogGroup">
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-column-id="uuid" data-type="string" data-identifier="true" data-visible="false">{{ lang._('ID') }}</th>
|
||||
<th data-column-id="name" data-type="string">{{ lang._('Name') }}</th>
|
||||
<th data-column-id="member" data-type="string" data-formatter="member_count">{{ lang._('Member Count') }}</th>
|
||||
<th data-column-id="description" data-type="string">{{ lang._('Description') }}</th>
|
||||
<th data-column-id="commands" data-width="10em" data-formatter="commands" data-sortable="false">{{ lang._('Commands') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>
|
||||
<button data-action="add" type="button" class="btn btn-xs btn-primary"><span class="fa fa-fw fa-plus"></span></button>
|
||||
<button data-action="deleteSelected" type="button" class="btn btn-xs btn-default"><span class="fa fa-fw fa-trash-o"></span></button>
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
{{ partial('layout_partials/base_bootgrid_table', formGridGroup + {'command_width': '10em'})}}
|
||||
</div>
|
||||
|
||||
{{ partial("layout_partials/base_dialog",['fields':formDialogEditGroup,'id':'DialogGroup','label':lang._('Edit Group')])}}
|
||||
{{ partial("layout_partials/base_dialog",['fields':formDialogEditGroup,'id':formGridGroup['edit_dialog_id'],'label':lang._('Edit Group')])}}
|
||||
|
||||
@ -28,7 +28,7 @@
|
||||
'use strict';
|
||||
|
||||
$( document ).ready(function () {
|
||||
let grid_group = $("#grid-group").UIBootgrid({
|
||||
let grid_priv = $("#{{formGridPriv['table_id']}}").UIBootgrid({
|
||||
search:'/api/auth/priv/search/',
|
||||
get:'/api/auth/priv/get_item/',
|
||||
set:'/api/auth/priv/set_item/',
|
||||
@ -58,27 +58,15 @@
|
||||
}
|
||||
});
|
||||
|
||||
$('button[data-action="add"]').hide();
|
||||
$('button[data-action="deleteSelected"]').hide();
|
||||
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<div class="tab-content content-box">
|
||||
<div id="group" class="tab-pane fade in active">
|
||||
<table id="grid-group" class="table table-condensed table-hover table-striped table-responsive" data-editDialog="DialogPriv">
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-column-id="id" data-type="string" data-identifier="true">{{ lang._('ID') }}</th>
|
||||
<th data-column-id="name" data-type="string">{{ lang._('Name') }}</th>
|
||||
<th data-column-id="match" data-type="string" data-formatter="lines">{{ lang._('Match') }}</th>
|
||||
<th data-column-id="users" data-type="string" data-formatter="count" data-sortable="false">{{ lang._('Users') }}</th>
|
||||
<th data-column-id="groups" data-type="string" data-formatter="count" data-sortable="false">{{ lang._('Groups') }}</th>
|
||||
<th data-column-id="commands" data-width="10em" data-formatter="commands" data-sortable="false">{{ lang._('Commands') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{{ partial('layout_partials/base_bootgrid_table', formGridPriv)}}
|
||||
</div>
|
||||
|
||||
{{ partial("layout_partials/base_dialog",['fields':formDialogEditPriv,'id':'DialogPriv','label':lang._('Edit Privilege')])}}
|
||||
{{ partial("layout_partials/base_dialog",['fields':formDialogEditPriv,'id':formGridPriv['edit_dialog_id'],'label':lang._('Edit Privilege')])}}
|
||||
|
||||
@ -28,7 +28,7 @@
|
||||
'use strict';
|
||||
|
||||
$( document ).ready(function () {
|
||||
let grid_user = $("#grid-user").UIBootgrid({
|
||||
let grid_user = $("#{{formGridUser['table_id']}}").UIBootgrid({
|
||||
search:'/api/auth/user/search/',
|
||||
get:'/api/auth/user/get/',
|
||||
add:'/api/auth/user/add/',
|
||||
@ -43,7 +43,7 @@
|
||||
let refid = $(this).data("row-id") !== undefined ? $(this).data("row-id") : '';
|
||||
ajaxGet('/api/auth/user/get/' + refid, {}, function(data){
|
||||
if (data.user) {
|
||||
window.location ='/ui/trust/cert/#user=' + data.user.name ;
|
||||
window.location ='/ui/trust/cert#user=' + data.user.name ;
|
||||
}
|
||||
});
|
||||
},
|
||||
@ -171,6 +171,8 @@
|
||||
$('.datepicker').datepicker({format: 'mm/dd/yyyy'});
|
||||
/* format authorizedkeys */
|
||||
$("#user\\.authorizedkeys").css('max-width', 'inherit').prop('wrap', 'off');
|
||||
|
||||
$("#grid-user-buttons").children().insertAfter($("#{{ formGridUser['table_id'] }} tfoot [data-action='deleteSelected']"));
|
||||
});
|
||||
|
||||
</script>
|
||||
@ -182,35 +184,17 @@
|
||||
.tooltip-inner {
|
||||
max-width: 1000px !important;
|
||||
}
|
||||
.btn-user-action {
|
||||
margin-left: 3px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<ul class="nav nav-tabs" data-tabs="tabs" id="maintabs">
|
||||
<li class="active"><a data-toggle="tab" href="#user">{{ lang._('Users') }}</a></li>
|
||||
<li><a data-toggle="tab" href="#apikeys" id="tab_apikeys"> {{ lang._('ApiKeys') }} </a></li>
|
||||
</ul>
|
||||
<div class="tab-content content-box">
|
||||
<div id="user" class="tab-pane fade in active">
|
||||
<table id="grid-user" class="table table-condensed table-hover table-striped table-responsive" data-editDialog="DialogUser">
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-column-id="uuid" data-type="string" data-identifier="true" data-visible="false">{{ lang._('ID') }}</th>
|
||||
<th data-column-id="name" data-type="string" data-formatter="username">{{ lang._('Name') }}</th>
|
||||
<th data-column-id="email" data-type="string" data-visible="false">{{ lang._('Email') }}</th>
|
||||
<th data-column-id="comments" data-type="string" data-visible="false">{{ lang._('Comments') }}</th>
|
||||
<th data-column-id="language" data-type="string" data-visible="false">{{ lang._('Language') }}</th>
|
||||
<th data-column-id="group_memberships" data-type="string">{{ lang._('Groups') }}</th>
|
||||
<th data-column-id="descr" data-type="string">{{ lang._('Description') }}</th>
|
||||
<th data-column-id="commands" data-width="10em" data-formatter="commands" data-sortable="false">{{ lang._('Commands') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>
|
||||
<button data-action="add" type="button" class="btn btn-xs btn-primary"><span class="fa fa-fw fa-plus"></span></button>
|
||||
<button data-action="deleteSelected" type="button" class="btn btn-xs btn-default"><span class="fa fa-fw fa-trash-o"></span></button>
|
||||
|
||||
<div id="grid-user-buttons" style="display: none;">
|
||||
<button
|
||||
id="upload_users"
|
||||
type="button"
|
||||
@ -218,13 +202,14 @@
|
||||
data-endpoint='/api/auth/user/upload'
|
||||
title="{{ lang._('Import csv') }}"
|
||||
data-toggle="tooltip"
|
||||
class="btn btn-xs"
|
||||
><span class="fa fa-fw fa-upload"></span></button>
|
||||
<button id="download_users" type="button" title="{{ lang._('Export as csv') }}" data-toggle="tooltip" class="btn btn-xs"><span class="fa fa-fw fa-table"></span></button>
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
class="btn btn-xs btn-user-action"
|
||||
><span class="fa fa-fw fa-upload"></span></button>
|
||||
<button id="download_users" type="button" title="{{ lang._('Export as csv') }}" data-toggle="tooltip" class="btn btn-xs btn-user-action"><span class="fa fa-fw fa-table"></span></button>
|
||||
</div>
|
||||
|
||||
<div class="tab-content content-box">
|
||||
<div id="user" class="tab-pane fade in active">
|
||||
{{ partial('layout_partials/base_bootgrid_table', formGridUser + {'command_width': '9em'})}}
|
||||
</div>
|
||||
<div id="apikeys" class="tab-pane fade in">
|
||||
<table id="grid-apikey" class="table table-condensed table-hover table-striped table-responsive" data-editDialog="DialogUser">
|
||||
@ -250,4 +235,4 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{ partial("layout_partials/base_dialog",['fields':formDialogEditUser,'id':'DialogUser','label':lang._('Edit User')])}}
|
||||
{{ partial("layout_partials/base_dialog",['fields':formDialogEditUser,'id':formGridUser['edit_dialog_id'],'label':lang._('Edit User')])}}
|
||||
|
||||
@ -130,7 +130,7 @@
|
||||
* perform backend action and install poller to update status
|
||||
*/
|
||||
function backend(type) {
|
||||
$.upgrade_check = type == 'check'
|
||||
$.upgrade_check = type == 'check';
|
||||
|
||||
$('#update_status').html('');
|
||||
$('#updatelist').hide();
|
||||
@ -647,7 +647,13 @@
|
||||
backend('audit');
|
||||
} else if (window.location.hash == '#checkupdate') {
|
||||
// dashboard link: run check automatically after delay
|
||||
setTimeout(function () { backend('check'); }, 2000);
|
||||
setTimeout(function () {
|
||||
ajaxGet('/api/core/firmware/running', {}, function(data, status) {
|
||||
if (data['status'] != 'busy') {
|
||||
backend('check');
|
||||
}
|
||||
});
|
||||
}, 2000);
|
||||
}
|
||||
});
|
||||
|
||||
@ -661,7 +667,7 @@
|
||||
$("#firmware_mirror").find('option').remove();
|
||||
$("#firmware_type").find('option').remove();
|
||||
$("#firmware_flavour").find('option').remove();
|
||||
$("#firmware_reboot").prop('checked', firmwareconfig['reboot'] !== '');
|
||||
$("#firmware_reboot").prop('checked', firmwareconfig['reboot'] == '1');
|
||||
|
||||
$.each(firmwareoptions.mirrors, function(key, value) {
|
||||
var selected = false;
|
||||
@ -758,7 +764,7 @@
|
||||
confopt.mirror = $("#firmware_mirror_value").val();
|
||||
confopt.flavour = $("#firmware_flavour_value").val();
|
||||
confopt.type = $("#firmware_type").val();
|
||||
confopt.reboot = $("#firmware_reboot").is(":checked");
|
||||
confopt.reboot = $("#firmware_reboot").is(":checked") ? '1' : '0';
|
||||
confopt.subscription = $("#firmware_subscription").val();
|
||||
ajaxCall('/api/core/firmware/set', { 'firmware': confopt }, function (data, status) {
|
||||
$("#settingstab_progress").removeClass("fa fa-spinner fa-pulse");
|
||||
|
||||
@ -41,6 +41,10 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
$('#grid-arp').bootgrid('reload');
|
||||
});
|
||||
|
||||
$("#refresh").click(function() {
|
||||
$("#grid-arp").bootgrid("reload");
|
||||
});
|
||||
|
||||
$("#flushModal").click(function(event){
|
||||
BootstrapDialog.show({
|
||||
type:BootstrapDialog.TYPE_DANGER,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user