# #
###############################################################################
-VPN_SECURITY_POLICIES_CONFIG_SETTINGS="CIPHER COMPRESSION GROUP_TYPE \
- INTEGRITY PSEUDO_RANDOM_FUNCTION KEY_EXCHANGE LIFETIME PFS"
+VPN_SECURITY_POLICIES_CONFIG_SETTINGS="CIPHERS COMPRESSION GROUP_TYPES \
+ INTEGRITIES PSEUDO_RANDOM_FUNCTIONS KEY_EXCHANGE LIFETIME PFS"
VPN_SECURITY_POLICIES_READONLY="system performance"
VPN_DEFAULT_SECURITY_POLICY="system"
[NULL]="null"
)
-declare -A VPN_SUPPORTED_PSEUDO_RANDOM_FUNCTION=(
+declare -A VPN_SUPPORTED_PSEUDO_RANDOM_FUNCTIONS=(
[MD5]="MD5"
# SHA
[AES-CMAC]="prfaescmac"
)
-declare -A VPN_SUPPORTED_INTEGRITY=(
+declare -A VPN_SUPPORTED_INTEGRITIES=(
[MD5]="MD5-HMAC"
# SHA
# Curve25519
[CURVE25519]="256 bit Elliptic Curve 25519"
+
+ # Curve448
+ [CURVE448]="224 bit Elliptic Curve 448"
)
declare -A GROUP_TYPE_TO_STRONGSWAN=(
[ECP384BP]="ecp384bp"
[ECP512BP]="ecp512bp"
- # Curve25519
+ # More Curves
[CURVE25519]="curve25519"
+ [CURVE448]="curve448"
)
cli_vpn_security_policies() {
shift 2
case "${key}" in
- cipher|compression|integrity|lifetime|pfs|show)
+ ciphers|compression|integrities|lifetime|pfs|show)
vpn_security_policies_${key} ${security_policy} "$@"
;;
- group-type)
- vpn_security_policies_group_type ${security_policy} "$@"
+ pseudo-random-functions)
+ vpn_security_policies_pseudo_random_functions "${security_policy}" "$@"
+ ;;
+ group-types)
+ vpn_security_policies_group_types ${security_policy} "$@"
;;
key-exchange)
vpn_security_policies_key_exchange ${security_policy} "$@"
# because we print 'Group Types' but the variable is named 'GROUP_TYPES'
cli_print_fmt1 1 "Ciphers:"
local cipher
- for cipher in ${CIPHER}; do
+ for cipher in ${CIPHERS}; do
cli_print_fmt1 2 "${VPN_SUPPORTED_CIPHERS[${cipher}]-${cipher}}"
done
cli_space
cli_print_fmt1 1 "Integrity:"
local integrity
- for integrity in ${INTEGRITY}; do
- cli_print_fmt1 2 "${VPN_SUPPORTED_INTEGRITY[${integrity}]-${integrity}}"
+ for integrity in ${INTEGRITIES}; do
+ cli_print_fmt1 2 "${VPN_SUPPORTED_INTEGRITIES[${integrity}]-${integrity}}"
+ done
+ cli_space
+
+ cli_print_fmt1 1 "Pseudo Random Functions:"
+ local prf
+ for prf in ${PSEUDO_RANDOM_FUNCTIONS}; do
+ cli_print_fmt1 2 "${VPN_SUPPORTED_PSEUDO_RANDOM_FUNCTIONS[${prf}]-${prf}}"
done
cli_space
cli_print_fmt1 1 "Group Types:"
local group_type
- for group_type in ${GROUP_TYPE}; do
+ for group_type in ${GROUP_TYPES}; do
cli_print_fmt1 2 "${VPN_SUPPORTED_GROUP_TYPES[${group_type}]-${group_type}}"
done
cli_space
# This function parses the parameters for the 'cipher' command
-vpn_security_policies_cipher(){
+vpn_security_policies_ciphers() {
local name=${1}
shift
return ${EXIT_ERROR}
fi
- local CIPHER
- if ! vpn_security_policies_read_config ${name} "CIPHER"; then
+ local CIPHERS
+ if ! vpn_security_policies_read_config ${name} "CIPHERS"; then
return ${EXIT_ERROR}
fi
# Remove duplicated entries to proceed the list safely
- CIPHER="$(list_unique ${CIPHER})"
+ CIPHERS="$(list_unique ${CIPHERS})"
local ciphers_added
local ciphers_removed
fi
done
- CIPHER="${ciphers_set}"
+ CIPHERS="${ciphers_set}"
# Perform incremental updates
else
# Perform all removals
for cipher in ${ciphers_removed}; do
- if ! list_remove CIPHER ${cipher}; then
+ if ! list_remove CIPHERS ${cipher}; then
warning "${cipher} was not on the list and could not be removed"
fi
done
for cipher in ${ciphers_added}; do
if vpn_security_policies_cipher_supported ${cipher}; then
- if ! list_append_unique CIPHER ${cipher}; then
+ if ! list_append_unique CIPHERS ${cipher}; then
warning "${cipher} is already on the cipher list"
fi
else
fi
# Check if the list contain at least one valid cipher
- if list_is_empty CIPHER; then
+ if list_is_empty CIPHERS; then
error "Cannot save an empty cipher list"
return ${EXIT_ERROR}
fi
# Save everything
- if ! vpn_security_policies_write_config_key ${name} "CIPHER" ${CIPHER}; then
+ if ! vpn_security_policies_write_config_key ${name} "CIPHERS" ${CIPHERS}; then
log ERROR "The changes for the vpn security policy ${name} could not be written."
fi
cli_headline 1 "Current cipher list for ${name}:"
- for cipher in ${CIPHER}; do
+ for cipher in ${CIPHERS}; do
cli_print_fmt1 1 "${cipher}" "${VPN_SUPPORTED_CIPHERS[${cipher}]}"
done
}
}
# This function parses the parameters for the 'group-type' command
-vpn_security_policies_group_type(){
+vpn_security_policies_group_types() {
local name=${1}
shift
return ${EXIT_ERROR}
fi
- local GROUP_TYPE
- if ! vpn_security_policies_read_config ${name} "GROUP_TYPE"; then
+ local GROUP_TYPES
+ if ! vpn_security_policies_read_config ${name} "GROUP_TYPES"; then
return ${EXIT_ERROR}
fi
# Remove duplicated entries to proceed the list safely
- GROUP_TYPE="$(list_unique ${GROUP_TYPE})"
+ GROUP_TYPES="$(list_unique ${GROUP_TYPES})"
local group_types_added
local group_types_removed
fi
done
- GROUP_TYPE="${group_types_set}"
+ GROUP_TYPES="${group_types_set}"
# Perform incremental updates
else
# Perform all removals
for group_type in ${group_types_removed}; do
- if ! list_remove GROUP_TYPE ${group_type}; then
+ if ! list_remove GROUP_TYPES ${group_type}; then
warning "${group_type} was not on the list and could not be removed"
fi
done
for group_type in ${group_types_added}; do
if vpn_security_policies_group_type_supported ${group_type}; then
- if ! list_append_unique GROUP_TYPE ${group_type}; then
+ if ! list_append_unique GROUP_TYPES ${group_type}; then
warning "${group_type} is already on the group type list"
fi
else
fi
# Check if the list contain at least one valid group_type
- if list_is_empty GROUP_TYPE; then
+ if list_is_empty GROUP_TYPES; then
error "Cannot save an empty group type list"
return ${EXIT_ERROR}
fi
# Save everything
- if ! vpn_security_policies_write_config_key ${name} "GROUP_TYPE" ${GROUP_TYPE}; then
+ if ! vpn_security_policies_write_config_key ${name} "GROUP_TYPES" ${GROUP_TYPES}; then
log ERROR "The changes for the vpn security policy ${name} could not be written."
fi
cli_headline 1 "Current group type list for ${name}:"
- for group_type in ${GROUP_TYPE}; do
+ for group_type in ${GROUP_TYPES}; do
cli_print_fmt1 1 "${group_type}" "${VPN_SUPPORTED_GROUP_TYPES[${group_type}]}"
done
}
# This function parses the parameters for the 'integrity' command
-vpn_security_policies_integrity(){
+vpn_security_policies_integrities() {
local name=${1}
shift
if [ $# -eq 0 ]; then
- log ERROR "You must pass at least one value after integrity"
+ log ERROR "You must pass at least one value"
return ${EXIT_ERROR}
fi
- local INTEGRITY
- if ! vpn_security_policies_read_config ${name} "INTEGRITY"; then
+ local INTEGRITIES
+ if ! vpn_security_policies_read_config ${name} "INTEGRITIES"; then
return ${EXIT_ERROR}
fi
# Remove duplicated entries to proceed the list safely
- INTEGRITY="$(list_unique ${INTEGRITY})"
+ INTEGRITIES="$(list_unique ${INTEGRITIES})"
local integritys_added
local integritys_removed
fi
done
- INTEGRITY="${integritys_set}"
+ INTEGRITIES="${integritys_set}"
# Perform incremental updates
else
# Perform all removals
for integrity in ${integritys_removed}; do
- if ! list_remove INTEGRITY ${integrity}; then
+ if ! list_remove INTEGRITIES ${integrity}; then
warning "${integrity} was not on the list and could not be removed"
fi
done
for integrity in ${integritys_added}; do
if vpn_security_policies_integrity_supported ${integrity}; then
- if ! list_append_unique INTEGRITY ${integrity}; then
+ if ! list_append_unique INTEGRITIES ${integrity}; then
warning "${integrity} is already on the integrity list"
fi
else
fi
# Check if the list contain at least one valid integrity
- if list_is_empty INTEGRITY; then
+ if list_is_empty INTEGRITIES; then
error "Cannot save an empty integrity hashes list"
return ${EXIT_ERROR}
fi
# Save everything
- if ! vpn_security_policies_write_config_key ${name} "INTEGRITY" ${INTEGRITY}; then
+ if ! vpn_security_policies_write_config_key ${name} "INTEGRITIES" ${INTEGRITIES}; then
log ERROR "The changes for the vpn security policy ${name} could not be written."
fi
cli_headline 1 "Current integrity hashes list for ${name}:"
- for integrity in ${INTEGRITY}; do
- cli_print_fmt1 1 "${integrity}" "${VPN_SUPPORTED_INTEGRITY[${integrity}]}"
+ for integrity in ${INTEGRITIES}; do
+ cli_print_fmt1 1 "${integrity}" "${VPN_SUPPORTED_INTEGRITIES[${integrity}]}"
+ done
+}
+
+# This function parses the parameters for the 'pseudo-random-functions' command
+vpn_security_policies_pseudo_random_functions() {
+ local name=${1}
+ shift
+
+ if [ $# -eq 0 ]; then
+ log ERROR "You must pass at least one value"
+ return ${EXIT_ERROR}
+ fi
+
+ local PSEUDO_RANDOM_FUNCTIONS
+ if ! vpn_security_policies_read_config ${name} "PSEUDO_RANDOM_FUNCTIONS"; then
+ return ${EXIT_ERROR}
+ fi
+
+ # Remove duplicated entries to proceed the list safely
+ PSEUDO_RANDOM_FUNCTIONS="$(list_unique ${PSEUDO_RANDOM_FUNCTIONS})"
+
+ local prfs_added
+ local prfs_removed
+ local prfs_set
+
+ while [ $# -gt 0 ]; do
+ local arg="${1}"
+
+ case "${arg}" in
+ +*)
+ list_append prfs_added "${arg:1}"
+ ;;
+ -*)
+ list_append prfs_removed "${arg:1}"
+ ;;
+ [A-Z0-9]*)
+ list_append prfs_set "${arg}"
+ ;;
+ *)
+ error "Invalid argument: ${arg}"
+ return ${EXIT_ERROR}
+ ;;
+ esac
+ shift
+ done
+
+ # Check if the user is trying a mixed operation
+ if ! list_is_empty prfs_set && (! list_is_empty prfs_added || ! list_is_empty prfs_removed); then
+ error "You cannot reset the pseudo random function list and add or remove functions at the same time"
+ return ${EXIT_ERROR}
+ fi
+
+ # Set new psudo random function list
+ if ! list_is_empty prfs_set; then
+ # Check if all PRFs are valid
+ local prf
+ for prf in ${prfs_set}; do
+ if ! vpn_security_policies_pseudo_random_function_supported "${prf}"; then
+ error "Unsupported pseudo random function: ${prf}"
+ return ${EXIT_ERROR}
+ fi
+ done
+
+ PSEUDO_RANDOM_FUNCTIONS="${prfs_set}"
+
+ # Perform incremental updates
+ else
+ local prf
+
+ # Perform all removals
+ for prf in ${prfs_removed}; do
+ if ! list_remove PSEUDO_RANDOM_FUNCTIONS "${prf}"; then
+ warning "${prf} was not on the list and could not be removed"
+ fi
+ done
+
+ for prf in ${prfs_added}; do
+ if vpn_security_policies_pseudo_random_function_supported "${prf}"; then
+ if ! list_append_unique PSEUDO_RANDOM_FUNCTIONS "${prf}"; then
+ warning "${prf} is already on the list"
+ fi
+ else
+ warning "${prf} is unknown or unsupported and could not be added"
+ fi
+ done
+ fi
+
+ # Check if the list contain at least one valid value
+ if list_is_empty PSEUDO_RANDOM_FUNCTIONS; then
+ error "Cannot save an empty list of pseudo random functions"
+ return ${EXIT_ERROR}
+ fi
+
+ # Save everything
+ if ! vpn_security_policies_write_config_key "${name}" "PSEUDO_RANDOM_FUNCTIONS" "${PSEUDO_RANDOM_FUNCTIONS}"; then
+ log ERROR "The changes for the VPN security policy ${name} could not be written"
+ fi
+
+ cli_headline 1 "Current pseudo random function list for ${name}:"
+ for prf in ${PSEUDO_RANDOM_FUNCTIONS}; do
+ cli_print_fmt1 1 "${prf}" "${VPN_SUPPORTED_PSEUDO_RANDOM_FUNCTIONS[${prf}]}"
done
}
vpn_security_policies_integrity_supported() {
local integrity=${1}
- list_match ${integrity} ${!VPN_SUPPORTED_INTEGRITY[@]}
+ list_match ${integrity} ${!VPN_SUPPORTED_INTEGRITIES[@]}
+}
+
+vpn_security_policies_pseudo_random_function_supported() {
+ local prf="${1}"
+
+ list_match "${prf}" ${!VPN_SUPPORTED_PSEUDO_RANDOM_FUNCTIONS[@]}
}
vpn_security_policies_cipher_is_aead() {
local proposals
local cipher
- for cipher in ${CIPHER}; do
+ for cipher in ${CIPHERS}; do
# Translate cipher
local _cipher=${CIPHER_TO_STRONGSWAN[${cipher}]}
if vpn_security_policies_cipher_is_aead "${cipher}"; then
local prf
- for prf in ${PSEUDO_RANDOM_FUNCTION}; do
+ for prf in ${PSEUDO_RANDOM_FUNCTIONS}; do
local _prf="${PSEUDO_RANDOM_FUNCTION_TO_STRONGSWAN[${prf}]}"
if ! isset _prf; then
fi
local group_type
- for group_type in ${GROUP_TYPE}; do
+ for group_type in ${GROUP_TYPES}; do
local _group_type=${GROUP_TYPE_TO_STRONGSWAN[${group_type}]}
if ! isset _group_type; then
done
else
local integrity
- for integrity in ${INTEGRITY}; do
+ for integrity in ${INTEGRITIES}; do
local _integrity=${INTEGRITY_TO_STRONGSWAN[${integrity}]}
if ! isset _integrity; then
fi
local group_type
- for group_type in ${GROUP_TYPE}; do
+ for group_type in ${GROUP_TYPES}; do
local _group_type=${GROUP_TYPE_TO_STRONGSWAN[${group_type}]}
if ! isset _group_type; then
local proposals
local cipher
- for cipher in ${CIPHER}; do
+ for cipher in ${CIPHERS}; do
# Translate cipher
local _cipher=${CIPHER_TO_STRONGSWAN[${cipher}]}
if vpn_security_policies_cipher_is_aead ${cipher}; then
local group_type
- for group_type in ${GROUP_TYPE}; do
+ for group_type in ${GROUP_TYPES}; do
local _group_type=${GROUP_TYPE_TO_STRONGSWAN[${group_type}]}
if ! isset _group_type; then
done
else
local integrity
- for integrity in ${INTEGRITY}; do
+ for integrity in ${INTEGRITIES}; do
local _integrity=${INTEGRITY_TO_STRONGSWAN[${integrity}]}
if ! isset _integrity; then
fi
local group_type
- for group_type in ${GROUP_TYPE}; do
+ for group_type in ${GROUP_TYPES}; do
local _group_type=${GROUP_TYPE_TO_STRONGSWAN[${group_type}]}
if ! isset _group_type; then