From d91d70dd378a4a91c740b03b0852432ef128b24a Mon Sep 17 00:00:00 2001 From: mh Date: Fri, 4 Nov 2016 18:52:39 +0100 Subject: store key & hostname --- lib/puppet/parser/functions/generate_onion_key.rb | 22 ++++++--- manifests/daemon/onion_service.pp | 56 +++++++++++++++++++++++ manifests/daemon/onions_service.pp | 56 ----------------------- spec/functions/generate_onion_key_spec.rb | 10 ++-- templates/torrc.hidden_service.erb | 6 --- templates/torrc.onion_service.erb | 6 +++ 6 files changed, 82 insertions(+), 74 deletions(-) create mode 100644 manifests/daemon/onion_service.pp delete mode 100644 manifests/daemon/onions_service.pp delete mode 100644 templates/torrc.hidden_service.erb create mode 100644 templates/torrc.onion_service.erb diff --git a/lib/puppet/parser/functions/generate_onion_key.rb b/lib/puppet/parser/functions/generate_onion_key.rb index 2964268..9ee5351 100644 --- a/lib/puppet/parser/functions/generate_onion_key.rb +++ b/lib/puppet/parser/functions/generate_onion_key.rb @@ -7,12 +7,13 @@ Requires a location to load and store the private key, as well an identifier, wh Example: - res = generate_onion_key('/tmp','my_secrect_key') + res = generate_onion_key('/tmp','my_secret_key') notice "Onion Address: \${res[0]" notice "Priavte Key: \${res[1]" -If /tmp/my_secrect_key.key exists, it will be loaded and the onion address will be generated from it. +It will also store the onion address under /tmp/my_secret_key.hostname. +If /tmp/my_secret_key.key exists, but not the hostname file. Then the function will be loaded and the onion address will be generated from it. EOS ) do |args| @@ -24,17 +25,24 @@ If /tmp/my_secrect_key.key exists, it will be loaded and the onion address will raise(Puppet::ParseError, "generate_onion_key(): requires location (#{location}) to be a directory") unless File.directory?(location) path = File.join(location,identifier) - private_key = if File.exists?(path) - pk = OpenSSL::PKey::RSA.new(File.read(path)) - raise(Puppet::ParseError, "generate_onion_key(): key in path #{path} must have a length of 1024bit") unless (pk.n.num_bytes * 8) == 1024 + private_key = if File.exists?(kf="#{path}.key") + pk = OpenSSL::PKey::RSA.new(File.read(kf)) + raise(Puppet::ParseError, "generate_onion_key(): key in path #{kf} must have a length of 1024bit") unless (pk.n.num_bytes * 8) == 1024 pk else # 1024 is hardcoded by tor pk = OpenSSL::PKey::RSA.generate(1024) - File.open(path,'w'){|f| f << pk.to_s } + File.open(kf,'w'){|f| f << pk.to_s } pk end + onion_address = if File.exists?(hf="#{path}.hostname") + File.read(hf) + else + oa = function_onion_address([private_key]) + File.open(hf,'w'){|f| f << oa.to_s } + oa + end - [ function_onion_address([private_key]), private_key.to_s ] + [ onion_address, private_key.to_s ] end end diff --git a/manifests/daemon/onion_service.pp b/manifests/daemon/onion_service.pp new file mode 100644 index 0000000..2625521 --- /dev/null +++ b/manifests/daemon/onion_service.pp @@ -0,0 +1,56 @@ +# onion services definition +define tor::daemon::onion_service( + $ensure = present, + $ports = [], + $data_dir = $tor::daemon::data_dir, + $private_key = undef, + $private_key_name = $name, + $private_key_store_path = undef, +) { + + $data_dir_path = "${data_dir}/${name}" + include ::tor::daemon::params + concat::fragment { "05.onion_service.${name}": + ensure => $ensure, + content => template('tor/torrc.onion_service.erb'), + order => '05', + target => $tor::daemon::config_file, + } + if $private_key or ($private_key_name and $private_key_store_path) { + if $private_key and ($private_key_name and $private_key_store_path) { + fail("Either private_key OR (private_key_name AND private_key_store_path) must be set, but not all three of them") + } + if $private_key_store_path and $private_key_name { + $tmp = generate_onion_key($private_key_store_path,$private_key_name) + $os_hostname = $tmp[0] + $real_private_key = $tmp[1] + } else { + $os_hostname = onion_address($private_key) + $real_private_key = $private_key + } + file{ + $data_dir_path: + ensure => directory, + purge => true, + force => true, + recurse => true, + owner => $tor::daemon::params::user, + group => $tor::daemon::params::group, + mode => '0600', + require => Package['tor']; + "${data_dir_path}/private_key": + content => $real_private_key, + owner => $tor::daemon::params::user, + group => $tor::daemon::params::group, + mode => '0600', + notify => Service['tor']; + "${data_dir_path}/hostname": + content => "${os_hostname}.onion\n", + owner => $tor::daemon::params::user, + group => $tor::daemon::params::group, + mode => '0600', + notify => Service['tor']; + } + } +} + diff --git a/manifests/daemon/onions_service.pp b/manifests/daemon/onions_service.pp deleted file mode 100644 index 2625521..0000000 --- a/manifests/daemon/onions_service.pp +++ /dev/null @@ -1,56 +0,0 @@ -# onion services definition -define tor::daemon::onion_service( - $ensure = present, - $ports = [], - $data_dir = $tor::daemon::data_dir, - $private_key = undef, - $private_key_name = $name, - $private_key_store_path = undef, -) { - - $data_dir_path = "${data_dir}/${name}" - include ::tor::daemon::params - concat::fragment { "05.onion_service.${name}": - ensure => $ensure, - content => template('tor/torrc.onion_service.erb'), - order => '05', - target => $tor::daemon::config_file, - } - if $private_key or ($private_key_name and $private_key_store_path) { - if $private_key and ($private_key_name and $private_key_store_path) { - fail("Either private_key OR (private_key_name AND private_key_store_path) must be set, but not all three of them") - } - if $private_key_store_path and $private_key_name { - $tmp = generate_onion_key($private_key_store_path,$private_key_name) - $os_hostname = $tmp[0] - $real_private_key = $tmp[1] - } else { - $os_hostname = onion_address($private_key) - $real_private_key = $private_key - } - file{ - $data_dir_path: - ensure => directory, - purge => true, - force => true, - recurse => true, - owner => $tor::daemon::params::user, - group => $tor::daemon::params::group, - mode => '0600', - require => Package['tor']; - "${data_dir_path}/private_key": - content => $real_private_key, - owner => $tor::daemon::params::user, - group => $tor::daemon::params::group, - mode => '0600', - notify => Service['tor']; - "${data_dir_path}/hostname": - content => "${os_hostname}.onion\n", - owner => $tor::daemon::params::user, - group => $tor::daemon::params::group, - mode => '0600', - notify => Service['tor']; - } - } -} - diff --git a/spec/functions/generate_onion_key_spec.rb b/spec/functions/generate_onion_key_spec.rb index 07a9f91..355f862 100644 --- a/spec/functions/generate_onion_key_spec.rb +++ b/spec/functions/generate_onion_key_spec.rb @@ -4,7 +4,7 @@ require 'fileutils' describe 'generate_onion_key' do before(:all) do @tmp_path = File.expand_path(File.join(File.dirname(__FILE__),'..','fixtures','tmp')) - @test_path = File.join(@tmp_path,'test') + @test_path = File.join(@tmp_path,'test.key') @drpsyff5srkctr7h_str = "-----BEGIN RSA PRIVATE KEY----- MIICXAIBAAKBgQC9OUBOkL73n43ogC/Jma54/ZZDEpoisqpkGJHgbcRGJIxcqqfL PbnT3hD5SUCVXxLnzWDCTwTe2VOzIUlBXmslwVXnCJh/XGZg9NHiNU3EAZTwu1g9 @@ -51,10 +51,10 @@ znq+qT/KbJlwy/27X/auCAzD5rJ9VVzyWiu8nnwICS8= expect(return_value.size).to be(2) end it 'creates and stores the key' do - expect(return_value.last).to be_eql(File.read(File.join(@tmp_path,'test'))) + expect(return_value.last).to be_eql(File.read(File.join(@tmp_path,'test.key'))) end it 'returns a proper onion address' do - expect(return_value.first).to be_eql(scope.function_onion_address([File.read(File.join(@tmp_path,'test'))])) + expect(return_value.first).to be_eql(scope.function_onion_address([File.read(File.join(@tmp_path,'test.key'))])) end it 'does not recreate a key once created' do expect(scope.function_generate_onion_key([@tmp_path,'test'])).to be_eql(scope.function_generate_onion_key([@tmp_path,'test'])) @@ -65,9 +65,9 @@ znq+qT/KbJlwy/27X/auCAzD5rJ9VVzyWiu8nnwICS8= end context 'with an existing key' do before(:all) do - File.open(@test_path,'w'){|f| f << @drpsyff5srkctr7h_str } + File.open(File.join(@tmp_path,'test3.key'),'w'){|f| f << @drpsyff5srkctr7h_str } end - it { is_expected.to run.with_params(@tmp_path,'test').and_return(['drpsyff5srkctr7h',@drpsyff5srkctr7h_str]) } + it { is_expected.to run.with_params(@tmp_path,'test3').and_return(['drpsyff5srkctr7h',@drpsyff5srkctr7h_str]) } end end end diff --git a/templates/torrc.hidden_service.erb b/templates/torrc.hidden_service.erb deleted file mode 100644 index 77168d8..0000000 --- a/templates/torrc.hidden_service.erb +++ /dev/null @@ -1,6 +0,0 @@ -# hidden service <%= @name %> -HiddenServiceDir <%= @data_dir_path %> -<% Array(@ports).each do |port| -%> -HiddenServicePort <%= port =~ /^\d+$/ ? "#{port} 127.0.0.1:#{port}" : port %> -<% end -%> - diff --git a/templates/torrc.onion_service.erb b/templates/torrc.onion_service.erb new file mode 100644 index 0000000..77168d8 --- /dev/null +++ b/templates/torrc.onion_service.erb @@ -0,0 +1,6 @@ +# hidden service <%= @name %> +HiddenServiceDir <%= @data_dir_path %> +<% Array(@ports).each do |port| -%> +HiddenServicePort <%= port =~ /^\d+$/ ? "#{port} 127.0.0.1:#{port}" : port %> +<% end -%> + -- cgit v1.2.3