Skip to content

Commit

Permalink
Merge branch 'release/0.3.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
iphoting committed May 4, 2014
2 parents 945bc45 + 9acf6b8 commit e7103fe
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 12 deletions.
6 changes: 5 additions & 1 deletion ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
= 0.3.0 / 2014-05-04
* Documentation updates.
* Added support for `URLStringProbe`, via `--url-probe`.

= 0.2.1 / 2014-04-19
* Implement unit testing.
* Switch to a portable and native uuidgen implementation.
Expand All @@ -18,4 +22,4 @@
* Improved Documentation.

= 0.0.1 / 2014-03-26
* Initial Release.
* Initial Release.
21 changes: 17 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,22 @@

OpenVPN iOS Configuration Profile Utility

[![GitHub version](https://badge.fury.io/gh/iphoting%2Fovpnmcgen.rb.svg)](http://badge.fury.io/gh/iphoting%2Fovpnmcgen.rb) [![Gem Version](https://badge.fury.io/rb/ovpnmcgen.rb.svg)](http://badge.fury.io/rb/ovpnmcgen.rb) [![Build Status](https://travis-ci.org/iphoting/ovpnmcgen.rb.svg?branch=master)](https://travis-ci.org/iphoting/ovpnmcgen.rb)
[![Stories in Ready](https://badge.waffle.io/iphoting/ovpnmcgen.rb.png?label=ready&title=Ready)](http://waffle.io/iphoting/ovpnmcgen.rb)
[![GitHub version](https://badge.fury.io/gh/iphoting%2Fovpnmcgen.rb.svg)](http://badge.fury.io/gh/iphoting%2Fovpnmcgen.rb)
[![Gem Version](https://badge.fury.io/rb/ovpnmcgen.rb.svg)](http://badge.fury.io/rb/ovpnmcgen.rb)
[![Build Status](https://travis-ci.org/iphoting/ovpnmcgen.rb.svg?branch=master)](https://travis-ci.org/iphoting/ovpnmcgen.rb)

Generates iOS configuration profiles (.mobileconfig) that configures OpenVPN for use with VPN-on-Demand that are not accessible through the Apple Configurator or the iPhone Configuration Utility.

Although there are many possible VPN-on-Demand (VoD) triggers, this utility currently only implements `SSIDMatch` and `InterfaceTypeMatch`. For 'high' (default) security level, the following algorithm is executed upon network changes, in order:
Although there are many possible VPN-on-Demand (VoD) triggers, this utility currently only implements `SSIDMatch`, `InterfaceTypeMatch`, and optionally `URLStringProbe`. For 'high' (default) security level, the following algorithm is executed upon network changes, in order:

- If wireless SSID matches any specified with `--trusted-ssids`, tear down the VPN connection and do not reconnect on demand.
- Else if wireless SSID matches any specified with `--untrusted-ssids`, unconditionally bring up the VPN connection on the next network attempt.
- Else if the primary network interface becomes Wifi (any SSID except those above), unconditionally bring up the VPN connection on the next network attempt.
- Else if the primary network interface becomes Cellular, leave any existing VPN connection up, but do not reconnect on demand.
- Else, unconditionally bring up the VPN connection on the next network attempt.

Note: The other match triggers, such as `DNSDomainMatch`, `DNSServerAddressMatch`, `URLStringProbe`, and per-connection domain inspection (`ActionParameters`), are not implemented. I reckon some kind of DSL will need to be built to support them; pull-requests are welcome.
Note: The other match triggers, such as `DNSDomainMatch`, `DNSServerAddressMatch`, and per-connection domain inspection (`ActionParameters`), are not implemented. I reckon some kind of DSL will need to be built to support them; pull-requests are welcome.

## Installation

Expand Down Expand Up @@ -55,6 +58,7 @@ Usage: ovpnmcgen.rb generate [options] <user> <device>
--cert-uuid UUID Override a Certificate payload UUID.
-t, --trusted-ssids SSIDS List of comma-separated trusted SSIDs.
-u, --untrusted-ssids SSIDS List of comma-separated untrusted SSIDs.
--url-probe URL This URL must return HTTP status 200, without redirection, before the VPN service will try establishing.
--ovpnconfigfile FILE Path to OpenVPN client config file.
-o, --output FILE Output to file. [Default: stdout]
```
Expand All @@ -79,6 +83,14 @@ For 'medium' security level, the following algorithm is executed upon network ch
- Else if the primary network interface becomes Cellular, leave any existing VPN connection up, but do not reconnect on demand.
- Else, unconditionally bring up the VPN connection on the next network attempt.

### URL Probe

Apple provides a `URLStringProbe` test condition where a VPN connection will only be established, if and only if a specified URL is successfully fetched (returning a 200 HTTP status code) without redirection.

This feature can be enabled for statistical and maintenance-protection reasons. Otherwise, it can also workaround a circular limitation with unsecured wireless captive portals. See Known Issues below for further elaboration.

By enabling this option, you will need to reliably and quickly respond with HTTP status code 200 at the URL string supplied.

## Examples

### Typical Usage
Expand Down Expand Up @@ -235,6 +247,7 @@ Output:
--p12file path/to/john-ipad.p12 --p12pass p12passphrase john ipad

Output similar to above:

```
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
Expand Down Expand Up @@ -323,7 +336,7 @@ Output similar to above:

Workaround: Manually disable VPN-on-Demand in Settings.app > VPN > Server (i) option screen. Reenable only after Internet access is available.

TODO: Implement `URLStringProbe` where, if and only if this URL is successfully fetched (returning a 200 HTTP status code) without redirection, will the VPN service be required, relied on, and brought up.
Solution: Implement `URLStringProbe` where, if and only if this URL is successfully fetched (returning a 200 HTTP status code) without redirection, will the VPN service be required, relied on, and brought up. Enable with the `--url-probe` flag.

## TODO

Expand Down
2 changes: 2 additions & 0 deletions bin/ovpnmcgen.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
c.option '--cert-uuid UUID', 'Override a Certificate payload UUID.'
c.option '-t', '--trusted-ssids SSIDS', Array, 'List of comma-separated trusted SSIDs.'
c.option '-u', '--untrusted-ssids SSIDS', Array, 'List of comma-separated untrusted SSIDs.'
c.option '--url-probe URL', 'This URL must return HTTP status 200, without redirection, before the VPN service will try establishing.'
c.option '--ovpnconfigfile FILE', 'Path to OpenVPN client config file.'
c.option '-o', '--output FILE', 'Output to file. [Default: stdout]'
c.action do |args, options|
Expand Down Expand Up @@ -60,6 +61,7 @@
}
inputs[:ovpnconfigfile] = options.ovpnconfigfile if options.ovpnconfigfile
inputs[:tafile] = options.tafile if options.tafile
inputs[:url_probe] = options.url_probe if options.url_probe

unless options.output
puts Ovpnmcgen.generate(inputs)
Expand Down
29 changes: 29 additions & 0 deletions features/gen_basic.feature
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,35 @@ Feature: Basic Generate Functionality
\s*<integer>0</integer>
"""

Scenario: The url-probe flag is set.
When I run `ovpnmcgen.rb g --host aruba.cucumber.org --cafile ca.crt --p12file p12file.p12 --url-probe 'https://url.to.probe/' cucumber aruba`
Then the output should match:
"""
<key>URLStringProbe</key>
\s*<string>https://url.to.probe/</string>
"""
And the output should match:
"""
<dict>
\s*<key>Action</key>
\s*<string>Ignore</string>
\s*</dict>
"""

Scenario: The url-probe flag is not set.
When I run `ovpnmcgen.rb g --host aruba.cucumber.org --cafile ca.crt --p12file p12file.p12 cucumber aruba`
Then the output should not contain:
"""
<key>URLStringProbe</key>
"""
And the output should not match:
"""
<dict>
\s*<key>Action</key>
\s*<string>Ignore</string>
\s*</dict>
"""

Scenario: The [un]trusted-ssids flags are set.
When I run `ovpnmcgen.rb g --host aruba.cucumber.org --cafile ca.crt --p12file p12file.p12 --trusted-ssids trusted1,trusted2 --untrusted-ssids evil3,evil4 cucumber aruba`
Then the output should match:
Expand Down
21 changes: 15 additions & 6 deletions lib/ovpnmcgen.rb
Original file line number Diff line number Diff line change
Expand Up @@ -63,18 +63,16 @@ def generate(inputs = {})
'SSIDMatch' => untrusted_ssids,
'Action' => 'Connect'
}
vpnOnDemandRules << vodTrusted if trusted_ssids
vpnOnDemandRules << vodUntrusted if untrusted_ssids

vpnOnDemandRules << { # Untrust all Wifi
vodWifiOnly = { # Untrust all Wifi
'InterfaceTypeMatch' => 'WiFi',
'Action' => case inputs[:security_level]
when 'paranoid', 'high'
'Connect'
else # medium
'Ignore'
end
} << { # Trust Cellular
}
vodCellularOnly = { # Trust Cellular
'InterfaceTypeMatch' => 'Cellular',
'Action' => case inputs[:security_level]
when 'paranoid'
Expand All @@ -84,10 +82,21 @@ def generate(inputs = {})
else # medium
'Disconnect'
end
} << { # Default catch-all
}
vodDefault = { # Default catch-all
'Action' => 'Connect'
}

# Insert URLStringProbe conditions when enabled with --url-probe
vodTrusted['URLStringProbe'] = vodUntrusted['URLStringProbe'] = vodWifiOnly['URLStringProbe'] = vodCellularOnly['URLStringProbe'] = vodDefault['URLStringProbe'] = inputs[:url_probe] if inputs[:url_probe]

vpnOnDemandRules << vodTrusted if trusted_ssids
vpnOnDemandRules << vodUntrusted if untrusted_ssids
vpnOnDemandRules << vodWifiOnly << vodCellularOnly << vodDefault
vpnOnDemandRules << { # Default catch-all when URLStringProbe is enabled and returns false to prevent circular race.
'Action' => 'Ignore'
} if inputs[:url_probe]

cert = {
'Password' => p12pass,
'PayloadCertificateFileName' => "#{user}-#{device}.p12",
Expand Down
2 changes: 1 addition & 1 deletion lib/ovpnmcgen/version.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module Ovpnmcgen
VERSION = "0.2.1"
VERSION = "0.3.0"
SUMMARY = "An OpenVPN iOS Configuration Profile (.mobileconfig) Utility"
end

0 comments on commit e7103fe

Please sign in to comment.