# -*- coding: utf-8; mode: tcl; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- vim:fenc=utf-8:ft=tcl:et:sw=4:ts=4:sts=4

PortSystem              1.0

name                    macos-vpn-server
# use the latest macOS version as the version number of this port
version                 10.14.5
revision                1
homepage                https://opensource.apple.com/source/ppp/ppp-838/Helpers/vpnd/vpnd.5.auto.html
categories              net
platforms               darwin
supported_archs         noarch
maintainers             {ieee.org:s.t.smith @essandess} openmaintainer
license                 BSD
distfiles

set SystemConfigurationPath /Library/Preferences/SystemConfiguration

description             macOS VPN (L2TP-IPSec-PSK) Server.
long_description ${description} \
    Native macOS VPN Server L2TP-IPSec-PSK configuration using vpnd. This\
    configuration is based upon macOS Server.app's VPN server prior to its\
    deprecation in Server.app version 5.7. See `man 5 vpnd` and\
    ${SystemConfigurationPath}/com.apple.RemoteAccessServers.plist\
    for details.

# uncomment if memorable passwords used
# depends_build-append    port:sf-pwgen

use_configure           no

build {}

set sharePath ${prefix}/share/${name}

destroot {
    xinstall -d \
        ${destroot}${sharePath}${SystemConfigurationPath}
    xinstall -m 0644 -W ${filespath} \
        com.apple.RemoteAccessServers.plist.macports \
        ${destroot}${sharePath}${SystemConfigurationPath}
}

startupitem.create      yes
startupitem.name        ${name}
startupitem.executable  /usr/sbin/vpnd \
                            -x \
                            -i \
                            org.macports.ppp.l2tp

pre-activate {
    # Add the necessary keychain item for the VPN PSK
    set vpn_keychain_item [exec /bin/sh -c "RV=\"\" ; /usr/bin/security find-generic-password -a org.macports.ppp.l2tp -s com.apple.net.racoon /Library/Keychains/System.keychain 1> /dev/null 2>&1 && RV=com.apple.net.racoon || /usr/bin/true ; echo \"\${RV}\""]
    if {[string trim ${vpn_keychain_item}] == ""} {
        set vpn_pre_shared_secret [exec /usr/bin/openssl rand -base64 24]
        system "/usr/bin/security add-generic-password -a org.macports.ppp.l2tp -s com.apple.net.racoon -T /usr/sbin/racoon -w ${vpn_pre_shared_secret} -U /Library/Keychains/System.keychain"
        # delete command:
        # sudo /usr/bin/security delete-generic-password -a org.macports.ppp.l2tp -s com.apple.net.racoon /Library/Keychains/System.keychain
        set vpn_keychain_item [exec /bin/sh -c "RV=\"\" ; /usr/bin/security find-generic-password -a org.macports.ppp.l2tp -s com.apple.net.racoon /Library/Keychains/System.keychain 1> /dev/null 2>&1 && RV=com.apple.net.racoon || /usr/bin/true ; echo \"\${RV}\""]
        if {[string trim ${vpn_keychain_item}] == ""} {
            ui_warn "Keychain item com.apple.net.racoon for VPN PSK failed to be created."
        }
    }
}

# Network configuration
# hard-coded examples
set vpn_vpnhost         host.domain.tld
set vpn_offeredsearchdomain \
                        domain.tld.
set vpn_offeredserveraddress \
                        10.0.1.1
set vpn_network         10.0.1.

