class OpenvpnPlugin::Openvpn
Public Instance Methods
add_ca_extensions(ca_cert)
click to toggle source
# File lib/chef/knife/openvpn.rb, line 85 def add_ca_extensions(ca_cert) ef = get_extensions_factory ca_cert, ca_cert ca_cert.add_extension(ef.create_extension('basicConstraints', 'CA:TRUE', true)) ca_cert.add_extension(ef.create_extension('keyUsage', 'keyCertSign, cRLSign', true)) ca_cert.add_extension(ef.create_extension('subjectKeyIdentifier', 'hash', false)) ca_cert.add_extension(ef.create_extension('authorityKeyIdentifier', 'keyid:always', false)) end
add_endentity_extensions(entity_cert, ca_cert, is_user = false)
click to toggle source
# File lib/chef/knife/openvpn.rb, line 93 def add_endentity_extensions(entity_cert, ca_cert, is_user = false) ef = get_extensions_factory entity_cert, ca_cert entity_cert.add_extension(ef.create_extension('keyUsage', 'digitalSignature', true)) entity_cert.add_extension(ef.create_extension('subjectKeyIdentifier', 'hash', false)) entity_cert.add_extension(ef.create_extension('nsCertType', 'server')) unless is_user end
check_databag_secret()
click to toggle source
# File lib/chef/knife/openvpn.rb, line 40 def check_databag_secret databag_secret_file = File.join(Dir.pwd, config[:databag_secret_file]) || Chef::Config[:knife][:secret_file] unless File.exist? databag_secret_file fail_with "Can't find encrypted databag secret file at #{databag_secret_file}." end end
check_existing_databag(server_name, fail_if_exists = false)
click to toggle source
# File lib/chef/knife/openvpn.rb, line 47 def check_existing_databag(server_name, fail_if_exists = false) databag_directory = File.join(Dir.pwd, "data_bags/openvpn-#{server_name}") if File.directory? databag_directory if fail_if_exists # databag exists and we want to create new fail_with "Data bag directory #{databag_directory} already exists." end else unless fail_if_exists # no such databag, but we want to use it fail_with "Data bag #{databag_directory} not exists." end end end
fail_with(error_message)
click to toggle source
# File lib/chef/knife/openvpn.rb, line 60 def fail_with(error_message) ui.error "Error: #{error_message}" exit 1 end
generate_cert_and_key(subject, cert_config, selfsigned = false, ca_cert = nil, ca_key = nil, is_user = false)
click to toggle source
# File lib/chef/knife/openvpn.rb, line 100 def generate_cert_and_key(subject, cert_config, selfsigned = false, ca_cert = nil, ca_key = nil, is_user = false) key = OpenSSL::PKey::RSA.generate(cert_config['rsa_keysize']) cert = OpenSSL::X509::Certificate.new cert.version = 2 cert.serial = Time.now.to_i cert.public_key = key.public_key cert.not_after = Time.now + (cert_config['years_to_expire'] * 365 * 24 * 60 * 60) cert.not_before = Time.now - (24 * 60 * 60) if selfsigned cert.subject = subject cert.issuer = subject add_ca_extensions(cert) cert.sign(key, OpenSSL::Digest::SHA256.new) else if ca_cert.nil? || ca_key.nil? fail_with "CA key or cert isn't specified" end cert.subject = subject cert.issuer = ca_cert.subject add_endentity_extensions(cert, ca_cert, is_user) cert.sign(ca_key, OpenSSL::Digest::SHA256.new) end if is_user require 'highline/import' passphrase = ask('Enter a passphrase [blank for passphraseless]: ') { |q| q.echo = false } unless passphrase == '' cipher = OpenSSL::Cipher.new('AES-256-CBC') key = key.export(cipher, passphrase) end end [cert, key] end
get_databag_name(server_name)
click to toggle source
# File lib/chef/knife/openvpn.rb, line 191 def get_databag_name(server_name) databag_name = "openvpn-#{server_name}" databag_name end
get_databag_path(server_name)
click to toggle source
# File lib/chef/knife/openvpn.rb, line 186 def get_databag_path(server_name) directory_path = File.join(Dir.pwd, "data_bags/openvpn-#{server_name}") directory_path end
get_extensions_factory(subject_cert, issuer_cert)
click to toggle source
# File lib/chef/knife/openvpn.rb, line 78 def get_extensions_factory(subject_cert, issuer_cert) factory = OpenSSL::X509::ExtensionFactory.new factory.subject_certificate = subject_cert factory.issuer_certificate = issuer_cert factory end
issue_crl(revoke_info, serial, lastup, nextup, extensions, issuer, issuer_key, digest)
click to toggle source
# File lib/chef/knife/openvpn.rb, line 137 def issue_crl(revoke_info, serial, lastup, nextup, extensions, issuer, issuer_key, digest) crl = OpenSSL::X509::CRL.new crl.issuer = issuer.subject crl.version = 1 crl.last_update = lastup crl.next_update = nextup revoke_info.each do |rserial, time, reason_code| revoked = OpenSSL::X509::Revoked.new revoked.serial = if rserial.is_a? OpenSSL::BN rserial else OpenSSL::BN.new(rserial) end revoked.time = if time.is_a? time else Time.parse(time) end enum = OpenSSL::ASN1::Enumerated(reason_code) ext = OpenSSL::X509::Extension.new('CRLReason', enum) revoked.add_extension(ext) crl.add_revoked(revoked) end ef = OpenSSL::X509::ExtensionFactory.new ef.issuer_certificate = issuer ef.crl = crl crlnum = OpenSSL::ASN1::Integer(serial) crl.add_extension(OpenSSL::X509::Extension.new('crlNumber', crlnum)) extensions.each do |oid, value, critical| crl.add_extension(ef.create_extension(oid, value, critical)) end crl.sign(issuer_key, digest) crl end
load_cert_and_key(cert_str, key_str, force = false)
click to toggle source
# File lib/chef/knife/openvpn.rb, line 176 def load_cert_and_key(cert_str, key_str, force = false) cert = OpenSSL::X509::Certificate.new cert_str key = if force key_str else OpenSSL::PKey::RSA.new key_str end [cert, key] end
load_databag_item(databag_name, item_id)
click to toggle source
# File lib/chef/knife/openvpn.rb, line 209 def load_databag_item(databag_name, item_id) secret = load_databag_secret item = Chef::EncryptedDataBagItem.load(databag_name, item_id, secret) item end
load_databag_secret()
click to toggle source
# File lib/chef/knife/openvpn.rb, line 72 def load_databag_secret databag_secret_file = File.join(Dir.pwd, config[:databag_secret_file]) || Chef::Config[:knife][:secret_file] secret = Chef::EncryptedDataBagItem.load_secret(databag_secret_file) secret end
make_name(cn, cert_config)
click to toggle source
# File lib/chef/knife/openvpn.rb, line 65 def make_name(cn, cert_config) name = OpenSSL::X509::Name.new name.add_entry 'CN', cn %w(C L O OU ST mail).each { |entry| name.add_entry(entry, cert_config[entry]) } name end
run()
click to toggle source
# File lib/chef/knife/openvpn.rb, line 29 def run ui.info 'knife openvpn (user|server) action ARGS OPTS' end
save_databag_item(id, server_name, item_hash, force = false)
click to toggle source
# File lib/chef/knife/openvpn.rb, line 196 def save_databag_item(id, server_name, item_hash, force = false) databag_path = get_databag_path server_name item_hash['id'] = id item_path = File.join(databag_path, "#{id}.json") secret = load_databag_secret encrypted_data = Chef::EncryptedDataBagItem.encrypt_data_bag_item(item_hash, secret) if force || !File.exist?(item_path) File.write item_path, JSON.pretty_generate(encrypted_data) else fail_with "#{item_path} already exists" end end