class VPN::Config::Generator

Attributes

auth_name[RW]
auth_pass[RW]
certificate_pass[RW]
certificate_path[RW]
data_file[RW]
endpoints[RW]
identifier[RW]
provider[RW]

Public Class Methods

new(auth_name: nil, auth_pass: nil, identifier: nil, certificate_path: nil, certificate_pass: nil, provider: nil, endpoints: nil, data_file: nil) click to toggle source
# File lib/vpn/config/generator.rb, line 11
def initialize(auth_name: nil, auth_pass: nil, identifier: nil,
    certificate_path: nil, certificate_pass: nil, provider: nil,
    endpoints: nil, data_file: nil)
  @auth_name = auth_name
  @auth_pass = auth_pass
  @identifier = identifier || "com.example.vpn"
  @certificate_path = certificate_path
  @certificate_pass = certificate_pass
  @provider = provider || "Private Internet Access"
  @endpoints = endpoints
  @data_file = data_file || VPN::Config::PROVIDERS_PATH
end

Public Instance Methods

enabled_vpns() click to toggle source
# File lib/vpn/config/generator.rb, line 43
def enabled_vpns
  if endpoints && endpoints.any?
    vpns.select {|e| endpoints.include? e["name"] }
  else
    vpns
  end
end
generate_plist() click to toggle source
# File lib/vpn/config/generator.rb, line 51
def generate_plist
  config.to_plist
end
generate_signed_plist() click to toggle source
# File lib/vpn/config/generator.rb, line 55
def generate_signed_plist
  private_key = p12.key
  signing_cert = p12.certificate

  private_key = p12.key
  intermediate_certs = p12.ca_certs
  signing_cert = p12.certificate

  # Read configuration profile
  configuration_profile_data = generate_plist

  # Sign the configuration profile
  signing_flags = OpenSSL::PKCS7::BINARY
  signature = OpenSSL::PKCS7.sign(signing_cert, private_key,
                                  configuration_profile_data, intermediate_certs,
                                  signing_flags)

  signature.to_der
end
providers() click to toggle source
# File lib/vpn/config/generator.rb, line 24
def providers
  @providers ||= YAML.load_file(data_file)["providers"]
end
selected_provider() click to toggle source
# File lib/vpn/config/generator.rb, line 28
def selected_provider
  @selected_provider ||= begin
    prov = providers.find {|pr| pr["name"] == provider }
    if prov
      prov
    else
      raise ArgumentError, "Provider '#{provider}' not found"
    end
  end
end
vpns() click to toggle source
# File lib/vpn/config/generator.rb, line 39
def vpns
  @vpns ||= selected_provider["endpoints"]
end

Private Instance Methods

config() click to toggle source
# File lib/vpn/config/generator.rb, line 100
def config
  {
    "PayloadDescription" => "VPN settings for #{selected_provider["name"]}",
    "PayloadDisplayName" => selected_provider["name"],
    "PayloadIdentifier" => identifier,
    "PayloadOrganization" => "",
    "PayloadRemovalDisallowed" => false,
    "PayloadType" => "Configuration",
    "PayloadUUID" => selected_provider["uuid"],
    "PayloadVersion" => 1,

    "PayloadContent" => enabled_vpns.each_with_index.map do |vpn, index|
      {
        "EAP" => {},
        "IPSec" => {
          "AuthenticationMethod" => "SharedSecret",
          "SharedSecret" => StringIO.new(vpn["shared_secret"]),
        },
        "IPv4" => {
          "OverridePrimary" => 1
        },
        "PPP" => {
          "AuthName" => auth_name,
          "AuthPassword" => auth_pass,
          "TokenCard" => false,
          "CommRemoteAddress" => vpn["host"],
        },
        "PayloadDescription" => "Configures VPN settings, including authentication.",
        "PayloadDisplayName" => "VPN (#{vpn["name"]})",
        "PayloadIdentifier" => "#{identifier}.vpn#{index}",
        "PayloadOrganization" => "",
        "PayloadType" => "com.apple.vpn.managed",
        "PayloadUUID" => vpn["uuid"],
        "PayloadVersion" => 1,
        "Proxies" => {},
        "UserDefinedName" => vpn["name"],
        "VPNType" => "L2TP"
      }
    end
  }
end
default_p12() click to toggle source
# File lib/vpn/config/generator.rb, line 92
def default_p12
  @default_certificate ||= begin
    path = File.expand_path("../../../../snake-oil/certificate.p12", __FILE__)
    cert = File.read(path)
    OpenSSL::PKCS12.new(cert, "Swordfish")
  end
end
p12() click to toggle source
# File lib/vpn/config/generator.rb, line 77
def p12
  @p12 ||= begin
    if certificate_path
      path = File.expand_path(certificate_path)
      unless File.exists? path
        raise ArgumentError, "File not found: #{certificate_path}"
      end
      cert = File.read(path)
      OpenSSL::PKCS12.new(cert, certificate_pass)
    else
      default_p12
    end
  end
end