post-activate {
    # copy to actual config file if it doesn't already exist
    if ![file exists ${SystemConfigurationPath}/com.apple.RemoteAccessServers.plist] {
        xinstall -m 0644 ${sharePath}${SystemConfigurationPath}/com.apple.RemoteAccessServers.plist.macports \
            ${SystemConfigurationPath}/com.apple.RemoteAccessServers.plist

        # use network settings for installed example configuration
        set vpn_vpnhost [exec /bin/hostname -f]
        set vpn_offeredsearchdomain [exec /bin/hostname -f | /usr/bin/sed -E -e "s|^\[^.\]+\\.(.*)\$|\\1.|"]
        set vpn_offeredserveraddress [exec /usr/sbin/scutil --dns | /usr/bin/grep "DNS configuration (for scoped queries)" -A 7 | /usr/bin/grep nameserver | /usr/bin/sed -E -e "s|^\[\[:space:\]\]*nameserver.+\[\[:space:\]\]*:\[\[:space:\]\]+||" | /usr/bin/head -1]
        set vpn_network [exec /bin/sh -c "/sbin/ifconfig `/usr/sbin/netstat -nr | /usr/bin/awk '{ if (\$1 ~/default/) { print \$NF} }' | /usr/bin/head -1` | /usr/bin/awk '{ if (\$1 ~/inet\$/) { print \$2} }' | /usr/bin/sed -E -e 's|\\.\[0-9\]{1,3}\$|\\.|'"]
        set vpn_destaddressrange_start ${vpn_network}245
        set vpn_destaddressrange_end ${vpn_network}254

        reinplace "s|@VPN_OFFEREDSEARCHDOMAIN@|${vpn_offeredsearchdomain}|g" \
            ${SystemConfigurationPath}/com.apple.RemoteAccessServers.plist
        reinplace "s|@VPN_OFFEREDSERVERADDRESS@|${vpn_offeredserveraddress}|g" \
            ${SystemConfigurationPath}/com.apple.RemoteAccessServers.plist
        reinplace "s|@VPN_DESTADDRESSRANGE_START@|${vpn_destaddressrange_start}|g" \
            ${SystemConfigurationPath}/com.apple.RemoteAccessServers.plist
        reinplace "s|@VPN_DESTADDRESSRANGE_END@|${vpn_destaddressrange_end}|g" \
            ${SystemConfigurationPath}/com.apple.RemoteAccessServers.plist
        reinplace "s|@VPN_VPNHOST@|${vpn_vpnhost}|g" \
            ${SystemConfigurationPath}/com.apple.RemoteAccessServers.plist

        ui_msg "Configuring VPN Network with:

	VPNHost				${vpn_vpnhost}
	OfferedServerAddresses (DNS)	${vpn_offeredserveraddress}
	OfferedSearchDomains		${vpn_offeredsearchdomain}
	DestAddressRanges		${vpn_destaddressrange_start} to ${vpn_destaddressrange_end}

        This configuration can be changed in the file:

	${SystemConfigurationPath}/com.apple.RemoteAccessServers.plist

        See `man 5 vpnd` for details."
    }

    # Add launchd.plist keys to MacPorts launchdaemon
    # Copied from com.apple.ppp.l2tp.plist
    reinplace \
        "s|^<key>ProgramArguments</key>|<key>ProcessType</key><string>Interactive</string>\\
<key>PreventsSleep</key><true/>\\
<key>EnableTransactions</key><false/>\\
<key>EnablePressuredExit</key><false/>\\
&|" \
        ${prefix}/etc/${startupitem.location}/org.macports.${name}/org.macports.${name}.plist
}

notes "The macOS VPN Server's initial configuration uses installation-time\
    network settings to provide a basic, working VPN server.

    Users must reconfigure the installation for their own network\
    specifics by editing the files:

	${SystemConfigurationPath}/com.apple.RemoteAccessServers.plist

See `man 5 vpnd` for details.

    The VPN Pre-Shared Secret is stored in the System Keychain item\
    com.apple.net.racoon, available within Keychain Access.app or\
    /usr/bin/security.

    Post Installation:

 1. It is necessary to configure local accounts for CHAP authentication\
    by adding ',SMB-NT,CRAM-MD5,RECOVERABLE' to the account's\
    AuthenticationAuthority ShadowHash list of methods.

dscl . read /Users/username AuthenticationAuthority
sudo dscl . change /Users/username AuthenticationAuthority \\
    \";ShadowHash;HASHLIST:<SALTED-SHA512-PBKDF2,SRP-RFC5054-4096-SHA512-PBKDF2>\" \\
    \";ShadowHash;HASHLIST:<SALTED-SHA512-PBKDF2,SRP-RFC5054-4096-SHA512-PBKDF2,SMB-NT,CRAM-MD5,RECOVERABLE>\"
passwd

    The `passwd` command or re-login may be necessary to populate macOS's\
    user shadow hash database. Note that MS-CHAPv2 is compromised, and the\
    only secure component of this VPN is a strong random PSK.

 2. The router and firewall must be configured to forward and pass UDP ports\
    500, 1701, and 4500."

livecheck.type         none