+# Export Apple profile to browser
+} elsif ($cgiparams{'ACTION'} eq $Lang::tr{'download apple profile'}) {
+ # Read global configuration
+ &General::readhash("${General::swroot}/vpn/settings", \%vpnsettings);
+
+ # Read connections
+ &General::readhasharray("${General::swroot}/vpn/config", \%confighash);
+ my $key = $cgiparams{'KEY'};
+
+ # Create a UUID generator
+ my $uuid = Data::UUID->new();
+
+ my $uuid1 = $uuid->create_str();
+ my $uuid2 = $uuid->create_str();
+
+ my $ca = "";
+ my $ca_uuid = $uuid->create_str();
+
+ my $cert = "";
+ my $cert_uuid = $uuid->create_str();
+
+ # Read and encode the CA & certificate
+ if ($confighash{$key}[4] eq "cert") {
+ my $ca_path = "${General::swroot}/ca/cacert.pem";
+ my $cert_path = "${General::swroot}/certs/$confighash{$key}[1].p12";
+
+ # Read the CA and encode it into Base64
+ open(CA, "<${ca_path}");
+ local($/) = undef; # slurp
+ $ca = MIME::Base64::encode_base64(<CA>);
+ close(CA);
+
+ # Read certificate and encode it into Base64
+ open(CERT, "<${cert_path}");
+ local($/) = undef; # slurp
+ $cert = MIME::Base64::encode_base64(<CERT>);
+ close(CERT);
+ }
+
+ print "Content-Type: application/octet-stream\n";
+ print "Content-Disposition: attachment; filename=" . $confighash{$key}[1] . ".mobileconfig\n";
+ print "\n"; # end headers
+
+ # Use our own FQDN if nothing else is configured
+ my $endpoint = ($vpnsettings{'RW_ENDPOINT'} ne "") ? $vpnsettings{'RW_ENDPOINT'} : &hostname();
+
+ print "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n";
+ print "<plist version=\"1.0\">\n";
+ print " <dict>\n";
+ print " <key>PayloadDisplayName</key>\n";
+ print " <string>$confighash{$key}[1]</string>\n";
+ print " <key>PayloadIdentifier</key>\n";
+ print " <string>$confighash{$key}[1]</string>\n";
+ print " <key>PayloadUUID</key>\n";
+ print " <string>${uuid1}</string>\n";
+ print " <key>PayloadType</key>\n";
+ print " <string>Configuration</string>\n";
+ print " <key>PayloadVersion</key>\n";
+ print " <integer>1</integer>\n";
+ print " <key>PayloadContent</key>\n";
+ print " <array>\n";
+ print " <dict>\n";
+ print " <key>PayloadIdentifier</key>\n";
+ print " <string>org.example.vpn1.conf1</string>\n";
+ print " <key>PayloadUUID</key>\n";
+ print " <string>${uuid2}</string>\n";
+ print " <key>PayloadType</key>\n";
+ print " <string>com.apple.vpn.managed</string>\n";
+ print " <key>PayloadVersion</key>\n";
+ print " <integer>1</integer>\n";
+ print " <key>UserDefinedName</key>\n";
+ print " <string>$confighash{$key}[1]</string>\n";
+ print " <key>VPNType</key>\n";
+ print " <string>IKEv2</string>\n";
+ print " <key>IKEv2</key>\n";
+ print " <dict>\n";
+ print " <key>RemoteAddress</key>\n";
+ print " <string>$endpoint</string>\n";
+
+ # PFS
+ my $pfs = $confighash{$key}[28];
+ if ($pfs eq "on") {
+ print " <key>EnablePFS</key>\n";
+ print " <true/>\n";
+ }
+
+ # IKE Cipher Suite
+ print " <key>IKESecurityAssociationParameters</key>\n";
+ print " <dict>\n";
+
+ # Encryption
+ foreach my $cipher (split(/\|/,$confighash{$key}[18])) {
+ # Skip all unsupported ciphers
+ next unless (exists $APPLE_CIPHERS{$cipher});
+
+ print " <key>EncryptionAlgorithm</key>\n";
+ print " <string>$APPLE_CIPHERS{$cipher}</string>\n";
+ last;
+ }
+
+ # Integrity
+ foreach my $integrity (split(/\|/,$confighash{$key}[19])) {
+ # Skip all unsupported algorithms
+ next unless (exists $APPLE_INTEGRITIES{$integrity});
+
+ print " <key>IntegrityAlgorithm</key>\n";
+ print " <string>$APPLE_INTEGRITIES{$integrity}</string>\n";
+ last;
+ }
+
+ # Diffie Hellman Groups
+ foreach my $group (split(/\|/,$confighash{$key}[20])) {
+ # Skip all unsupported algorithms
+ next unless (exists $APPLE_DH_GROUPS{$group});
+
+ print " <key>DiffieHellmanGroup</key>\n";
+ print " <string>$APPLE_DH_GROUPS{$group}</string>\n";
+ last;
+ }
+
+ # Lifetime
+ my $lifetime = $confighash{$key}[16] * 60;
+ print " <key>LifeTimeInMinutes</key>\n";
+ print " <integer>$lifetime</integer>\n";
+ print " </dict>\n";
+
+ # ESP Cipher Suite
+ print " <key>ChildSecurityAssociationParameters</key>\n";
+ print " <dict>\n";
+
+ # Encryption
+ foreach my $cipher (split(/\|/,$confighash{$key}[21])) {
+ # Skip all unsupported ciphers
+ next unless (exists $APPLE_CIPHERS{$cipher});
+
+ print " <key>EncryptionAlgorithm</key>\n";
+ print " <string>$APPLE_CIPHERS{$cipher}</string>\n";
+ last;
+ }
+
+ # Integrity
+ foreach my $integrity (split(/\|/,$confighash{$key}[22])) {
+ # Skip all unsupported algorithms
+ next unless (exists $APPLE_INTEGRITIES{$integrity});
+
+ print " <key>IntegrityAlgorithm</key>\n";
+ print " <string>$APPLE_INTEGRITIES{$integrity}</string>\n";
+ last;
+ }
+
+ # Diffie Hellman Groups
+ foreach my $group (split(/\|/,$confighash{$key}[23])) {
+ # Skip all unsupported algorithms
+ next unless (exists $APPLE_DH_GROUPS{$group});
+
+ print " <key>DiffieHellmanGroup</key>\n";
+ print " <string>$APPLE_DH_GROUPS{$group}</string>\n";
+ last;
+ }
+
+ # Lifetime
+ my $lifetime = $confighash{$key}[17] * 60;
+ print " <key>LifeTimeInMinutes</key>\n";
+ print " <integer>$lifetime</integer>\n";
+ print " </dict>\n";
+
+
+ # Left ID
+ if ($confighash{$key}[9]) {
+ my $leftid = $confighash{$key}[9];
+
+ # Strip leading @ from FQDNs
+ if ($leftid =~ m/^@(.*)$/) {
+ $leftid = $1;
+ }
+
+ print " <key>LocalIdentifier</key>\n";
+ print " <string>$leftid</string>\n";
+ }
+
+ # Right ID
+ if ($confighash{$key}[7]) {
+ my $rightid = $confighash{$key}[7];
+
+ # Strip leading @ from FQDNs
+ if ($rightid =~ m/^@(.*)$/) {
+ $rightid = $1;
+ }
+
+ print " <key>RemoteIdentifier</key>\n";
+ print " <string>$rightid</string>\n";
+ }
+
+ if ($confighash{$key}[4] eq "cert") {
+ print " <key>AuthenticationMethod</key>\n";
+ print " <string>Certificate</string>\n";
+
+ print " <key>PayloadCertificateUUID</key>\n";
+ print " <string>${cert_uuid}</string>\n";
+ } else {
+ print " <key>AuthenticationMethod</key>\n";
+ print " <string>SharedSecret</string>\n";
+ print " <key>SharedSecret</key>\n";
+ print " <string>$confighash{$key}[5]</string>\n";
+ }
+
+ print " <key>ExtendedAuthEnabled</key>\n";
+ print " <integer>0</integer>\n";
+
+ # These are not needed, but we provide some default to stop iPhone asking for credentials
+ print " <key>AuthName</key>\n";
+ print " <string>$confighash{$key}[1]</string>\n";
+ print " <key>AuthPassword</key>\n";
+ print " <string></string>\n";
+ print " </dict>\n";
+ print " </dict>\n";
+
+ if ($confighash{$key}[4] eq "cert") {
+ print " <dict>\n";
+ print " <key>PayloadIdentifier</key>\n";
+ print " <string>org.example.vpn1.client</string>\n";
+ print " <key>PayloadDisplayName</key>\n";
+ print " <string>$confighash{$key}[1]</string>\n";
+ print " <key>PayloadUUID</key>\n";
+ print " <string>${cert_uuid}</string>\n";
+ print " <key>PayloadType</key>\n";
+ print " <string>com.apple.security.pkcs12</string>\n";
+ print " <key>PayloadVersion</key>\n";
+ print " <integer>1</integer>\n";
+ print " <key>PayloadContent</key>\n";
+ print " <data>\n";
+
+ foreach (split /\n/,${cert}) {
+ print " $_\n";
+ }
+
+ print " </data>\n";
+ print " </dict>\n";
+
+ print " <dict>\n";
+ print " <key>PayloadIdentifier</key>\n";
+ print " <string>org.example.ca</string>\n";
+ print " <key>PayloadUUID</key>\n";
+ print " <string>${ca_uuid}</string>\n";
+ print " <key>PayloadType</key>\n";
+ print " <string>com.apple.security.root</string>\n";
+ print " <key>PayloadVersion</key>\n";
+ print " <integer>1</integer>\n";
+ print " <key>PayloadContent</key>\n";
+ print " <data>\n";
+
+ foreach (split /\n/,${ca}) {
+ print " $_\n";
+ }
+
+ print " </data>\n";
+ print " </dict>\n";
+ }
+
+ print " </array>\n";
+ print " </dict>\n";
+ print "</plist>\n";
+
+ # Done
+ exit(0);