From 30f42d5869f65d3171878b4d6d94e9c3813f02cf Mon Sep 17 00:00:00 2001 From: elijah Date: Fri, 23 Nov 2012 01:49:23 -0800 Subject: initial work toward 'leap test'. for now, it generates an openvpn config for client testing. try 'leap init-test' --- lib/leap_cli/commands/ca.rb | 43 ++++++++++++++++++++++-- lib/leap_cli/commands/test.rb | 26 +++++++++++++++ lib/leap_cli/path.rb | 76 +++++++++++++++++++++---------------------- lib/leap_cli/util.rb | 9 +++++ 4 files changed, 113 insertions(+), 41 deletions(-) create mode 100644 lib/leap_cli/commands/test.rb (limited to 'lib') diff --git a/lib/leap_cli/commands/ca.rb b/lib/leap_cli/commands/ca.rb index 5aa0cde..05bdb2b 100644 --- a/lib/leap_cli/commands/ca.rb +++ b/lib/leap_cli/commands/ca.rb @@ -144,7 +144,7 @@ module LeapCli; module Commands cert.not_before = today cert.not_after = years_from_today(1) cert.parent = ca_root - cert.sign! test_cert_signing_profile + cert.sign! domain_test_signing_profile write_file! [:commercial_cert, manager.provider.domain], cert.to_pem log "please replace this file with the real certificate you get from a CA using #{Path.relative_path([:commercial_csr, manager.provider.domain])}" end @@ -217,6 +217,19 @@ module LeapCli; module Commands write_file!([:node_x509_cert, node.name], cert.to_pem) end + def generate_test_client_cert + cert = CertificateAuthority::Certificate.new + cert.serial_number.number = cert_serial_number(manager.provider.domain) + cert.subject.common_name = random_common_name(manager.provider.domain) + cert.not_before = today + cert.not_after = years_from_today(1) + cert.key_material.generate_key(1024) # just for testing, remember! + cert.parent = ca_root + cert.sign! client_test_signing_profile + write_file! :test_client_key, cert.key_material.private_key.to_pem + write_file! :test_client_cert, cert.to_pem + end + def ca_root @ca_root ||= begin load_certificate_file(:ca_cert, :ca_key) @@ -277,7 +290,7 @@ module LeapCli; module Commands # with our own CA (for testing purposes). Typically, this cert would # be purchased from a commercial CA, and not signed this way. # - def test_cert_signing_profile + def domain_test_signing_profile { "digest" => "SHA256", "extensions" => { @@ -291,6 +304,24 @@ module LeapCli; module Commands } end + # + # This is used when signing a dummy client certificate that is only to be + # used for testing. + # + def client_test_signing_profile + { + "digest" => "SHA256", + "extensions" => { + "keyUsage" => { + "usage" => ["digitalSignature", "keyAgreement"] + }, + "extendedKeyUsage" => { + "usage" => ["clientAuth"] + } + } + } + end + def dns_names_for_node(node) names = [node.domain.internal] if node['dns'] && node.dns['aliases'] && node.dns.aliases.any? @@ -310,6 +341,14 @@ module LeapCli; module Commands Digest::MD5.hexdigest("#{domain_name} -- #{Time.now}").to_i(16) end + # + # for the random common name, we need a text string that will be unique across all certs. + # ruby 1.8 doesn't have a built-in uuid generator, or we would use SecureRandom.uuid + # + def random_common_name(domain_name) + cert_serial_number(domain_name).to_s(36) + end + def today t = Time.now Time.utc t.year, t.month, t.day diff --git a/lib/leap_cli/commands/test.rb b/lib/leap_cli/commands/test.rb new file mode 100644 index 0000000..dc08652 --- /dev/null +++ b/lib/leap_cli/commands/test.rb @@ -0,0 +1,26 @@ +module LeapCli; module Commands + + desc 'Creates files needed to run tests' + command :'init-test' do |c| + c.action do |global_options,options,args| + generate_test_client_cert + generate_test_client_openvpn_config + end + end + + desc 'Run tests' + command :test do |c| + c.action do |global_options,options,args| + log 'not yet implemented' + end + end + + private + + def generate_test_client_openvpn_config + template = read_file! Path.find_file(:test_client_openvpn_template) + config = Util.erb_eval(template, binding) + write_file! :test_client_openvpn_config, config + end + +end; end diff --git a/lib/leap_cli/path.rb b/lib/leap_cli/path.rb index 98f4f99..27ffcce 100644 --- a/lib/leap_cli/path.rb +++ b/lib/leap_cli/path.rb @@ -19,6 +19,10 @@ module LeapCli; module Path :service_config => 'services/#{arg}.json', :tag_config => 'tags/#{arg}.json', + # input templates + :provider_json_template => 'files/service-definitions/provider.json.erb', + :eip_service_json_template => 'files/service-definitions/eip-service.json.erb', + # input data files :commercial_cert => 'files/cert/#{arg}.crt', :commercial_key => 'files/cert/#{arg}.key', @@ -38,9 +42,15 @@ module LeapCli; module Path :commercial_csr => 'files/cert/#{arg}.csr', :commercial_cert => 'files/cert/#{arg}.crt', :commercial_ca_cert => 'files/cert/commercial_ca.crt', - :node_x509_key => 'files/nodes/#{arg}/#{arg}.key', - :node_x509_cert => 'files/nodes/#{arg}/#{arg}.crt', - :vagrantfile => 'test/Vagrantfile' + :node_x509_key => 'files/nodes/#{arg}/#{arg}.key', + :node_x509_cert => 'files/nodes/#{arg}/#{arg}.crt', + :vagrantfile => 'test/Vagrantfile', + + # testing files + :test_client_key => 'test/cert/client.key', + :test_client_cert => 'test/cert/client.crt', + :test_client_openvpn_config => 'test/openvpn/client.ovpn', + :test_client_openvpn_template => 'test/openvpn/client.ovpn.erb' } # @@ -103,42 +113,30 @@ module LeapCli; module Path # all the places we search for a file when using find_file. # this is perhaps too many places. # - def self.search_path - @search_path ||= begin - search_path = [] - [Path.provider_base, Path.provider].each do |provider| - files_dir = named_path(:files_dir, provider) - search_path << provider - search_path << named_path(:files_dir, provider) - search_path << named_path(:nodes_dir, files_dir) - search_path << named_path(:services_dir, files_dir) - search_path << named_path(:tags_dir, files_dir) - end - search_path - end - end - - # - # tries to find a file somewhere with 'filename' (which is probably in the form [node.name, filename]) - # - def self.find_file(filename) - # named path? - if filename.is_a? Array - path = named_path(filename, Path.provider_base) - return path if File.exists?(path) - path = named_path(filename, provider) - return path if File.exists?(path) - end - - # otherwise, lets search - search_path.each do |path_root| - path = [path_root, name, filename].join('/') - return path if File.exists?(path) - end - search_path.each do |path_root| - path = [path_root, filename].join('/') - return path if File.exists?(path) - end + # def self.search_path + # @search_path ||= begin + # search_path = [] + # [Path.provider_base, Path.provider].each do |provider| + # #files_dir = named_path(:files_dir, provider) + # search_path << provider + # #search_path << named_path(:files_dir, provider) + # #search_path << named_path(:nodes_dir, files_dir) + # #search_path << named_path(:services_dir, files_dir) + # #search_path << named_path(:tags_dir, files_dir) + # end + # search_path + # end + # end + + # + # tries to find a file somewhere + # + def self.find_file(arg) + file_path = named_path(arg, Path.provider) + return file_path if File.exists?(file_path) + + file_path = named_path(arg, Path.provider_base) + return file_path if File.exists?(file_path) # give up return nil diff --git a/lib/leap_cli/util.rb b/lib/leap_cli/util.rb index 0b0fb9e..c3adbdc 100644 --- a/lib/leap_cli/util.rb +++ b/lib/leap_cli/util.rb @@ -1,6 +1,7 @@ require 'digest/md5' require 'paint' require 'fileutils' +require 'erb' module LeapCli @@ -276,6 +277,14 @@ module LeapCli STDOUT.puts end + ## + ## ERB + ## + + def erb_eval(string, binding=nil) + ERB.new(string, nil, '%<>-').result(binding) + end + end end -- cgit v1.2.3