From 554a252e13c206fd2b0d80af49a3a8ecf516fb83 Mon Sep 17 00:00:00 2001 From: Voob of Doom Date: Fri, 4 May 2012 22:49:57 +0200 Subject: [PATCH 01/81] made it look like a gem --- Gemfile | 10 + Gemfile.lock | 38 ++++ lib/config_generator.rb | 32 +++ lib/key_builder.rb | 142 +++++++++++++ lib/key_config.rb | 9 + lib/key_db.rb | 62 ++++++ lib/key_tracker.rb | 158 ++++++++++++++ lib/manager.rb | 55 +++++ vpnmaker.rb | 459 +--------------------------------------- 9 files changed, 514 insertions(+), 451 deletions(-) create mode 100644 Gemfile create mode 100644 Gemfile.lock create mode 100644 lib/config_generator.rb create mode 100644 lib/key_builder.rb create mode 100644 lib/key_config.rb create mode 100644 lib/key_db.rb create mode 100644 lib/key_tracker.rb create mode 100644 lib/manager.rb diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..a088815 --- /dev/null +++ b/Gemfile @@ -0,0 +1,10 @@ +source 'https://rubygems.org' + +gem "pry" +gem 'pry-doc' #, :git => 'https://github.com/pry/pry-doc.git' +gem 'pry-rails' #, :git => 'https://github.com/rweng/pry-rails.git' +gem 'pry-nav' #, :git => 'https://github.com/nixme/pry-nav.git' +# gem 'pry-coolline' #, :git => 'https://github.com/pry/pry-coolline.git' +gem 'pry-syntax-hacks' #, :git => 'https://github.com/ConradIrwin/pry-syntax-hacks.git' +gem 'pry-stack_explorer' #, :git => 'https://github.com/pry/pry-stack_explorer.git' +gem 'pry-exception_explorer' #, :git => 'https://github.com/pry/pry-exception_explorer.git' diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 0000000..e947aef --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,38 @@ +GEM + remote: https://rubygems.org/ + specs: + binding_of_caller (0.6.7) + coderay (1.0.6) + method_source (0.7.1) + pry (0.9.9.4) + coderay (~> 1.0.5) + method_source (~> 0.7.1) + slop (>= 2.4.4, < 3) + pry-doc (0.4.1) + pry (>= 0.9.0) + yard (~> 0.7.4) + pry-exception_explorer (0.1.9) + pry-stack_explorer (>= 0.3.9) + pry-nav (0.2.1) + pry (~> 0.9.9) + pry-rails (0.1.6) + pry + pry-stack_explorer (0.4.2) + binding_of_caller (~> 0.6.2) + pry (~> 0.9.9) + pry-syntax-hacks (0.0.6) + pry (>= 0.9.8) + slop (2.4.4) + yard (0.7.5) + +PLATFORMS + ruby + +DEPENDENCIES + pry + pry-doc + pry-exception_explorer + pry-nav + pry-rails + pry-stack_explorer + pry-syntax-hacks diff --git a/lib/config_generator.rb b/lib/config_generator.rb new file mode 100644 index 0000000..b5b5766 --- /dev/null +++ b/lib/config_generator.rb @@ -0,0 +1,32 @@ +module VPNMaker + class ConfigGenerator + def initialize(mgr) + @mgr = mgr + end + + def client_conf(client) + { + :gen_host => Socket.gethostname, + :server => @mgr.config[:server], + :client => @mgr.config[:client] + }.merge(client) + end + + def server_conf + { + :gen_host => Socket.gethostname + }.merge(@mgr.config[:server]) + end + + def apply_erb(name, cnf) + erb = File.read(__FILE__.path(name)) + ERB.new(erb).result(HashBinding.from_hash(cnf).binding) + end + + def server; apply_erb('server.erb', server_conf); end + + def client(client) + apply_erb('client.erb', client_conf(client)); + end + end +end diff --git a/lib/key_builder.rb b/lib/key_builder.rb new file mode 100644 index 0000000..785c55f --- /dev/null +++ b/lib/key_builder.rb @@ -0,0 +1,142 @@ +module VPNMaker + class KeyBuilder + def initialize(tracker, config) + @tmpdir = '/tmp/keybuilder' + clean_tmpdir + @tracker = tracker + @config = config + end + + def clean_tmpdir + FileUtils.rm_rf(@tmpdir) + FileUtils.mkdir_p(@tmpdir) + end + + def cnfpath; "/tmp/openssl-#{$$}.cnf"; end + + def opensslvars + { + :key_size => 1024, + :key_dir => @tmpdir, + :key_country => @config[:key_properties][:country], + :key_province => @config[:key_properties][:province], + :key_city => @config[:key_properties][:city], + :key_org => @config[:key_properties][:organization], + :key_email => @config[:key_properties][:email], + :key_org => @config[:key_properties][:organization], + :key_ou => 'Organization Unit', + :key_cn => 'Common Name', + :key_name => 'Name' + } + end + + def init + `touch #{@dir}/index.txt` + `echo 01 > #{@dir}/serial` + end + + def opensslcnf(hash={}) + c = cnfpath + + File.open(cnfpath, 'w') do |f| + f.write(ERB.new(File.read(__FILE__.path('openssl.erb'))).\ + result(HashBinding.from_hash(opensslvars.merge(hash)).binding)) + end + + c + end + + # Build Diffie-Hellman parameters for the server side of an SSL/TLS connection. + def build_dh_key(keysize=1024) + `openssl dhparam -out #{tmppath('dh.pem')} #{keysize}` + @tracker.set_dh(tmpfile('dh.pem')) + end + + def ca + @tracker[:ca] + end + + def gen_crl + `openssl ca -gencrl -crldays 3650 -keyfile #{tmppath('ca.key')} -cert #{tmppath('ca.crt')} -out #{tmppath('crl.pem')} -config #{opensslcnf}` + end + + def build_ca + index = tmppath('index.txt') + + FileUtils.touch(index) + + `openssl req -batch -days 3650 -nodes -new -x509 -keyout #{@tmpdir}/ca.key -out #{@tmpdir}/ca.crt -config #{opensslcnf}` + gen_crl + @tracker.set_ca(tmpfile('ca.key'), tmpfile('ca.crt'), tmpfile('crl.pem'), tmpfile('index.txt'), "01\n") + end + + def build_server_key + place_file('ca.crt') + place_file('ca.key') + place_file('index.txt') + place_file('serial') + + `openssl req -batch -days 3650 -nodes -new -keyout #{tmppath('server.key')} -out #{tmppath('server.csr')} -extensions server -config #{opensslcnf}` + `openssl ca -batch -days 3650 -out #{tmppath('server.crt')} -in #{tmppath('server.csr')} -extensions server -config #{opensslcnf}` + + @tracker.set_server_key(tmpfile('server.key'), tmpfile('server.crt'), tmpfile('index.txt'), tmpfile('serial')) + end + + def build_ta_key + `openvpn --genkey --secret #{tmppath('ta.key')}` + @tracker.set_ta_key(tmpfile('ta.key')) + end + + def place_file(name) + if data = @tracker.db.data(name) + File.open(File.join(@tmpdir, name), 'w') {|f| f.write(data)} + else + raise "No data for #{name}" + end + end + + def tmppath(f, extn=nil); File.join(@tmpdir, extn ? "#{f}.#{extn}" : f); end + def tmpfile(*args); File.read(tmppath(*args)); end + + def build_key(user, name, email, pass, delegate) + h = {:key_cn => user, :key_name => name, :key_email => email} + place_file('ca.crt') + place_file('ca.key') + place_file('index.txt') + place_file('serial') + if pass + pass_spec = "-passin 'pass:#{pass}' -passout 'pass:#{pass}'" + else + pass_spec = '-nodes' + end + + `openssl req -batch -days 3650 -new -keyout #{tmppath(user, 'key')} -out #{tmppath(user, 'csr')} -config #{opensslcnf(h)} #{pass_spec}` + `openssl ca -batch -days 3650 -out #{tmppath(user, 'crt')} -in #{tmppath(user, 'csr')} -config #{opensslcnf(h)}` + # TODO: this still asks for the export password + `openssl pkcs12 -export -clcerts -in #{tmppath(user, 'crt')} -inkey #{tmppath(user, 'key')} -out #{tmppath(user, 'p12')} #{pass_spec}` + @tracker.send(delegate, user, name, email, tmpfile(user, 'key'), tmpfile(user, 'crt'), tmpfile(user, 'p12'), tmpfile('index.txt'), tmpfile('serial')) + end + + def revoke_key(user, version) + h = {:key_cn => ""} + place_file('ca.crt') + place_file('ca.key') + place_file('crl.pem') + place_file('index.txt') + place_file('serial') + + user_crt = tmppath(user, 'crt') + rev_crt = tmppath('rev-test.crt') + File.open(user_crt, 'w') {|f| f.write(@tracker.key(user, version, 'crt'))} + `openssl ca -revoke #{user_crt} -keyfile #{tmppath('ca.key')} -cert #{tmppath('ca.crt')} -config #{opensslcnf(h)}` + gen_crl + + File.open(rev_crt, 'w') {|f| f.write(File.read(tmppath('ca.crt'))); f.write(File.read(tmppath('crl.pem')))} + if `openssl verify -CAfile #{rev_crt} -crl_check #{user_crt}` =~ /certificate revoked/ + @tracker.user_key_revoked(user, version, tmpfile('crl.pem'), tmpfile('index.txt')) + else + raise "Revocation verification failed: openssl isn't recognizing it" + end + end + end +end diff --git a/lib/key_config.rb b/lib/key_config.rb new file mode 100644 index 0000000..65227cd --- /dev/null +++ b/lib/key_config.rb @@ -0,0 +1,9 @@ +module VPNMaker + class KeyConfig + def initialize(path) + @config = YAML.load_file(path) + end + + def [](k); @config[k]; end + end +end diff --git a/lib/key_db.rb b/lib/key_db.rb new file mode 100644 index 0000000..c6cf77f --- /dev/null +++ b/lib/key_db.rb @@ -0,0 +1,62 @@ +module VPNMaker + class KeyDB + def initialize(path) + @path = path + @db = File.exists?(path) ? YAML.load_file(path) : {} + @touched = false + end + + def [](k); @db[k]; end + + def []=(k, v) + @db[k] = v + @db[:modified] = Time.now + @touched = true + end + + def touched! + @touched = true + @db[:modified] = Time.now + end + + + def datadir; self[:datadir]; end + + def data_path(k) + File.join(File.dirname(@path), self.datadir, k) + end + + def dump(k, v, overwrite=false) + p = data_path(k) + raise "#{k} already exists" if File.exists?(p) && !overwrite + File.open(p, 'w') {|f| f.write(v)} + @touched = true + end + + def data(k) + File.exists?(data_path(k)) ? File.read(data_path(k)) : nil + end + + def disk_version + File.exists?(@path) ? YAML.load_file(@path)[:version] : 0 + end + + def sync + if disk_version == @db[:version] + if @touched + FileUtils.mkdir_p(self.datadir) + @db[:version] += 1 + File.open(@path, 'w') {|f| f.write(@db.to_yaml)} + true + else + false + end + else + raise "Disk version of #{@path} (#{disk_version}) != loaded version (#{@db[:version]}). " + \ + "Try reloading and making your changes again." + end + end + + def version; @db[:version]; end + end +end diff --git a/lib/key_tracker.rb b/lib/key_tracker.rb new file mode 100644 index 0000000..0e5780c --- /dev/null +++ b/lib/key_tracker.rb @@ -0,0 +1,158 @@ +module VPNMaker + class KeyTracker + attr_reader :builder + attr_reader :db + attr_reader :config + + def self.generate(name, path=nil) + path ||= '/tmp' + dir = File.join(File.expand_path(path), name + '.vpn') + + FileUtils.mkdir_p(dir) + datadir = "#{name}_data" + dbpath = File.join(dir, "#{name}.db.yaml") + + d = KeyDB.new(dbpath) + d[:version] = 0 + d[:modified] = Time.now + d[:users] = {} + d[:datadir] = datadir + d.sync + end + + def assert_user(user) + raise "User doesn't exist: #{user}" unless @db[:users][user] + end + + def ca; @db[:ca]; end + + def set_ca(key, crt, crl, index, serial) + raise "CA already set" if @db[:ca] + + @db[:ca] = {:modified => Time.now} + @db.dump('ca.key', key) + @db.dump('ca.crt', crt) + @db.dump('crl.pem', crl) + @db.dump('index.txt', index) + @db.dump('serial', serial) + @db.touched! + @db.sync + end + + def set_server_key(key, crt, index, serial) + raise "Server key already set" if @db[:server] + + @db[:server] = {:modified => Time.now} + @db.dump('server.key', key) + @db.dump('server.crt', crt) + @db.dump('index.txt', index, true) + @db.dump('serial', serial, true) + @db.touched! + @db.sync + end + + def set_ta_key(ta) + raise "TA key already set" if @db[:ta] + + @db[:ta] = {:modified => Time.now} + @db.dump('ta.key', ta) + @db.touched! + @db.sync + end + + def set_dh(dh) + raise "DH key already set" if @db[:dh] + + @db[:dh] = {:modified => Time.now} + @db.dump('dh.pem', dh) + @db.touched! + @db.sync + end + + def add_key(user, key, crt, p12, ver) + @db.dump("#{user}-#{ver}.key", key) + @db.dump("#{user}-#{ver}.crt", crt) + @db.dump("#{user}-#{ver}.p12", p12) + end + + def key(user, ver, type) + @db.data("#{user}-#{ver}.#{type}") + end + + def add_user(user, name, email, key, crt, p12, index, serial) + raise "User must be a non-empty string" unless user.is_a?(String) && user.size > 0 + raise "User already exists: #{user}" if @db[:users][user] + + @db[:users][user] = { + :user => user, + :name => name, + :email => email, + :active_key => 0, + :revoked => [], + :modified => Time.now + } + @db.dump('serial', serial, true) + @db.dump('index.txt', index, true) + add_key(user, key, crt, p12, 0) + @db.touched! + @db.sync + end + + def add_user_key(user, name, email, key, crt, p12, index, serial) + assert_user(user) + + u = @db[:users][user] + u[:modified] = Time.now + u[:active_key] += 1 + add_key(user, key, crt, p12, u[:active_key]) + + @db.dump('serial', serial, true) + @db.dump('index.txt', index, true) + + @db.touched! + @db.sync + end + + def user_key_revoked(user, version, crl, index) + assert_user(user) + + raise "Verison must be an int" unless version.kind_of?(Integer) + u = @db[:users][user] + u[:revoked] << version + u[:modified] = Time.now + @db.dump('index.txt', index, true) + @db.dump('crl.pem', crl, true) + @db.touched! + @db.sync + end + + def revoked?(user, version) + assert_user(user) + + @db[:users][user][:revoked].include?(version) + end + + def active_key_version(user) + assert_user(user) + + @db[:users][user][:active_key] + end + + def user(user) + assert_user(user) + @db[:users][user] + end + + def users; @db[:users]; end + + def initialize(name, dir) + @db = KeyDB.new(File.join(dir, name + '.db.yaml')) + @config = KeyConfig.new(File.join(dir, name + '.config.yaml')) + @builder = KeyBuilder.new(self, @config) + end + end + + def self.generate(name, path) + KeyTracker.generate(name, path) + end +end diff --git a/lib/manager.rb b/lib/manager.rb new file mode 100644 index 0000000..763f3fa --- /dev/null +++ b/lib/manager.rb @@ -0,0 +1,55 @@ +module VPNMaker + class Manager + attr_reader :tracker + + def self.vpn_name(dir); dir =~ /(^|\/)([^\/\.]+)\.vpn/ ? $2 : nil; end + + def initialize(dir) + name = self.class.vpn_name(File.expand_path(dir)) + @tracker = KeyTracker.new(name, File.expand_path(dir)) + end + + def config; @tracker.config; end + + def build_ca; @tracker.builder.build_ca; end + def build_server + @tracker.builder.build_server_key + @tracker.builder.build_ta_key + @tracker.builder.build_dh_key + end + + def create_user(user, name, email, pass=nil) + @tracker.builder.build_key(user, name, email, pass, :add_user) + end + + def revoke_all(user) + cur = @tracker.active_key_version(user) + while cur >= 0 + unless @tracker.revoked?(user, cur) + @tracker.builder.revoke_key(user, cur) + end + cur -= 1 + end + end + + def regenerate_user(user, pass=nil) + revoke_all(user) + u = @tracker.user(user) + @tracker.builder.build_key(user, u[:name], u[:email], pass, :add_user_key) + end + + def delete_user(user) + revoke_all(user) + end + + def users + @tracker.users.keys + end + + def user(user) + @tracker.user(user) + end + + def config_generator; ConfigGenerator.new(self); end + end +end diff --git a/vpnmaker.rb b/vpnmaker.rb index 7deeabf..a76dd91 100644 --- a/vpnmaker.rb +++ b/vpnmaker.rb @@ -5,6 +5,8 @@ require 'erb' require 'socket' +require 'pry' + class String def path(p) File.join(File.dirname(__FILE__), p) @@ -24,455 +26,10 @@ def binding; super; end # normally private end module VPNMaker - class ConfigGenerator - def initialize(mgr) - @mgr = mgr - end - - def client_conf(client) - { - :gen_host => Socket.gethostname, - :server => @mgr.config[:server], - :client => @mgr.config[:client] - }.merge(client) - end - - def server_conf - { - :gen_host => Socket.gethostname - }.merge(@mgr.config[:server]) - end - - def apply_erb(name, cnf) - erb = File.read(__FILE__.path(name)) - ERB.new(erb).result(HashBinding.from_hash(cnf).binding) - end - - def server; apply_erb('server.erb', server_conf); end - - def client(client) - apply_erb('client.erb', client_conf(client)); - end - end - - class KeyDB - def initialize(path) - @path = path - @db = File.exists?(path) ? YAML.load_file(path) : {} - @touched = false - end - - def [](k); @db[k]; end - - def []=(k, v) - @db[k] = v - @db[:modified] = Time.now - @touched = true - end - - def touched! - @touched = true - @db[:modified] = Time.now - end - - - def datadir; self[:datadir]; end - - def data_path(k) - File.join(File.dirname(@path), self.datadir, k) - end - - def dump(k, v, overwrite=false) - p = data_path(k) - raise "#{k} already exists" if File.exists?(p) && !overwrite - File.open(p, 'w') {|f| f.write(v)} - @touched = true - end - - def data(k) - File.exists?(data_path(k)) ? File.read(data_path(k)) : nil - end - - def disk_version - File.exists?(@path) ? YAML.load_file(@path)[:version] : 0 - end - - def sync - if disk_version == @db[:version] - if @touched - FileUtils.mkdir_p(self.datadir) - @db[:version] += 1 - File.open(@path, 'w') {|f| f.write(@db.to_yaml)} - true - else - false - end - else - raise "Disk version of #{@path} (#{disk_version}) != loaded version (#{@db[:version]}). " + \ - "Try reloading and making your changes again." - end - end - - def version; @db[:version]; end - end - - class KeyConfig - def initialize(path) - @config = YAML.load_file(path) - end - - def [](k); @config[k]; end - end - - class KeyTracker - attr_reader :builder - attr_reader :db - attr_reader :config - - def self.generate(name, path=nil) - path ||= '/tmp' - dir = File.join(File.expand_path(path), name + '.vpn') - - FileUtils.mkdir_p(dir) - datadir = "#{name}_data" - dbpath = File.join(dir, "#{name}.db.yaml") - - d = KeyDB.new(dbpath) - d[:version] = 0 - d[:modified] = Time.now - d[:users] = {} - d[:datadir] = datadir - d.sync - end - - def assert_user(user) - raise "User doesn't exist: #{user}" unless @db[:users][user] - end - - def ca; @db[:ca]; end - - def set_ca(key, crt, crl, index, serial) - raise "CA already set" if @db[:ca] - - @db[:ca] = {:modified => Time.now} - @db.dump('ca.key', key) - @db.dump('ca.crt', crt) - @db.dump('crl.pem', crl) - @db.dump('index.txt', index) - @db.dump('serial', serial) - @db.touched! - @db.sync - end - - def set_server_key(key, crt, index, serial) - raise "Server key already set" if @db[:server] - - @db[:server] = {:modified => Time.now} - @db.dump('server.key', key) - @db.dump('server.crt', crt) - @db.dump('index.txt', index, true) - @db.dump('serial', serial, true) - @db.touched! - @db.sync - end - - def set_ta_key(ta) - raise "TA key already set" if @db[:ta] - - @db[:ta] = {:modified => Time.now} - @db.dump('ta.key', ta) - @db.touched! - @db.sync - end - - def set_dh(dh) - raise "DH key already set" if @db[:dh] - - @db[:dh] = {:modified => Time.now} - @db.dump('dh.pem', dh) - @db.touched! - @db.sync - end - - def add_key(user, key, crt, p12, ver) - @db.dump("#{user}-#{ver}.key", key) - @db.dump("#{user}-#{ver}.crt", crt) - @db.dump("#{user}-#{ver}.p12", p12) - end - - def key(user, ver, type) - @db.data("#{user}-#{ver}.#{type}") - end - - def add_user(user, name, email, key, crt, p12, index, serial) - raise "User must be a non-empty string" unless user.is_a?(String) && user.size > 0 - raise "User already exists: #{user}" if @db[:users][user] - - @db[:users][user] = { - :user => user, - :name => name, - :email => email, - :active_key => 0, - :revoked => [], - :modified => Time.now - } - @db.dump('serial', serial, true) - @db.dump('index.txt', index, true) - add_key(user, key, crt, p12, 0) - @db.touched! - @db.sync - end - - def add_user_key(user, name, email, key, crt, p12, index, serial) - assert_user(user) - - u = @db[:users][user] - u[:modified] = Time.now - u[:active_key] += 1 - add_key(user, key, crt, p12, u[:active_key]) - - @db.dump('serial', serial, true) - @db.dump('index.txt', index, true) - - @db.touched! - @db.sync - end - - def user_key_revoked(user, version, crl, index) - assert_user(user) - - raise "Verison must be an int" unless version.kind_of?(Integer) - u = @db[:users][user] - u[:revoked] << version - u[:modified] = Time.now - @db.dump('index.txt', index, true) - @db.dump('crl.pem', crl, true) - @db.touched! - @db.sync - end - - def revoked?(user, version) - assert_user(user) - - @db[:users][user][:revoked].include?(version) - end - - def active_key_version(user) - assert_user(user) - - @db[:users][user][:active_key] - end - - def user(user) - assert_user(user) - @db[:users][user] - end - - def users; @db[:users]; end - - def initialize(name, dir) - @db = KeyDB.new(File.join(dir, name + '.db.yaml')) - @config = KeyConfig.new(File.join(dir, name + '.config.yaml')) - @builder = KeyBuilder.new(self, @config) - end - end - - def self.generate(name, path) - KeyTracker.generate(name, path) - end - - class Manager - attr_reader :tracker - - def self.vpn_name(dir); dir =~ /(^|\/)([^\/\.]+)\.vpn/ ? $2 : nil; end - - def initialize(dir) - name = self.class.vpn_name(File.expand_path(dir)) - @tracker = KeyTracker.new(name, File.expand_path(dir)) - end - - def config; @tracker.config; end - - def build_ca; @tracker.builder.build_ca; end - def build_server - @tracker.builder.build_server_key - @tracker.builder.build_ta_key - @tracker.builder.build_dh_key - end - - def create_user(user, name, email, pass=nil) - @tracker.builder.build_key(user, name, email, pass, :add_user) - end - - def revoke_all(user) - cur = @tracker.active_key_version(user) - while cur >= 0 - unless @tracker.revoked?(user, cur) - @tracker.builder.revoke_key(user, cur) - end - cur -= 1 - end - end - - def regenerate_user(user, pass=nil) - revoke_all(user) - u = @tracker.user(user) - @tracker.builder.build_key(user, u[:name], u[:email], pass, :add_user_key) - end - - def delete_user(user) - revoke_all(user) - end - - def users - @tracker.users.keys - end - - def user(user) - @tracker.user(user) - end - - def config_generator; ConfigGenerator.new(self); end - end - - class KeyBuilder - def initialize(tracker, config) - @tmpdir = '/tmp/keybuilder' - clean_tmpdir - @tracker = tracker - @config = config - end - - def clean_tmpdir - FileUtils.rm_rf(@tmpdir) - FileUtils.mkdir_p(@tmpdir) - end - - def cnfpath; "/tmp/openssl-#{$$}.cnf"; end - - def opensslvars - { - :key_size => 1024, - :key_dir => @tmpdir, - :key_country => @config[:key_properties][:country], - :key_province => @config[:key_properties][:province], - :key_city => @config[:key_properties][:city], - :key_org => @config[:key_properties][:organization], - :key_email => @config[:key_properties][:email], - :key_org => @config[:key_properties][:organization], - :key_ou => 'Organization Unit', - :key_cn => 'Common Name', - :key_name => 'Name' - } - end - - def init - `touch #{@dir}/index.txt` - `echo 01 > #{@dir}/serial` - end - - def opensslcnf(hash={}) - c = cnfpath - - File.open(cnfpath, 'w') do |f| - f.write(ERB.new(File.read(__FILE__.path('openssl.erb'))).\ - result(HashBinding.from_hash(opensslvars.merge(hash)).binding)) - end - - c - end - - # Build Diffie-Hellman parameters for the server side of an SSL/TLS connection. - def build_dh_key(keysize=1024) - `openssl dhparam -out #{tmppath('dh.pem')} #{keysize}` - @tracker.set_dh(tmpfile('dh.pem')) - end - - def ca - @tracker[:ca] - end - - def gen_crl - `openssl ca -gencrl -crldays 3650 -keyfile #{tmppath('ca.key')} -cert #{tmppath('ca.crt')} -out #{tmppath('crl.pem')} -config #{opensslcnf}` - end - - def build_ca - index = tmppath('index.txt') - - FileUtils.touch(index) - - `openssl req -batch -days 3650 -nodes -new -x509 -keyout #{@tmpdir}/ca.key -out #{@tmpdir}/ca.crt -config #{opensslcnf}` - gen_crl - @tracker.set_ca(tmpfile('ca.key'), tmpfile('ca.crt'), tmpfile('crl.pem'), tmpfile('index.txt'), "01\n") - end - - def build_server_key - place_file('ca.crt') - place_file('ca.key') - place_file('index.txt') - place_file('serial') - - `openssl req -batch -days 3650 -nodes -new -keyout #{tmppath('server.key')} -out #{tmppath('server.csr')} -extensions server -config #{opensslcnf}` - `openssl ca -batch -days 3650 -out #{tmppath('server.crt')} -in #{tmppath('server.csr')} -extensions server -config #{opensslcnf}` - - @tracker.set_server_key(tmpfile('server.key'), tmpfile('server.crt'), tmpfile('index.txt'), tmpfile('serial')) - end - - def build_ta_key - `openvpn --genkey --secret #{tmppath('ta.key')}` - @tracker.set_ta_key(tmpfile('ta.key')) - end - - def place_file(name) - if data = @tracker.db.data(name) - File.open(File.join(@tmpdir, name), 'w') {|f| f.write(data)} - else - raise "No data for #{name}" - end - end - - def tmppath(f, extn=nil); File.join(@tmpdir, extn ? "#{f}.#{extn}" : f); end - def tmpfile(*args); File.read(tmppath(*args)); end - - def build_key(user, name, email, pass, delegate) - h = {:key_cn => user, :key_name => name, :key_email => email} - place_file('ca.crt') - place_file('ca.key') - place_file('index.txt') - place_file('serial') - if pass - pass_spec = "-passin 'pass:#{pass}' -passout 'pass:#{pass}'" - else - pass_spec = '-nodes' - end - - `openssl req -batch -days 3650 -new -keyout #{tmppath(user, 'key')} -out #{tmppath(user, 'csr')} -config #{opensslcnf(h)} #{pass_spec}` - `openssl ca -batch -days 3650 -out #{tmppath(user, 'crt')} -in #{tmppath(user, 'csr')} -config #{opensslcnf(h)}` - # TODO: this still asks for the export password - `openssl pkcs12 -export -clcerts -in #{tmppath(user, 'crt')} -inkey #{tmppath(user, 'key')} -out #{tmppath(user, 'p12')} #{pass_spec}` - @tracker.send(delegate, user, name, email, tmpfile(user, 'key'), tmpfile(user, 'crt'), tmpfile(user, 'p12'), tmpfile('index.txt'), tmpfile('serial')) - end - - def revoke_key(user, version) - h = {:key_cn => ""} - place_file('ca.crt') - place_file('ca.key') - place_file('crl.pem') - place_file('index.txt') - place_file('serial') - - user_crt = tmppath(user, 'crt') - rev_crt = tmppath('rev-test.crt') - File.open(user_crt, 'w') {|f| f.write(@tracker.key(user, version, 'crt'))} - `openssl ca -revoke #{user_crt} -keyfile #{tmppath('ca.key')} -cert #{tmppath('ca.crt')} -config #{opensslcnf(h)}` - gen_crl - - File.open(rev_crt, 'w') {|f| f.write(File.read(tmppath('ca.crt'))); f.write(File.read(tmppath('crl.pem')))} - if `openssl verify -CAfile #{rev_crt} -crl_check #{user_crt}` =~ /certificate revoked/ - @tracker.user_key_revoked(user, version, tmpfile('crl.pem'), tmpfile('index.txt')) - else - raise "Revocation verification failed: openssl isn't recognizing it" - end - end - end + autoload :ConfigGenerator, 'lib/config_generator' + autoload :KeyDB, 'lib/key_db' + autoload :KeyConfig, 'lib/key_config' + autoload :KeyTracker, 'lib/key_tracker' + autoload :Manager, 'lib/manager' + autoload :KeyBuilder, 'lib/key_builder' end From 394cd83d78ecb59916f87061522f5674631a51a3 Mon Sep 17 00:00:00 2001 From: Voob of Doom Date: Sat, 5 May 2012 13:39:17 +0200 Subject: [PATCH 02/81] server.haml works --- Gemfile | 3 +++ Gemfile.lock | 2 ++ lib/config_generator.rb | 11 +++++++++-- server.haml | 37 +++++++++++++++++++++++++++++++++++++ vpnmaker.rb | 16 ++++++++++------ 5 files changed, 61 insertions(+), 8 deletions(-) create mode 100644 server.haml diff --git a/Gemfile b/Gemfile index a088815..2533c04 100644 --- a/Gemfile +++ b/Gemfile @@ -8,3 +8,6 @@ gem 'pry-nav' #, :git => 'https://github.com/nixme/pry-nav.git' gem 'pry-syntax-hacks' #, :git => 'https://github.com/ConradIrwin/pry-syntax-hacks.git' gem 'pry-stack_explorer' #, :git => 'https://github.com/pry/pry-stack_explorer.git' gem 'pry-exception_explorer' #, :git => 'https://github.com/pry/pry-exception_explorer.git' + +gem 'ipaddr_extensions' +#, :git => 'git://github.com/jamesotron/IPAddrExtensions.git' diff --git a/Gemfile.lock b/Gemfile.lock index e947aef..af7a180 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -3,6 +3,7 @@ GEM specs: binding_of_caller (0.6.7) coderay (1.0.6) + ipaddr_extensions (2012.1.13) method_source (0.7.1) pry (0.9.9.4) coderay (~> 1.0.5) @@ -29,6 +30,7 @@ PLATFORMS ruby DEPENDENCIES + ipaddr_extensions pry pry-doc pry-exception_explorer diff --git a/lib/config_generator.rb b/lib/config_generator.rb index b5b5766..b52ab13 100644 --- a/lib/config_generator.rb +++ b/lib/config_generator.rb @@ -23,10 +23,17 @@ def apply_erb(name, cnf) ERB.new(erb).result(HashBinding.from_hash(cnf).binding) end - def server; apply_erb('server.erb', server_conf); end + def server + haml_vars = server_conf.dup + haml_vars[:base_ip] = ((a = IPAddr.new haml_vars[:base_ip]); {:net => a.to_s, :mask => a.subnet_mask.to_s}) + haml_vars[:bridgednets] = haml_vars[:bridgednets].map {|net| a = (IPAddr.new net); {:net => a.to_s, :mask => a.subnet_mask.to_s}} + haml_vars[:subnets] = haml_vars[:subnets].map {|net| a = (IPAddr.new net); {:net => a.to_s, :mask => a.subnet_mask.to_s}} + template = File.read(__FILE__.path('server.haml')) + Haml::Engine.new(template).render(Object.new, haml_vars) + end def client(client) - apply_erb('client.erb', client_conf(client)); + apply_erb('client.erb', client_conf(client)) end end end diff --git a/server.haml b/server.haml new file mode 100644 index 0000000..37b59e6 --- /dev/null +++ b/server.haml @@ -0,0 +1,37 @@ +-# Auto-generated by vpnmaker on <%= @gen_host %> at <%= Time.now.to_s %> +-# See http://github.com/pc/vpnmaker + +mode server +tls-server +local #{host} +port #{port} +proto udp + +dev tun0 +server #{base_ip[:net]} #{base_ip[:mask]} + +- subnets.each do |net| + route #{net[:net]} #{net[:mask]} + push route #{net[:mask]} #{net[:mask]} + +- bridgednets.each do |net| + push route #{net[:net]} #{net[:mask]} + +user #{user} +group #{group} +dh #{root}/keys/dh.pem +ca #{root}/keys/ca.crt +cert #{root}/keys/server.crt +key #{root}/keys/server.key +crl-verify #{root}/keys/crl.pem + +keepalive 10 120 + +log #{log} + +persist-tun +persist-key + +tls-auth #{root}/keys/ta.key 0 +client-config-dir #{root}/ccd +:plain diff --git a/vpnmaker.rb b/vpnmaker.rb index a76dd91..fe12cf0 100644 --- a/vpnmaker.rb +++ b/vpnmaker.rb @@ -5,6 +5,10 @@ require 'erb' require 'socket' +require 'ipaddr' +require 'ipaddr_extensions' +require 'haml' + require 'pry' class String @@ -26,10 +30,10 @@ def binding; super; end # normally private end module VPNMaker - autoload :ConfigGenerator, 'lib/config_generator' - autoload :KeyDB, 'lib/key_db' - autoload :KeyConfig, 'lib/key_config' - autoload :KeyTracker, 'lib/key_tracker' - autoload :Manager, 'lib/manager' - autoload :KeyBuilder, 'lib/key_builder' + autoload :ConfigGenerator, './lib/config_generator' + autoload :KeyDB, './lib/key_db' + autoload :KeyConfig, './lib/key_config' + autoload :KeyTracker, './lib/key_tracker' + autoload :Manager, './lib/manager' + autoload :KeyBuilder, './lib/key_builder' end From 1ea31a181f4f8b5a6ec223a9e5984e3ec28cd03f Mon Sep 17 00:00:00 2001 From: Voob of Doom Date: Sat, 5 May 2012 15:00:45 +0200 Subject: [PATCH 03/81] making it look like gem --- .gitignore | 1 + client.erb => lib/client.erb | 0 lib/client.haml | 13 +++++++++ openssl.erb => lib/openssl.erb | 0 server.haml => lib/server.haml | 0 vpnmaker.rb => lib/vpnmaker.rb | 12 ++++---- lib/{ => vpnmaker}/config_generator.rb | 0 lib/{ => vpnmaker}/key_builder.rb | 0 lib/{ => vpnmaker}/key_config.rb | 0 lib/{ => vpnmaker}/key_db.rb | 0 lib/{ => vpnmaker}/key_tracker.rb | 0 lib/{ => vpnmaker}/manager.rb | 0 server.erb | 40 -------------------------- 13 files changed, 20 insertions(+), 46 deletions(-) create mode 100644 .gitignore rename client.erb => lib/client.erb (100%) create mode 100644 lib/client.haml rename openssl.erb => lib/openssl.erb (100%) rename server.haml => lib/server.haml (100%) rename vpnmaker.rb => lib/vpnmaker.rb (62%) rename lib/{ => vpnmaker}/config_generator.rb (100%) rename lib/{ => vpnmaker}/key_builder.rb (100%) rename lib/{ => vpnmaker}/key_config.rb (100%) rename lib/{ => vpnmaker}/key_db.rb (100%) rename lib/{ => vpnmaker}/key_tracker.rb (100%) rename lib/{ => vpnmaker}/manager.rb (100%) delete mode 100644 server.erb diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b844b14 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +Gemfile.lock diff --git a/client.erb b/lib/client.erb similarity index 100% rename from client.erb rename to lib/client.erb diff --git a/lib/client.haml b/lib/client.haml new file mode 100644 index 0000000..3afcf1a --- /dev/null +++ b/lib/client.haml @@ -0,0 +1,13 @@ +remote #{server[:host]} #{server[:port]} udp +persist-key +tls-client +tls-auth ta.key 1 +pull +ca ca.crt +dev tun +persist-tun +cert #{user} #{(revoked.max || -1) + 1}.crt +nobind +key #{user} #{(revoked.max || -1) + 1}.key +remote-cert-tls server +:plain diff --git a/openssl.erb b/lib/openssl.erb similarity index 100% rename from openssl.erb rename to lib/openssl.erb diff --git a/server.haml b/lib/server.haml similarity index 100% rename from server.haml rename to lib/server.haml diff --git a/vpnmaker.rb b/lib/vpnmaker.rb similarity index 62% rename from vpnmaker.rb rename to lib/vpnmaker.rb index fe12cf0..6a57007 100644 --- a/vpnmaker.rb +++ b/lib/vpnmaker.rb @@ -30,10 +30,10 @@ def binding; super; end # normally private end module VPNMaker - autoload :ConfigGenerator, './lib/config_generator' - autoload :KeyDB, './lib/key_db' - autoload :KeyConfig, './lib/key_config' - autoload :KeyTracker, './lib/key_tracker' - autoload :Manager, './lib/manager' - autoload :KeyBuilder, './lib/key_builder' + autoload :ConfigGenerator, './vpnmaker/config_generator' + autoload :KeyDB, './vpnmaker/key_db' + autoload :KeyConfig, './vpnmaker/key_config' + autoload :KeyTracker, './vpnmaker/key_tracker' + autoload :Manager, './vpnmaker/manager' + autoload :KeyBuilder, './vpnmaker/key_builder' end diff --git a/lib/config_generator.rb b/lib/vpnmaker/config_generator.rb similarity index 100% rename from lib/config_generator.rb rename to lib/vpnmaker/config_generator.rb diff --git a/lib/key_builder.rb b/lib/vpnmaker/key_builder.rb similarity index 100% rename from lib/key_builder.rb rename to lib/vpnmaker/key_builder.rb diff --git a/lib/key_config.rb b/lib/vpnmaker/key_config.rb similarity index 100% rename from lib/key_config.rb rename to lib/vpnmaker/key_config.rb diff --git a/lib/key_db.rb b/lib/vpnmaker/key_db.rb similarity index 100% rename from lib/key_db.rb rename to lib/vpnmaker/key_db.rb diff --git a/lib/key_tracker.rb b/lib/vpnmaker/key_tracker.rb similarity index 100% rename from lib/key_tracker.rb rename to lib/vpnmaker/key_tracker.rb diff --git a/lib/manager.rb b/lib/vpnmaker/manager.rb similarity index 100% rename from lib/manager.rb rename to lib/vpnmaker/manager.rb diff --git a/server.erb b/server.erb deleted file mode 100644 index edbbbd9..0000000 --- a/server.erb +++ /dev/null @@ -1,40 +0,0 @@ -# Auto-generated by vpnmaker on <%= @gen_host %> at <%= Time.now.to_s %> -# See http://github.com/pc/vpnmaker - -mode server -tls-server - -local <%= @host %> -port <%= @port %> -proto udp - -dev tun0 -server <%= @base_ip %> <%= @base_netmask %> -<% @subnets.each do |net| %> -route <%= net[:base_ip] %> <%= net[:netmask] %> -push "route <%= net[:base_ip] %> <%= net[:netmask] %>"<% end %> -<% @bridgednets.each do |net| %> -push "route <%= net[:base_ip] %> <%= net[:netmask] %>"<% end %> - -# Drop privileges to user/group nobody -user <%= @user %> -group <%= @group %> - -dh <%= @root %>/keys/dh.pem - -ca <%= @root %>/keys/ca.crt -cert <%= @root %>/keys/server.crt -key <%= @root %>/keys/server.key -crl-verify <%= @root %>/keys/crl.pem - -keepalive 10 120 # ping every 10 secs; no reply for 120 secs -> down - -log <%= @log %> - -# try to give same IP to client as before -persist-tun -persist-key - -tls-auth <%= @root %>/keys/ta.key 0 - -client-config-dir <%= @root %>/ccd From 452dfcf740089c35acf4e740f85d540cd6962c54 Mon Sep 17 00:00:00 2001 From: Voob of Doom Date: Sat, 5 May 2012 22:03:57 +0200 Subject: [PATCH 04/81] switched completely to haml --- Gemfile | 4 +- Gemfile.lock | 2 + bin/vpnmaker | 1 + lib/client.erb | 15 -- lib/client.haml | 4 +- lib/openssl.erb | 290 ------------------------------- lib/openssl.haml | 144 +++++++++++++++ lib/server.haml | 13 +- lib/vpnmaker.rb | 5 + lib/vpnmaker/config_generator.rb | 9 +- lib/vpnmaker/key_builder.rb | 3 +- 11 files changed, 168 insertions(+), 322 deletions(-) create mode 100755 bin/vpnmaker delete mode 100644 lib/client.erb delete mode 100644 lib/openssl.erb create mode 100644 lib/openssl.haml diff --git a/Gemfile b/Gemfile index 2533c04..c7e08f0 100644 --- a/Gemfile +++ b/Gemfile @@ -4,10 +4,12 @@ gem "pry" gem 'pry-doc' #, :git => 'https://github.com/pry/pry-doc.git' gem 'pry-rails' #, :git => 'https://github.com/rweng/pry-rails.git' gem 'pry-nav' #, :git => 'https://github.com/nixme/pry-nav.git' -# gem 'pry-coolline' #, :git => 'https://github.com/pry/pry-coolline.git' gem 'pry-syntax-hacks' #, :git => 'https://github.com/ConradIrwin/pry-syntax-hacks.git' gem 'pry-stack_explorer' #, :git => 'https://github.com/pry/pry-stack_explorer.git' gem 'pry-exception_explorer' #, :git => 'https://github.com/pry/pry-exception_explorer.git' gem 'ipaddr_extensions' #, :git => 'git://github.com/jamesotron/IPAddrExtensions.git' + +gem 'haml' +# gem 'slim' diff --git a/Gemfile.lock b/Gemfile.lock index af7a180..83a1b1e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -3,6 +3,7 @@ GEM specs: binding_of_caller (0.6.7) coderay (1.0.6) + haml (3.1.4) ipaddr_extensions (2012.1.13) method_source (0.7.1) pry (0.9.9.4) @@ -30,6 +31,7 @@ PLATFORMS ruby DEPENDENCIES + haml ipaddr_extensions pry pry-doc diff --git a/bin/vpnmaker b/bin/vpnmaker new file mode 100755 index 0000000..49ffd26 --- /dev/null +++ b/bin/vpnmaker @@ -0,0 +1 @@ +#!/usr/bin/env ruby diff --git a/lib/client.erb b/lib/client.erb deleted file mode 100644 index 8e5e7ee..0000000 --- a/lib/client.erb +++ /dev/null @@ -1,15 +0,0 @@ -# Auto-generated by vpnmaker on <%= @gen_host %> at <%= Time.now.to_s %> -# See http://github.com/pc/vpnmaker - -remote <%= @server[:host] %> <%= @server[:port] %> udp -persist-key -tls-client -tls-auth ta.key 1 -pull -ca ca.crt -dev tun -persist-tun -cert <%= @user %>-<%= (@revoked.max || -1) + 1 %>.crt -nobind -key <%= @user %>-<%= (@revoked.max || -1) + 1 %>.key -remote-cert-tls server diff --git a/lib/client.haml b/lib/client.haml index 3afcf1a..9aa98c5 100644 --- a/lib/client.haml +++ b/lib/client.haml @@ -6,8 +6,8 @@ pull ca ca.crt dev tun persist-tun -cert #{user} #{(revoked.max || -1) + 1}.crt +cert #{user}-#{(revoked.max || - 1) + 1}.crt nobind -key #{user} #{(revoked.max || -1) + 1}.key +key #{user}-#{(revoked.max || - 1) + 1}.key remote-cert-tls server :plain diff --git a/lib/openssl.erb b/lib/openssl.erb deleted file mode 100644 index 0ff5916..0000000 --- a/lib/openssl.erb +++ /dev/null @@ -1,290 +0,0 @@ -# For use with vpnmaker, originally from easy-rsa version 2.0 - -# -# OpenSSL example configuration file. -# This is mostly being used for generation of certificate requests. -# - -# This definition stops the following lines choking if HOME isn't -# defined. -HOME = . -RANDFILE = $ENV::HOME/.rnd -openssl_conf = openssl_init - -[ openssl_init ] -# Extra OBJECT IDENTIFIER info: -#oid_file = $ENV::HOME/.oid -oid_section = new_oids -engines = engine_section - -# To use this configuration file with the "-extfile" option of the -# "openssl x509" utility, name here the section containing the -# X.509v3 extensions to use: -# extensions = -# (Alternatively, use a configuration file that has only -# X.509v3 extensions in its main [= default] section.) - -[ new_oids ] - -# We can add new OIDs in here for use by 'ca' and 'req'. -# Add a simple OID like this: -# testoid1=1.2.3.4 -# Or use config file substitution like this: -# testoid2=${testoid1}.5.6 - -#################################################################### -[ ca ] -default_ca = CA_default # The default ca section - -#################################################################### -[ CA_default ] - -dir = <%= @key_dir %> # Where everything is kept -certs = $dir # Where the issued certs are kept -crl_dir = $dir # Where the issued crl are kept -database = $dir/index.txt # database index file. -new_certs_dir = $dir # default place for new certs. - -certificate = $dir/ca.crt # The CA certificate -serial = $dir/serial # The current serial number -crl = $dir/crl.pem # The current CRL -private_key = $dir/ca.key # The private key -RANDFILE = $dir/.rand # private random number file - -x509_extensions = usr_cert # The extentions to add to the cert - -# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs -# so this is commented out by default to leave a V1 CRL. -# crl_extensions = crl_ext - -default_days = 3650 # how long to certify for -default_crl_days= 30 # how long before next CRL -default_md = md5 # which md to use. -preserve = no # keep passed DN ordering - -# A few difference way of specifying how similar the request should look -# For type CA, the listed attributes must be the same, and the optional -# and supplied fields are just that :-) -policy = policy_anything - -# For the CA policy -[ policy_match ] -countryName = match -stateOrProvinceName = match -organizationName = match -organizationalUnitName = optional -commonName = supplied -name = optional -emailAddress = optional - -# For the 'anything' policy -# At this point in time, you must list all acceptable 'object' -# types. -[ policy_anything ] -countryName = optional -stateOrProvinceName = optional -localityName = optional -organizationName = optional -organizationalUnitName = optional -commonName = supplied -name = optional -emailAddress = optional - -#################################################################### -[ req ] -default_bits = <%= @key_size %> -default_keyfile = privkey.pem -distinguished_name = req_distinguished_name -attributes = req_attributes -x509_extensions = v3_ca # The extentions to add to the self signed cert - -# Passwords for private keys if not present they will be prompted for -# input_password = secret -# output_password = secret - -# This sets a mask for permitted string types. There are several options. -# default: PrintableString, T61String, BMPString. -# pkix : PrintableString, BMPString. -# utf8only: only UTF8Strings. -# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings). -# MASK:XXXX a literal mask value. -# WARNING: current versions of Netscape crash on BMPStrings or UTF8Strings -# so use this option with caution! -string_mask = nombstr - -# req_extensions = v3_req # The extensions to add to a certificate request - -[ req_distinguished_name ] -countryName = Country Name (2 letter code) -countryName_default = <%= @key_country %> -countryName_min = 2 -countryName_max = 2 - -stateOrProvinceName = State or Province Name (full name) -stateOrProvinceName_default = <%= @key_province %> - -localityName = Locality Name (eg, city) -localityName_default = <%= @key_city %> - -0.organizationName = Organization Name (eg, company) -0.organizationName_default = <%= @key_org %> - -# we can do this but it is not needed normally :-) -#1.organizationName = Second Organization Name (eg, company) -#1.organizationName_default = World Wide Web Pty Ltd - -organizationalUnitName = Organizational Unit Name (eg, section) -#organizationalUnitName_default = - -commonName = Common Name (eg, your name or your server\'s hostname) -commonName_max = 64 - -name = Name -name_max = 64 - -emailAddress = Email Address -emailAddress_default = <%= @key_email %> -emailAddress_max = 40 - -# JY -- added for batch mode -organizationalUnitName_default = <%= @key_ou %> -commonName_default = <%= @key_cn %> -name_default = <%= @key_name %> - -# SET-ex3 = SET extension number 3 - -[ req_attributes ] -challengePassword = A challenge password -challengePassword_min = 4 -challengePassword_max = 20 - -unstructuredName = An optional company name - -[ usr_cert ] - -# These extensions are added when 'ca' signs a request. - -# This goes against PKIX guidelines but some CAs do it and some software -# requires this to avoid interpreting an end user certificate as a CA. - -basicConstraints=CA:FALSE - -# Here are some examples of the usage of nsCertType. If it is omitted -# the certificate can be used for anything *except* object signing. - -# This is OK for an SSL server. -# nsCertType = server - -# For an object signing certificate this would be used. -# nsCertType = objsign - -# For normal client use this is typical -# nsCertType = client, email - -# and for everything including object signing: -# nsCertType = client, email, objsign - -# This is typical in keyUsage for a client certificate. -# keyUsage = nonRepudiation, digitalSignature, keyEncipherment - -# This will be displayed in Netscape's comment listbox. -nsComment = "Easy-RSA Generated Certificate" - -# PKIX recommendations harmless if included in all certificates. -subjectKeyIdentifier=hash -authorityKeyIdentifier=keyid,issuer:always -extendedKeyUsage=clientAuth -keyUsage = digitalSignature - -# This stuff is for subjectAltName and issuerAltname. -# Import the email address. -# subjectAltName=email:copy - -# Copy subject details -# issuerAltName=issuer:copy - -#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem -#nsBaseUrl -#nsRevocationUrl -#nsRenewalUrl -#nsCaPolicyUrl -#nsSslServerName - -[ server ] - -# JY ADDED -- Make a cert with nsCertType set to "server" -basicConstraints=CA:FALSE -nsCertType = server -nsComment = "Easy-RSA Generated Server Certificate" -subjectKeyIdentifier=hash -authorityKeyIdentifier=keyid,issuer:always -extendedKeyUsage=serverAuth -keyUsage = digitalSignature, keyEncipherment - -[ v3_req ] - -# Extensions to add to a certificate request - -basicConstraints = CA:FALSE -keyUsage = nonRepudiation, digitalSignature, keyEncipherment - -[ v3_ca ] - - -# Extensions for a typical CA - - -# PKIX recommendation. - -subjectKeyIdentifier=hash - -authorityKeyIdentifier=keyid:always,issuer:always - -# This is what PKIX recommends but some broken software chokes on critical -# extensions. -#basicConstraints = critical,CA:true -# So we do this instead. -basicConstraints = CA:true - -# Key usage: this is typical for a CA certificate. However since it will -# prevent it being used as an test self-signed certificate it is best -# left out by default. -# keyUsage = cRLSign, keyCertSign - -# Some might want this also -# nsCertType = sslCA, emailCA - -# Include email address in subject alt name: another PKIX recommendation -# subjectAltName=email:copy -# Copy issuer details -# issuerAltName=issuer:copy - -# DER hex encoding of an extension: beware experts only! -# obj=DER:02:03 -# Where 'obj' is a standard or added object -# You can even override a supported extension: -# basicConstraints= critical, DER:30:03:01:01:FF - -[ crl_ext ] - -# CRL extensions. -# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL. - -# issuerAltName=issuer:copy -authorityKeyIdentifier=keyid:always,issuer:always - -[ engine_section ] -# -# If you are using PKCS#11 -# Install engine_pkcs11 of opensc (www.opensc.org) -# And uncomment the following -# verify that dynamic_path points to the correct location -# -# pkcs11 = pkcs11_section - -[ pkcs11_section ] -engine_id = pkcs11 -dynamic_path = /usr/lib/engines/engine_pkcs11.so -MODULE_PATH = blub # $ENV::PKCS11_MODULE_PATH -PIN = blub # $ENV::PKCS11_PIN -init = 0 \ No newline at end of file diff --git a/lib/openssl.haml b/lib/openssl.haml new file mode 100644 index 0000000..3d01705 --- /dev/null +++ b/lib/openssl.haml @@ -0,0 +1,144 @@ +HOME = . +RANDFILE = $ENV::HOME/.rnd +openssl_conf = openssl_init + +[ openssl_init ] +oid_section = new_oids +engines = engine_section + +[ new_oids ] +[ ca ] +default_ca = CA_default + +[CA_default ] + +dir = #{key_dir} +certs = $dir # Where the issued certs are kept +crl_dir = $dir # Where the issued crl are kept +database = $dir/index.txt # database index file. +new_certs_dir = $dir # default place for new certs. + +certificate = $dir/ca.crt # The CA certificate +serial = $dir/serial # The current serial number +crl = $dir/crl.pem # The current CRL +private_key = $dir/ca.key # The private key +RANDFILE = $dir/.rand # private random number file + +x509_extensions = usr_cert # The extentions to add to the cert + +default_days = 3650 # how long to certify for +default_crl_days= 30 # how long before next CRL +default_md = md5 # which md to use. +preserve = no # keep passed DN ordering + +policy = policy_anything + +[ policy_match ] +countryName = match +stateOrProvinceName = match +organizationName = match +organizationalUnitName = optional +commonName = supplied +name = optional +emailAddress = optional + +[ policy_anything ] +countryName = optional +stateOrProvinceName = optional +localityName = optional +organizationName = optional +organizationalUnitName = optional +commonName = supplied +name = optional +emailAddress = optional + +[ req ] +default_bits = #{key_size} +default_keyfile = privkey.pem +distinguished_name = req_distinguished_name +attributes = req_attributes +x509_extensions = v3_ca # The extentions to add to the self signed cert + +string_mask = nombstr + +[ req_distinguished_name ] +countryName = Country Name (2 letter code) +countryName_default = #{key_country} +countryName_min = 2 +countryName_max = 2 + +stateOrProvinceName = State or Province Name (full name) +stateOrProvinceName_default = #{key_province} + +localityName = Locality Name (eg, city) +localityName_default = #{key_city} + +0.organizationName = Organization Name (eg, company) +0.organizationName_default = #{key_org} + +organizationalUnitName = Organizational Unit Name (eg, section) + +commonName = Common Name (eg, your name or your server\'s hostname) +commonName_max = 64 + +name = Name +name_max = 64 + +emailAddress = Email Address +emailAddress_default = #{key_email} +emailAddress_max = 40 + +organizationalUnitName_default = #{key_ou} +commonName_default = #{key_cn} +name_default = #{key_name} + +[ req_attributes ] +challengePassword = A challenge password +challengePassword_min = 4 +challengePassword_max = 20 + +unstructuredName = An optional company name + +[ usr_cert ] + +basicConstraints=CA:FALSE +nsComment = "Easy-RSA Generated Certificate" + +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid,issuer:always +extendedKeyUsage=clientAuth +keyUsage = digitalSignature + +[ server ] + +basicConstraints=CA:FALSE +nsCertType = server +nsComment = "Easy-RSA Generated Server Certificate" +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid,issuer:always +extendedKeyUsage=serverAuth +keyUsage = digitalSignature, keyEncipherment + +[ v3_req ] + +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +[ v3_ca ] +subjectKeyIdentifier=hash + +authorityKeyIdentifier=keyid:always,issuer:always +basicConstraints = CA:true + +[ crl_ext ] +authorityKeyIdentifier=keyid:always,issuer:always + +[ engine_section ] + +[ pkcs11_section ] +engine_id = pkcs11 +dynamic_path = /usr/lib/engines/engine_pkcs11.so +MODULE_PATH = blub # $ENV::PKCS11_MODULE_PATH +PIN = blub # $ENV::PKCS11_PIN +init = 0 +:plain diff --git a/lib/server.haml b/lib/server.haml index 37b59e6..b58d65f 100644 --- a/lib/server.haml +++ b/lib/server.haml @@ -1,6 +1,5 @@ --# Auto-generated by vpnmaker on <%= @gen_host %> at <%= Time.now.to_s %> --# See http://github.com/pc/vpnmaker - +\# Auto-generated by vpnmaker on #{gen_host} #{Time.now.to_s} +\# See http://github.com/pc/vpnmaker mode server tls-server local #{host} @@ -9,14 +8,16 @@ proto udp dev tun0 server #{base_ip[:net]} #{base_ip[:mask]} - +\ +\# subnets.each do - subnets.each do |net| route #{net[:net]} #{net[:mask]} push route #{net[:mask]} #{net[:mask]} - +\ +\# bridgednets.each do - bridgednets.each do |net| push route #{net[:net]} #{net[:mask]} - +\ user #{user} group #{group} dh #{root}/keys/dh.pem diff --git a/lib/vpnmaker.rb b/lib/vpnmaker.rb index 6a57007..5151726 100644 --- a/lib/vpnmaker.rb +++ b/lib/vpnmaker.rb @@ -8,6 +8,7 @@ require 'ipaddr' require 'ipaddr_extensions' require 'haml' +require 'slim' require 'pry' @@ -36,4 +37,8 @@ module VPNMaker autoload :KeyTracker, './vpnmaker/key_tracker' autoload :Manager, './vpnmaker/manager' autoload :KeyBuilder, './vpnmaker/key_builder' + + def self.generate(*args) + KeyTracker.generate(args.first, args.last) + end end diff --git a/lib/vpnmaker/config_generator.rb b/lib/vpnmaker/config_generator.rb index b52ab13..58ef095 100644 --- a/lib/vpnmaker/config_generator.rb +++ b/lib/vpnmaker/config_generator.rb @@ -18,11 +18,6 @@ def server_conf }.merge(@mgr.config[:server]) end - def apply_erb(name, cnf) - erb = File.read(__FILE__.path(name)) - ERB.new(erb).result(HashBinding.from_hash(cnf).binding) - end - def server haml_vars = server_conf.dup haml_vars[:base_ip] = ((a = IPAddr.new haml_vars[:base_ip]); {:net => a.to_s, :mask => a.subnet_mask.to_s}) @@ -33,7 +28,9 @@ def server end def client(client) - apply_erb('client.erb', client_conf(client)) + haml_vars = client_conf(client).dup + template = File.read(__FILE__.path('client.haml')) + Haml::Engine.new(template).render(Object.new, haml_vars) end end end diff --git a/lib/vpnmaker/key_builder.rb b/lib/vpnmaker/key_builder.rb index 785c55f..bf84988 100644 --- a/lib/vpnmaker/key_builder.rb +++ b/lib/vpnmaker/key_builder.rb @@ -39,8 +39,7 @@ def opensslcnf(hash={}) c = cnfpath File.open(cnfpath, 'w') do |f| - f.write(ERB.new(File.read(__FILE__.path('openssl.erb'))).\ - result(HashBinding.from_hash(opensslvars.merge(hash)).binding)) + f.write(Haml::Engine.new(File.read __FILE__.path('openssl.haml')).render(Object.new, opensslvars.merge(hash))) end c From d92ce453a80473863099c2904b5be7533bfc4438 Mon Sep 17 00:00:00 2001 From: Voob of Doom Date: Sat, 5 May 2012 22:18:16 +0200 Subject: [PATCH 05/81] cleaned up gemlock --- Gemfile.lock | 42 ------------------------------------------ 1 file changed, 42 deletions(-) delete mode 100644 Gemfile.lock diff --git a/Gemfile.lock b/Gemfile.lock deleted file mode 100644 index 83a1b1e..0000000 --- a/Gemfile.lock +++ /dev/null @@ -1,42 +0,0 @@ -GEM - remote: https://rubygems.org/ - specs: - binding_of_caller (0.6.7) - coderay (1.0.6) - haml (3.1.4) - ipaddr_extensions (2012.1.13) - method_source (0.7.1) - pry (0.9.9.4) - coderay (~> 1.0.5) - method_source (~> 0.7.1) - slop (>= 2.4.4, < 3) - pry-doc (0.4.1) - pry (>= 0.9.0) - yard (~> 0.7.4) - pry-exception_explorer (0.1.9) - pry-stack_explorer (>= 0.3.9) - pry-nav (0.2.1) - pry (~> 0.9.9) - pry-rails (0.1.6) - pry - pry-stack_explorer (0.4.2) - binding_of_caller (~> 0.6.2) - pry (~> 0.9.9) - pry-syntax-hacks (0.0.6) - pry (>= 0.9.8) - slop (2.4.4) - yard (0.7.5) - -PLATFORMS - ruby - -DEPENDENCIES - haml - ipaddr_extensions - pry - pry-doc - pry-exception_explorer - pry-nav - pry-rails - pry-stack_explorer - pry-syntax-hacks From fd31eea325e2011c0aded8694536451af3e9f563 Mon Sep 17 00:00:00 2001 From: Voip Scout Date: Sun, 6 May 2012 12:31:25 +0200 Subject: [PATCH 06/81] Version bump to 0.0.0 --- VERSION | 1 + 1 file changed, 1 insertion(+) create mode 100644 VERSION diff --git a/VERSION b/VERSION new file mode 100644 index 0000000..bd52db8 --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +0.0.0 \ No newline at end of file From 6b7ecc6a7336d0ae741d881dd9675c2e4cb0812c Mon Sep 17 00:00:00 2001 From: Voip Scout Date: Sun, 6 May 2012 12:32:51 +0200 Subject: [PATCH 07/81] added jeweler --- .document | 5 ++ .gitignore | 50 ++++++++++++++++++ Gemfile | 24 ++++++--- Rakefile | 129 +++++++++++++++++++++++++++++++++-------------- bin/vpnmaker | 10 ++++ lib/vpnmaker.rb | 5 +- vpnmaker.gemspec | 97 +++++++++++++++++++++++++++++++++++ 7 files changed, 274 insertions(+), 46 deletions(-) create mode 100644 .document create mode 100644 vpnmaker.gemspec diff --git a/.document b/.document new file mode 100644 index 0000000..3d618dd --- /dev/null +++ b/.document @@ -0,0 +1,5 @@ +lib/**/*.rb +bin/* +- +features/**/*.feature +LICENSE.txt diff --git a/.gitignore b/.gitignore index b844b14..757d622 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,51 @@ +# rcov generated +coverage +coverage.data + +# rdoc generated +rdoc + +# yard generated +doc +.yardoc + +# bundler +.bundle + +# jeweler generated +pkg + +# Have editor/IDE/OS specific files you need to ignore? Consider using a global gitignore: +# +# * Create a file at ~/.gitignore +# * Include files you want ignored +# * Run: git config --global core.excludesfile ~/.gitignore +# +# After doing this, these files will be ignored in all your git projects, +# saving you from having to 'pollute' every project you touch with them +# +# Not sure what to needs to be ignored for particular editors/OSes? Here's some ideas to get you started. (Remember, remove the leading # of the line) +# +# For MacOS: +# +.DS_Store + +# For TextMate +*.tmproj +tmtags + +# For emacs: +*~ +\#* +.\#* + +# For vim: +*.swp + +# For redcar: +.redcar + +# For rubinius: +*.rbc + Gemfile.lock diff --git a/Gemfile b/Gemfile index c7e08f0..5f500a4 100644 --- a/Gemfile +++ b/Gemfile @@ -1,15 +1,25 @@ source 'https://rubygems.org' -gem "pry" -gem 'pry-doc' #, :git => 'https://github.com/pry/pry-doc.git' -gem 'pry-rails' #, :git => 'https://github.com/rweng/pry-rails.git' -gem 'pry-nav' #, :git => 'https://github.com/nixme/pry-nav.git' -gem 'pry-syntax-hacks' #, :git => 'https://github.com/ConradIrwin/pry-syntax-hacks.git' -gem 'pry-stack_explorer' #, :git => 'https://github.com/pry/pry-stack_explorer.git' -gem 'pry-exception_explorer' #, :git => 'https://github.com/pry/pry-exception_explorer.git' +group :development do + gem "pry" + gem 'pry-doc' #, :git => 'https://github.com/pry/pry-doc.git' + gem 'pry-rails' #, :git => 'https://github.com/rweng/pry-rails.git' + gem 'pry-nav' #, :git => 'https://github.com/nixme/pry-nav.git' + gem 'pry-syntax-hacks' #, :git => 'https://github.com/ConradIrwin/pry-syntax-hacks.git' + gem 'pry-stack_explorer' #, :git => 'https://github.com/pry/pry-stack_explorer.git' + gem 'pry-exception_explorer' #, :git => 'https://github.com/pry/pry-exception_explorer.git' + gem "rdoc", "~> 3.12" + gem "bundler" #, "~> 1.0.0" + gem "jeweler" #, "~> 1.8.3" +end gem 'ipaddr_extensions' #, :git => 'git://github.com/jamesotron/IPAddrExtensions.git' gem 'haml' +gem 'trollop' +gem 'gibberish', :git => 'git://github.com/mdp/gibberish.git' +gem 'rubyzip', :git => 'git://github.com/aussiegeek/rubyzip.git' # gem 'slim' + +# gem 'slop', :git => 'git://github.com/injekt/slop.git' diff --git a/Rakefile b/Rakefile index 342c26f..ad479e6 100644 --- a/Rakefile +++ b/Rakefile @@ -1,44 +1,99 @@ -require 'highline/import' -require File.join(File.dirname(__FILE__), 'vpnmaker') +# encoding: utf-8 -def get_arg(argname, echo=true) - return ENV[argname] if ENV[argname] - ask("Value for #{argname}?") { |q| q.echo = false unless echo } +require 'rubygems' +require 'bundler' +begin + Bundler.setup(:default, :development) +rescue Bundler::BundlerError => e + $stderr.puts e.message + $stderr.puts "Run `bundle install` to install missing gems" + exit e.status_code end +require 'rake' -namespace :config do - desc 'Generate server config' - task :server => :environment do - puts $manager.config_generator.server - end - - desc 'Generate client config' - task :client => :environment do - username = get_arg('username') - puts $manager.config_generator.client($manager.user(username)) - end +require 'jeweler' +Jeweler::Tasks.new do |gem| + # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options + gem.name = "vpnmaker" + gem.executables = 'vpnmaker' + gem.homepage = "http://github.com/voipscout/vpnmaker" + gem.license = "MIT" + gem.summary = %Q{TODO: one-line summary of your gem} + gem.description = %Q{TODO: longer description of your gem} + gem.email = "voipscout@gmail.com" + gem.authors = ["Voip Scout"] + # dependencies defined in Gemfile end +Jeweler::RubygemsDotOrgTasks.new -namespace :user do - desc 'Create a new user' - task :create => :environment do - cn = get_arg('cn') - name = get_arg('name') - email = get_arg('email') - password = get_arg('password', false) - confirm_password = get_arg('confirm_password', false) - raise ArgumentError.new("Password mismatch") unless password == confirm_password - - if password.length > 0 - $manager.create_user(cn, name, email, password) - else - $manager.create_user(cn, name, email) - end - end -end +# require 'rake/testtask' +# Rake::TestTask.new(:test) do |test| +# test.libs << 'lib' << 'test' +# test.pattern = 'test/**/test_*.rb' +# test.verbose = true +# end + +# require 'rcov/rcovtask' +# Rcov::RcovTask.new do |test| +# test.libs << 'test' +# test.pattern = 'test/**/test_*.rb' +# test.verbose = true +# test.rcov_opts << '--exclude "gems/*"' +# end + +# task :default => :test -# Set up environment -task :environment do - vpndir = get_arg('vpndir') - $manager = VPNMaker::Manager.new(vpndir) +require 'rdoc/task' +Rake::RDocTask.new do |rdoc| + version = File.exist?('VERSION') ? File.read('VERSION') : "" + + rdoc.rdoc_dir = 'rdoc' + rdoc.title = "vpnmaker #{version}" + rdoc.rdoc_files.include('README*') + rdoc.rdoc_files.include('lib/**/*.rb') end + +# require 'highline/import' +# require File.join(File.dirname(__FILE__), 'vpnmaker') + +# def get_arg(argname, echo=true) +# return ENV[argname] if ENV[argname] +# ask("Value for #{argname}?") { |q| q.echo = false unless echo } +# end + +# namespace :config do +# desc 'Generate server config' +# task :server => :environment do +# puts $manager.config_generator.server +# end + +# desc 'Generate client config' +# task :client => :environment do +# username = get_arg('username') +# puts $manager.config_generator.client($manager.user(username)) +# end +# end + +# namespace :user do +# desc 'Create a new user' +# task :create => :environment do +# cn = get_arg('cn') +# name = get_arg('name') +# email = get_arg('email') +# password = get_arg('password', false) +# confirm_password = get_arg('confirm_password', false) +# raise ArgumentError.new("Password mismatch") unless password == confirm_password + +# if password.length > 0 +# $manager.create_user(cn, name, email, password) +# else +# $manager.create_user(cn, name, email) +# end +# end +# end + +# # Set up environment +# task :environment do +# vpndir = get_arg('vpndir') +# $manager = VPNMaker::Manager.new(vpndir) +# end diff --git a/bin/vpnmaker b/bin/vpnmaker index 49ffd26..d94baad 100755 --- a/bin/vpnmaker +++ b/bin/vpnmaker @@ -1 +1,11 @@ #!/usr/bin/env ruby +require_relative '../lib/vpnmaker.rb' +require 'trollop' + +opts = Trollop::options do + version "vpnmaker 0.0.1 (c) Coolio" + banner "vpnmaker [options]" + opt :verbose, 'Enable verbose mode' +end + +#raise Trollop::HelpNeeded if ARGV.empty? diff --git a/lib/vpnmaker.rb b/lib/vpnmaker.rb index 5151726..85867dc 100644 --- a/lib/vpnmaker.rb +++ b/lib/vpnmaker.rb @@ -1,14 +1,15 @@ require 'rubygems' +require 'gibberish' +require 'rubyzip' + require 'fileutils' require 'yaml' -require 'erb' require 'socket' require 'ipaddr' require 'ipaddr_extensions' require 'haml' -require 'slim' require 'pry' diff --git a/vpnmaker.gemspec b/vpnmaker.gemspec new file mode 100644 index 0000000..2285e93 --- /dev/null +++ b/vpnmaker.gemspec @@ -0,0 +1,97 @@ +# Generated by jeweler +# DO NOT EDIT THIS FILE DIRECTLY +# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec' +# -*- encoding: utf-8 -*- + +Gem::Specification.new do |s| + s.name = "vpnmaker" + s.version = "0.0.0" + + s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= + s.authors = ["Voip Scout"] + s.date = "2012-05-06" + s.description = "TODO: longer description of your gem" + s.email = "voipscout@gmail.com" + s.executables = ["vpnmaker"] + s.extra_rdoc_files = [ + "README.rdoc" + ] + s.files = [ + "Gemfile", + "README.rdoc", + "Rakefile", + "VERSION", + "bin/vpnmaker", + "foocorp.config.yaml", + "lib/client.haml", + "lib/openssl.haml", + "lib/server.haml", + "lib/vpnmaker.rb", + "lib/vpnmaker/config_generator.rb", + "lib/vpnmaker/key_builder.rb", + "lib/vpnmaker/key_config.rb", + "lib/vpnmaker/key_db.rb", + "lib/vpnmaker/key_tracker.rb", + "lib/vpnmaker/manager.rb" + ] + s.homepage = "http://github.com/voipscout/vpnmaker" + s.licenses = ["MIT"] + s.require_paths = ["lib"] + s.rubygems_version = "1.8.24" + s.summary = "TODO: one-line summary of your gem" + + if s.respond_to? :specification_version then + s.specification_version = 3 + + if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then + s.add_runtime_dependency(%q, [">= 0"]) + s.add_runtime_dependency(%q, [">= 0"]) + s.add_runtime_dependency(%q, [">= 0"]) + s.add_runtime_dependency(%q, [">= 0"]) + s.add_runtime_dependency(%q, [">= 0"]) + s.add_development_dependency(%q, [">= 0"]) + s.add_development_dependency(%q, [">= 0"]) + s.add_development_dependency(%q, [">= 0"]) + s.add_development_dependency(%q, [">= 0"]) + s.add_development_dependency(%q, [">= 0"]) + s.add_development_dependency(%q, [">= 0"]) + s.add_development_dependency(%q, [">= 0"]) + s.add_development_dependency(%q, ["~> 3.12"]) + s.add_development_dependency(%q, [">= 0"]) + s.add_development_dependency(%q, [">= 0"]) + else + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, ["~> 3.12"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + end + else + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, ["~> 3.12"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + end +end + From 7ca280308eb9db7a836cb685223bddbb0740d841 Mon Sep 17 00:00:00 2001 From: Voip Scout Date: Sun, 6 May 2012 12:35:09 +0200 Subject: [PATCH 08/81] Regenerate gemspec for version 0.0.0 --- vpnmaker.gemspec | 85 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 vpnmaker.gemspec diff --git a/vpnmaker.gemspec b/vpnmaker.gemspec new file mode 100644 index 0000000..257cdf3 --- /dev/null +++ b/vpnmaker.gemspec @@ -0,0 +1,85 @@ +# Generated by jeweler +# DO NOT EDIT THIS FILE DIRECTLY +# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec' +# -*- encoding: utf-8 -*- + +Gem::Specification.new do |s| + s.name = "vpnmaker" + s.version = "0.0.0" + + s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= + s.authors = ["Voip Scout"] + s.date = "2012-05-06" + s.description = "TODO: longer description of your gem" + s.email = "voipscout@gmail.com" + s.executables = ["vpnmaker"] + s.extra_rdoc_files = [ + "README.rdoc" + ] + s.files = [ + "README.rdoc", + "Rakefile", + "foocorp.config.yaml", + "vpnmaker.gemspec" + ] + s.homepage = "http://github.com/voipscout/vpnmaker" + s.licenses = ["MIT"] + s.require_paths = ["lib"] + s.rubygems_version = "1.8.24" + s.summary = "TODO: one-line summary of your gem" + + if s.respond_to? :specification_version then + s.specification_version = 3 + + if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then + s.add_runtime_dependency(%q, [">= 0"]) + s.add_runtime_dependency(%q, [">= 0"]) + s.add_runtime_dependency(%q, [">= 0"]) + s.add_runtime_dependency(%q, [">= 0"]) + s.add_runtime_dependency(%q, [">= 0"]) + s.add_development_dependency(%q, [">= 0"]) + s.add_development_dependency(%q, [">= 0"]) + s.add_development_dependency(%q, [">= 0"]) + s.add_development_dependency(%q, [">= 0"]) + s.add_development_dependency(%q, [">= 0"]) + s.add_development_dependency(%q, [">= 0"]) + s.add_development_dependency(%q, [">= 0"]) + s.add_development_dependency(%q, ["~> 3.12"]) + s.add_development_dependency(%q, [">= 0"]) + s.add_development_dependency(%q, [">= 0"]) + else + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, ["~> 3.12"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + end + else + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, ["~> 3.12"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + end +end + From 4157b97d96c61bd083129a530d4a2e93009bdd9b Mon Sep 17 00:00:00 2001 From: Voip Scout Date: Sun, 6 May 2012 12:41:02 +0200 Subject: [PATCH 09/81] rdoc changed --- README.rdoc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.rdoc b/README.rdoc index 3c761a1..d60ad51 100644 --- a/README.rdoc +++ b/README.rdoc @@ -1,6 +1,8 @@ +most of the code was stolen from here: http://github.com/pc/vpnmaker +i made a gem and converted it to use haml = VPNMaker -VPNMaker takes the teetering jankiness out of setting up and administering OpenVPN VPNs. +VPNMaker takes the teetering jankiness out of setting up and administering OpenVPN. == Key management @@ -77,7 +79,7 @@ To get OpenVPN set up, you should go back and edit foocorp.config.yaml, :log: /var/log/openvpn.log :host: foocorp.com :port: 1194 - + You may want to modify some of the values. Then, head back to irb, and do something like: >> puts mgr.config_generator.server From ca7ca54c95fe992905fca5dfe15947f731367ad8 Mon Sep 17 00:00:00 2001 From: Voip Scout Date: Sun, 6 May 2012 12:48:46 +0200 Subject: [PATCH 10/81] Regenerate gemspec for version 0.0.0 --- vpnmaker.gemspec | 98 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 vpnmaker.gemspec diff --git a/vpnmaker.gemspec b/vpnmaker.gemspec new file mode 100644 index 0000000..3b8f975 --- /dev/null +++ b/vpnmaker.gemspec @@ -0,0 +1,98 @@ +# Generated by jeweler +# DO NOT EDIT THIS FILE DIRECTLY +# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec' +# -*- encoding: utf-8 -*- + +Gem::Specification.new do |s| + s.name = "vpnmaker" + s.version = "0.0.0" + + s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= + s.authors = ["Voip Scout"] + s.date = "2012-05-06" + s.description = "TODO: longer description of your gem" + s.email = "voipscout@gmail.com" + s.executables = ["vpnmaker"] + s.extra_rdoc_files = [ + "README.rdoc" + ] + s.files = [ + ".document", + "Gemfile", + "README.rdoc", + "Rakefile", + "VERSION", + "bin/vpnmaker", + "foocorp.config.yaml", + "lib/client.haml", + "lib/openssl.haml", + "lib/server.haml", + "lib/vpnmaker.rb", + "lib/vpnmaker/config_generator.rb", + "lib/vpnmaker/key_builder.rb", + "lib/vpnmaker/key_config.rb", + "lib/vpnmaker/key_db.rb", + "lib/vpnmaker/key_tracker.rb", + "lib/vpnmaker/manager.rb" + ] + s.homepage = "http://github.com/voipscout/vpnmaker" + s.licenses = ["MIT"] + s.require_paths = ["lib"] + s.rubygems_version = "1.8.24" + s.summary = "TODO: one-line summary of your gem" + + if s.respond_to? :specification_version then + s.specification_version = 3 + + if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then + s.add_runtime_dependency(%q, [">= 0"]) + s.add_runtime_dependency(%q, [">= 0"]) + s.add_runtime_dependency(%q, [">= 0"]) + s.add_runtime_dependency(%q, [">= 0"]) + s.add_runtime_dependency(%q, [">= 0"]) + s.add_development_dependency(%q, [">= 0"]) + s.add_development_dependency(%q, [">= 0"]) + s.add_development_dependency(%q, [">= 0"]) + s.add_development_dependency(%q, [">= 0"]) + s.add_development_dependency(%q, [">= 0"]) + s.add_development_dependency(%q, [">= 0"]) + s.add_development_dependency(%q, [">= 0"]) + s.add_development_dependency(%q, ["~> 3.12"]) + s.add_development_dependency(%q, [">= 0"]) + s.add_development_dependency(%q, [">= 0"]) + else + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, ["~> 3.12"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + end + else + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, ["~> 3.12"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + end +end + From 1fc24f53e39de8bea81801fc8cdcb70214327cee Mon Sep 17 00:00:00 2001 From: Voip Scout Date: Sun, 6 May 2012 12:50:54 +0200 Subject: [PATCH 11/81] hopefully fixed it --- Rakefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Rakefile b/Rakefile index ad479e6..d1b2dc0 100644 --- a/Rakefile +++ b/Rakefile @@ -18,8 +18,8 @@ Jeweler::Tasks.new do |gem| gem.executables = 'vpnmaker' gem.homepage = "http://github.com/voipscout/vpnmaker" gem.license = "MIT" - gem.summary = %Q{TODO: one-line summary of your gem} - gem.description = %Q{TODO: longer description of your gem} + gem.summary = %Q{Makes it easy to manage OpenVPN} + gem.description = %Q{haml templates and key tracking} gem.email = "voipscout@gmail.com" gem.authors = ["Voip Scout"] # dependencies defined in Gemfile From ff65ed4546b26b45c544b2c74672e4aef6a39b68 Mon Sep 17 00:00:00 2001 From: Voip Scout Date: Sun, 6 May 2012 12:52:18 +0200 Subject: [PATCH 12/81] Regenerate gemspec for version 0.0.0 --- vpnmaker.gemspec | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/vpnmaker.gemspec b/vpnmaker.gemspec index 3b8f975..f89d214 100644 --- a/vpnmaker.gemspec +++ b/vpnmaker.gemspec @@ -10,7 +10,7 @@ Gem::Specification.new do |s| s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= s.authors = ["Voip Scout"] s.date = "2012-05-06" - s.description = "TODO: longer description of your gem" + s.description = "haml templates and key tracking" s.email = "voipscout@gmail.com" s.executables = ["vpnmaker"] s.extra_rdoc_files = [ @@ -33,13 +33,14 @@ Gem::Specification.new do |s| "lib/vpnmaker/key_config.rb", "lib/vpnmaker/key_db.rb", "lib/vpnmaker/key_tracker.rb", - "lib/vpnmaker/manager.rb" + "lib/vpnmaker/manager.rb", + "vpnmaker.gemspec" ] s.homepage = "http://github.com/voipscout/vpnmaker" s.licenses = ["MIT"] s.require_paths = ["lib"] s.rubygems_version = "1.8.24" - s.summary = "TODO: one-line summary of your gem" + s.summary = "Makes it easy to manage OpenVPN" if s.respond_to? :specification_version then s.specification_version = 3 From d2a2d0afc52950051c1bee5b4782fedef133418a Mon Sep 17 00:00:00 2001 From: Voip Scout Date: Sun, 6 May 2012 16:21:35 +0200 Subject: [PATCH 13/81] now using micro-optparse --- Gemfile | 8 +++++--- bin/vpnmaker | 34 ++++++++++++++++++++++++++++------ lib/vpnmaker.rb | 2 +- 3 files changed, 34 insertions(+), 10 deletions(-) diff --git a/Gemfile b/Gemfile index 5f500a4..517320c 100644 --- a/Gemfile +++ b/Gemfile @@ -8,7 +8,7 @@ group :development do gem 'pry-syntax-hacks' #, :git => 'https://github.com/ConradIrwin/pry-syntax-hacks.git' gem 'pry-stack_explorer' #, :git => 'https://github.com/pry/pry-stack_explorer.git' gem 'pry-exception_explorer' #, :git => 'https://github.com/pry/pry-exception_explorer.git' - gem "rdoc", "~> 3.12" + gem "rdoc" #, "~> 3.12" gem "bundler" #, "~> 1.0.0" gem "jeweler" #, "~> 1.8.3" end @@ -17,9 +17,11 @@ gem 'ipaddr_extensions' #, :git => 'git://github.com/jamesotron/IPAddrExtensions.git' gem 'haml' -gem 'trollop' + +gem 'micro-optparse', :git => 'git://github.com/florianpilz/micro-optparse.git' + gem 'gibberish', :git => 'git://github.com/mdp/gibberish.git' -gem 'rubyzip', :git => 'git://github.com/aussiegeek/rubyzip.git' +# gem 'rubyzip', :git => 'git://github.com/aussiegeek/rubyzip.git' # gem 'slim' # gem 'slop', :git => 'git://github.com/injekt/slop.git' diff --git a/bin/vpnmaker b/bin/vpnmaker index d94baad..baa9ab1 100755 --- a/bin/vpnmaker +++ b/bin/vpnmaker @@ -1,11 +1,33 @@ #!/usr/bin/env ruby require_relative '../lib/vpnmaker.rb' -require 'trollop' +require 'micro-optparse' +#require 'trollop' -opts = Trollop::options do - version "vpnmaker 0.0.1 (c) Coolio" - banner "vpnmaker [options]" - opt :verbose, 'Enable verbose mode' +module VPNMaker + module CLI + class Options + + + def self.parse + Parser.new do |p| + p.version = "vpnmaker 0.0.1 (c) VoipScout" + p.banner = <<-EOS +VPNMaker is a Ruby library and a cli tool to manage OpenVPN CA, configs and users. It currently supports HAML templates and uses YAML filestore as database backend. + +Usage: + vpnmaker --prefix [dir.vpn] + +Example: + +Options: +EOS + p.option :verbose, 'Enable verbose mode', :default => false + p.option :prefix, 'Path to .vpn directory to work with', :default => "" + end.process! + end + end + end end -#raise Trollop::HelpNeeded if ARGV.empty? +options = VPNMaker::CLI::Options.parse +pp options diff --git a/lib/vpnmaker.rb b/lib/vpnmaker.rb index 85867dc..d6ef474 100644 --- a/lib/vpnmaker.rb +++ b/lib/vpnmaker.rb @@ -1,7 +1,7 @@ require 'rubygems' require 'gibberish' -require 'rubyzip' +# require 'rubyzip' require 'fileutils' require 'yaml' From e2dfc8ee2e63173fbeff0bc8f8aea3e7a84ed154 Mon Sep 17 00:00:00 2001 From: Voip Scout Date: Sun, 6 May 2012 17:36:49 +0200 Subject: [PATCH 14/81] some cli working --- bin/vpnmaker | 38 ++++++++++++++++++++++++++++++++------ lib/vpnmaker.rb | 13 +++++++------ 2 files changed, 39 insertions(+), 12 deletions(-) diff --git a/bin/vpnmaker b/bin/vpnmaker index baa9ab1..b89778a 100755 --- a/bin/vpnmaker +++ b/bin/vpnmaker @@ -6,8 +6,6 @@ require 'micro-optparse' module VPNMaker module CLI class Options - - def self.parse Parser.new do |p| p.version = "vpnmaker 0.0.1 (c) VoipScout" @@ -15,19 +13,47 @@ module VPNMaker VPNMaker is a Ruby library and a cli tool to manage OpenVPN CA, configs and users. It currently supports HAML templates and uses YAML filestore as database backend. Usage: - vpnmaker --prefix [dir.vpn] + vpnmaker --rootpath [/etc/openvpn/my_server.vpn] Example: Options: EOS p.option :verbose, 'Enable verbose mode', :default => false - p.option :prefix, 'Path to .vpn directory to work with', :default => "" + p.option :rootpath, '.vpn directory path, new will be created if not found', :default => "" + p.option :server, '[create|destroy]', :default => "" + p.option :client, '[create|destroy]', :default => "" end.process! end + end #class Options + + class Commands + + attr_reader :opts + attr_accessor :mgr + def initialize + @opts = VPNMaker::CLI::Options.parse + do_commands + end + + def do_commands + if File.directory?(@opts[:rootpath]) + @mgr = VPNMaker::Manager.new @opts[:rootpath] + puts @mgr.config_generator.server + else + conf_name = @opts[:rootpath].split('/').last.split('.').first + VPNMaker.generate conf_name, @opts[:rootpath].gsub("#{conf_name}.vpn", '') + FileUtils.mkdir_p("#{@opts[:rootpath]}/#{conf_name}_data") unless File.directory?("#{@opts[:rootpath]}/#{conf_name}_data") + # This is the time to display rbcurses stuff to the user, so + # we can setup our CA + @mgr = VPNMaker::Manager.new @opts[:rootpath] + @mgr.build_ca + puts @mgr.config + end + + end end end end -options = VPNMaker::CLI::Options.parse -pp options +VPNMaker::CLI::Commands.new diff --git a/lib/vpnmaker.rb b/lib/vpnmaker.rb index d6ef474..88628a7 100644 --- a/lib/vpnmaker.rb +++ b/lib/vpnmaker.rb @@ -32,12 +32,13 @@ def binding; super; end # normally private end module VPNMaker - autoload :ConfigGenerator, './vpnmaker/config_generator' - autoload :KeyDB, './vpnmaker/key_db' - autoload :KeyConfig, './vpnmaker/key_config' - autoload :KeyTracker, './vpnmaker/key_tracker' - autoload :Manager, './vpnmaker/manager' - autoload :KeyBuilder, './vpnmaker/key_builder' + path = __FILE__.gsub(File.basename(__FILE__), '') + autoload :ConfigGenerator, "#{path}vpnmaker/config_generator" + autoload :KeyDB, "#{path}vpnmaker/key_db" + autoload :KeyConfig, "#{path}vpnmaker/key_config" + autoload :KeyTracker, "#{path}vpnmaker/key_tracker" + autoload :Manager, "#{path}vpnmaker/manager" + autoload :KeyBuilder, "#{path}vpnmaker/key_builder" def self.generate(*args) KeyTracker.generate(args.first, args.last) From bfa93eea0a107792fa9bac7adaf6ad86646899d1 Mon Sep 17 00:00:00 2001 From: Voip Scout Date: Sun, 6 May 2012 22:59:00 +0200 Subject: [PATCH 15/81] intermittent --- Gemfile | 5 +++++ bin/vpnmaker | 1 - 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index 517320c..d30e75e 100644 --- a/Gemfile +++ b/Gemfile @@ -18,7 +18,12 @@ gem 'ipaddr_extensions' gem 'haml' +# cli stuff gem 'micro-optparse', :git => 'git://github.com/florianpilz/micro-optparse.git' +gem 'hashugar', :git => 'git://github.com/jsuchal/hashugar.git' +gem 'highline', :git => 'https://github.com/JEG2/highline.git' +#gem 'rbcurse-core', :git => 'git://github.com/rkumar/rbcurse-core.git' +#gem 'rbcurse-extras', :git => 'git://github.com/rkumar/rbcurse-extras.git' gem 'gibberish', :git => 'git://github.com/mdp/gibberish.git' # gem 'rubyzip', :git => 'git://github.com/aussiegeek/rubyzip.git' diff --git a/bin/vpnmaker b/bin/vpnmaker index b89778a..9796fb1 100755 --- a/bin/vpnmaker +++ b/bin/vpnmaker @@ -1,7 +1,6 @@ #!/usr/bin/env ruby require_relative '../lib/vpnmaker.rb' require 'micro-optparse' -#require 'trollop' module VPNMaker module CLI From a762e70e362eaea5d04e70aeb2262b39875e8dfc Mon Sep 17 00:00:00 2001 From: Voip Scout Date: Wed, 9 May 2012 00:45:44 +0200 Subject: [PATCH 16/81] decided finally on main.rb as optparser --- Gemfile | 4 +- bin/vpnmaker | 220 +++++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 183 insertions(+), 41 deletions(-) diff --git a/Gemfile b/Gemfile index d30e75e..433e821 100644 --- a/Gemfile +++ b/Gemfile @@ -20,8 +20,10 @@ gem 'haml' # cli stuff gem 'micro-optparse', :git => 'git://github.com/florianpilz/micro-optparse.git' +gem 'main', :git => 'git://github.com/ahoward/main.git' + gem 'hashugar', :git => 'git://github.com/jsuchal/hashugar.git' -gem 'highline', :git => 'https://github.com/JEG2/highline.git' +gem 'highline' #, :git => 'https://github.com/JEG2/highline.git' #gem 'rbcurse-core', :git => 'git://github.com/rkumar/rbcurse-core.git' #gem 'rbcurse-extras', :git => 'git://github.com/rkumar/rbcurse-extras.git' diff --git a/bin/vpnmaker b/bin/vpnmaker index 9796fb1..57665fd 100755 --- a/bin/vpnmaker +++ b/bin/vpnmaker @@ -1,58 +1,198 @@ #!/usr/bin/env ruby require_relative '../lib/vpnmaker.rb' -require 'micro-optparse' +#require 'micro-optparse' +#require 'highline' +require 'highline/import' +require 'main' +# vpnmaker init [path] +# vpnmaker server [create|destroy] --path [path] +# vpnmaker client [create|destroy|regenerate] [client_name] --path [path] +# vpnmaker cfg server --path [path] +# vpnmaker cfg client [name] --path [path] + +#TODO: use ~/.vpnmaker .vpnmaker and /etc/vpnmaker | maybe vpnmakerrc module VPNMaker module CLI class Options - def self.parse - Parser.new do |p| - p.version = "vpnmaker 0.0.1 (c) VoipScout" - p.banner = <<-EOS -VPNMaker is a Ruby library and a cli tool to manage OpenVPN CA, configs and users. It currently supports HAML templates and uses YAML filestore as database backend. - -Usage: - vpnmaker --rootpath [/etc/openvpn/my_server.vpn] - -Example: - -Options: -EOS - p.option :verbose, 'Enable verbose mode', :default => false - p.option :rootpath, '.vpn directory path, new will be created if not found', :default => "" - p.option :server, '[create|destroy]', :default => "" - p.option :client, '[create|destroy]', :default => "" - end.process! - end + # main DSL + Main do + version '0.0.1' + author 'Copyleft(cl) VoipScout - No rights reserved' + + mode('init') { + argument('arg1') {puts 'i am arg1'} + keyword('keywrd1') {puts 'keyword'} + option('opt1') {puts 'woop woop'} + environment('env1') {puts 'environ'} + + def run + puts "init run" + end + + + } + + mode('server') { + argument('server_config_fname') { + description "filename to save server configuration to" + argument :optional + cast :string + arity -1 + #TODO: highline, how to not crlf after #agree + validate {|fname| File.exist?(fname) ? agree("file exists, overwrite?") : true } + } + def run + puts "server run..." + puts "need to save fname=#{params['server_config_fname'].value}" if params['server_config_fname'].given? + end + } + + mode('client') { + # argument('new') {puts 'i am arg1'} + # keyword('keywrd1') {puts 'keyword'} + # option('opt1') {puts 'woop woop'} + # environment('FUCKER') { + # This reads ENV + # cast :string + # synopsis 'export FUCKER=value' + # } + + mode('list') { + description "ie. vpnmaker clients list all" + def run + pp db.users + end + } + + mode('config') { + } + + mode('create') { + keyword('passwd') { + argument :optional + cast :string + arity 1 + default 'passwd' + } + def run + params['client_name'].values.each_with_index do |c, i| + db.create_user(c, c, "#{c}@#{db.config[:key_properties][:email].split('@').last}", (params['passwd'].values[i])) + end +binding.pry + end + } + + mode('destroy') { + def run + + end + } + + mode('regenerate') { + } + + argument('client_name') { + argument :optional + arity -1 + cast :string + #synopsis 'client_name' + description "This is the basename of client certificate file" + # validate {|name| ? YAML.load_file(path) : {}} + } + + environment('VPNMAKER_DIR') { + required + arity 1 + cast :string + description "export VPNMAKER_DIR=\"/my/config/vpnmaker.vpn\"" + validate {|dir_name| File.directory?(dir_name)} + } + + def run + puts "client run" + end + + } + + # Global run() is overwritten by specific mode run + def run + puts "Hitting global run()" + params.each {|p| pp "#{p.class} - #{p.name} => #{p.value}"} + @opts = params + pp @opts + end + + def db + VPNMaker::Manager.new params['VPNMAKER_DIR'].value + end + + + end # + end #class Options - class Commands - attr_reader :opts - attr_accessor :mgr + class Menu + + attr_reader :cfg def initialize - @opts = VPNMaker::CLI::Options.parse - do_commands + menu end - def do_commands - if File.directory?(@opts[:rootpath]) - @mgr = VPNMaker::Manager.new @opts[:rootpath] - puts @mgr.config_generator.server - else - conf_name = @opts[:rootpath].split('/').last.split('.').first - VPNMaker.generate conf_name, @opts[:rootpath].gsub("#{conf_name}.vpn", '') - FileUtils.mkdir_p("#{@opts[:rootpath]}/#{conf_name}_data") unless File.directory?("#{@opts[:rootpath]}/#{conf_name}_data") - # This is the time to display rbcurses stuff to the user, so - # we can setup our CA - @mgr = VPNMaker::Manager.new @opts[:rootpath] - @mgr.build_ca - puts @mgr.config + def menu + say("\nDo you have a yaml file to use as initial config?") + choose do |menu| + menu.layout = :one_line + # menu.index = :letter + # menu.prompt = 'Y/N?' + menu.choice(:yes) do |cmd, details| + ask_for_file_location + end + menu.choice(:no) do ask_for_config_values end end + end + + def ask_for_file_location + path = ask("Please enter the full path") + @cfg = File.exist?(path) ? YAML.load_file(path) : say('File not found') + end + def ask_for_config_values + @cfg = ask('Going to take some info now', ) do |q| + end end - end + end #class Menu + + # class Commands + + # attr_reader :opts + # attr_accessor :mgr + # def initialize + # @opts = VPNMaker::CLI::Options.parse + # do_commands + # end + + # def do_commands + # if File.directory?(@opts[:rootpath]) + # @mgr = VPNMaker::Manager.new @opts[:rootpath] + # puts @mgr.config_generator.server + # else + # conf_name = @opts[:rootpath].split('/').last.split('.').first + # VPNMaker.generate conf_name, @opts[:rootpath].gsub("#{conf_name}.vpn", '') + # FileUtils.mkdir_p("#{@opts[:rootpath]}/#{conf_name}_data") unless File.directory?("#{@opts[:rootpath]}/#{conf_name}_data") + # # This is the time to ask a few questions, + # # so we can setup our CA + # File.open("#{@opts[:rootpath]}/#{conf_name}.config.yaml", 'w') {|f| f.write(Menu.new.cfg.to_yaml)} + # @mgr = VPNMaker::Manager.new @opts[:rootpath] + # @mgr.build_ca + # pp @mgr.config + # end + # end + # end #class Commands + end end -VPNMaker::CLI::Commands.new +#VPNMaker::CLI::Commands.new +VPNMaker::CLI::Options.new From 4494c65ba446f8c00964caa39c4e83ddbb5270bd Mon Sep 17 00:00:00 2001 From: Voip Scout Date: Wed, 9 May 2012 03:55:09 +0200 Subject: [PATCH 17/81] client, init cli work --- bin/vpnmaker | 124 +++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 106 insertions(+), 18 deletions(-) diff --git a/bin/vpnmaker b/bin/vpnmaker index 57665fd..9b252bc 100755 --- a/bin/vpnmaker +++ b/bin/vpnmaker @@ -14,6 +14,25 @@ require 'main' #TODO: use ~/.vpnmaker .vpnmaker and /etc/vpnmaker | maybe vpnmakerrc module VPNMaker module CLI + module RFC822 + EmailAddress = begin + qtext = '[^\\x0d\\x22\\x5c\\x80-\\xff]' + dtext = '[^\\x0d\\x5b-\\x5d\\x80-\\xff]' + atom = '[^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-' + + '\\x3c\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+' + quoted_pair = '\\x5c[\\x00-\\x7f]' + domain_literal = "\\x5b(?:#{dtext}|#{quoted_pair})*\\x5d" + quoted_string = "\\x22(?:#{qtext}|#{quoted_pair})*\\x22" + domain_ref = atom + sub_domain = "(?:#{domain_ref}|#{domain_literal})" + word = "(?:#{atom}|#{quoted_string})" + domain = "#{sub_domain}(?:\\x2e#{sub_domain})*" + local_part = "#{word}(?:\\x2e#{word})*" + addr_spec = "#{local_part}\\x40#{domain}" + pattern = /\A#{addr_spec.force_encoding('ASCII-8BIT')}\z/ + end + end + class Options # main DSL Main do @@ -21,16 +40,71 @@ module VPNMaker author 'Copyleft(cl) VoipScout - No rights reserved' mode('init') { - argument('arg1') {puts 'i am arg1'} - keyword('keywrd1') {puts 'keyword'} - option('opt1') {puts 'woop woop'} - environment('env1') {puts 'environ'} + mode('cli') { + argument('country') { + required + cast :string + arity 1 + } + argument('province') { + required + cast :string + arity 1 + } + argument('city') { + required + cast :string + arity 1 + } + argument('organization') { + required + cast :string + arity 1 + } + argument('email') { + required + cast :string + arity 1 + validate {|e| e =~ RFC822::EmailAddress} + } + + } #mode 'cli' + argument('conf_name') { + required + cast :string + arity 1 + } + argument('new_dir_path') { + required + cast :string + arity 1 + validate {|dir| File.directory?(dir)} + } def run - puts "init run" + name = params['conf_name'].value + dir = params['new_dir_path'].value + VPNMaker.generate name, dir + FileUtils.mkdir_p(File.expand_path(dir) + "/" + name + ".vpn" + "/" + name + "_data") + + if params['email'].given? + initial_config = { + :key_properties => { + :country => params['country'].value, + :province => params['province'].value, + :city => params['city'].value, + :organization => params['organization'].value, + :email => params['email'].value + } + } + File.open((File.expand_path(dir) + "/" + name + ".vpn" + "/" + name + ".config.yaml"), 'w') {|f| f.write(initial_config.to_yaml)} + mgr = VPNMaker::Manager.new((File.expand_path(dir) + "/" + name + ".vpn")) + mgr.build_ca + else + say('Time to mod yaml files') + # File.open("#{@opts[:rootpath]}/#{conf_name}.config.yaml", 'w') {|f| f.write(Menu.new.cfg.to_yaml)} + end end - - } mode('server') { @@ -49,14 +123,6 @@ module VPNMaker } mode('client') { - # argument('new') {puts 'i am arg1'} - # keyword('keywrd1') {puts 'keyword'} - # option('opt1') {puts 'woop woop'} - # environment('FUCKER') { - # This reads ENV - # cast :string - # synopsis 'export FUCKER=value' - # } mode('list') { description "ie. vpnmaker clients list all" @@ -75,21 +141,43 @@ module VPNMaker arity 1 default 'passwd' } + def run params['client_name'].values.each_with_index do |c, i| - db.create_user(c, c, "#{c}@#{db.config[:key_properties][:email].split('@').last}", (params['passwd'].values[i])) + db.create_user(c, c, "#{c}@#{db.config[:key_properties][:email].split('@').last}", (params['passwd'].values[i])) if db.users.select {|r| r =~ /#{c}/}.empty? end -binding.pry end } mode('destroy') { + option('all') { + argument :optional + cast :bool + } def run - + if params['all'].value + db.users.each {|u| db.delete_user(u)} unless db.users.size == 0 + else + params['client_name'].values.each do |c| + db.delete_user(c) unless !db.user(c) + end + end end } mode('regenerate') { + keyword('passwd') { + argument :optional + cast :string + arity 1 + default 'passwd' + } + + def run + params['client_name'].values.each_with_index do |c, i| + db.regenerate_user(c, params['passwd'].values[i]) + end + end } argument('client_name') { From f5fab3d3a0a2e44835f7f4a67865ddcc2c22566e Mon Sep 17 00:00:00 2001 From: Voip Scout Date: Wed, 9 May 2012 04:59:03 +0200 Subject: [PATCH 18/81] all client, init. strange things happen though... --- bin/vpnmaker | 96 +++++++++------------------------------------------- 1 file changed, 16 insertions(+), 80 deletions(-) diff --git a/bin/vpnmaker b/bin/vpnmaker index 9b252bc..f20529d 100755 --- a/bin/vpnmaker +++ b/bin/vpnmaker @@ -5,12 +5,6 @@ require_relative '../lib/vpnmaker.rb' require 'highline/import' require 'main' -# vpnmaker init [path] -# vpnmaker server [create|destroy] --path [path] -# vpnmaker client [create|destroy|regenerate] [client_name] --path [path] -# vpnmaker cfg server --path [path] -# vpnmaker cfg client [name] --path [path] - #TODO: use ~/.vpnmaker .vpnmaker and /etc/vpnmaker | maybe vpnmakerrc module VPNMaker module CLI @@ -79,7 +73,7 @@ module VPNMaker required cast :string arity 1 - validate {|dir| File.directory?(dir)} + validate {|dir| File.directory?(File.expand_path(dir))} } def run name = params['conf_name'].value @@ -102,7 +96,6 @@ module VPNMaker mgr.build_ca else say('Time to mod yaml files') - # File.open("#{@opts[:rootpath]}/#{conf_name}.config.yaml", 'w') {|f| f.write(Menu.new.cfg.to_yaml)} end end } @@ -125,9 +118,10 @@ module VPNMaker mode('client') { mode('list') { - description "ie. vpnmaker clients list all" + description "ie. vpnmaker clients list" def run - pp db.users + pp db.users.select {|u| !db.user(u)[:revoked].include?(db.user(u)[:active_key])} + # db.users.each{|u| puts db.user(u)} end } @@ -144,7 +138,8 @@ module VPNMaker def run params['client_name'].values.each_with_index do |c, i| - db.create_user(c, c, "#{c}@#{db.config[:key_properties][:email].split('@').last}", (params['passwd'].values[i])) if db.users.select {|r| r =~ /#{c}/}.empty? + passwd = params['passwd'].values[i] ? params['passwd'].values[i] : params['passwd'].default + db.create_user(c, c, "#{c}@#{db.config[:key_properties][:email].split('@').last}", passwd) if db.users.select {|r| r =~ /#{c}/}.empty? end end } @@ -175,7 +170,8 @@ module VPNMaker def run params['client_name'].values.each_with_index do |c, i| - db.regenerate_user(c, params['passwd'].values[i]) + passwd = params['passwd'].values[i] ? params['passwd'].values[i] : params['passwd'].default + db.regenerate_user(c, passwd) end end } @@ -185,16 +181,16 @@ module VPNMaker arity -1 cast :string #synopsis 'client_name' - description "This is the basename of client certificate file" + description "username" # validate {|name| ? YAML.load_file(path) : {}} } - - environment('VPNMAKER_DIR') { + # environment('VPNMAKER_DIR') + keyword('dir') { required arity 1 cast :string - description "export VPNMAKER_DIR=\"/my/config/vpnmaker.vpn\"" - validate {|dir_name| File.directory?(dir_name)} + description "ie. /my/config/vpnmaker.vpn" + validate {|dir_name| File.directory?(File.expand_path(dir_name))} } def run @@ -212,7 +208,7 @@ module VPNMaker end def db - VPNMaker::Manager.new params['VPNMAKER_DIR'].value + VPNMaker::Manager.new params['dir'].value end @@ -220,67 +216,7 @@ module VPNMaker end #class Options + end #module CLI +end #module VPNMaker - class Menu - - attr_reader :cfg - def initialize - menu - end - - def menu - say("\nDo you have a yaml file to use as initial config?") - choose do |menu| - menu.layout = :one_line - # menu.index = :letter - # menu.prompt = 'Y/N?' - menu.choice(:yes) do |cmd, details| - ask_for_file_location - end - menu.choice(:no) do ask_for_config_values end - end - end - - def ask_for_file_location - path = ask("Please enter the full path") - @cfg = File.exist?(path) ? YAML.load_file(path) : say('File not found') - end - - def ask_for_config_values - @cfg = ask('Going to take some info now', ) do |q| - end - end - end #class Menu - - # class Commands - - # attr_reader :opts - # attr_accessor :mgr - # def initialize - # @opts = VPNMaker::CLI::Options.parse - # do_commands - # end - - # def do_commands - # if File.directory?(@opts[:rootpath]) - # @mgr = VPNMaker::Manager.new @opts[:rootpath] - # puts @mgr.config_generator.server - # else - # conf_name = @opts[:rootpath].split('/').last.split('.').first - # VPNMaker.generate conf_name, @opts[:rootpath].gsub("#{conf_name}.vpn", '') - # FileUtils.mkdir_p("#{@opts[:rootpath]}/#{conf_name}_data") unless File.directory?("#{@opts[:rootpath]}/#{conf_name}_data") - # # This is the time to ask a few questions, - # # so we can setup our CA - # File.open("#{@opts[:rootpath]}/#{conf_name}.config.yaml", 'w') {|f| f.write(Menu.new.cfg.to_yaml)} - # @mgr = VPNMaker::Manager.new @opts[:rootpath] - # @mgr.build_ca - # pp @mgr.config - # end - # end - # end #class Commands - - end -end - -#VPNMaker::CLI::Commands.new VPNMaker::CLI::Options.new From 8b2212051532457178f820b5291e2e1d20c06401 Mon Sep 17 00:00:00 2001 From: Voip Scout Date: Wed, 9 May 2012 18:19:08 +0200 Subject: [PATCH 19/81] fixed annoying data_dir bug --- Gemfile | 7 +------ lib/vpnmaker/key_db.rb | 2 +- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/Gemfile b/Gemfile index 433e821..b95d987 100644 --- a/Gemfile +++ b/Gemfile @@ -17,18 +17,13 @@ gem 'ipaddr_extensions' #, :git => 'git://github.com/jamesotron/IPAddrExtensions.git' gem 'haml' - -# cli stuff -gem 'micro-optparse', :git => 'git://github.com/florianpilz/micro-optparse.git' gem 'main', :git => 'git://github.com/ahoward/main.git' gem 'hashugar', :git => 'git://github.com/jsuchal/hashugar.git' gem 'highline' #, :git => 'https://github.com/JEG2/highline.git' + #gem 'rbcurse-core', :git => 'git://github.com/rkumar/rbcurse-core.git' #gem 'rbcurse-extras', :git => 'git://github.com/rkumar/rbcurse-extras.git' gem 'gibberish', :git => 'git://github.com/mdp/gibberish.git' # gem 'rubyzip', :git => 'git://github.com/aussiegeek/rubyzip.git' -# gem 'slim' - -# gem 'slop', :git => 'git://github.com/injekt/slop.git' diff --git a/lib/vpnmaker/key_db.rb b/lib/vpnmaker/key_db.rb index c6cf77f..51383af 100644 --- a/lib/vpnmaker/key_db.rb +++ b/lib/vpnmaker/key_db.rb @@ -44,7 +44,7 @@ def disk_version def sync if disk_version == @db[:version] if @touched - FileUtils.mkdir_p(self.datadir) + FileUtils.mkdir_p(File.dirname(@path) + "/" + self.datadir) @db[:version] += 1 File.open(@path, 'w') {|f| f.write(@db.to_yaml)} true From 64e9bf45e7c74565fd6d4d14c938798543b8d415 Mon Sep 17 00:00:00 2001 From: Voip Scout Date: Wed, 9 May 2012 19:58:03 +0200 Subject: [PATCH 20/81] intermittent --- bin/vpnmaker | 12 ++++++++- .../example_vpnmaker_site.config.yaml | 26 ++++++++++--------- 2 files changed, 25 insertions(+), 13 deletions(-) rename foocorp.config.yaml => lib/example_vpnmaker_site.config.yaml (65%) diff --git a/bin/vpnmaker b/bin/vpnmaker index f20529d..ac1fbd7 100755 --- a/bin/vpnmaker +++ b/bin/vpnmaker @@ -79,7 +79,12 @@ module VPNMaker name = params['conf_name'].value dir = params['new_dir_path'].value VPNMaker.generate name, dir - FileUtils.mkdir_p(File.expand_path(dir) + "/" + name + ".vpn" + "/" + name + "_data") + data_dir = (File.expand_path(dir) + "/" + name + ".vpn" + "/" + name + "_data") + template_dir = (File.expand_path(dir) + "/" + name + ".vpn" + "/" + name + "_templates") + client_config_dir = (File.expand_path(dir) + "/" + name + ".vpn" + "/" + name + "_client_configs") + + [data_dir, template_dir, client_config_dir].each {|dir| FileUtils.mkdir_p(dir)} + FileUtils.cp Dir.glob(File.dirname(File.expand_path __FILE__).gsub('/bin', '/lib') + "/*.haml"), template_dir if params['email'].given? initial_config = { @@ -89,6 +94,11 @@ module VPNMaker :city => params['city'].value, :organization => params['organization'].value, :email => params['email'].value + }, + :site_vpnmaker => { + :data_dir => data_dir.split('/').last, + :template_dir => template_dir.split('/').last, + :client_conf_dir => client_config_dir.split('/').last } } File.open((File.expand_path(dir) + "/" + name + ".vpn" + "/" + name + ".config.yaml"), 'w') {|f| f.write(initial_config.to_yaml)} diff --git a/foocorp.config.yaml b/lib/example_vpnmaker_site.config.yaml similarity index 65% rename from foocorp.config.yaml rename to lib/example_vpnmaker_site.config.yaml index 5f28a0f..6d5667a 100644 --- a/foocorp.config.yaml +++ b/lib/example_vpnmaker_site.config.yaml @@ -1,24 +1,26 @@ +--- +:key_properties: + :country: US + :province: CA + :city: San Francisco + :organization: myorg + :email: security@my.org + :server: - :base_ip: 10.10.10.0 + :base_ip: 10.10.10.0/24 :bridgednets: # real networks to bridge via the VPN server - - 172.16.0.0 + - 172.16.0.0/24 :subnets: # subnets that exist only on the VPN - - 10.10.11.0 + - 10.10.11.0/8 + - 10.11.2.0/24 :user: nobody :group: nogroup - :root: /root/openvpn + :root: /etc/openvpn :log: /var/log/openvpn.log - :host: vpn.foocorp.com + :host: staging.pvstream.in :port: 1194 :client: :subnet: 172.16.0.0 :local_endpoint: 10.10.10.100 :remote_endpoint: 10.10.10.1 - -:key_properties: - :country: US - :province: CA - :city: San Francisco - :organization: FooCorp Inc - :email: sec@foocorp.com From e5529e7e619d3b4ddff63aad335c95459cd228e0 Mon Sep 17 00:00:00 2001 From: Voip Scout Date: Wed, 9 May 2012 20:36:52 +0200 Subject: [PATCH 21/81] init now created templates in .vpn dir --- bin/vpnmaker | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/bin/vpnmaker b/bin/vpnmaker index ac1fbd7..d1b0fb6 100755 --- a/bin/vpnmaker +++ b/bin/vpnmaker @@ -78,13 +78,16 @@ module VPNMaker def run name = params['conf_name'].value dir = params['new_dir_path'].value + VPNMaker.generate name, dir + data_dir = (File.expand_path(dir) + "/" + name + ".vpn" + "/" + name + "_data") template_dir = (File.expand_path(dir) + "/" + name + ".vpn" + "/" + name + "_templates") client_config_dir = (File.expand_path(dir) + "/" + name + ".vpn" + "/" + name + "_client_configs") [data_dir, template_dir, client_config_dir].each {|dir| FileUtils.mkdir_p(dir)} - FileUtils.cp Dir.glob(File.dirname(File.expand_path __FILE__).gsub('/bin', '/lib') + "/*.haml"), template_dir + lib_dir = File.dirname(File.expand_path __FILE__).gsub('/bin', '/lib') + FileUtils.cp Dir.glob(lib_dir + "/*.haml"), template_dir if params['email'].given? initial_config = { @@ -101,9 +104,11 @@ module VPNMaker :client_conf_dir => client_config_dir.split('/').last } } - File.open((File.expand_path(dir) + "/" + name + ".vpn" + "/" + name + ".config.yaml"), 'w') {|f| f.write(initial_config.to_yaml)} + example_config = YAML.load_file(lib_dir + "/example_vpnmaker_site.config.yaml").to_yaml.gsub(/\n|---/, "\n# ") + File.open((File.expand_path(dir) + "/" + name + ".vpn" + "/" + name + ".config.yaml"), 'w') {|f| f.write(initial_config.to_yaml + example_config)} mgr = VPNMaker::Manager.new((File.expand_path(dir) + "/" + name + ".vpn")) mgr.build_ca + say("Please edit files in #{template_dir} and #{dir}/#{name}.vpn/#{name}.config.yaml before proceeding further") else say('Time to mod yaml files') end From f43a33d7bb1b5516107cbe47a954d235951bc724 Mon Sep 17 00:00:00 2001 From: Voip Scout Date: Wed, 9 May 2012 23:50:14 +0200 Subject: [PATCH 22/81] server config generator baby steps --- bin/vpnmaker | 23 +++++++++++++++++-- lib/server.haml | 38 +++++++++++++++++++++++++++----- lib/vpnmaker.rb | 3 ++- lib/vpnmaker/config_generator.rb | 28 ++++++++++++++++++----- lib/vpnmaker/key_builder.rb | 2 +- lib/vpnmaker/key_tracker.rb | 2 ++ lib/vpnmaker/manager.rb | 2 +- 7 files changed, 82 insertions(+), 16 deletions(-) diff --git a/bin/vpnmaker b/bin/vpnmaker index d1b0fb6..8aea903 100755 --- a/bin/vpnmaker +++ b/bin/vpnmaker @@ -98,7 +98,7 @@ module VPNMaker :organization => params['organization'].value, :email => params['email'].value }, - :site_vpnmaker => { + :site => { :data_dir => data_dir.split('/').last, :template_dir => template_dir.split('/').last, :client_conf_dir => client_config_dir.split('/').last @@ -116,7 +116,25 @@ module VPNMaker } mode('server') { - argument('server_config_fname') { + mode('build') { + def run + db.build_server + end + } + mode('config') { + def run + puts db.config_generator.server + end + } + keyword('dir') { + required + arity 1 + cast :string + description "ie. /my/config/vpnmaker.vpn" + validate {|dir_name| File.directory?(File.expand_path(dir_name))} + } + + argument('server_config_name') { description "filename to save server configuration to" argument :optional cast :string @@ -125,6 +143,7 @@ module VPNMaker validate {|fname| File.exist?(fname) ? agree("file exists, overwrite?") : true } } def run + puts "server run..." puts "need to save fname=#{params['server_config_fname'].value}" if params['server_config_fname'].given? end diff --git a/lib/server.haml b/lib/server.haml index b58d65f..f0e306a 100644 --- a/lib/server.haml +++ b/lib/server.haml @@ -20,11 +20,38 @@ server #{base_ip[:net]} #{base_ip[:mask]} \ user #{user} group #{group} -dh #{root}/keys/dh.pem -ca #{root}/keys/ca.crt -cert #{root}/keys/server.crt -key #{root}/keys/server.key -crl-verify #{root}/keys/crl.pem +- if type == :default + + + #{dh} + + + + #{ca} + + + + #{cert} + + + + #{key} + + + + #{crl} + + + + #{ta} + + +- else + dh #{root}/keys/dh.pem + ca #{root}/keys/ca.crt + cert #{root}/keys/server.crt + key #{root}/keys/server.key + crl-verify #{root}/keys/crl.pem keepalive 10 120 @@ -34,5 +61,4 @@ persist-tun persist-key tls-auth #{root}/keys/ta.key 0 -client-config-dir #{root}/ccd :plain diff --git a/lib/vpnmaker.rb b/lib/vpnmaker.rb index 88628a7..0aed0d1 100644 --- a/lib/vpnmaker.rb +++ b/lib/vpnmaker.rb @@ -32,7 +32,8 @@ def binding; super; end # normally private end module VPNMaker - path = __FILE__.gsub(File.basename(__FILE__), '') + path = (File.dirname File.expand_path(__FILE__)) + "/" + autoload :ConfigGenerator, "#{path}vpnmaker/config_generator" autoload :KeyDB, "#{path}vpnmaker/key_db" autoload :KeyConfig, "#{path}vpnmaker/key_config" diff --git a/lib/vpnmaker/config_generator.rb b/lib/vpnmaker/config_generator.rb index 58ef095..307c8fb 100644 --- a/lib/vpnmaker/config_generator.rb +++ b/lib/vpnmaker/config_generator.rb @@ -1,9 +1,22 @@ module VPNMaker class ConfigGenerator - def initialize(mgr) - @mgr = mgr + def initialize(*args) + @mgr = args.shift.first + args.empty? ? (@runtime_cfg = default_template) : (@runtime_cfg = args.shift) end + def default_template + dirname = (@mgr.tracker.path + "/" + @mgr.config[:site][:data_dir]) + { + :type => :default, + :dh => File.read(dirname + "/dh.pem"), + :ca => File.read(dirname + "/ca.crt"), + :cert => File.read(dirname + "/server.crt"), + :key => File.read(dirname + "/server.key"), + :crl => File.read(dirname + "/crl.pem"), + :ta => File.read(dirname + "/ta.key") + } + end def client_conf(client) { :gen_host => Socket.gethostname, @@ -15,7 +28,7 @@ def client_conf(client) def server_conf { :gen_host => Socket.gethostname - }.merge(@mgr.config[:server]) + }.merge(@mgr.config[:server]).merge(@runtime_cfg) end def server @@ -23,13 +36,18 @@ def server haml_vars[:base_ip] = ((a = IPAddr.new haml_vars[:base_ip]); {:net => a.to_s, :mask => a.subnet_mask.to_s}) haml_vars[:bridgednets] = haml_vars[:bridgednets].map {|net| a = (IPAddr.new net); {:net => a.to_s, :mask => a.subnet_mask.to_s}} haml_vars[:subnets] = haml_vars[:subnets].map {|net| a = (IPAddr.new net); {:net => a.to_s, :mask => a.subnet_mask.to_s}} - template = File.read(__FILE__.path('server.haml')) + template = File.read(@mgr.tracker.path + \ + "/" + @mgr.config[:site][:template_dir] + \ + "/" + 'server.haml') Haml::Engine.new(template).render(Object.new, haml_vars) end def client(client) haml_vars = client_conf(client).dup - template = File.read(__FILE__.path('client.haml')) + template = File.read(@mgr.tracker.path + \ + "/" + @mgr.config[:site][:template_dir] + \ + "/" + 'client.haml') + # template = File.read(__FILE__.path('client.haml')) Haml::Engine.new(template).render(Object.new, haml_vars) end end diff --git a/lib/vpnmaker/key_builder.rb b/lib/vpnmaker/key_builder.rb index bf84988..e4ae6a0 100644 --- a/lib/vpnmaker/key_builder.rb +++ b/lib/vpnmaker/key_builder.rb @@ -39,7 +39,7 @@ def opensslcnf(hash={}) c = cnfpath File.open(cnfpath, 'w') do |f| - f.write(Haml::Engine.new(File.read __FILE__.path('openssl.haml')).render(Object.new, opensslvars.merge(hash))) + f.write(Haml::Engine.new(File.read(@tracker.path + "/" + @config[:site][:template_dir] + "/" + 'openssl.haml')).render(Object.new, opensslvars.merge(hash))) end c diff --git a/lib/vpnmaker/key_tracker.rb b/lib/vpnmaker/key_tracker.rb index 0e5780c..edab3e7 100644 --- a/lib/vpnmaker/key_tracker.rb +++ b/lib/vpnmaker/key_tracker.rb @@ -3,6 +3,7 @@ class KeyTracker attr_reader :builder attr_reader :db attr_reader :config + attr_reader :path def self.generate(name, path=nil) path ||= '/tmp' @@ -146,6 +147,7 @@ def user(user) def users; @db[:users]; end def initialize(name, dir) + @path = dir @db = KeyDB.new(File.join(dir, name + '.db.yaml')) @config = KeyConfig.new(File.join(dir, name + '.config.yaml')) @builder = KeyBuilder.new(self, @config) diff --git a/lib/vpnmaker/manager.rb b/lib/vpnmaker/manager.rb index 763f3fa..f8552ec 100644 --- a/lib/vpnmaker/manager.rb +++ b/lib/vpnmaker/manager.rb @@ -50,6 +50,6 @@ def user(user) @tracker.user(user) end - def config_generator; ConfigGenerator.new(self); end + def config_generator(*args); ConfigGenerator.new([self] + args); end end end From 177b0e7f4b5b1a0b5d0e4b2cf8c5445f074ef043 Mon Sep 17 00:00:00 2001 From: Voip Scout Date: Thu, 10 May 2012 00:38:04 +0200 Subject: [PATCH 23/81] intermittent --- bin/vpnmaker | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/bin/vpnmaker b/bin/vpnmaker index 8aea903..d4d5d0f 100755 --- a/bin/vpnmaker +++ b/bin/vpnmaker @@ -119,6 +119,7 @@ module VPNMaker mode('build') { def run db.build_server + say('Please edit your config.yaml if you haven\'t done so yet') end } mode('config') { @@ -160,6 +161,11 @@ module VPNMaker } mode('config') { + def run + params['client_name'].values.each do |c| + puts db.config_generator.client(db.user(c)) + end + end } mode('create') { From f19d3888070e302c01f18f69247e47d53050a130 Mon Sep 17 00:00:00 2001 From: Voip Scout Date: Thu, 10 May 2012 01:23:28 +0200 Subject: [PATCH 24/81] client|server config|build seem to work --- lib/client.haml | 58 +++++++++++++++++++++++++++----- lib/vpnmaker/config_generator.rb | 18 +++++----- 2 files changed, 58 insertions(+), 18 deletions(-) diff --git a/lib/client.haml b/lib/client.haml index 9aa98c5..45c2b12 100644 --- a/lib/client.haml +++ b/lib/client.haml @@ -1,13 +1,53 @@ +client +dev tun +proto udp remote #{server[:host]} #{server[:port]} udp +remote-random +resolv-retry infinite +nobind persist-key -tls-client -tls-auth ta.key 1 -pull -ca ca.crt -dev tun persist-tun -cert #{user}-#{(revoked.max || - 1) + 1}.crt -nobind -key #{user}-#{(revoked.max || - 1) + 1}.key -remote-cert-tls server +\# +\#tls-remote must equal CN of ca in the hosts x509 +\# +tls-remote #{server[:host]} + +float +cipher AES-256-CBC +comp-lzo +verb 3 +ping 30 + +- if type == :default + + #{dh} + + + + #{ca} + + + + #{cert} + + + + #{key} + + + + #{ta} + + +- else + tls-client + tls-auth ta.key 1 + pull + ca ca.crt + dev tun + persist-tun + cert #{user}-#{(revoked.max || - 1) + 1}.crt + nobind + key #{user}-#{(revoked.max || - 1) + 1}.key + remote-cert-tls server :plain diff --git a/lib/vpnmaker/config_generator.rb b/lib/vpnmaker/config_generator.rb index 307c8fb..9c8c80f 100644 --- a/lib/vpnmaker/config_generator.rb +++ b/lib/vpnmaker/config_generator.rb @@ -6,15 +6,12 @@ def initialize(*args) end def default_template - dirname = (@mgr.tracker.path + "/" + @mgr.config[:site][:data_dir]) + @dirname = (@mgr.tracker.path + "/" + @mgr.config[:site][:data_dir]) { :type => :default, - :dh => File.read(dirname + "/dh.pem"), - :ca => File.read(dirname + "/ca.crt"), - :cert => File.read(dirname + "/server.crt"), - :key => File.read(dirname + "/server.key"), - :crl => File.read(dirname + "/crl.pem"), - :ta => File.read(dirname + "/ta.key") + :dh => File.read(@dirname + "/dh.pem"), + :ca => File.read(@dirname + "/ca.crt"), + :ta => File.read(@dirname + "/ta.key") } end def client_conf(client) @@ -22,13 +19,16 @@ def client_conf(client) :gen_host => Socket.gethostname, :server => @mgr.config[:server], :client => @mgr.config[:client] - }.merge(client) + }.merge(client).merge(:key => File.read(@dirname + "/#{client[:user]}-#{(client[:revoked].max || - 1) + 1}.key" ), + :cert => File.read(@dirname + "/#{client[:user]}-#{(client[:revoked].max || - 1) + 1}.crt")).merge(@runtime_cfg) end def server_conf { :gen_host => Socket.gethostname - }.merge(@mgr.config[:server]).merge(@runtime_cfg) + }.merge(@mgr.config[:server]).merge(@runtime_cfg).merge(:key => File.read(@dirname + "/server.key"), + :cert => File.read(@dirname + "/server.crt"), + :crl => File.read(@dirname + "/crl.pem")) end def server From cd90ec197fca64f264aa947a54db6a8b7af31d70 Mon Sep 17 00:00:00 2001 From: Voip Scout Date: Thu, 10 May 2012 01:26:00 +0200 Subject: [PATCH 25/81] Version bump to 1.0.0 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index bd52db8..afaf360 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.0.0 \ No newline at end of file +1.0.0 \ No newline at end of file From dda5fc799a7eecd7d6bc8f1e1772c7ab48bcd15e Mon Sep 17 00:00:00 2001 From: Voip Scout Date: Thu, 10 May 2012 01:27:25 +0200 Subject: [PATCH 26/81] gemfile fixes before release --- Gemfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile b/Gemfile index b95d987..1764779 100644 --- a/Gemfile +++ b/Gemfile @@ -19,11 +19,11 @@ gem 'ipaddr_extensions' gem 'haml' gem 'main', :git => 'git://github.com/ahoward/main.git' -gem 'hashugar', :git => 'git://github.com/jsuchal/hashugar.git' +#gem 'hashugar', :git => 'git://github.com/jsuchal/hashugar.git' gem 'highline' #, :git => 'https://github.com/JEG2/highline.git' #gem 'rbcurse-core', :git => 'git://github.com/rkumar/rbcurse-core.git' #gem 'rbcurse-extras', :git => 'git://github.com/rkumar/rbcurse-extras.git' -gem 'gibberish', :git => 'git://github.com/mdp/gibberish.git' +# gem 'gibberish', :git => 'git://github.com/mdp/gibberish.git' # gem 'rubyzip', :git => 'git://github.com/aussiegeek/rubyzip.git' From 525a8c30be7ffbc49f88f08a87e7ad5ad7f7682a Mon Sep 17 00:00:00 2001 From: Voip Scout Date: Thu, 10 May 2012 01:39:24 +0200 Subject: [PATCH 27/81] Regenerate gemspec for version 1.0.0 --- vpnmaker.gemspec | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/vpnmaker.gemspec b/vpnmaker.gemspec index f89d214..78051ef 100644 --- a/vpnmaker.gemspec +++ b/vpnmaker.gemspec @@ -5,11 +5,11 @@ Gem::Specification.new do |s| s.name = "vpnmaker" - s.version = "0.0.0" + s.version = "1.0.0" s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= s.authors = ["Voip Scout"] - s.date = "2012-05-06" + s.date = "2012-05-09" s.description = "haml templates and key tracking" s.email = "voipscout@gmail.com" s.executables = ["vpnmaker"] @@ -23,8 +23,8 @@ Gem::Specification.new do |s| "Rakefile", "VERSION", "bin/vpnmaker", - "foocorp.config.yaml", "lib/client.haml", + "lib/example_vpnmaker_site.config.yaml", "lib/openssl.haml", "lib/server.haml", "lib/vpnmaker.rb", @@ -48,9 +48,8 @@ Gem::Specification.new do |s| if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then s.add_runtime_dependency(%q, [">= 0"]) s.add_runtime_dependency(%q, [">= 0"]) - s.add_runtime_dependency(%q, [">= 0"]) - s.add_runtime_dependency(%q, [">= 0"]) - s.add_runtime_dependency(%q, [">= 0"]) + s.add_runtime_dependency(%q
, [">= 0"]) + s.add_runtime_dependency(%q, [">= 0"]) s.add_development_dependency(%q, [">= 0"]) s.add_development_dependency(%q, [">= 0"]) s.add_development_dependency(%q, [">= 0"]) @@ -58,15 +57,14 @@ Gem::Specification.new do |s| s.add_development_dependency(%q, [">= 0"]) s.add_development_dependency(%q, [">= 0"]) s.add_development_dependency(%q, [">= 0"]) - s.add_development_dependency(%q, ["~> 3.12"]) + s.add_development_dependency(%q, [">= 0"]) s.add_development_dependency(%q, [">= 0"]) s.add_development_dependency(%q, [">= 0"]) else s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q
, [">= 0"]) + s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) @@ -74,16 +72,15 @@ Gem::Specification.new do |s| s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, ["~> 3.12"]) + s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) end else s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q
, [">= 0"]) + s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) @@ -91,7 +88,7 @@ Gem::Specification.new do |s| s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, ["~> 3.12"]) + s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) end From eee5a6bf2db8b89144a65fe1efbaaca28f932543 Mon Sep 17 00:00:00 2001 From: Voip Scout Date: Thu, 10 May 2012 02:37:52 +0200 Subject: [PATCH 28/81] fixed something in config gen --- Gemfile | 4 ++-- lib/vpnmaker/config_generator.rb | 9 +++++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/Gemfile b/Gemfile index 1764779..bd188d9 100644 --- a/Gemfile +++ b/Gemfile @@ -25,5 +25,5 @@ gem 'highline' #, :git => 'https://github.com/JEG2/highline.git' #gem 'rbcurse-core', :git => 'git://github.com/rkumar/rbcurse-core.git' #gem 'rbcurse-extras', :git => 'git://github.com/rkumar/rbcurse-extras.git' -# gem 'gibberish', :git => 'git://github.com/mdp/gibberish.git' -# gem 'rubyzip', :git => 'git://github.com/aussiegeek/rubyzip.git' +gem 'gibberish', :git => 'git://github.com/mdp/gibberish.git' +gem 'rubyzip', :git => 'git://github.com/aussiegeek/rubyzip.git' diff --git a/lib/vpnmaker/config_generator.rb b/lib/vpnmaker/config_generator.rb index 9c8c80f..b43c2af 100644 --- a/lib/vpnmaker/config_generator.rb +++ b/lib/vpnmaker/config_generator.rb @@ -14,13 +14,18 @@ def default_template :ta => File.read(@dirname + "/ta.key") } end + def client_conf(client) + fname = client[:user] + '-' + ((client[:revoked].max || - 1) + 1).to_s + separator = '-----BEGIN CERTIFICATE-----' + cert = File.read(@dirname + "/#{fname}.crt").split(separator).last.insert(0, separator) + { :gen_host => Socket.gethostname, :server => @mgr.config[:server], :client => @mgr.config[:client] - }.merge(client).merge(:key => File.read(@dirname + "/#{client[:user]}-#{(client[:revoked].max || - 1) + 1}.key" ), - :cert => File.read(@dirname + "/#{client[:user]}-#{(client[:revoked].max || - 1) + 1}.crt")).merge(@runtime_cfg) + }.merge(client).merge(:key => File.read(@dirname + "/#{fname}.key" ), + :cert => cert).merge(@runtime_cfg) end def server_conf From e687d8e606d51fb587280d851f9b3f351e97280d Mon Sep 17 00:00:00 2001 From: Voip Scout Date: Thu, 10 May 2012 16:53:24 +0200 Subject: [PATCH 29/81] fixed bug in cert passwd handling --- Gemfile | 31 +++++++++++++++++---- bin/vpnmaker | 25 +++++++++++++++-- lib/client.haml | 1 + lib/datastore.rb | 47 ++++++++++++++++++++++++++++++++ lib/datastore/ca.rb | 22 +++++++++++++++ lib/datastore/user.rb | 23 ++++++++++++++++ lib/server.haml | 22 +++++++-------- lib/vpnmaker.rb | 2 ++ lib/vpnmaker/config_generator.rb | 5 ++-- lib/vpnmaker/key_builder.rb | 6 ++-- 10 files changed, 160 insertions(+), 24 deletions(-) create mode 100644 lib/datastore.rb create mode 100644 lib/datastore/ca.rb create mode 100644 lib/datastore/user.rb diff --git a/Gemfile b/Gemfile index bd188d9..67ebd90 100644 --- a/Gemfile +++ b/Gemfile @@ -13,17 +13,38 @@ group :development do gem "jeweler" #, "~> 1.8.3" end -gem 'ipaddr_extensions' -#, :git => 'git://github.com/jamesotron/IPAddrExtensions.git' - gem 'haml' -gem 'main', :git => 'git://github.com/ahoward/main.git' -#gem 'hashugar', :git => 'git://github.com/jsuchal/hashugar.git' +# cli options parser +gem 'main', :git => 'git://github.com/ahoward/main.git' gem 'highline' #, :git => 'https://github.com/JEG2/highline.git' +#gem 'hashugar', :git => 'git://github.com/jsuchal/hashugar.git' #gem 'rbcurse-core', :git => 'git://github.com/rkumar/rbcurse-core.git' #gem 'rbcurse-extras', :git => 'git://github.com/rkumar/rbcurse-extras.git' +# openssl wrappers gem 'gibberish', :git => 'git://github.com/mdp/gibberish.git' +gem 'cert_lib', :git => 'git://github.com/victorgrey/cert_lib.git' + +# model stuff +gem 'datamapper', "~> 1.2.0" +# gem 'dm-do-adapter' +gem 'dm-aggregates' +gem 'dm-types', "~> 1.2.1" +gem 'dm-observer' +gem 'dm-migrations' +gem 'dm-timestamps' +gem 'dm-serializer', "~> 1.2.0" +gem 'dm-validations' +gem 'dm-mysql-adapter' + +# support libs +gem 'chronic' +gem 'ipaddr_extensions' +#, :git => 'git://github.com/jamesotron/IPAddrExtensions.git' gem 'rubyzip', :git => 'git://github.com/aussiegeek/rubyzip.git' + +# reporting +gem 'ruport' +gem 'ruport-util' diff --git a/bin/vpnmaker b/bin/vpnmaker index d4d5d0f..f798f01 100755 --- a/bin/vpnmaker +++ b/bin/vpnmaker @@ -55,6 +55,21 @@ module VPNMaker cast :string arity 1 } + argument('organization_unit') { + required + cast :string + arity 1 + } + argument('common_name') { + required + cast :string + arity 1 + } + argument('key_name') { + required + cast :string + arity 1 + } argument('email') { required cast :string @@ -96,6 +111,9 @@ module VPNMaker :province => params['province'].value, :city => params['city'].value, :organization => params['organization'].value, + :organization_unit => params['organization_unit'].value, + :common_name => params['common_name'].value, + :name => params['key_name'].value, :email => params['email'].value }, :site => { @@ -104,7 +122,7 @@ module VPNMaker :client_conf_dir => client_config_dir.split('/').last } } - example_config = YAML.load_file(lib_dir + "/example_vpnmaker_site.config.yaml").to_yaml.gsub(/\n|---/, "\n# ") + example_config = YAML.load_file(lib_dir + "/example_vpnmaker_site.config.yaml").to_yaml.gsub(/\n|---/, "\n#") File.open((File.expand_path(dir) + "/" + name + ".vpn" + "/" + name + ".config.yaml"), 'w') {|f| f.write(initial_config.to_yaml + example_config)} mgr = VPNMaker::Manager.new((File.expand_path(dir) + "/" + name + ".vpn")) mgr.build_ca @@ -178,8 +196,9 @@ module VPNMaker def run params['client_name'].values.each_with_index do |c, i| - passwd = params['passwd'].values[i] ? params['passwd'].values[i] : params['passwd'].default - db.create_user(c, c, "#{c}@#{db.config[:key_properties][:email].split('@').last}", passwd) if db.users.select {|r| r =~ /#{c}/}.empty? + email = "#{c}@#{db.config[:key_properties][:email].split('@').last}" + passwd = params['passwd'].values[i] + (passwd ? db.create_user(c, c, email, passwd) : db.create_user(c, c, email)) if db.users.select {|r| r =~ /#{c}/}.empty? end end } diff --git a/lib/client.haml b/lib/client.haml index 45c2b12..3faf89c 100644 --- a/lib/client.haml +++ b/lib/client.haml @@ -7,6 +7,7 @@ resolv-retry infinite nobind persist-key persist-tun +comp-lzo \# \#tls-remote must equal CN of ca in the hosts x509 \# diff --git a/lib/datastore.rb b/lib/datastore.rb new file mode 100644 index 0000000..7a8226e --- /dev/null +++ b/lib/datastore.rb @@ -0,0 +1,47 @@ +module VPNMaker + module DataStore + require 'dm-core' + require 'dm-do-adapter' + require 'dm-observer' + require 'dm-migrations' + require 'dm-timestamps' + require 'dm-serializer' + require 'dm-validations' + require 'dm-aggregates' + require 'dm-types' + #require 'do_mysql' + require 'dm-mysql-adapter' + + # require 'base64' + # require 'chronic' + # require 'phony' + + # require 'ansi/mixin' + # require 'ansi/progressbar' + # require 'ansi/table' + # require 'percentise' + # require 'stamp' + + # require 'munger' + # require 'ruport' + # require 'ruport/util' + + # require 'dm-sqlite-adapter' + # require 'do_sqlite3' + + # DataMapper::Logger.new($stdout, :debug) + + path = (File.dirname File.expand_path(__FILE__)) + "/" + autoload :User, "#{path}datastore/user" + autoload :CA, "#{path}datastore/ca" + + DataMapper.setup(:default, { + :host => '127.0.0.1', + :port => 3306, + :database => 'vpnmaker', + :adapter => 'mysql', + :username => 'root', + :password => 'gavno.123!'}) + + end +end diff --git a/lib/datastore/ca.rb b/lib/datastore/ca.rb new file mode 100644 index 0000000..6956a74 --- /dev/null +++ b/lib/datastore/ca.rb @@ -0,0 +1,22 @@ +module VPNMaker + module DataStore + class CA + include DataMapper::Resource + + property :id, Serial + property :updated_at, DateTime + property :created_at, DateTime + + property :name, String + property :country, String + property :province, String + property :city, String + property :organization, String + property :email, String + + DataMapper::Model.raise_on_save_failure = true + DataMapper.finalize + DataMapper.auto_upgrade! + end + end +end diff --git a/lib/datastore/user.rb b/lib/datastore/user.rb new file mode 100644 index 0000000..63681a4 --- /dev/null +++ b/lib/datastore/user.rb @@ -0,0 +1,23 @@ +module VPNMaker + module DataStore + class User + include DataMapper::Resource + + property :id, Serial + property :updated_at, DateTime + property :created_at, DateTime + + property :cn, String + property :name, String + property :email, String + property :active_key, Integer + property :revoked, Object + + def user; cn; end; + + DataMapper::Model.raise_on_save_failure = true + DataMapper.finalize + DataMapper.auto_upgrade! + end + end +end diff --git a/lib/server.haml b/lib/server.haml index f0e306a..cfaf0eb 100644 --- a/lib/server.haml +++ b/lib/server.haml @@ -1,23 +1,27 @@ \# Auto-generated by vpnmaker on #{gen_host} #{Time.now.to_s} \# See http://github.com/pc/vpnmaker mode server -tls-server -local #{host} -port #{port} -proto udp dev tun0 +local #{host} +proto udp +port #{port} server #{base_ip[:net]} #{base_ip[:mask]} +tls-server +comp-lzo \ \# subnets.each do - subnets.each do |net| route #{net[:net]} #{net[:mask]} - push route #{net[:mask]} #{net[:mask]} + push route #{net[:net]} #{net[:mask]} \ \# bridgednets.each do - bridgednets.each do |net| push route #{net[:net]} #{net[:mask]} \ +push "redirect-gateway" +client-to-client +\ user #{user} group #{group} - if type == :default @@ -42,9 +46,9 @@ group #{group} #{crl} - + #{ta} - + - else dh #{root}/keys/dh.pem @@ -54,11 +58,7 @@ group #{group} crl-verify #{root}/keys/crl.pem keepalive 10 120 - log #{log} - persist-tun persist-key - -tls-auth #{root}/keys/ta.key 0 :plain diff --git a/lib/vpnmaker.rb b/lib/vpnmaker.rb index 0aed0d1..b8d84ed 100644 --- a/lib/vpnmaker.rb +++ b/lib/vpnmaker.rb @@ -34,6 +34,8 @@ def binding; super; end # normally private module VPNMaker path = (File.dirname File.expand_path(__FILE__)) + "/" + autoload :DataStore, "#{path}datastore" + autoload :ConfigGenerator, "#{path}vpnmaker/config_generator" autoload :KeyDB, "#{path}vpnmaker/key_db" autoload :KeyConfig, "#{path}vpnmaker/key_config" diff --git a/lib/vpnmaker/config_generator.rb b/lib/vpnmaker/config_generator.rb index b43c2af..2a8a5a3 100644 --- a/lib/vpnmaker/config_generator.rb +++ b/lib/vpnmaker/config_generator.rb @@ -29,10 +29,12 @@ def client_conf(client) end def server_conf + separator = '-----BEGIN CERTIFICATE-----' + cert = File.read(@dirname + "/server.crt").split(separator).last.insert(0, separator) { :gen_host => Socket.gethostname }.merge(@mgr.config[:server]).merge(@runtime_cfg).merge(:key => File.read(@dirname + "/server.key"), - :cert => File.read(@dirname + "/server.crt"), + :cert => cert, :crl => File.read(@dirname + "/crl.pem")) end @@ -52,7 +54,6 @@ def client(client) template = File.read(@mgr.tracker.path + \ "/" + @mgr.config[:site][:template_dir] + \ "/" + 'client.haml') - # template = File.read(__FILE__.path('client.haml')) Haml::Engine.new(template).render(Object.new, haml_vars) end end diff --git a/lib/vpnmaker/key_builder.rb b/lib/vpnmaker/key_builder.rb index e4ae6a0..95ae196 100644 --- a/lib/vpnmaker/key_builder.rb +++ b/lib/vpnmaker/key_builder.rb @@ -24,9 +24,9 @@ def opensslvars :key_org => @config[:key_properties][:organization], :key_email => @config[:key_properties][:email], :key_org => @config[:key_properties][:organization], - :key_ou => 'Organization Unit', - :key_cn => 'Common Name', - :key_name => 'Name' + :key_ou => @config[:key_properties][:organization_unit], + :key_cn => @config[:key_properties][:common_name], + :key_name => @config[:key_properties][:name] } end From 3706b62a26f486e02b0b20cd6d744e3fdd79b23d Mon Sep 17 00:00:00 2001 From: Voip Scout Date: Thu, 10 May 2012 16:54:35 +0200 Subject: [PATCH 30/81] Version bump to 1.0.1 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index afaf360..7f20734 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.0.0 \ No newline at end of file +1.0.1 \ No newline at end of file From a7798ebecb67327657e770b4a3462b8234e2aa40 Mon Sep 17 00:00:00 2001 From: Voip Scout Date: Thu, 10 May 2012 16:56:00 +0200 Subject: [PATCH 31/81] Regenerate gemspec for version 1.0.1 --- vpnmaker.gemspec | 58 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 53 insertions(+), 5 deletions(-) diff --git a/vpnmaker.gemspec b/vpnmaker.gemspec index 78051ef..bab313a 100644 --- a/vpnmaker.gemspec +++ b/vpnmaker.gemspec @@ -5,11 +5,11 @@ Gem::Specification.new do |s| s.name = "vpnmaker" - s.version = "1.0.0" + s.version = "1.0.1" s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= s.authors = ["Voip Scout"] - s.date = "2012-05-09" + s.date = "2012-05-10" s.description = "haml templates and key tracking" s.email = "voipscout@gmail.com" s.executables = ["vpnmaker"] @@ -24,6 +24,9 @@ Gem::Specification.new do |s| "VERSION", "bin/vpnmaker", "lib/client.haml", + "lib/datastore.rb", + "lib/datastore/ca.rb", + "lib/datastore/user.rb", "lib/example_vpnmaker_site.config.yaml", "lib/openssl.haml", "lib/server.haml", @@ -46,10 +49,25 @@ Gem::Specification.new do |s| s.specification_version = 3 if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then - s.add_runtime_dependency(%q, [">= 0"]) s.add_runtime_dependency(%q, [">= 0"]) s.add_runtime_dependency(%q
, [">= 0"]) s.add_runtime_dependency(%q, [">= 0"]) + s.add_runtime_dependency(%q, [">= 0"]) + s.add_runtime_dependency(%q, [">= 0"]) + s.add_runtime_dependency(%q, ["~> 1.2.0"]) + s.add_runtime_dependency(%q, [">= 0"]) + s.add_runtime_dependency(%q, ["~> 1.2.1"]) + s.add_runtime_dependency(%q, [">= 0"]) + s.add_runtime_dependency(%q, [">= 0"]) + s.add_runtime_dependency(%q, [">= 0"]) + s.add_runtime_dependency(%q, ["~> 1.2.0"]) + s.add_runtime_dependency(%q, [">= 0"]) + s.add_runtime_dependency(%q, [">= 0"]) + s.add_runtime_dependency(%q, [">= 0"]) + s.add_runtime_dependency(%q, [">= 0"]) + s.add_runtime_dependency(%q, [">= 0"]) + s.add_runtime_dependency(%q, [">= 0"]) + s.add_runtime_dependency(%q, [">= 0"]) s.add_development_dependency(%q, [">= 0"]) s.add_development_dependency(%q, [">= 0"]) s.add_development_dependency(%q, [">= 0"]) @@ -61,10 +79,25 @@ Gem::Specification.new do |s| s.add_development_dependency(%q, [">= 0"]) s.add_development_dependency(%q, [">= 0"]) else - s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) s.add_dependency(%q
, [">= 0"]) s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, ["~> 1.2.0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, ["~> 1.2.1"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, ["~> 1.2.0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) @@ -77,10 +110,25 @@ Gem::Specification.new do |s| s.add_dependency(%q, [">= 0"]) end else - s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) s.add_dependency(%q
, [">= 0"]) s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, ["~> 1.2.0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, ["~> 1.2.1"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, ["~> 1.2.0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) From 694b61fda1b782d345a3fc79ad59169b80d95444 Mon Sep 17 00:00:00 2001 From: Voip Scout Date: Thu, 10 May 2012 17:04:58 +0200 Subject: [PATCH 32/81] fixing deps --- Gemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index 67ebd90..c50ff38 100644 --- a/Gemfile +++ b/Gemfile @@ -25,7 +25,7 @@ gem 'highline' #, :git => 'https://github.com/JEG2/highline.git' # openssl wrappers gem 'gibberish', :git => 'git://github.com/mdp/gibberish.git' -gem 'cert_lib', :git => 'git://github.com/victorgrey/cert_lib.git' +#gem 'cert_lib', :git => 'git://github.com/victorgrey/cert_lib.git' # model stuff gem 'datamapper', "~> 1.2.0" From 5c8d9498d214b4d045f5a02f4ca59333266a6fbe Mon Sep 17 00:00:00 2001 From: Voip Scout Date: Thu, 10 May 2012 17:05:30 +0200 Subject: [PATCH 33/81] Version bump to 1.0.2 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 7f20734..e6d5cb8 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.0.1 \ No newline at end of file +1.0.2 \ No newline at end of file From d1a1248fedc0029f3fd10d9d02d80137efd4ef98 Mon Sep 17 00:00:00 2001 From: Voip Scout Date: Thu, 10 May 2012 17:05:57 +0200 Subject: [PATCH 34/81] Regenerate gemspec for version 1.0.2 --- vpnmaker.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vpnmaker.gemspec b/vpnmaker.gemspec index bab313a..f7c9625 100644 --- a/vpnmaker.gemspec +++ b/vpnmaker.gemspec @@ -5,7 +5,7 @@ Gem::Specification.new do |s| s.name = "vpnmaker" - s.version = "1.0.1" + s.version = "1.0.2" s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= s.authors = ["Voip Scout"] From de07db973e2a5f2d5f046a75b02529b429328648 Mon Sep 17 00:00:00 2001 From: Voip Scout Date: Thu, 10 May 2012 17:13:05 +0200 Subject: [PATCH 35/81] Version bump to 1.0.3 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index e6d5cb8..e4c0d46 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.0.2 \ No newline at end of file +1.0.3 \ No newline at end of file From adcac45b237b95fe57dea9f20768b69e377e6583 Mon Sep 17 00:00:00 2001 From: Voip Scout Date: Thu, 10 May 2012 17:13:25 +0200 Subject: [PATCH 36/81] Regenerate gemspec for version 1.0.3 --- vpnmaker.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vpnmaker.gemspec b/vpnmaker.gemspec index f7c9625..da69cb4 100644 --- a/vpnmaker.gemspec +++ b/vpnmaker.gemspec @@ -5,7 +5,7 @@ Gem::Specification.new do |s| s.name = "vpnmaker" - s.version = "1.0.2" + s.version = "1.0.3" s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= s.authors = ["Voip Scout"] From 1ec35cb5aeb97ae8182d27cdc0ff8458f0e70bbe Mon Sep 17 00:00:00 2001 From: Voip Scout Date: Thu, 10 May 2012 17:19:04 +0200 Subject: [PATCH 37/81] fixing deps --- Gemfile | 2 +- vpnmaker.gemspec | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/Gemfile b/Gemfile index 67ebd90..c50ff38 100644 --- a/Gemfile +++ b/Gemfile @@ -25,7 +25,7 @@ gem 'highline' #, :git => 'https://github.com/JEG2/highline.git' # openssl wrappers gem 'gibberish', :git => 'git://github.com/mdp/gibberish.git' -gem 'cert_lib', :git => 'git://github.com/victorgrey/cert_lib.git' +#gem 'cert_lib', :git => 'git://github.com/victorgrey/cert_lib.git' # model stuff gem 'datamapper', "~> 1.2.0" diff --git a/vpnmaker.gemspec b/vpnmaker.gemspec index da69cb4..ab951ea 100644 --- a/vpnmaker.gemspec +++ b/vpnmaker.gemspec @@ -53,7 +53,6 @@ Gem::Specification.new do |s| s.add_runtime_dependency(%q
, [">= 0"]) s.add_runtime_dependency(%q, [">= 0"]) s.add_runtime_dependency(%q, [">= 0"]) - s.add_runtime_dependency(%q, [">= 0"]) s.add_runtime_dependency(%q, ["~> 1.2.0"]) s.add_runtime_dependency(%q, [">= 0"]) s.add_runtime_dependency(%q, ["~> 1.2.1"]) @@ -83,7 +82,6 @@ Gem::Specification.new do |s| s.add_dependency(%q
, [">= 0"]) s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, ["~> 1.2.0"]) s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, ["~> 1.2.1"]) @@ -114,7 +112,6 @@ Gem::Specification.new do |s| s.add_dependency(%q
, [">= 0"]) s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, ["~> 1.2.0"]) s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, ["~> 1.2.1"]) From 2328b3739677fcb134b1e13dd77f672a6cfee699 Mon Sep 17 00:00:00 2001 From: Voip Scout Date: Thu, 10 May 2012 17:21:12 +0200 Subject: [PATCH 38/81] Version bump to 1.0.4 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index e4c0d46..a6a3a43 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.0.3 \ No newline at end of file +1.0.4 \ No newline at end of file From a5b992c853164aba39f99bb22a6a051e94a729b8 Mon Sep 17 00:00:00 2001 From: Voip Scout Date: Thu, 10 May 2012 17:22:49 +0200 Subject: [PATCH 39/81] fixing deps --- lib/datastore.rb | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/datastore.rb b/lib/datastore.rb index 7a8226e..d8d4b03 100644 --- a/lib/datastore.rb +++ b/lib/datastore.rb @@ -35,13 +35,13 @@ module DataStore autoload :User, "#{path}datastore/user" autoload :CA, "#{path}datastore/ca" - DataMapper.setup(:default, { - :host => '127.0.0.1', - :port => 3306, - :database => 'vpnmaker', - :adapter => 'mysql', - :username => 'root', - :password => 'gavno.123!'}) + # DataMapper.setup(:default, { + # :host => '127.0.0.1', + # :port => 3306, + # :database => 'vpnmaker', + # :adapter => 'mysql', + # :username => 'root', + # :password => 'gavno.123!'}) end end From ade3436ca48408b826b9c5afdba2f9b869a2b82a Mon Sep 17 00:00:00 2001 From: Voip Scout Date: Thu, 10 May 2012 17:23:19 +0200 Subject: [PATCH 40/81] Version bump to 1.0.5 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index a6a3a43..1464c52 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.0.4 \ No newline at end of file +1.0.5 \ No newline at end of file From e075e4b2a725c938250c696876061c9e4dd30859 Mon Sep 17 00:00:00 2001 From: Voip Scout Date: Thu, 10 May 2012 17:23:47 +0200 Subject: [PATCH 41/81] Regenerate gemspec for version 1.0.4 --- vpnmaker.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vpnmaker.gemspec b/vpnmaker.gemspec index ab951ea..3911f1b 100644 --- a/vpnmaker.gemspec +++ b/vpnmaker.gemspec @@ -5,7 +5,7 @@ Gem::Specification.new do |s| s.name = "vpnmaker" - s.version = "1.0.3" + s.version = "1.0.4" s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= s.authors = ["Voip Scout"] From 14e0344a2151b5835ce5a4e7a3e268ee5cc6974a Mon Sep 17 00:00:00 2001 From: Voip Scout Date: Thu, 10 May 2012 17:26:21 +0200 Subject: [PATCH 42/81] Version bump to 1.0.5 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index a6a3a43..1464c52 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.0.4 \ No newline at end of file +1.0.5 \ No newline at end of file From 955238439d5af3d2a083d95a5fe54b8b5121fcaa Mon Sep 17 00:00:00 2001 From: Voip Scout Date: Thu, 10 May 2012 17:26:23 +0200 Subject: [PATCH 43/81] Version bump to 1.0.6 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 1464c52..ece61c6 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.0.5 \ No newline at end of file +1.0.6 \ No newline at end of file From c2e4188ef372e3e24a4597c284487a7b8ddbbeef Mon Sep 17 00:00:00 2001 From: Voip Scout Date: Thu, 10 May 2012 17:29:37 +0200 Subject: [PATCH 44/81] Regenerate gemspec for version 1.0.6 --- vpnmaker.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vpnmaker.gemspec b/vpnmaker.gemspec index 3911f1b..712662b 100644 --- a/vpnmaker.gemspec +++ b/vpnmaker.gemspec @@ -5,7 +5,7 @@ Gem::Specification.new do |s| s.name = "vpnmaker" - s.version = "1.0.4" + s.version = "1.0.6" s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= s.authors = ["Voip Scout"] From bb610da4a70f911a48147ca024924893abf268af Mon Sep 17 00:00:00 2001 From: Voip Scout Date: Thu, 10 May 2012 18:37:10 +0200 Subject: [PATCH 45/81] passwd --- bin/vpnmaker | 1 + lib/server.haml | 7 +--- lib/vpnmaker/key_builder.rb | 7 ++-- vpnmaker.gemspec | 73 +++++++++++++++++++++++++++++-------- 4 files changed, 65 insertions(+), 23 deletions(-) diff --git a/bin/vpnmaker b/bin/vpnmaker index f798f01..53f6ca0 100755 --- a/bin/vpnmaker +++ b/bin/vpnmaker @@ -188,6 +188,7 @@ module VPNMaker mode('create') { keyword('passwd') { + description "This is PKCS12 password, default is \"passwd\"" argument :optional cast :string arity 1 diff --git a/lib/server.haml b/lib/server.haml index cfaf0eb..e2a3de6 100644 --- a/lib/server.haml +++ b/lib/server.haml @@ -1,7 +1,6 @@ \# Auto-generated by vpnmaker on #{gen_host} #{Time.now.to_s} \# See http://github.com/pc/vpnmaker mode server - dev tun0 local #{host} proto udp @@ -9,6 +8,8 @@ port #{port} server #{base_ip[:net]} #{base_ip[:mask]} tls-server comp-lzo +cipher AES-256-CBC + crl-verify #{root}/keys/crl.pem \ \# subnets.each do - subnets.each do |net| @@ -42,10 +43,6 @@ group #{group} #{key} - - #{crl} - - #{ta} diff --git a/lib/vpnmaker/key_builder.rb b/lib/vpnmaker/key_builder.rb index 95ae196..b7cfcd3 100644 --- a/lib/vpnmaker/key_builder.rb +++ b/lib/vpnmaker/key_builder.rb @@ -108,10 +108,11 @@ def build_key(user, name, email, pass, delegate) else pass_spec = '-nodes' end - - `openssl req -batch -days 3650 -new -keyout #{tmppath(user, 'key')} -out #{tmppath(user, 'csr')} -config #{opensslcnf(h)} #{pass_spec}` + `openssl req -batch -days 3650 -new -keyout #{tmppath(user, 'key')} -out #{tmppath(user, 'csr')} -config #{opensslcnf(h)} -nodes` `openssl ca -batch -days 3650 -out #{tmppath(user, 'crt')} -in #{tmppath(user, 'csr')} -config #{opensslcnf(h)}` - # TODO: this still asks for the export password + # TODO: this still asks for the export password and we hack + # around it from bin/vpnmaker. This is actually something that + # should only be generated dynamically upon user request. `openssl pkcs12 -export -clcerts -in #{tmppath(user, 'crt')} -inkey #{tmppath(user, 'key')} -out #{tmppath(user, 'p12')} #{pass_spec}` @tracker.send(delegate, user, name, email, tmpfile(user, 'key'), tmpfile(user, 'crt'), tmpfile(user, 'p12'), tmpfile('index.txt'), tmpfile('serial')) end diff --git a/vpnmaker.gemspec b/vpnmaker.gemspec index 3b8f975..c8fd51c 100644 --- a/vpnmaker.gemspec +++ b/vpnmaker.gemspec @@ -5,12 +5,12 @@ Gem::Specification.new do |s| s.name = "vpnmaker" - s.version = "0.0.0" + s.version = "1.0.1" s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= s.authors = ["Voip Scout"] - s.date = "2012-05-06" - s.description = "TODO: longer description of your gem" + s.date = "2012-05-10" + s.description = "haml templates and key tracking" s.email = "voipscout@gmail.com" s.executables = ["vpnmaker"] s.extra_rdoc_files = [ @@ -23,8 +23,11 @@ Gem::Specification.new do |s| "Rakefile", "VERSION", "bin/vpnmaker", - "foocorp.config.yaml", "lib/client.haml", + "lib/datastore.rb", + "lib/datastore/ca.rb", + "lib/datastore/user.rb", + "lib/example_vpnmaker_site.config.yaml", "lib/openssl.haml", "lib/server.haml", "lib/vpnmaker.rb", @@ -33,23 +36,37 @@ Gem::Specification.new do |s| "lib/vpnmaker/key_config.rb", "lib/vpnmaker/key_db.rb", "lib/vpnmaker/key_tracker.rb", - "lib/vpnmaker/manager.rb" + "lib/vpnmaker/manager.rb", + "vpnmaker.gemspec" ] s.homepage = "http://github.com/voipscout/vpnmaker" s.licenses = ["MIT"] s.require_paths = ["lib"] s.rubygems_version = "1.8.24" - s.summary = "TODO: one-line summary of your gem" + s.summary = "Makes it easy to manage OpenVPN" if s.respond_to? :specification_version then s.specification_version = 3 if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then - s.add_runtime_dependency(%q, [">= 0"]) s.add_runtime_dependency(%q, [">= 0"]) - s.add_runtime_dependency(%q, [">= 0"]) + s.add_runtime_dependency(%q
, [">= 0"]) + s.add_runtime_dependency(%q, [">= 0"]) s.add_runtime_dependency(%q, [">= 0"]) + s.add_runtime_dependency(%q, ["~> 1.2.0"]) + s.add_runtime_dependency(%q, [">= 0"]) + s.add_runtime_dependency(%q, ["~> 1.2.1"]) + s.add_runtime_dependency(%q, [">= 0"]) + s.add_runtime_dependency(%q, [">= 0"]) + s.add_runtime_dependency(%q, [">= 0"]) + s.add_runtime_dependency(%q, ["~> 1.2.0"]) + s.add_runtime_dependency(%q, [">= 0"]) + s.add_runtime_dependency(%q, [">= 0"]) + s.add_runtime_dependency(%q, [">= 0"]) + s.add_runtime_dependency(%q, [">= 0"]) s.add_runtime_dependency(%q, [">= 0"]) + s.add_runtime_dependency(%q, [">= 0"]) + s.add_runtime_dependency(%q, [">= 0"]) s.add_development_dependency(%q, [">= 0"]) s.add_development_dependency(%q, [">= 0"]) s.add_development_dependency(%q, [">= 0"]) @@ -57,15 +74,28 @@ Gem::Specification.new do |s| s.add_development_dependency(%q, [">= 0"]) s.add_development_dependency(%q, [">= 0"]) s.add_development_dependency(%q, [">= 0"]) - s.add_development_dependency(%q, ["~> 3.12"]) + s.add_development_dependency(%q, [">= 0"]) s.add_development_dependency(%q, [">= 0"]) s.add_development_dependency(%q, [">= 0"]) else - s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q
, [">= 0"]) + s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, ["~> 1.2.0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, ["~> 1.2.1"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, ["~> 1.2.0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) @@ -73,16 +103,29 @@ Gem::Specification.new do |s| s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, ["~> 3.12"]) + s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) end else - s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q
, [">= 0"]) + s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, ["~> 1.2.0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, ["~> 1.2.1"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, ["~> 1.2.0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) @@ -90,7 +133,7 @@ Gem::Specification.new do |s| s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, ["~> 3.12"]) + s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) end From dde3f19bbc5e00a801cbf9be7bdee73b1cf71582 Mon Sep 17 00:00:00 2001 From: Voip Scout Date: Thu, 10 May 2012 18:44:27 +0200 Subject: [PATCH 46/81] Version bump to 1.0.7 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index ece61c6..f9cbc01 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.0.6 \ No newline at end of file +1.0.7 \ No newline at end of file From fae58b18e96cdd05a50845bbb18e393041e6caba Mon Sep 17 00:00:00 2001 From: Voip Scout Date: Thu, 10 May 2012 18:45:25 +0200 Subject: [PATCH 47/81] gemspec back --- vpnmaker.gemspec | 140 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 vpnmaker.gemspec diff --git a/vpnmaker.gemspec b/vpnmaker.gemspec new file mode 100644 index 0000000..0bbd5e0 --- /dev/null +++ b/vpnmaker.gemspec @@ -0,0 +1,140 @@ +# Generated by jeweler +# DO NOT EDIT THIS FILE DIRECTLY +# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec' +# -*- encoding: utf-8 -*- + +Gem::Specification.new do |s| + s.name = "vpnmaker" + s.version = "1.0.7" + + s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= + s.authors = ["Voip Scout"] + s.date = "2012-05-10" + s.description = "haml templates and key tracking" + s.email = "voipscout@gmail.com" + s.executables = ["vpnmaker"] + s.extra_rdoc_files = [ + "README.rdoc" + ] + s.files = [ + ".document", + "Gemfile", + "README.rdoc", + "Rakefile", + "VERSION", + "bin/vpnmaker", + "lib/client.haml", + "lib/datastore.rb", + "lib/datastore/ca.rb", + "lib/datastore/user.rb", + "lib/example_vpnmaker_site.config.yaml", + "lib/openssl.haml", + "lib/server.haml", + "lib/vpnmaker.rb", + "lib/vpnmaker/config_generator.rb", + "lib/vpnmaker/key_builder.rb", + "lib/vpnmaker/key_config.rb", + "lib/vpnmaker/key_db.rb", + "lib/vpnmaker/key_tracker.rb", + "lib/vpnmaker/manager.rb" + ] + s.homepage = "http://github.com/voipscout/vpnmaker" + s.licenses = ["MIT"] + s.require_paths = ["lib"] + s.rubygems_version = "1.8.24" + s.summary = "Makes it easy to manage OpenVPN" + + if s.respond_to? :specification_version then + s.specification_version = 3 + + if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then + s.add_runtime_dependency(%q, [">= 0"]) + s.add_runtime_dependency(%q
, [">= 0"]) + s.add_runtime_dependency(%q, [">= 0"]) + s.add_runtime_dependency(%q, [">= 0"]) + s.add_runtime_dependency(%q, ["~> 1.2.0"]) + s.add_runtime_dependency(%q, [">= 0"]) + s.add_runtime_dependency(%q, ["~> 1.2.1"]) + s.add_runtime_dependency(%q, [">= 0"]) + s.add_runtime_dependency(%q, [">= 0"]) + s.add_runtime_dependency(%q, [">= 0"]) + s.add_runtime_dependency(%q, ["~> 1.2.0"]) + s.add_runtime_dependency(%q, [">= 0"]) + s.add_runtime_dependency(%q, [">= 0"]) + s.add_runtime_dependency(%q, [">= 0"]) + s.add_runtime_dependency(%q, [">= 0"]) + s.add_runtime_dependency(%q, [">= 0"]) + s.add_runtime_dependency(%q, [">= 0"]) + s.add_runtime_dependency(%q, [">= 0"]) + s.add_development_dependency(%q, [">= 0"]) + s.add_development_dependency(%q, [">= 0"]) + s.add_development_dependency(%q, [">= 0"]) + s.add_development_dependency(%q, [">= 0"]) + s.add_development_dependency(%q, [">= 0"]) + s.add_development_dependency(%q, [">= 0"]) + s.add_development_dependency(%q, [">= 0"]) + s.add_development_dependency(%q, [">= 0"]) + s.add_development_dependency(%q, [">= 0"]) + s.add_development_dependency(%q, [">= 0"]) + else + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q
, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, ["~> 1.2.0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, ["~> 1.2.1"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, ["~> 1.2.0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + end + else + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q
, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, ["~> 1.2.0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, ["~> 1.2.1"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, ["~> 1.2.0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) + end +end + From 2ec264176d0bae5882a4cfd6e6d4d13493c2ad03 Mon Sep 17 00:00:00 2001 From: Voip Scout Date: Thu, 10 May 2012 18:49:06 +0200 Subject: [PATCH 48/81] Regenerate gemspec for version 1.0.7 --- vpnmaker.gemspec | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/vpnmaker.gemspec b/vpnmaker.gemspec index e191f61..7e97917 100644 --- a/vpnmaker.gemspec +++ b/vpnmaker.gemspec @@ -5,11 +5,7 @@ Gem::Specification.new do |s| s.name = "vpnmaker" -<<<<<<< HEAD - s.version = "1.0.6" -======= s.version = "1.0.7" ->>>>>>> release/1.0.7 s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= s.authors = ["Voip Scout"] @@ -40,7 +36,8 @@ Gem::Specification.new do |s| "lib/vpnmaker/key_config.rb", "lib/vpnmaker/key_db.rb", "lib/vpnmaker/key_tracker.rb", - "lib/vpnmaker/manager.rb" + "lib/vpnmaker/manager.rb", + "vpnmaker.gemspec" ] s.homepage = "http://github.com/voipscout/vpnmaker" s.licenses = ["MIT"] From f8a8ae317e5bd8a11a911ce7c87612cf9eb60a70 Mon Sep 17 00:00:00 2001 From: Voip Scout Date: Thu, 10 May 2012 19:50:54 +0200 Subject: [PATCH 49/81] tuning haml templates --- lib/client.haml | 1 + lib/example_vpnmaker_site.config.yaml | 2 +- lib/server.haml | 21 ++++++++++++--------- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/lib/client.haml b/lib/client.haml index 3faf89c..33984d1 100644 --- a/lib/client.haml +++ b/lib/client.haml @@ -51,4 +51,5 @@ ping 30 nobind key #{user}-#{(revoked.max || - 1) + 1}.key remote-cert-tls server + :plain diff --git a/lib/example_vpnmaker_site.config.yaml b/lib/example_vpnmaker_site.config.yaml index 6d5667a..9d23119 100644 --- a/lib/example_vpnmaker_site.config.yaml +++ b/lib/example_vpnmaker_site.config.yaml @@ -17,7 +17,7 @@ :group: nogroup :root: /etc/openvpn :log: /var/log/openvpn.log - :host: staging.pvstream.in + :host: MY_HOST_FQDN :port: 1194 :client: diff --git a/lib/server.haml b/lib/server.haml index e2a3de6..3ea9bb7 100644 --- a/lib/server.haml +++ b/lib/server.haml @@ -9,16 +9,18 @@ server #{base_ip[:net]} #{base_ip[:mask]} tls-server comp-lzo cipher AES-256-CBC - crl-verify #{root}/keys/crl.pem +crl-verify /etc/openvpn/crl.pem \ -\# subnets.each do -- subnets.each do |net| - route #{net[:net]} #{net[:mask]} - push route #{net[:net]} #{net[:mask]} +- if subnets + \# subnets.each do + - subnets.each do |net| + route #{net[:net]} #{net[:mask]} + push route #{net[:net]} #{net[:mask]} \ -\# bridgednets.each do -- bridgednets.each do |net| - push route #{net[:net]} #{net[:mask]} +- if bridgednets + \# bridgednets.each do + - bridgednets.each do |net| + push route #{net[:net]} #{net[:mask]} \ push "redirect-gateway" client-to-client @@ -55,7 +57,8 @@ group #{group} crl-verify #{root}/keys/crl.pem keepalive 10 120 -log #{log} +\#log #{log} persist-tun persist-key + :plain From c91664fecdc9eabb03a23165d8cd2501ffb36bda Mon Sep 17 00:00:00 2001 From: Voip Scout Date: Thu, 10 May 2012 20:25:33 +0200 Subject: [PATCH 50/81] sane defaults in templates now --- lib/server.haml | 12 ++++++------ lib/vpnmaker/config_generator.rb | 7 ++++--- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/lib/server.haml b/lib/server.haml index 3ea9bb7..61f4f4a 100644 --- a/lib/server.haml +++ b/lib/server.haml @@ -9,22 +9,22 @@ server #{base_ip[:net]} #{base_ip[:mask]} tls-server comp-lzo cipher AES-256-CBC -crl-verify /etc/openvpn/crl.pem -\ -- if subnets +crl-verify #{crl_path}/crl.pem + +- unless subnets.empty? \# subnets.each do - subnets.each do |net| route #{net[:net]} #{net[:mask]} push route #{net[:net]} #{net[:mask]} -\ -- if bridgednets + +- unless bridgednets.empty? \# bridgednets.each do - bridgednets.each do |net| push route #{net[:net]} #{net[:mask]} \ push "redirect-gateway" client-to-client -\ + user #{user} group #{group} - if type == :default diff --git a/lib/vpnmaker/config_generator.rb b/lib/vpnmaker/config_generator.rb index 2a8a5a3..b810f3d 100644 --- a/lib/vpnmaker/config_generator.rb +++ b/lib/vpnmaker/config_generator.rb @@ -32,7 +32,8 @@ def server_conf separator = '-----BEGIN CERTIFICATE-----' cert = File.read(@dirname + "/server.crt").split(separator).last.insert(0, separator) { - :gen_host => Socket.gethostname + :gen_host => Socket.gethostname, + :crl_path => @mgr.tracker.path }.merge(@mgr.config[:server]).merge(@runtime_cfg).merge(:key => File.read(@dirname + "/server.key"), :cert => cert, :crl => File.read(@dirname + "/crl.pem")) @@ -41,8 +42,8 @@ def server_conf def server haml_vars = server_conf.dup haml_vars[:base_ip] = ((a = IPAddr.new haml_vars[:base_ip]); {:net => a.to_s, :mask => a.subnet_mask.to_s}) - haml_vars[:bridgednets] = haml_vars[:bridgednets].map {|net| a = (IPAddr.new net); {:net => a.to_s, :mask => a.subnet_mask.to_s}} - haml_vars[:subnets] = haml_vars[:subnets].map {|net| a = (IPAddr.new net); {:net => a.to_s, :mask => a.subnet_mask.to_s}} + haml_vars[:bridgednets] ? (haml_vars[:bridgednets] = haml_vars[:bridgednets].map {|net| a = (IPAddr.new net); {:net => a.to_s, :mask => a.subnet_mask.to_s}}) : (haml_vars[:bridgednets] = Hash.new) + haml_vars[:subnets] ? (haml_vars[:subnets] = haml_vars[:subnets].map {|net| a = (IPAddr.new net); {:net => a.to_s, :mask => a.subnet_mask.to_s}}) : (haml_vars[:subnets] = Hash.new) template = File.read(@mgr.tracker.path + \ "/" + @mgr.config[:site][:template_dir] + \ "/" + 'server.haml') From e8abce416c705583c0aab6d93ffaf493a007a402 Mon Sep 17 00:00:00 2001 From: Voip Scout Date: Thu, 10 May 2012 20:27:08 +0200 Subject: [PATCH 51/81] Version bump to 1.0.8 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index f9cbc01..337a6a8 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.0.7 \ No newline at end of file +1.0.8 \ No newline at end of file From 6681fcc45d20d6083d89850428f9dbe6fa41896f Mon Sep 17 00:00:00 2001 From: Voip Scout Date: Thu, 10 May 2012 20:28:33 +0200 Subject: [PATCH 52/81] Regenerate gemspec for version 1.0.8 --- vpnmaker.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vpnmaker.gemspec b/vpnmaker.gemspec index 7e97917..ca08d1e 100644 --- a/vpnmaker.gemspec +++ b/vpnmaker.gemspec @@ -5,7 +5,7 @@ Gem::Specification.new do |s| s.name = "vpnmaker" - s.version = "1.0.7" + s.version = "1.0.8" s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= s.authors = ["Voip Scout"] From 920d461409d2c747ce77e1261be7697e5f738c65 Mon Sep 17 00:00:00 2001 From: Voip Scout Date: Thu, 10 May 2012 23:54:07 +0200 Subject: [PATCH 53/81] saner configs yet --- README.rdoc | 18 +++++++++++++----- bin/vpnmaker | 37 ++++++++++++++++++++++++++++++++++++- lib/server.haml | 2 +- 3 files changed, 50 insertions(+), 7 deletions(-) diff --git a/README.rdoc b/README.rdoc index d60ad51..676e083 100644 --- a/README.rdoc +++ b/README.rdoc @@ -1,10 +1,18 @@ -most of the code was stolen from here: http://github.com/pc/vpnmaker -i made a gem and converted it to use haml +most of the code was stolen from here: http://github.com/pc/vpnmaker, thank you! +i made a gem, converted it to use haml, added bin/vpnmaker cli = VPNMaker VPNMaker takes the teetering jankiness out of setting up and administering OpenVPN. -== Key management +It comes without any guarantees, the code seems to work for me, your mileage will invariably vary! +== Usage +* vpnmaker -h is your best friend +help format sucks, but it's better then using easy-rsa or doing openssl by hand +== Example +>>#vpnmaker init cli conf_name new_dir_path country province city organization organization_unit common_name key_name email + +== From the forked version: +=== Key management To set up your VPN, run: @@ -67,7 +75,7 @@ When Joe leaves the company, we can do: Which does the same revocation as in regenerate_user, but doesn't generate new keys. -== OpenVPN management +=== OpenVPN management To get OpenVPN set up, you should go back and edit foocorp.config.yaml, and add the following section: @@ -86,6 +94,6 @@ You may want to modify some of the values. Then, head back to irb, and do someth Which will output a config file that you can copy and paste into openvpn.conf on your server. You'll want make sure that the following files exist in /root/openvpn (or whatever your root directory is): ca.crt (so that the server can verify the validity of client certificates), dh.pem (for encryption of the connection), server.crt (the server's public key), server.key (the server's private key), ta.key (shared secret between server and clients), and crl.pem (so that the server will reject revoked certificates). -== OpenVPN client +=== OpenVPN client Each client will need: user.key, user.crt, ca.crt and ta.key. Make sure to enable tls-auth = 1. diff --git a/bin/vpnmaker b/bin/vpnmaker index 53f6ca0..bef724c 100755 --- a/bin/vpnmaker +++ b/bin/vpnmaker @@ -145,6 +145,42 @@ module VPNMaker puts db.config_generator.server end } + mode('install') { + description "this will make /etc/openvpn/[your server].ovpn.conf and crl.pem and some files to make NAT work, look into basedir" + def run + #FIXME: This needs to be cleaned up + iptables_nat_rules = < Date: Thu, 10 May 2012 23:55:31 +0200 Subject: [PATCH 54/81] Version bump to 1.0.9 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 337a6a8..e5a4a5e 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.0.8 \ No newline at end of file +1.0.9 \ No newline at end of file From 95abaaaa8a691d1456a1056529c7602b0455b09b Mon Sep 17 00:00:00 2001 From: Voip Scout Date: Thu, 10 May 2012 23:56:40 +0200 Subject: [PATCH 55/81] Regenerate gemspec for version 1.0.9 --- vpnmaker.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vpnmaker.gemspec b/vpnmaker.gemspec index ca08d1e..a3e99d7 100644 --- a/vpnmaker.gemspec +++ b/vpnmaker.gemspec @@ -5,7 +5,7 @@ Gem::Specification.new do |s| s.name = "vpnmaker" - s.version = "1.0.8" + s.version = "1.0.9" s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= s.authors = ["Voip Scout"] From 04486e6ac8d9615a2b4d697192f6f873ac666e22 Mon Sep 17 00:00:00 2001 From: Voip Scout Date: Fri, 11 May 2012 00:47:25 +0200 Subject: [PATCH 56/81] even saner template --- lib/server.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/server.haml b/lib/server.haml index 61f4f4a..250088c 100644 --- a/lib/server.haml +++ b/lib/server.haml @@ -2,7 +2,7 @@ \# See http://github.com/pc/vpnmaker mode server dev tun0 -local #{host} +\#local #{host} proto udp port #{port} server #{base_ip[:net]} #{base_ip[:mask]} From aacddef3dce881b7b5a3bd45abf3dfe87cf9ee78 Mon Sep 17 00:00:00 2001 From: Voip Scout Date: Fri, 11 May 2012 10:53:31 +0200 Subject: [PATCH 57/81] deps --- Gemfile | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/Gemfile b/Gemfile index c50ff38..9e8c7f1 100644 --- a/Gemfile +++ b/Gemfile @@ -27,24 +27,24 @@ gem 'highline' #, :git => 'https://github.com/JEG2/highline.git' gem 'gibberish', :git => 'git://github.com/mdp/gibberish.git' #gem 'cert_lib', :git => 'git://github.com/victorgrey/cert_lib.git' + # model stuff -gem 'datamapper', "~> 1.2.0" -# gem 'dm-do-adapter' -gem 'dm-aggregates' -gem 'dm-types', "~> 1.2.1" -gem 'dm-observer' -gem 'dm-migrations' -gem 'dm-timestamps' -gem 'dm-serializer', "~> 1.2.0" -gem 'dm-validations' -gem 'dm-mysql-adapter' +# gem 'datamapper', "~> 1.2.0" +# gem 'dm-aggregates' +# gem 'dm-types', "~> 1.2.1" +# gem 'dm-observer' +# gem 'dm-migrations' +# gem 'dm-timestamps' +# gem 'dm-serializer', "~> 1.2.0" +# gem 'dm-validations' +# gem 'dm-mysql-adapter' # support libs gem 'chronic' gem 'ipaddr_extensions' #, :git => 'git://github.com/jamesotron/IPAddrExtensions.git' -gem 'rubyzip', :git => 'git://github.com/aussiegeek/rubyzip.git' +# gem 'rubyzip', :git => 'git://github.com/aussiegeek/rubyzip.git' # reporting -gem 'ruport' -gem 'ruport-util' +# gem 'ruport' +# gem 'ruport-util' From a4e1b8d4bd7455a57fb6bc6c2b039c1e36a1b404 Mon Sep 17 00:00:00 2001 From: Voip Scout Date: Fri, 11 May 2012 10:55:23 +0200 Subject: [PATCH 58/81] Version bump to 1.0.10 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 66c4c22..437d26b 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.0.9 +1.0.10 \ No newline at end of file From bf9c0a42e661f94279aac4d5abb91ee7d37c98ed Mon Sep 17 00:00:00 2001 From: Voip Scout Date: Fri, 11 May 2012 10:55:35 +0200 Subject: [PATCH 59/81] Regenerate gemspec for version 1.0.10 --- vpnmaker.gemspec | 40 ++-------------------------------------- 1 file changed, 2 insertions(+), 38 deletions(-) diff --git a/vpnmaker.gemspec b/vpnmaker.gemspec index a3e99d7..47cfc25 100644 --- a/vpnmaker.gemspec +++ b/vpnmaker.gemspec @@ -5,11 +5,11 @@ Gem::Specification.new do |s| s.name = "vpnmaker" - s.version = "1.0.9" + s.version = "1.0.10" s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= s.authors = ["Voip Scout"] - s.date = "2012-05-10" + s.date = "2012-05-11" s.description = "haml templates and key tracking" s.email = "voipscout@gmail.com" s.executables = ["vpnmaker"] @@ -53,20 +53,8 @@ Gem::Specification.new do |s| s.add_runtime_dependency(%q
, [">= 0"]) s.add_runtime_dependency(%q, [">= 0"]) s.add_runtime_dependency(%q, [">= 0"]) - s.add_runtime_dependency(%q, ["~> 1.2.0"]) - s.add_runtime_dependency(%q, [">= 0"]) - s.add_runtime_dependency(%q, ["~> 1.2.1"]) - s.add_runtime_dependency(%q, [">= 0"]) - s.add_runtime_dependency(%q, [">= 0"]) - s.add_runtime_dependency(%q, [">= 0"]) - s.add_runtime_dependency(%q, ["~> 1.2.0"]) - s.add_runtime_dependency(%q, [">= 0"]) - s.add_runtime_dependency(%q, [">= 0"]) s.add_runtime_dependency(%q, [">= 0"]) s.add_runtime_dependency(%q, [">= 0"]) - s.add_runtime_dependency(%q, [">= 0"]) - s.add_runtime_dependency(%q, [">= 0"]) - s.add_runtime_dependency(%q, [">= 0"]) s.add_development_dependency(%q, [">= 0"]) s.add_development_dependency(%q, [">= 0"]) s.add_development_dependency(%q, [">= 0"]) @@ -82,20 +70,8 @@ Gem::Specification.new do |s| s.add_dependency(%q
, [">= 0"]) s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, ["~> 1.2.0"]) - s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, ["~> 1.2.1"]) - s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, ["~> 1.2.0"]) - s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) @@ -112,20 +88,8 @@ Gem::Specification.new do |s| s.add_dependency(%q
, [">= 0"]) s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, ["~> 1.2.0"]) - s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, ["~> 1.2.1"]) - s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, ["~> 1.2.0"]) - s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) From 56207485239881f0c1a10757936a649bf5b423bc Mon Sep 17 00:00:00 2001 From: Voip Scout Date: Sat, 12 May 2012 18:38:16 +0200 Subject: [PATCH 60/81] as suggested by patrick --- Gemfile | 2 ++ Rakefile | 63 ---------------------------------------------------- bin/vpnmaker | 36 ++++++------------------------ 3 files changed, 9 insertions(+), 92 deletions(-) diff --git a/Gemfile b/Gemfile index 9e8c7f1..1a7e382 100644 --- a/Gemfile +++ b/Gemfile @@ -48,3 +48,5 @@ gem 'ipaddr_extensions' # reporting # gem 'ruport' # gem 'ruport-util' + +gem 'ya_email_validator' diff --git a/Rakefile b/Rakefile index d1b2dc0..ebb5382 100644 --- a/Rakefile +++ b/Rakefile @@ -1,5 +1,4 @@ # encoding: utf-8 - require 'rubygems' require 'bundler' begin @@ -26,23 +25,6 @@ Jeweler::Tasks.new do |gem| end Jeweler::RubygemsDotOrgTasks.new -# require 'rake/testtask' -# Rake::TestTask.new(:test) do |test| -# test.libs << 'lib' << 'test' -# test.pattern = 'test/**/test_*.rb' -# test.verbose = true -# end - -# require 'rcov/rcovtask' -# Rcov::RcovTask.new do |test| -# test.libs << 'test' -# test.pattern = 'test/**/test_*.rb' -# test.verbose = true -# test.rcov_opts << '--exclude "gems/*"' -# end - -# task :default => :test - require 'rdoc/task' Rake::RDocTask.new do |rdoc| version = File.exist?('VERSION') ? File.read('VERSION') : "" @@ -52,48 +34,3 @@ Rake::RDocTask.new do |rdoc| rdoc.rdoc_files.include('README*') rdoc.rdoc_files.include('lib/**/*.rb') end - -# require 'highline/import' -# require File.join(File.dirname(__FILE__), 'vpnmaker') - -# def get_arg(argname, echo=true) -# return ENV[argname] if ENV[argname] -# ask("Value for #{argname}?") { |q| q.echo = false unless echo } -# end - -# namespace :config do -# desc 'Generate server config' -# task :server => :environment do -# puts $manager.config_generator.server -# end - -# desc 'Generate client config' -# task :client => :environment do -# username = get_arg('username') -# puts $manager.config_generator.client($manager.user(username)) -# end -# end - -# namespace :user do -# desc 'Create a new user' -# task :create => :environment do -# cn = get_arg('cn') -# name = get_arg('name') -# email = get_arg('email') -# password = get_arg('password', false) -# confirm_password = get_arg('confirm_password', false) -# raise ArgumentError.new("Password mismatch") unless password == confirm_password - -# if password.length > 0 -# $manager.create_user(cn, name, email, password) -# else -# $manager.create_user(cn, name, email) -# end -# end -# end - -# # Set up environment -# task :environment do -# vpndir = get_arg('vpndir') -# $manager = VPNMaker::Manager.new(vpndir) -# end diff --git a/bin/vpnmaker b/bin/vpnmaker index bef724c..8237018 100755 --- a/bin/vpnmaker +++ b/bin/vpnmaker @@ -2,35 +2,20 @@ require_relative '../lib/vpnmaker.rb' #require 'micro-optparse' #require 'highline' +require 'ya_email_validator' require 'highline/import' require 'main' + +class String; include YaEmailValidator; end + #TODO: use ~/.vpnmaker .vpnmaker and /etc/vpnmaker | maybe vpnmakerrc module VPNMaker module CLI - module RFC822 - EmailAddress = begin - qtext = '[^\\x0d\\x22\\x5c\\x80-\\xff]' - dtext = '[^\\x0d\\x5b-\\x5d\\x80-\\xff]' - atom = '[^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-' + - '\\x3c\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+' - quoted_pair = '\\x5c[\\x00-\\x7f]' - domain_literal = "\\x5b(?:#{dtext}|#{quoted_pair})*\\x5d" - quoted_string = "\\x22(?:#{qtext}|#{quoted_pair})*\\x22" - domain_ref = atom - sub_domain = "(?:#{domain_ref}|#{domain_literal})" - word = "(?:#{atom}|#{quoted_string})" - domain = "#{sub_domain}(?:\\x2e#{sub_domain})*" - local_part = "#{word}(?:\\x2e#{word})*" - addr_spec = "#{local_part}\\x40#{domain}" - pattern = /\A#{addr_spec.force_encoding('ASCII-8BIT')}\z/ - end - end - class Options # main DSL Main do - version '0.0.1' + version File.read(File.expand_path("../..", __FILE__) + "/VERSION") author 'Copyleft(cl) VoipScout - No rights reserved' mode('init') { @@ -74,7 +59,7 @@ module VPNMaker required cast :string arity 1 - validate {|e| e =~ RFC822::EmailAddress} + validate {|e| e.email?} } } #mode 'cli' @@ -122,6 +107,7 @@ module VPNMaker :client_conf_dir => client_config_dir.split('/').last } } + example_config = YAML.load_file(lib_dir + "/example_vpnmaker_site.config.yaml").to_yaml.gsub(/\n|---/, "\n#") File.open((File.expand_path(dir) + "/" + name + ".vpn" + "/" + name + ".config.yaml"), 'w') {|f| f.write(initial_config.to_yaml + example_config)} mgr = VPNMaker::Manager.new((File.expand_path(dir) + "/" + name + ".vpn")) @@ -294,14 +280,6 @@ EOS } - # Global run() is overwritten by specific mode run - def run - puts "Hitting global run()" - params.each {|p| pp "#{p.class} - #{p.name} => #{p.value}"} - @opts = params - pp @opts - end - def db VPNMaker::Manager.new params['dir'].value end From 274c242dbd7770bf49bcafef128f90ed234f8e05 Mon Sep 17 00:00:00 2001 From: Voip Scout Date: Sat, 12 May 2012 18:47:07 +0200 Subject: [PATCH 61/81] get_init_config method --- bin/vpnmaker | 88 +++++++++++++++++++++++++++------------------------- 1 file changed, 45 insertions(+), 43 deletions(-) diff --git a/bin/vpnmaker b/bin/vpnmaker index 8237018..7e13b2a 100755 --- a/bin/vpnmaker +++ b/bin/vpnmaker @@ -6,7 +6,7 @@ require 'ya_email_validator' require 'highline/import' require 'main' - +# This validates email addresses class String; include YaEmailValidator; end #TODO: use ~/.vpnmaker .vpnmaker and /etc/vpnmaker | maybe vpnmakerrc @@ -75,47 +75,9 @@ module VPNMaker arity 1 validate {|dir| File.directory?(File.expand_path(dir))} } - def run - name = params['conf_name'].value - dir = params['new_dir_path'].value - - VPNMaker.generate name, dir - - data_dir = (File.expand_path(dir) + "/" + name + ".vpn" + "/" + name + "_data") - template_dir = (File.expand_path(dir) + "/" + name + ".vpn" + "/" + name + "_templates") - client_config_dir = (File.expand_path(dir) + "/" + name + ".vpn" + "/" + name + "_client_configs") - - [data_dir, template_dir, client_config_dir].each {|dir| FileUtils.mkdir_p(dir)} - lib_dir = File.dirname(File.expand_path __FILE__).gsub('/bin', '/lib') - FileUtils.cp Dir.glob(lib_dir + "/*.haml"), template_dir - - if params['email'].given? - initial_config = { - :key_properties => { - :country => params['country'].value, - :province => params['province'].value, - :city => params['city'].value, - :organization => params['organization'].value, - :organization_unit => params['organization_unit'].value, - :common_name => params['common_name'].value, - :name => params['key_name'].value, - :email => params['email'].value - }, - :site => { - :data_dir => data_dir.split('/').last, - :template_dir => template_dir.split('/').last, - :client_conf_dir => client_config_dir.split('/').last - } - } - example_config = YAML.load_file(lib_dir + "/example_vpnmaker_site.config.yaml").to_yaml.gsub(/\n|---/, "\n#") - File.open((File.expand_path(dir) + "/" + name + ".vpn" + "/" + name + ".config.yaml"), 'w') {|f| f.write(initial_config.to_yaml + example_config)} - mgr = VPNMaker::Manager.new((File.expand_path(dir) + "/" + name + ".vpn")) - mgr.build_ca - say("Please edit files in #{template_dir} and #{dir}/#{name}.vpn/#{name}.config.yaml before proceeding further") - else - say('Time to mod yaml files') - end + def run + get_init_config end } @@ -284,11 +246,51 @@ EOS VPNMaker::Manager.new params['dir'].value end + def get_init_config + name = params['conf_name'].value + dir = params['new_dir_path'].value + + VPNMaker.generate name, dir + + data_dir = (File.expand_path(dir) + "/" + name + ".vpn" + "/" + name + "_data") + template_dir = (File.expand_path(dir) + "/" + name + ".vpn" + "/" + name + "_templates") + client_config_dir = (File.expand_path(dir) + "/" + name + ".vpn" + "/" + name + "_client_configs") + + [data_dir, template_dir, client_config_dir].each {|dir| FileUtils.mkdir_p(dir)} + lib_dir = File.dirname(File.expand_path __FILE__).gsub('/bin', '/lib') + FileUtils.cp Dir.glob(lib_dir + "/*.haml"), template_dir + + if params['email'].given? + initial_config = { + :key_properties => { + :country => params['country'].value, + :province => params['province'].value, + :city => params['city'].value, + :organization => params['organization'].value, + :organization_unit => params['organization_unit'].value, + :common_name => params['common_name'].value, + :name => params['key_name'].value, + :email => params['email'].value + }, + :site => { + :data_dir => data_dir.split('/').last, + :template_dir => template_dir.split('/').last, + :client_conf_dir => client_config_dir.split('/').last + } + } - end # + example_config = YAML.load_file(lib_dir + "/example_vpnmaker_site.config.yaml").to_yaml.gsub(/\n|---/, "\n#") + File.open((File.expand_path(dir) + "/" + name + ".vpn" + "/" + name + ".config.yaml"), 'w') {|f| f.write(initial_config.to_yaml + example_config)} + mgr = VPNMaker::Manager.new((File.expand_path(dir) + "/" + name + ".vpn")) + mgr.build_ca + say("Please edit files in #{template_dir} and #{dir}/#{name}.vpn/#{name}.config.yaml before proceeding further") + else + say('Time to mod yaml files') + end + end + end # Main {} end #class Options - end #module CLI end #module VPNMaker From 0dcec9ab17281ea7c64e867b06069dd1ca2b698a Mon Sep 17 00:00:00 2001 From: Voip Scout Date: Sat, 12 May 2012 18:48:31 +0200 Subject: [PATCH 62/81] Version bump to 1.0.11 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 437d26b..8684498 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.0.10 \ No newline at end of file +1.0.11 \ No newline at end of file From 066084e03a3771c717eebad9db9164edf0d5a28d Mon Sep 17 00:00:00 2001 From: Voip Scout Date: Sat, 12 May 2012 18:48:50 +0200 Subject: [PATCH 63/81] Regenerate gemspec for version 1.0.11 --- vpnmaker.gemspec | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/vpnmaker.gemspec b/vpnmaker.gemspec index 47cfc25..83184c1 100644 --- a/vpnmaker.gemspec +++ b/vpnmaker.gemspec @@ -5,11 +5,11 @@ Gem::Specification.new do |s| s.name = "vpnmaker" - s.version = "1.0.10" + s.version = "1.0.11" s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= s.authors = ["Voip Scout"] - s.date = "2012-05-11" + s.date = "2012-05-12" s.description = "haml templates and key tracking" s.email = "voipscout@gmail.com" s.executables = ["vpnmaker"] @@ -55,6 +55,7 @@ Gem::Specification.new do |s| s.add_runtime_dependency(%q, [">= 0"]) s.add_runtime_dependency(%q, [">= 0"]) s.add_runtime_dependency(%q, [">= 0"]) + s.add_runtime_dependency(%q, [">= 0"]) s.add_development_dependency(%q, [">= 0"]) s.add_development_dependency(%q, [">= 0"]) s.add_development_dependency(%q, [">= 0"]) @@ -72,6 +73,7 @@ Gem::Specification.new do |s| s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) @@ -90,6 +92,7 @@ Gem::Specification.new do |s| s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) From 3be4192b1ffc5a1bcc9ba516386f56b9fabf62d6 Mon Sep 17 00:00:00 2001 From: Robert McLeod Date: Mon, 21 Apr 2014 13:10:03 +1200 Subject: [PATCH 64/81] added rspec and added some passing spec, with 1 failing spec --- Gemfile | 2 ++ Rakefile | 8 +++++++ spec/lib/vpnmaker/key_tracker_spec.rb | 8 +++++++ spec/lib/vpnmaker/manager_spec.rb | 32 +++++++++++++++++++++++++++ spec/spec_helper.rb | 26 ++++++++++++++++++++++ 5 files changed, 76 insertions(+) create mode 100644 spec/lib/vpnmaker/key_tracker_spec.rb create mode 100644 spec/lib/vpnmaker/manager_spec.rb create mode 100644 spec/spec_helper.rb diff --git a/Gemfile b/Gemfile index 1a7e382..a33c69e 100644 --- a/Gemfile +++ b/Gemfile @@ -11,6 +11,8 @@ group :development do gem "rdoc" #, "~> 3.12" gem "bundler" #, "~> 1.0.0" gem "jeweler" #, "~> 1.8.3" + gem "rspec" + gem "fakefs", require: false end gem 'haml' diff --git a/Rakefile b/Rakefile index ebb5382..0505085 100644 --- a/Rakefile +++ b/Rakefile @@ -1,6 +1,7 @@ # encoding: utf-8 require 'rubygems' require 'bundler' + begin Bundler.setup(:default, :development) rescue Bundler::BundlerError => e @@ -9,6 +10,12 @@ rescue Bundler::BundlerError => e exit e.status_code end require 'rake' +require "rspec/core/rake_task" + +RSpec::Core::RakeTask.new + +task :test => :spec + require 'jeweler' Jeweler::Tasks.new do |gem| @@ -34,3 +41,4 @@ Rake::RDocTask.new do |rdoc| rdoc.rdoc_files.include('README*') rdoc.rdoc_files.include('lib/**/*.rb') end + diff --git a/spec/lib/vpnmaker/key_tracker_spec.rb b/spec/lib/vpnmaker/key_tracker_spec.rb new file mode 100644 index 0000000..c978c33 --- /dev/null +++ b/spec/lib/vpnmaker/key_tracker_spec.rb @@ -0,0 +1,8 @@ +require 'spec_helper' + +describe VPNMaker::KeyTracker, fakefs: true do + it "should generate the config folders" do + VPNMaker::KeyTracker.generate("my", vpn_root) + expect(File.directory? vpn_root(:my)).to be_true + end +end \ No newline at end of file diff --git a/spec/lib/vpnmaker/manager_spec.rb b/spec/lib/vpnmaker/manager_spec.rb new file mode 100644 index 0000000..dbb3c91 --- /dev/null +++ b/spec/lib/vpnmaker/manager_spec.rb @@ -0,0 +1,32 @@ +require 'spec_helper' +require 'fileutils' + +describe VPNMaker::Manager, fakefs: true do + before(:each) do + FileUtils.mkdir_p "/tmp/keybuilder" + end + + context "when there is no config file" do + it "should raise an error" do + expect { VPNMaker::Manager.new vpn_root(:my) }.to raise_error + end + end + + context "when there is a config file" do + before(:each) do + VPNMaker.generate "my", vpn_root + File.open("#{vpn_root(:my)}/my.config.yaml", "w") { |f| f.write key_props.to_yaml } + end + + it "should create an instance of manager" do + expect( VPNMaker::Manager.new vpn_root(:my) ).to be_an_instance_of VPNMaker::Manager + end + + it "should be able to build the ca files" do + VPNMaker::Manager.new( vpn_root(:my) ).build_ca + expect(File.exist? "#{vpn_data(:my)}/ca.crt").to be_true + expect(File.exist? "#{vpn_data(:my)}/ca.key").to be_true + end + end + +end \ No newline at end of file diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb new file mode 100644 index 0000000..8ec495c --- /dev/null +++ b/spec/spec_helper.rb @@ -0,0 +1,26 @@ +require 'vpnmaker' +require 'fakefs/spec_helpers' + +RSpec.configure do |config| + config.include FakeFS::SpecHelpers, fakefs: true +end + +def vpn_root(name=nil) + return "/vpns" if name.nil? + "/vpns/#{name}.vpn" +end + +def vpn_data(name) + "#{vpn_root(name)}/#{name}_data" +end + +def key_props + { :key_properties => { + :country => "US", + :province => "CA", + :city => "San Francisco", + :organization => "Entropy", + :email => "test@example.com" + } + } +end \ No newline at end of file From 10b6d13ddca4608c1f8586934e26e57c03bb5442 Mon Sep 17 00:00:00 2001 From: Robert McLeod Date: Mon, 21 Apr 2014 14:01:07 +1200 Subject: [PATCH 65/81] chasing down a bug in KeyBuilder - added console to the rake task (not working yet) - made a templates directory for the haml files - made an examples directory --- Rakefile | 17 +++++++++++++++++ lib/vpnmaker.rb | 16 ++++++++++++++-- lib/vpnmaker/key_builder.rb | 6 +++++- spec/lib/vpnmaker/manager_spec.rb | 1 + {lib => templates}/openssl.haml | 0 .../vpn.config.yaml | 0 6 files changed, 37 insertions(+), 3 deletions(-) rename {lib => templates}/openssl.haml (100%) rename lib/example_vpnmaker_site.config.yaml => templates/vpn.config.yaml (100%) diff --git a/Rakefile b/Rakefile index 0505085..fab19cc 100644 --- a/Rakefile +++ b/Rakefile @@ -16,6 +16,23 @@ RSpec::Core::RakeTask.new task :test => :spec +task :console do + begin + # use Pry if it exists + require 'pry' + require 'vpnmaker' + Pry.start + rescue LoadError + require 'irb' + require 'irb/completion' + require 'vpnmaker' + ARGV.clear + IRB.start + end +end + +task :c => :console + require 'jeweler' Jeweler::Tasks.new do |gem| diff --git a/lib/vpnmaker.rb b/lib/vpnmaker.rb index b8d84ed..b7588ec 100644 --- a/lib/vpnmaker.rb +++ b/lib/vpnmaker.rb @@ -43,7 +43,19 @@ module VPNMaker autoload :Manager, "#{path}vpnmaker/manager" autoload :KeyBuilder, "#{path}vpnmaker/key_builder" - def self.generate(*args) - KeyTracker.generate(args.first, args.last) + class << self + def root + spec = Gem::Specification.find_by_name("VPNMaker") + spec.gem_dir + end + + def template_path(name=nil) + return "#{root}/templates" if name.nil? + "#{root}/templates/#{name}" + end + + def generate(*args) + KeyTracker.generate(args.first, args.last) + end end end diff --git a/lib/vpnmaker/key_builder.rb b/lib/vpnmaker/key_builder.rb index b7cfcd3..d5dd5cd 100644 --- a/lib/vpnmaker/key_builder.rb +++ b/lib/vpnmaker/key_builder.rb @@ -38,8 +38,12 @@ def init def opensslcnf(hash={}) c = cnfpath + template = File.read(VPNMaker.template_path('openssl.haml')) + haml = Haml::Engine.new(template) + config = haml.render(Object.new, opensslvars.merge(hash)) + File.open(cnfpath, 'w') do |f| - f.write(Haml::Engine.new(File.read(@tracker.path + "/" + @config[:site][:template_dir] + "/" + 'openssl.haml')).render(Object.new, opensslvars.merge(hash))) + f.write(config) end c diff --git a/spec/lib/vpnmaker/manager_spec.rb b/spec/lib/vpnmaker/manager_spec.rb index dbb3c91..717caec 100644 --- a/spec/lib/vpnmaker/manager_spec.rb +++ b/spec/lib/vpnmaker/manager_spec.rb @@ -23,6 +23,7 @@ end it "should be able to build the ca files" do + raise RuntimeError, VPNMaker.template_path VPNMaker::Manager.new( vpn_root(:my) ).build_ca expect(File.exist? "#{vpn_data(:my)}/ca.crt").to be_true expect(File.exist? "#{vpn_data(:my)}/ca.key").to be_true diff --git a/lib/openssl.haml b/templates/openssl.haml similarity index 100% rename from lib/openssl.haml rename to templates/openssl.haml diff --git a/lib/example_vpnmaker_site.config.yaml b/templates/vpn.config.yaml similarity index 100% rename from lib/example_vpnmaker_site.config.yaml rename to templates/vpn.config.yaml From 799d89f0d401ba62a9141c415182b2baa9e1c0f6 Mon Sep 17 00:00:00 2001 From: Robert McLeod Date: Mon, 21 Apr 2014 14:16:11 +1200 Subject: [PATCH 66/81] tidied up the gemspec file --- vpnmaker.gemspec | 43 ++++++++++--------------------------------- 1 file changed, 10 insertions(+), 33 deletions(-) diff --git a/vpnmaker.gemspec b/vpnmaker.gemspec index 83184c1..e774be1 100644 --- a/vpnmaker.gemspec +++ b/vpnmaker.gemspec @@ -4,46 +4,23 @@ # -*- encoding: utf-8 -*- Gem::Specification.new do |s| + s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= + s.name = "vpnmaker" s.version = "1.0.11" - - s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= - s.authors = ["Voip Scout"] + s.authors = ["Voip Scout", "Robert McLeod"] + s.email = "voipscout@gmail.com" s.date = "2012-05-12" s.description = "haml templates and key tracking" - s.email = "voipscout@gmail.com" - s.executables = ["vpnmaker"] - s.extra_rdoc_files = [ - "README.rdoc" - ] - s.files = [ - ".document", - "Gemfile", - "README.rdoc", - "Rakefile", - "VERSION", - "bin/vpnmaker", - "lib/client.haml", - "lib/datastore.rb", - "lib/datastore/ca.rb", - "lib/datastore/user.rb", - "lib/example_vpnmaker_site.config.yaml", - "lib/openssl.haml", - "lib/server.haml", - "lib/vpnmaker.rb", - "lib/vpnmaker/config_generator.rb", - "lib/vpnmaker/key_builder.rb", - "lib/vpnmaker/key_config.rb", - "lib/vpnmaker/key_db.rb", - "lib/vpnmaker/key_tracker.rb", - "lib/vpnmaker/manager.rb", - "vpnmaker.gemspec" - ] + s.summary = "Makes it easy to manage OpenVPN" s.homepage = "http://github.com/voipscout/vpnmaker" s.licenses = ["MIT"] - s.require_paths = ["lib"] s.rubygems_version = "1.8.24" - s.summary = "Makes it easy to manage OpenVPN" + + s.executables = ["vpnmaker"] + s.extra_rdoc_files = ["README.rdoc"] + s.files = `git ls-files`.split($/) + s.require_paths = ["lib"] if s.respond_to? :specification_version then s.specification_version = 3 From f0926dc644ecf232c525ddf9dc20afc8ea9e9fce Mon Sep 17 00:00:00 2001 From: Robert McLeod Date: Mon, 21 Apr 2014 14:51:59 +1200 Subject: [PATCH 67/81] fixed the bug, had to ditch fakefs though Due to the way we load the HAML templates using fakefs means that VPNMaker won't find the templates --- Gemfile | 1 - lib/vpnmaker.rb | 20 ++++++++++---------- root | 1 + spec/lib/vpn_maker_spec.rb | 14 ++++++++++++++ spec/lib/vpnmaker/key_tracker_spec.rb | 7 ++++++- spec/lib/vpnmaker/manager_spec.rb | 8 ++++++-- spec/spec_helper.rb | 11 +++++++---- vpnmaker.gemspec | 1 - 8 files changed, 44 insertions(+), 19 deletions(-) create mode 100644 root create mode 100644 spec/lib/vpn_maker_spec.rb diff --git a/Gemfile b/Gemfile index a33c69e..9f96816 100644 --- a/Gemfile +++ b/Gemfile @@ -12,7 +12,6 @@ group :development do gem "bundler" #, "~> 1.0.0" gem "jeweler" #, "~> 1.8.3" gem "rspec" - gem "fakefs", require: false end gem 'haml' diff --git a/lib/vpnmaker.rb b/lib/vpnmaker.rb index b7588ec..91ada84 100644 --- a/lib/vpnmaker.rb +++ b/lib/vpnmaker.rb @@ -32,21 +32,21 @@ def binding; super; end # normally private end module VPNMaker - path = (File.dirname File.expand_path(__FILE__)) + "/" - autoload :DataStore, "#{path}datastore" + ROOT = File.dirname File.dirname __FILE__ - autoload :ConfigGenerator, "#{path}vpnmaker/config_generator" - autoload :KeyDB, "#{path}vpnmaker/key_db" - autoload :KeyConfig, "#{path}vpnmaker/key_config" - autoload :KeyTracker, "#{path}vpnmaker/key_tracker" - autoload :Manager, "#{path}vpnmaker/manager" - autoload :KeyBuilder, "#{path}vpnmaker/key_builder" + autoload :DataStore, File.join(ROOT, "lib", "datastore") + autoload :ConfigGenerator, File.join(ROOT, "lib", "vpnmaker", "config_generator") + autoload :KeyDB, File.join(ROOT, "lib", "vpnmaker", "key_db") + autoload :KeyConfig, File.join(ROOT, "lib", "vpnmaker", "key_config") + autoload :KeyTracker, File.join(ROOT, "lib", "vpnmaker", "key_tracker") + autoload :Manager, File.join(ROOT, "lib", "vpnmaker", "manager") + autoload :KeyBuilder, File.join(ROOT, "lib", "vpnmaker", "key_builder") class << self + def root - spec = Gem::Specification.find_by_name("VPNMaker") - spec.gem_dir + VPNMaker::ROOT end def template_path(name=nil) diff --git a/root b/root new file mode 100644 index 0000000..c25f980 --- /dev/null +++ b/root @@ -0,0 +1 @@ +/home/robert/src/vpnmaker \ No newline at end of file diff --git a/spec/lib/vpn_maker_spec.rb b/spec/lib/vpn_maker_spec.rb new file mode 100644 index 0000000..09214c6 --- /dev/null +++ b/spec/lib/vpn_maker_spec.rb @@ -0,0 +1,14 @@ +require 'spec_helper' + +describe VPNMaker do + + after(:each) do + FileUtils.rm_rf vpn_root + end + + it "should generate a vpn" do + VPNMaker.generate("my", vpn_root) + expect(File.exist? vpn_root(:my)).to be_true + end + +end \ No newline at end of file diff --git a/spec/lib/vpnmaker/key_tracker_spec.rb b/spec/lib/vpnmaker/key_tracker_spec.rb index c978c33..e881cf2 100644 --- a/spec/lib/vpnmaker/key_tracker_spec.rb +++ b/spec/lib/vpnmaker/key_tracker_spec.rb @@ -1,6 +1,11 @@ require 'spec_helper' -describe VPNMaker::KeyTracker, fakefs: true do +describe VPNMaker::KeyTracker do + + after(:each) do + FileUtils.rm_rf vpn_root + end + it "should generate the config folders" do VPNMaker::KeyTracker.generate("my", vpn_root) expect(File.directory? vpn_root(:my)).to be_true diff --git a/spec/lib/vpnmaker/manager_spec.rb b/spec/lib/vpnmaker/manager_spec.rb index 717caec..9d24065 100644 --- a/spec/lib/vpnmaker/manager_spec.rb +++ b/spec/lib/vpnmaker/manager_spec.rb @@ -1,11 +1,15 @@ require 'spec_helper' require 'fileutils' -describe VPNMaker::Manager, fakefs: true do +describe VPNMaker::Manager do before(:each) do FileUtils.mkdir_p "/tmp/keybuilder" end + after(:each) do + FileUtils.rm_rf vpn_root + end + context "when there is no config file" do it "should raise an error" do expect { VPNMaker::Manager.new vpn_root(:my) }.to raise_error @@ -23,7 +27,7 @@ end it "should be able to build the ca files" do - raise RuntimeError, VPNMaker.template_path +expect(File.exist? "/home/robert/src/vpnmaker/templates/openssl.haml").to be_true VPNMaker::Manager.new( vpn_root(:my) ).build_ca expect(File.exist? "#{vpn_data(:my)}/ca.crt").to be_true expect(File.exist? "#{vpn_data(:my)}/ca.key").to be_true diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 8ec495c..0ae0315 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,13 +1,16 @@ require 'vpnmaker' -require 'fakefs/spec_helpers' RSpec.configure do |config| - config.include FakeFS::SpecHelpers, fakefs: true +end + +def testfs + root = File.dirname File.dirname __FILE__ + "#{root}/tmp" end def vpn_root(name=nil) - return "/vpns" if name.nil? - "/vpns/#{name}.vpn" + return "#{testfs}/vpns" if name.nil? + "#{testfs}/vpns/#{name}.vpn" end def vpn_data(name) diff --git a/vpnmaker.gemspec b/vpnmaker.gemspec index e774be1..f2599a4 100644 --- a/vpnmaker.gemspec +++ b/vpnmaker.gemspec @@ -15,7 +15,6 @@ Gem::Specification.new do |s| s.summary = "Makes it easy to manage OpenVPN" s.homepage = "http://github.com/voipscout/vpnmaker" s.licenses = ["MIT"] - s.rubygems_version = "1.8.24" s.executables = ["vpnmaker"] s.extra_rdoc_files = ["README.rdoc"] From 158fc0d58f65b88df0fd171996c8a835eac21401 Mon Sep 17 00:00:00 2001 From: Robert McLeod Date: Mon, 21 Apr 2014 15:01:09 +1200 Subject: [PATCH 68/81] fixed the manager spec --- spec/lib/vpnmaker/manager_spec.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/spec/lib/vpnmaker/manager_spec.rb b/spec/lib/vpnmaker/manager_spec.rb index 9d24065..b901b27 100644 --- a/spec/lib/vpnmaker/manager_spec.rb +++ b/spec/lib/vpnmaker/manager_spec.rb @@ -27,7 +27,6 @@ end it "should be able to build the ca files" do -expect(File.exist? "/home/robert/src/vpnmaker/templates/openssl.haml").to be_true VPNMaker::Manager.new( vpn_root(:my) ).build_ca expect(File.exist? "#{vpn_data(:my)}/ca.crt").to be_true expect(File.exist? "#{vpn_data(:my)}/ca.key").to be_true From 76505caa856182089b4854515cc1513777e0f3c4 Mon Sep 17 00:00:00 2001 From: Robert McLeod Date: Mon, 21 Apr 2014 15:01:41 +1200 Subject: [PATCH 69/81] made the config generator use templates from the template directory also replaced string concats with File.join --- lib/vpnmaker/config_generator.rb | 32 ++++++++++++++++---------------- {lib => templates}/client.haml | 0 {lib => templates}/server.haml | 0 3 files changed, 16 insertions(+), 16 deletions(-) rename {lib => templates}/client.haml (100%) rename {lib => templates}/server.haml (100%) diff --git a/lib/vpnmaker/config_generator.rb b/lib/vpnmaker/config_generator.rb index b810f3d..b80be45 100644 --- a/lib/vpnmaker/config_generator.rb +++ b/lib/vpnmaker/config_generator.rb @@ -6,37 +6,39 @@ def initialize(*args) end def default_template - @dirname = (@mgr.tracker.path + "/" + @mgr.config[:site][:data_dir]) + @dirname = (File.join(@mgr, @mgr.tracker.path, @mgr.config[:site][:data_dir])) { :type => :default, - :dh => File.read(@dirname + "/dh.pem"), - :ca => File.read(@dirname + "/ca.crt"), - :ta => File.read(@dirname + "/ta.key") + :dh => File.read(File.join(@dirname, "dh.pem")), + :ca => File.read(File.join(@dirname, "ca.crt")), + :ta => File.read(File.join(@dirname, "ta.key")) } end def client_conf(client) fname = client[:user] + '-' + ((client[:revoked].max || - 1) + 1).to_s separator = '-----BEGIN CERTIFICATE-----' - cert = File.read(@dirname + "/#{fname}.crt").split(separator).last.insert(0, separator) + cert = File.read(File.join(@dirname, "#{fname}.crt")).split(separator).last.insert(0, separator) { :gen_host => Socket.gethostname, :server => @mgr.config[:server], :client => @mgr.config[:client] - }.merge(client).merge(:key => File.read(@dirname + "/#{fname}.key" ), + }.merge(client).merge(:key => File.read(File.join(@dirname, "#{fname}.key")), :cert => cert).merge(@runtime_cfg) end def server_conf separator = '-----BEGIN CERTIFICATE-----' - cert = File.read(@dirname + "/server.crt").split(separator).last.insert(0, separator) + cert = File.read(File.join(@dirname, "server.crt")).split(separator).last.insert(0, separator) { :gen_host => Socket.gethostname, :crl_path => @mgr.tracker.path - }.merge(@mgr.config[:server]).merge(@runtime_cfg).merge(:key => File.read(@dirname + "/server.key"), - :cert => cert, - :crl => File.read(@dirname + "/crl.pem")) + }.merge(@mgr.config[:server]).merge(@runtime_cfg).merge( + :key => File.read(File.join(@dirname, "server.key")), + :cert => cert, + :crl => File.read(File.join(@dirname, "crl.pem")) + ) end def server @@ -44,17 +46,15 @@ def server haml_vars[:base_ip] = ((a = IPAddr.new haml_vars[:base_ip]); {:net => a.to_s, :mask => a.subnet_mask.to_s}) haml_vars[:bridgednets] ? (haml_vars[:bridgednets] = haml_vars[:bridgednets].map {|net| a = (IPAddr.new net); {:net => a.to_s, :mask => a.subnet_mask.to_s}}) : (haml_vars[:bridgednets] = Hash.new) haml_vars[:subnets] ? (haml_vars[:subnets] = haml_vars[:subnets].map {|net| a = (IPAddr.new net); {:net => a.to_s, :mask => a.subnet_mask.to_s}}) : (haml_vars[:subnets] = Hash.new) - template = File.read(@mgr.tracker.path + \ - "/" + @mgr.config[:site][:template_dir] + \ - "/" + 'server.haml') + + template = File.read(VPNMaker.template_path 'server.haml') Haml::Engine.new(template).render(Object.new, haml_vars) end def client(client) haml_vars = client_conf(client).dup - template = File.read(@mgr.tracker.path + \ - "/" + @mgr.config[:site][:template_dir] + \ - "/" + 'client.haml') + + template = File.read(VPNMaker.template_path 'client.haml') Haml::Engine.new(template).render(Object.new, haml_vars) end end diff --git a/lib/client.haml b/templates/client.haml similarity index 100% rename from lib/client.haml rename to templates/client.haml diff --git a/lib/server.haml b/templates/server.haml similarity index 100% rename from lib/server.haml rename to templates/server.haml From d9cb0346aca9669ac5747633529c7a5c0dd17485 Mon Sep 17 00:00:00 2001 From: Robert McLeod Date: Mon, 21 Apr 2014 15:27:00 +1200 Subject: [PATCH 70/81] moved intialize to the top of the file getting so confused thinking self.generate is initialize.... --- lib/vpnmaker/key_tracker.rb | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/lib/vpnmaker/key_tracker.rb b/lib/vpnmaker/key_tracker.rb index edab3e7..726577e 100644 --- a/lib/vpnmaker/key_tracker.rb +++ b/lib/vpnmaker/key_tracker.rb @@ -5,6 +5,13 @@ class KeyTracker attr_reader :config attr_reader :path + def initialize(name, dir) + @path = dir + @db = KeyDB.new(File.join(dir, name + '.db.yaml')) + @config = KeyConfig.new(File.join(dir, name + '.config.yaml')) + @builder = KeyBuilder.new(self, @config) + end + def self.generate(name, path=nil) path ||= '/tmp' dir = File.join(File.expand_path(path), name + '.vpn') @@ -13,12 +20,12 @@ def self.generate(name, path=nil) datadir = "#{name}_data" dbpath = File.join(dir, "#{name}.db.yaml") - d = KeyDB.new(dbpath) - d[:version] = 0 - d[:modified] = Time.now - d[:users] = {} - d[:datadir] = datadir - d.sync + db = KeyDB.new(dbpath) + db[:version] = 0 + db[:modified] = Time.now + db[:users] = {} + db[:datadir] = datadir + db.sync end def assert_user(user) @@ -145,13 +152,6 @@ def user(user) end def users; @db[:users]; end - - def initialize(name, dir) - @path = dir - @db = KeyDB.new(File.join(dir, name + '.db.yaml')) - @config = KeyConfig.new(File.join(dir, name + '.config.yaml')) - @builder = KeyBuilder.new(self, @config) - end end def self.generate(name, path) From bcc5763240755731a881318bd1b538c8482ac0bb Mon Sep 17 00:00:00 2001 From: Robert McLeod Date: Mon, 21 Apr 2014 15:27:58 +1200 Subject: [PATCH 71/81] made openssl config and tmp files be stored in vpn path instead of /tmp data leakage what? --- lib/vpnmaker/key_builder.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/vpnmaker/key_builder.rb b/lib/vpnmaker/key_builder.rb index d5dd5cd..21f5173 100644 --- a/lib/vpnmaker/key_builder.rb +++ b/lib/vpnmaker/key_builder.rb @@ -1,7 +1,7 @@ module VPNMaker class KeyBuilder def initialize(tracker, config) - @tmpdir = '/tmp/keybuilder' + @tmpdir = File.join tracker.path, "tmp" clean_tmpdir @tracker = tracker @config = config @@ -12,7 +12,7 @@ def clean_tmpdir FileUtils.mkdir_p(@tmpdir) end - def cnfpath; "/tmp/openssl-#{$$}.cnf"; end + def cnfpath; File.join @tmpdir, "openssl-#{$$}.cnf"; end def opensslvars { From ee3e604ff03c08a053affdfe0d4180935fb5c193 Mon Sep 17 00:00:00 2001 From: Robert McLeod Date: Mon, 21 Apr 2014 15:28:22 +1200 Subject: [PATCH 72/81] made the manager spec check for the existance of other files --- spec/lib/vpnmaker/manager_spec.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/spec/lib/vpnmaker/manager_spec.rb b/spec/lib/vpnmaker/manager_spec.rb index b901b27..551d2a1 100644 --- a/spec/lib/vpnmaker/manager_spec.rb +++ b/spec/lib/vpnmaker/manager_spec.rb @@ -26,11 +26,15 @@ expect( VPNMaker::Manager.new vpn_root(:my) ).to be_an_instance_of VPNMaker::Manager end - it "should be able to build the ca files" do + it "should build the intial keys and files" do VPNMaker::Manager.new( vpn_root(:my) ).build_ca expect(File.exist? "#{vpn_data(:my)}/ca.crt").to be_true expect(File.exist? "#{vpn_data(:my)}/ca.key").to be_true + expect(File.exist? "#{vpn_data(:my)}/crl.pem").to be_true + expect(File.exist? "#{vpn_data(:my)}/index.txt").to be_true + expect(File.exist? "#{vpn_data(:my)}/serial").to be_true end + end end \ No newline at end of file From 874c10a9188595df5e20da4b6678aa6a440932fd Mon Sep 17 00:00:00 2001 From: Robert McLeod Date: Mon, 21 Apr 2014 18:13:44 +1200 Subject: [PATCH 73/81] made key_builder raise BuildErrors when generated files are empty --- lib/vpnmaker.rb | 2 ++ lib/vpnmaker/key_builder.rb | 13 +++++++++++++ 2 files changed, 15 insertions(+) diff --git a/lib/vpnmaker.rb b/lib/vpnmaker.rb index 91ada84..bd3594f 100644 --- a/lib/vpnmaker.rb +++ b/lib/vpnmaker.rb @@ -33,6 +33,8 @@ def binding; super; end # normally private module VPNMaker + class BuildError < StandardError; end + ROOT = File.dirname File.dirname __FILE__ autoload :DataStore, File.join(ROOT, "lib", "datastore") diff --git a/lib/vpnmaker/key_builder.rb b/lib/vpnmaker/key_builder.rb index 21f5173..b079da8 100644 --- a/lib/vpnmaker/key_builder.rb +++ b/lib/vpnmaker/key_builder.rb @@ -52,6 +52,9 @@ def opensslcnf(hash={}) # Build Diffie-Hellman parameters for the server side of an SSL/TLS connection. def build_dh_key(keysize=1024) `openssl dhparam -out #{tmppath('dh.pem')} #{keysize}` + + raise BuildError, "DH key was empty" if tmpfile('dh.pem').empty? + @tracker.set_dh(tmpfile('dh.pem')) end @@ -61,6 +64,8 @@ def ca def gen_crl `openssl ca -gencrl -crldays 3650 -keyfile #{tmppath('ca.key')} -cert #{tmppath('ca.crt')} -out #{tmppath('crl.pem')} -config #{opensslcnf}` + + raise BuildError, "CRL was empty" if tmpfile('crl.pem').empty? end def build_ca @@ -69,7 +74,12 @@ def build_ca FileUtils.touch(index) `openssl req -batch -days 3650 -nodes -new -x509 -keyout #{@tmpdir}/ca.key -out #{@tmpdir}/ca.crt -config #{opensslcnf}` + gen_crl + + raise BuildError, "CA certificate was empty" if tmpfile('ca.crt').empty? + raise BuildError, "CA key was empty" if tmpfile('ca.key').empty? + @tracker.set_ca(tmpfile('ca.key'), tmpfile('ca.crt'), tmpfile('crl.pem'), tmpfile('index.txt'), "01\n") end @@ -82,6 +92,9 @@ def build_server_key `openssl req -batch -days 3650 -nodes -new -keyout #{tmppath('server.key')} -out #{tmppath('server.csr')} -extensions server -config #{opensslcnf}` `openssl ca -batch -days 3650 -out #{tmppath('server.crt')} -in #{tmppath('server.csr')} -extensions server -config #{opensslcnf}` + raise BuildError, "Server certificate was empty" if tmpfile('server.crt').empty? + raise BuildError, "Server key was empty" if tmpfile('server.key').empty? + @tracker.set_server_key(tmpfile('server.key'), tmpfile('server.crt'), tmpfile('index.txt'), tmpfile('serial')) end From 21e494278bcfeea7e1a5618e8b76a074ace1aedc Mon Sep 17 00:00:00 2001 From: Robert McLeod Date: Mon, 21 Apr 2014 18:14:53 +1200 Subject: [PATCH 74/81] changed the data dir location so it wasn't prefixed --- lib/vpnmaker/config_generator.rb | 2 +- lib/vpnmaker/key_tracker.rb | 3 +-- lib/vpnmaker/manager.rb | 4 +++- spec/spec_helper.rb | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/lib/vpnmaker/config_generator.rb b/lib/vpnmaker/config_generator.rb index b80be45..d3663c9 100644 --- a/lib/vpnmaker/config_generator.rb +++ b/lib/vpnmaker/config_generator.rb @@ -6,7 +6,7 @@ def initialize(*args) end def default_template - @dirname = (File.join(@mgr, @mgr.tracker.path, @mgr.config[:site][:data_dir])) + @dirname = (File.join(@mgr.data_dir)) { :type => :default, :dh => File.read(File.join(@dirname, "dh.pem")), diff --git a/lib/vpnmaker/key_tracker.rb b/lib/vpnmaker/key_tracker.rb index 726577e..4660ad1 100644 --- a/lib/vpnmaker/key_tracker.rb +++ b/lib/vpnmaker/key_tracker.rb @@ -17,14 +17,13 @@ def self.generate(name, path=nil) dir = File.join(File.expand_path(path), name + '.vpn') FileUtils.mkdir_p(dir) - datadir = "#{name}_data" dbpath = File.join(dir, "#{name}.db.yaml") db = KeyDB.new(dbpath) db[:version] = 0 db[:modified] = Time.now db[:users] = {} - db[:datadir] = datadir + db[:datadir] = "data" db.sync end diff --git a/lib/vpnmaker/manager.rb b/lib/vpnmaker/manager.rb index f8552ec..eda9535 100644 --- a/lib/vpnmaker/manager.rb +++ b/lib/vpnmaker/manager.rb @@ -1,17 +1,19 @@ module VPNMaker class Manager - attr_reader :tracker + attr_reader :tracker, :data_dir def self.vpn_name(dir); dir =~ /(^|\/)([^\/\.]+)\.vpn/ ? $2 : nil; end def initialize(dir) name = self.class.vpn_name(File.expand_path(dir)) @tracker = KeyTracker.new(name, File.expand_path(dir)) + @data_dir = File.join File.expand_path(dir), "data" end def config; @tracker.config; end def build_ca; @tracker.builder.build_ca; end + def build_server @tracker.builder.build_server_key @tracker.builder.build_ta_key diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 0ae0315..dd39266 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -14,7 +14,7 @@ def vpn_root(name=nil) end def vpn_data(name) - "#{vpn_root(name)}/#{name}_data" + "#{vpn_root(name)}/data" end def key_props From 87e4772876075fe51ade9d13adf39c98a4c03573 Mon Sep 17 00:00:00 2001 From: Robert McLeod Date: Mon, 21 Apr 2014 18:15:17 +1200 Subject: [PATCH 75/81] fixed bug where server.crt was generated empty --- lib/vpnmaker/key_builder.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/vpnmaker/key_builder.rb b/lib/vpnmaker/key_builder.rb index b079da8..e16c938 100644 --- a/lib/vpnmaker/key_builder.rb +++ b/lib/vpnmaker/key_builder.rb @@ -90,7 +90,7 @@ def build_server_key place_file('serial') `openssl req -batch -days 3650 -nodes -new -keyout #{tmppath('server.key')} -out #{tmppath('server.csr')} -extensions server -config #{opensslcnf}` - `openssl ca -batch -days 3650 -out #{tmppath('server.crt')} -in #{tmppath('server.csr')} -extensions server -config #{opensslcnf}` + `openssl req -batch -days 3650 -out #{tmppath('server.crt')} -in #{tmppath('server.csr')} -extensions server -config #{opensslcnf}` raise BuildError, "Server certificate was empty" if tmpfile('server.crt').empty? raise BuildError, "Server key was empty" if tmpfile('server.key').empty? From df7285f4a4de7dbf64976b9944ffef77ca9a8e14 Mon Sep 17 00:00:00 2001 From: Robert McLeod Date: Mon, 21 Apr 2014 18:16:06 +1200 Subject: [PATCH 76/81] added server props in test, used subject in manager spec, added a few specs --- spec/lib/vpnmaker/manager_spec.rb | 37 +++++++++++++++++++++++++++++++ spec/spec_helper.rb | 15 ++++++++++++- 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/spec/lib/vpnmaker/manager_spec.rb b/spec/lib/vpnmaker/manager_spec.rb index 551d2a1..5225784 100644 --- a/spec/lib/vpnmaker/manager_spec.rb +++ b/spec/lib/vpnmaker/manager_spec.rb @@ -2,6 +2,8 @@ require 'fileutils' describe VPNMaker::Manager do + subject(:manager) { VPNMaker::Manager.new( vpn_root(:my) ) } + before(:each) do FileUtils.mkdir_p "/tmp/keybuilder" end @@ -35,6 +37,41 @@ expect(File.exist? "#{vpn_data(:my)}/serial").to be_true end + it "should build the server keys" do + manager.build_ca + manager.build_server + expect(File.exist? "#{vpn_data(:my)}/server.crt").to be_true + expect(File.exist? "#{vpn_data(:my)}/server.key").to be_true + expect(File.exist? "#{vpn_data(:my)}/dh.pem").to be_true + expect(File.exist? "#{vpn_data(:my)}/ta.key").to be_true + end + + context "when there are no server configs" do + it "should raise an error" do + expect { + VPNMaker::Manager.new( vpn_root(:my) ).config_generator.server + }.to raise_error + end + end + + context "when there are server configs" do + before(:each) do + c = YAML.load_file("#{vpn_root(:my)}/my.config.yaml") + c.merge! server_props + File.open("#{vpn_root(:my)}/my.config.yaml", "w") { |f| f.write c.to_yaml } + end + + it "should build the server config" do + manager.build_ca + manager.build_server + # pry + config = manager.config_generator.server + expect(config).to include "10.10.10.0" + expect(config).to include "example.com" + expect(config).to include "1194" + end + end + end end \ No newline at end of file diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index dd39266..db5073c 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -22,8 +22,21 @@ def key_props :country => "US", :province => "CA", :city => "San Francisco", - :organization => "Entropy", + :organization => "VPNMaker", :email => "test@example.com" } } +end + +def server_props + { :server => { + :base_ip => "10.10.10.0", + :user => "nouser", + :group => "nogroup", + :root => "/root/openvpn", + :log => "/var/log/openvpn.log", + :host => "example.com", + :port => "1194" + } + } end \ No newline at end of file From d04614709be7ed832e0d257f5921bb0b68532ba5 Mon Sep 17 00:00:00 2001 From: Robert McLeod Date: Mon, 21 Apr 2014 20:12:32 +1200 Subject: [PATCH 77/81] renamed the VPNMaker spec file, used subject in manager spec --- spec/lib/vpnmaker/manager_spec.rb | 7 +++---- spec/lib/{vpn_maker_spec.rb => vpnmaker_spec.rb} | 0 2 files changed, 3 insertions(+), 4 deletions(-) rename spec/lib/{vpn_maker_spec.rb => vpnmaker_spec.rb} (100%) diff --git a/spec/lib/vpnmaker/manager_spec.rb b/spec/lib/vpnmaker/manager_spec.rb index 5225784..3ccff5f 100644 --- a/spec/lib/vpnmaker/manager_spec.rb +++ b/spec/lib/vpnmaker/manager_spec.rb @@ -25,11 +25,11 @@ end it "should create an instance of manager" do - expect( VPNMaker::Manager.new vpn_root(:my) ).to be_an_instance_of VPNMaker::Manager + expect( manager ).to be_an_instance_of VPNMaker::Manager end it "should build the intial keys and files" do - VPNMaker::Manager.new( vpn_root(:my) ).build_ca + manager.build_ca expect(File.exist? "#{vpn_data(:my)}/ca.crt").to be_true expect(File.exist? "#{vpn_data(:my)}/ca.key").to be_true expect(File.exist? "#{vpn_data(:my)}/crl.pem").to be_true @@ -49,7 +49,7 @@ context "when there are no server configs" do it "should raise an error" do expect { - VPNMaker::Manager.new( vpn_root(:my) ).config_generator.server + manager.config_generator.server }.to raise_error end end @@ -64,7 +64,6 @@ it "should build the server config" do manager.build_ca manager.build_server - # pry config = manager.config_generator.server expect(config).to include "10.10.10.0" expect(config).to include "example.com" diff --git a/spec/lib/vpn_maker_spec.rb b/spec/lib/vpnmaker_spec.rb similarity index 100% rename from spec/lib/vpn_maker_spec.rb rename to spec/lib/vpnmaker_spec.rb From 4d42be80122d852bc54cc9d2f94661ea6eddaf56 Mon Sep 17 00:00:00 2001 From: Robert McLeod Date: Mon, 21 Apr 2014 21:28:43 +1200 Subject: [PATCH 78/81] added some more user specs --- spec/lib/vpnmaker/manager_spec.rb | 36 +++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/spec/lib/vpnmaker/manager_spec.rb b/spec/lib/vpnmaker/manager_spec.rb index 3ccff5f..f83cd9f 100644 --- a/spec/lib/vpnmaker/manager_spec.rb +++ b/spec/lib/vpnmaker/manager_spec.rb @@ -46,6 +46,42 @@ expect(File.exist? "#{vpn_data(:my)}/ta.key").to be_true end + it "should create a new user" do + manager.build_ca + manager.build_server + manager.create_user 'joe', 'Joe Bloggs', 'joe.bloggs@example.com', 'password' + expect(manager.users).to include "joe" + end + + context "and a user has been created" do + before(:each) do + manager.build_ca + manager.build_server + manager.create_user 'joe', 'Joe Bloggs', 'joe.bloggs@example.com', 'password' + end + + it "should have user details" do + details = manager.user('joe') + expect(details).to be_a Hash + expect(details[:email]).to eq 'joe.bloggs@example.com' + end + + it "should have no revoked keys" do + details = manager.user('joe') + expect(details[:revoked]).to be_empty + expect(details[:active_key]).to eq 0 + end + + context "and a user has had a key revoked" do + it "should have a revoked key in the user details" do + manager.regenerate_user('joe', 'newpassword') + details = manager.user('joe') + expect(details[:revoked]).to eq [0] + expect(details[:active_key]).to eq 1 + end + end + end + context "when there are no server configs" do it "should raise an error" do expect { From a930ba894314623ab03019bbe2bd687745c6dd31 Mon Sep 17 00:00:00 2001 From: Robert McLeod Date: Mon, 21 Apr 2014 21:30:24 +1200 Subject: [PATCH 79/81] updated readme file --- README.rdoc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.rdoc b/README.rdoc index 676e083..4321e3b 100644 --- a/README.rdoc +++ b/README.rdoc @@ -97,3 +97,7 @@ Which will output a config file that you can copy and paste into openvpn.con === OpenVPN client Each client will need: user.key, user.crt, ca.crt and ta.key. Make sure to enable tls-auth = 1. + +== Testing + +Tests are done with Rspec. To run the tests simply run `bundle exec rake test` or `bundle exec rake spec`. \ No newline at end of file From a90ad8d4c74aa2b33680fc466bc949c76810a8fc Mon Sep 17 00:00:00 2001 From: Robert McLeod Date: Mon, 21 Apr 2014 21:47:55 +1200 Subject: [PATCH 80/81] switched to use bundle for rake tasks instead of jeweler --- Rakefile | 18 +----------------- vpnmaker.gemspec | 10 +--------- 2 files changed, 2 insertions(+), 26 deletions(-) diff --git a/Rakefile b/Rakefile index fab19cc..8223fef 100644 --- a/Rakefile +++ b/Rakefile @@ -1,6 +1,6 @@ # encoding: utf-8 require 'rubygems' -require 'bundler' +require 'bundler/gem_tasks' begin Bundler.setup(:default, :development) @@ -34,21 +34,6 @@ end task :c => :console -require 'jeweler' -Jeweler::Tasks.new do |gem| - # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options - gem.name = "vpnmaker" - gem.executables = 'vpnmaker' - gem.homepage = "http://github.com/voipscout/vpnmaker" - gem.license = "MIT" - gem.summary = %Q{Makes it easy to manage OpenVPN} - gem.description = %Q{haml templates and key tracking} - gem.email = "voipscout@gmail.com" - gem.authors = ["Voip Scout"] - # dependencies defined in Gemfile -end -Jeweler::RubygemsDotOrgTasks.new - require 'rdoc/task' Rake::RDocTask.new do |rdoc| version = File.exist?('VERSION') ? File.read('VERSION') : "" @@ -58,4 +43,3 @@ Rake::RDocTask.new do |rdoc| rdoc.rdoc_files.include('README*') rdoc.rdoc_files.include('lib/**/*.rb') end - diff --git a/vpnmaker.gemspec b/vpnmaker.gemspec index f2599a4..c72475e 100644 --- a/vpnmaker.gemspec +++ b/vpnmaker.gemspec @@ -1,13 +1,8 @@ -# Generated by jeweler -# DO NOT EDIT THIS FILE DIRECTLY -# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec' -# -*- encoding: utf-8 -*- - Gem::Specification.new do |s| s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= s.name = "vpnmaker" - s.version = "1.0.11" + s.version = "1.1" s.authors = ["Voip Scout", "Robert McLeod"] s.email = "voipscout@gmail.com" s.date = "2012-05-12" @@ -41,7 +36,6 @@ Gem::Specification.new do |s| s.add_development_dependency(%q, [">= 0"]) s.add_development_dependency(%q, [">= 0"]) s.add_development_dependency(%q, [">= 0"]) - s.add_development_dependency(%q, [">= 0"]) else s.add_dependency(%q, [">= 0"]) s.add_dependency(%q
, [">= 0"]) @@ -59,7 +53,6 @@ Gem::Specification.new do |s| s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, [">= 0"]) end else s.add_dependency(%q, [">= 0"]) @@ -78,7 +71,6 @@ Gem::Specification.new do |s| s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, [">= 0"]) end end From 60017c5d91aa39c6ee31de1f720fa2dc62aec818 Mon Sep 17 00:00:00 2001 From: Robert McLeod Date: Mon, 21 Apr 2014 22:15:57 +1200 Subject: [PATCH 81/81] added the version file in --- lib/vpnmaker/version.rb | 3 +++ vpnmaker.gemspec | 6 +++++- 2 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 lib/vpnmaker/version.rb diff --git a/lib/vpnmaker/version.rb b/lib/vpnmaker/version.rb new file mode 100644 index 0000000..993a6f6 --- /dev/null +++ b/lib/vpnmaker/version.rb @@ -0,0 +1,3 @@ +module VPNMaker + VERSION = "1.1" +end \ No newline at end of file diff --git a/vpnmaker.gemspec b/vpnmaker.gemspec index c72475e..28e64bc 100644 --- a/vpnmaker.gemspec +++ b/vpnmaker.gemspec @@ -1,8 +1,12 @@ +lib = File.expand_path("../lib", __FILE__) +$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) +require 'vpnmaker/version' + Gem::Specification.new do |s| s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= s.name = "vpnmaker" - s.version = "1.1" + s.version = VPNMaker::VERSION s.authors = ["Voip Scout", "Robert McLeod"] s.email = "voipscout@gmail.com" s.date = "2012-05-12"