diff options
47 files changed, 526 insertions, 217 deletions
diff --git a/Vagrantfile b/Vagrantfile index ba5451aa..cb9392e3 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -1,23 +1,39 @@ # -*- mode: ruby -*- # vi: set ft=ruby : -Vagrant.configure("2") do |vagrant_config| - vagrant_config.vm.define :node1 do |config| - # Please verify the sha512 sum of the downloaded box before importing it into vagrant ! - # see https://leap.se/en/docs/platform/details/development#Verify.vagrantbox.download - # for details +Vagrant.configure("2") do |config| + # Please verify the sha512 sum of the downloaded box before importing it into vagrant ! + # see https://leap.se/en/docs/platform/details/development#Verify.vagrantbox.download + # for details + + config.vm.define :"wheezy", primary: true do |config| config.vm.box = "LEAP/wheezy" - #config.vm.network :private_network, ip: "10.5.5.102" + config.vm.provider "virtualbox" do |v| + v.customize ["modifyvm", :id, "--natdnshostresolver1", "on"] + v.name = "wheezy" + end + + config.vm.provision "puppet" do |puppet| + puppet.manifests_path = "./vagrant" + puppet.module_path = "./puppet/modules" + puppet.manifest_file = "install-platform.pp" + puppet.options = "--verbose" + end + config.vm.provision "shell", path: "vagrant/configure-leap.sh" + config.ssh.username = "vagrant" # forward leap_web ports config.vm.network "forwarded_port", guest: 80, host:8080 config.vm.network "forwarded_port", guest: 443, host:4443 + end + + config.vm.define :"jessie", autostart: false do |config| + config.vm.box = "LEAP/jessie" config.vm.provider "virtualbox" do |v| - v.memory = 1024 v.customize ["modifyvm", :id, "--natdnshostresolver1", "on"] - v.name = "node1" + v.name = "jessie" end config.vm.provision "puppet" do |puppet| @@ -27,8 +43,11 @@ Vagrant.configure("2") do |vagrant_config| puppet.options = "--verbose" end config.vm.provision "shell", path: "vagrant/configure-leap.sh" - config.ssh.username = "vagrant" + # forward leap_web ports + config.vm.network "forwarded_port", guest: 80, host:8080 + config.vm.network "forwarded_port", guest: 443, host:4443 end + end diff --git a/lib/leap_cli/commands/vagrant.rb b/lib/leap_cli/commands/vagrant.rb index e2dfb8a9..bf683cb6 100644 --- a/lib/leap_cli/commands/vagrant.rb +++ b/lib/leap_cli/commands/vagrant.rb @@ -14,7 +14,7 @@ module LeapCli; module Commands "`config.vm.box` option. The value here should be the name of an installed box or a "+ "shorthand name of a box in HashiCorp's Atlas.", :arg_name => 'BASEBOX', - :default_value => 'LEAP/wheezy' + :default_value => 'LEAP/jessie' ) start.action do |global_options,options,args| vagrant_command(["up", "sandbox on"], args, options) @@ -146,7 +146,7 @@ module LeapCli; module Commands lines = [] netmask = IPAddr.new('255.255.255.255').mask(LeapCli.leapfile.vagrant_network.split('/').last).to_s - basebox = options[:basebox] || 'LEAP/wheezy' + basebox = options[:basebox] || 'LEAP/jessie' if vagrant_version <= Gem::Version.new('1.1.0') lines << %[Vagrant::Config.run do |config|] diff --git a/puppet/lib/puppet/parser/functions/sorted_yaml.rb b/puppet/lib/puppet/parser/functions/sorted_yaml.rb index fa0db4d2..46cd46ce 100644 --- a/puppet/lib/puppet/parser/functions/sorted_yaml.rb +++ b/puppet/lib/puppet/parser/functions/sorted_yaml.rb @@ -382,7 +382,19 @@ class Ya2YAML end module Puppet::Parser::Functions - newfunction(:sorted_yaml, :type => :rvalue, :doc => "This function outputs yaml, but ensures the keys are sorted.") do |argument| - return Ya2YAML.new()._ya2yaml(argument) + newfunction(:sorted_yaml, + :type => :rvalue, + :doc => "This function outputs yaml, but ensures the keys are sorted." + ) do |arguments| + + if arguments.is_a?(Array) + if arguments.size != 1 + raise(Puppet::ParseError, "sorted_yaml(): Wrong number of arguments given (#{arguments.size} for 1)") + end + yaml = arguments.first + else + yaml = arguments + end + return Ya2YAML.new()._ya2yaml(yaml) end end diff --git a/puppet/modules/apache b/puppet/modules/apache -Subproject c3e92a9b3cb02f1546b6b1570f10a968d380005 +Subproject 41815f55ec7187a75aec4717c78270593f9776d diff --git a/puppet/modules/couchdb b/puppet/modules/couchdb -Subproject cdde1e172b3ed2c6c1f203341e75bcef5c3c349 +Subproject 016ec71359f6b1b368624c6c94bac2b50979165 diff --git a/puppet/modules/haproxy b/puppet/modules/haproxy -Subproject b398f3cb0a67d1170d0564a3f03977f9a08c2b6 +Subproject af322a73c013f80a958ab7d5d31d0c75cf6d052 diff --git a/puppet/modules/leap_mx/manifests/init.pp b/puppet/modules/leap_mx/manifests/init.pp index 284662d2..5561e326 100644 --- a/puppet/modules/leap_mx/manifests/init.pp +++ b/puppet/modules/leap_mx/manifests/init.pp @@ -41,13 +41,7 @@ class leap_mx { notify => Service['leap-mx']; } - file { '/etc/default/leap_mx': - content => 'LOGFILE=/var/log/leap/mx.log', - owner => 'root', - group => 'root', - mode => '0644', - notify => Service['leap-mx']; - } + leap::logfile { 'mx': } # # LEAP-MX CODE AND DEPENDENCIES @@ -75,20 +69,4 @@ class leap_mx { hasrestart => true, require => [ Package['leap-mx'] ]; } - - augeas { - 'logrotate_mx': - context => '/files/etc/logrotate.d/leap-mx/rule', - changes => [ - 'set file /var/log/leap/mx.log', - 'set rotate 5', - 'set schedule daily', - 'clear nocreate', - 'rm create', - 'rm ifempty', - 'set compress compress', - 'set missingok missingok', - 'set copytruncate copytruncate' - ] - } } diff --git a/puppet/modules/site_apache/manifests/common.pp b/puppet/modules/site_apache/manifests/common.pp index 64beb231..dadf7ea5 100644 --- a/puppet/modules/site_apache/manifests/common.pp +++ b/puppet/modules/site_apache/manifests/common.pp @@ -1,8 +1,26 @@ +# install basic apache modules needed for all services (nagios, webapp) class site_apache::common { - include site_apache::module::rewrite + include apache::module::rewrite + include apache::module::env class { '::apache': no_default_site => true, ssl => true } + # needed for the mod_ssl config + include apache::module::mime + + # load mods depending on apache version + if ( $::lsbdistcodename == 'jessie' ) { + # apache >= 2.4, debian jessie + # needed for mod_ssl config + include apache::module::socache_shmcb + # generally needed + include apache::module::mpm_prefork + } else { + # apache < 2.4, debian wheezy + # for "Order" directive, i.e. main apache2.conf + include apache::module::authz_host + } + include site_apache::common::tls } diff --git a/puppet/modules/site_apache/manifests/module/alias.pp b/puppet/modules/site_apache/manifests/module/alias.pp deleted file mode 100644 index c1f5e185..00000000 --- a/puppet/modules/site_apache/manifests/module/alias.pp +++ /dev/null @@ -1,5 +0,0 @@ -class site_apache::module::alias ( $ensure = present ) -{ - - apache::module { 'alias': ensure => $ensure } -} diff --git a/puppet/modules/site_apache/manifests/module/expires.pp b/puppet/modules/site_apache/manifests/module/expires.pp deleted file mode 100644 index f73a5607..00000000 --- a/puppet/modules/site_apache/manifests/module/expires.pp +++ /dev/null @@ -1,4 +0,0 @@ -class site_apache::module::expires ( $ensure = present ) -{ - apache::module { 'expires': ensure => $ensure } -} diff --git a/puppet/modules/site_apache/manifests/module/headers.pp b/puppet/modules/site_apache/manifests/module/headers.pp deleted file mode 100644 index f7caa28c..00000000 --- a/puppet/modules/site_apache/manifests/module/headers.pp +++ /dev/null @@ -1,5 +0,0 @@ -class site_apache::module::headers ( $ensure = present ) -{ - - apache::module {'headers': ensure => $ensure } -} diff --git a/puppet/modules/site_apache/manifests/module/removeip.pp b/puppet/modules/site_apache/manifests/module/removeip.pp deleted file mode 100644 index f106167a..00000000 --- a/puppet/modules/site_apache/manifests/module/removeip.pp +++ /dev/null @@ -1,5 +0,0 @@ -class site_apache::module::removeip ( $ensure = present ) -{ - package { 'libapache2-mod-removeip': ensure => $ensure } - apache::module { 'removeip': ensure => $ensure } -} diff --git a/puppet/modules/site_apache/manifests/module/rewrite.pp b/puppet/modules/site_apache/manifests/module/rewrite.pp deleted file mode 100644 index 7ad00a0c..00000000 --- a/puppet/modules/site_apache/manifests/module/rewrite.pp +++ /dev/null @@ -1,5 +0,0 @@ -class site_apache::module::rewrite ( $ensure = present ) -{ - - apache::module { 'rewrite': ensure => $ensure } -} diff --git a/puppet/modules/site_apache/templates/vhosts.d/api.conf.erb b/puppet/modules/site_apache/templates/vhosts.d/api.conf.erb index 0396f54b..9efc6b41 100644 --- a/puppet/modules/site_apache/templates/vhosts.d/api.conf.erb +++ b/puppet/modules/site_apache/templates/vhosts.d/api.conf.erb @@ -1,14 +1,14 @@ <VirtualHost *:80> - ServerName <%= api_domain %> + ServerName <%= @api_domain %> RewriteEngine On - RewriteRule ^.*$ https://<%= api_domain -%>:<%= api_port -%>%{REQUEST_URI} [R=permanent,L] + RewriteRule ^.*$ https://<%= @api_domain -%>:<%= @api_port -%>%{REQUEST_URI} [R=permanent,L] CustomLog ${APACHE_LOG_DIR}/other_vhosts_access.log common </VirtualHost> -Listen 0.0.0.0:<%= api_port %> +Listen 0.0.0.0:<%= @api_port %> -<VirtualHost *:<%= api_port -%>> - ServerName <%= api_domain %> +<VirtualHost *:<%= @api_port -%>> + ServerName <%= @api_domain %> CustomLog ${APACHE_LOG_DIR}/other_vhosts_access.log common SSLCACertificatePath /etc/ssl/certs @@ -27,6 +27,12 @@ Listen 0.0.0.0:<%= api_port %> </IfModule> DocumentRoot /srv/leap/webapp/public + <% if Gem::Version.new(@apache_version) > Gem::Version.new('2.3') %> + <Directory /srv/leap/webapp/public> + AllowOverride None + Require all granted + </Directory> + <% end %> # Check for maintenance file and redirect all requests RewriteEngine On diff --git a/puppet/modules/site_apache/templates/vhosts.d/common.conf.erb b/puppet/modules/site_apache/templates/vhosts.d/common.conf.erb index 7f9fd5ab..cbb08c30 100644 --- a/puppet/modules/site_apache/templates/vhosts.d/common.conf.erb +++ b/puppet/modules/site_apache/templates/vhosts.d/common.conf.erb @@ -1,18 +1,18 @@ <VirtualHost *:80> - ServerName <%= webapp_domain %> - ServerAlias <%= domain_name %> - ServerAlias <%= domain %> - ServerAlias www.<%= domain %> + ServerName <%= @webapp_domain %> + ServerAlias <%= @domain_name %> + ServerAlias <%= @domain %> + ServerAlias www.<%= @domain %> RewriteEngine On - RewriteRule ^.*$ https://<%= webapp_domain -%>%{REQUEST_URI} [R=permanent,L] + RewriteRule ^.*$ https://<%= @webapp_domain -%>%{REQUEST_URI} [R=permanent,L] CustomLog ${APACHE_LOG_DIR}/other_vhosts_access.log common </VirtualHost> <VirtualHost *:443> - ServerName <%= webapp_domain %> - ServerAlias <%= domain_name %> - ServerAlias <%= domain %> - ServerAlias www.<%= domain %> + ServerName <%= @webapp_domain %> + ServerAlias <%= @domain_name %> + ServerAlias <%= @domain %> + ServerAlias www.<%= @domain %> CustomLog ${APACHE_LOG_DIR}/other_vhosts_access.log common SSLCACertificatePath /etc/ssl/certs @@ -32,6 +32,12 @@ <% if (defined? @services) and (@services.include? 'webapp') -%> DocumentRoot /srv/leap/webapp/public + <% if Gem::Version.new(@apache_version) > Gem::Version.new('2.3') %> + <Directory /srv/leap/webapp/public> + AllowOverride None + Require all granted + </Directory> + <% end %> RewriteEngine On # Check for maintenance file and redirect all requests @@ -69,4 +75,3 @@ </DirectoryMatch> <% end -%> </VirtualHost> - diff --git a/puppet/modules/site_apt/manifests/init.pp b/puppet/modules/site_apt/manifests/init.pp index cf49f870..635ba975 100644 --- a/puppet/modules/site_apt/manifests/init.pp +++ b/puppet/modules/site_apt/manifests/init.pp @@ -7,11 +7,19 @@ class site_apt { $apt_url_security = $apt_config['security'] $apt_url_backports = $apt_config['backports'] + # needed on jessie hosts for getting pnp4nagios from testing + if ( $::operatingsystemmajrelease == '8' ) { + $use_next_release = true + } else { + $use_next_release = false + } + class { 'apt': - custom_key_dir => 'puppet:///modules/site_apt/keys', - debian_url => $apt_url_basic, - security_url => $apt_url_security, - backports_url => $apt_url_backports + custom_key_dir => 'puppet:///modules/site_apt/keys', + debian_url => $apt_url_basic, + security_url => $apt_url_security, + backports_url => $apt_url_backports, + use_next_release => $use_next_release } # enable http://deb.leap.se debian package repository diff --git a/puppet/modules/site_apt/manifests/leap_repo.pp b/puppet/modules/site_apt/manifests/leap_repo.pp index 2d4ba0e1..462b2686 100644 --- a/puppet/modules/site_apt/manifests/leap_repo.pp +++ b/puppet/modules/site_apt/manifests/leap_repo.pp @@ -1,9 +1,11 @@ +# install leap deb repo together with leap-keyring package +# containing the apt signing key class site_apt::leap_repo { $platform = hiera_hash('platform') $major_version = $platform['major_version'] apt::sources_list { 'leap.list': - content => "deb http://deb.leap.se/${major_version} wheezy main\n", + content => "deb http://deb.leap.se/${major_version} ${::lsbdistcodename} main\n", before => Exec[refresh_apt] } diff --git a/puppet/modules/site_apt/manifests/sid_repo.pp b/puppet/modules/site_apt/manifests/sid_repo.pp new file mode 100644 index 00000000..7c1d8783 --- /dev/null +++ b/puppet/modules/site_apt/manifests/sid_repo.pp @@ -0,0 +1,11 @@ +# configure debian unstable aka "sid" +# currently only used for installations that +# use plain couchdb instead of bigcouch +class site_apt::sid_repo { + + apt::sources_list { 'debian_sid.list': + content => "deb http://httpredir.debian.org/debian/ sid main\n", + before => Exec[refresh_apt] + } + +} diff --git a/puppet/modules/site_apt/templates/jessie/postfix.seeds b/puppet/modules/site_apt/templates/jessie/postfix.seeds new file mode 100644 index 00000000..1a878ccc --- /dev/null +++ b/puppet/modules/site_apt/templates/jessie/postfix.seeds @@ -0,0 +1 @@ +postfix postfix/main_mailer_type select No configuration diff --git a/puppet/modules/site_apt/templates/secondary.list b/puppet/modules/site_apt/templates/secondary.list index 41334b0b..0c024549 100644 --- a/puppet/modules/site_apt/templates/secondary.list +++ b/puppet/modules/site_apt/templates/secondary.list @@ -1,3 +1,3 @@ # basic -deb http://ftp.debian.org/debian/ <%= lsbdistcodename %> main contrib non-free +deb http://ftp.debian.org/debian/ <%= @lsbdistcodename %> main contrib non-free diff --git a/puppet/modules/site_check_mk/manifests/agent/mx.pp b/puppet/modules/site_check_mk/manifests/agent/mx.pp index 98757b59..20cbcade 100644 --- a/puppet/modules/site_check_mk/manifests/agent/mx.pp +++ b/puppet/modules/site_check_mk/manifests/agent/mx.pp @@ -1,3 +1,4 @@ +# check check_mk agent checks for mx service class site_check_mk::agent::mx { # watch logs @@ -6,13 +7,13 @@ class site_check_mk::agent::mx { } # local nagios plugin checks via mrpe + # removed because leap_cli integrates a check for running mx procs already, + # which is also integrated into nagios (called "Mx/Are_MX_daemons_running") augeas { 'Leap_MX_Procs': incl => '/etc/check_mk/mrpe.cfg', lens => 'Spacevars.lns', - changes => [ - 'rm /files/etc/check_mk/mrpe.cfg/Leap_MX_Procs', - 'set Leap_MX_Procs \'/usr/lib/nagios/plugins/check_procs -w 1:1 -c 1:1 -a "/usr/bin/python /usr/bin/twistd --pidfile=/var/run/leap_mx.pid --rundir=/var/lib/leap_mx/ --python=/usr/share/app/leap_mx.tac --logfile=/var/log/leap/mx.log"\'' ], + changes => 'rm /files/etc/check_mk/mrpe.cfg/Leap_MX_Procs', require => File['/etc/check_mk/mrpe.cfg']; } diff --git a/puppet/modules/site_check_mk/manifests/server.pp b/puppet/modules/site_check_mk/manifests/server.pp index 57f68d3e..0159a050 100644 --- a/puppet/modules/site_check_mk/manifests/server.pp +++ b/puppet/modules/site_check_mk/manifests/server.pp @@ -17,6 +17,19 @@ class site_check_mk::server { ensure => installed, } + # we don't use check-mk-multisite, and the jessie version + # of this config file breaks with apache 2.4 + # until https://gitlab.com/shared-puppet-modules-group/apache/issues/11 + # is not fixed, we need to use a generic file type here + #apache::config::global { 'check-mk-multisite.conf': + # ensure => absent + #} + + file { '/etc/apache2/conf-enabled/check-mk-multisite.conf': + ensure => absent, + require => Package['check-mk-server']; + } + # override paths to use the system check_mk rather than OMD class { 'check_mk::config': site => '', diff --git a/puppet/modules/site_check_mk/templates/use_ssh.mk b/puppet/modules/site_check_mk/templates/use_ssh.mk index 0bebebcf..55269536 100644 --- a/puppet/modules/site_check_mk/templates/use_ssh.mk +++ b/puppet/modules/site_check_mk/templates/use_ssh.mk @@ -1,6 +1,6 @@ # http://mathias-kettner.de/checkmk_datasource_programs.html datasource_programs = [ -<% nagios_hosts.sort.each do |name,config| %> +<% @nagios_hosts.sort.each do |name,config| %> ( "ssh -l root -i /etc/check_mk/.ssh/id_rsa -p <%=config['ssh_port']%> <%=config['domain_internal']%> check_mk_agent", [ "<%=config['domain_internal']%>" ], ),<%- end -%> ] diff --git a/puppet/modules/site_config/manifests/packages/build_essential.pp b/puppet/modules/site_config/manifests/packages/build_essential.pp index 7dfb8b03..8f3b2641 100644 --- a/puppet/modules/site_config/manifests/packages/build_essential.pp +++ b/puppet/modules/site_config/manifests/packages/build_essential.pp @@ -4,8 +4,8 @@ class site_config::packages::build_essential { if !defined(Package['build-essential']) { package { - ['build-essential', 'g++', 'g++-4.7', 'gcc', 'gcc-4.6', 'gcc-4.7', 'cpp', 'cpp-4.6', 'cpp-4.7', 'libc6-dev']: + ['build-essential', 'cpp']: ensure => present } } -}
\ No newline at end of file +} diff --git a/puppet/modules/site_config/manifests/remove/files.pp b/puppet/modules/site_config/manifests/remove/files.pp index 466f50c8..67171259 100644 --- a/puppet/modules/site_config/manifests/remove/files.pp +++ b/puppet/modules/site_config/manifests/remove/files.pp @@ -11,6 +11,12 @@ class site_config::remove::files { + # Platform 0.8 removals + tidy { + '/etc/default/leap_mx':; + '/etc/logrotate.d/leap-mx':; + } + # # Platform 0.7 removals # @@ -20,13 +26,19 @@ class site_config::remove::files { '/etc/rsyslog.d/99-leap-mx.conf':; '/etc/rsyslog.d/01-webapp.conf':; '/etc/rsyslog.d/50-stunnel.conf':; - '/etc/logrotate.d/mx':; '/etc/logrotate.d/stunnel':; '/var/log/stunnel4/stunnel.log':; 'leap_mx': path => '/var/log/', recurse => true, matches => 'leap_mx*'; + # We rotate 5 logs, so we should only have mx.log, mx.log.[1-5], with an + # optional .gz suffix. The following will remove any logs that are out + # of this range + 'leap_mx_rotate': + path => '/var/log/leap/', + recurse => true, + matches => [ 'mx.log.[6-9](.gz)?', 'mx.log.[0-9][0-9]']; '/srv/leap/webapp/public/provider.json':; '/srv/leap/couchdb/designs/tmp_users': recurse => true, diff --git a/puppet/modules/site_config/manifests/ruby.pp b/puppet/modules/site_config/manifests/ruby.pp index 2a720114..5c13233d 100644 --- a/puppet/modules/site_config/manifests/ruby.pp +++ b/puppet/modules/site_config/manifests/ruby.pp @@ -1,14 +1,8 @@ +# install ruby, rubygems and bundler +# configure ruby settings common to all servers class site_config::ruby { Class[Ruby] -> Class[rubygems] -> Class[bundler::install] - class { '::ruby': ruby_version => '1.9.3' } + class { '::ruby': } class { 'bundler::install': install_method => 'package' } include rubygems } - - -# -# Ruby settings common to all servers -# -# Why this way? So that other classes can do 'include site_ruby' without creating redeclaration errors. -# See https://puppetlabs.com/blog/modeling-class-composition-with-parameterized-classes/ -# diff --git a/puppet/modules/site_config/manifests/ruby/dev.pp b/puppet/modules/site_config/manifests/ruby/dev.pp index 3ea6ca96..e6eb2f8a 100644 --- a/puppet/modules/site_config/manifests/ruby/dev.pp +++ b/puppet/modules/site_config/manifests/ruby/dev.pp @@ -1,6 +1,6 @@ +# install ruby dev packages needed for building some gems class site_config::ruby::dev inherits site_config::ruby { Class['::ruby'] { - ruby_version => '1.9.3', install_dev => true } # building gems locally probably requires build-essential and gcc: diff --git a/puppet/modules/site_couchdb/files/designs/identities/Identity.json b/puppet/modules/site_couchdb/files/designs/identities/Identity.json index 2ac092ab..b1c567c1 100644 --- a/puppet/modules/site_couchdb/files/designs/identities/Identity.json +++ b/puppet/modules/site_couchdb/files/designs/identities/Identity.json @@ -2,27 +2,33 @@ "_id": "_design/Identity", "language": "javascript", "views": { - "by_user_id": { - "map": " function(doc) {\n if ((doc['type'] == 'Identity') && (doc['user_id'] != null)) {\n emit(doc['user_id'], 1);\n }\n }\n", - "reduce": "_sum" - }, "by_address_and_destination": { "map": " function(doc) {\n if ((doc['type'] == 'Identity') && (doc['address'] != null) && (doc['destination'] != null)) {\n emit([doc['address'], doc['destination']], 1);\n }\n }\n", "reduce": "_sum" }, - "by_address": { - "map": " function(doc) {\n if ((doc['type'] == 'Identity') && (doc['address'] != null)) {\n emit(doc['address'], 1);\n }\n }\n", - "reduce": "_sum" + "all": { + "map": " function(doc) {\n if (doc['type'] == 'Identity') {\n emit(doc._id, null);\n }\n }\n" }, - "pgp_key_by_email": { - "map": " function(doc) {\n if (doc.type != 'Identity') {\n return;\n }\n if (typeof doc.keys === \"object\") {\n emit(doc.address, doc.keys[\"pgp\"]);\n }\n }\n" + "cert_fingerprints_by_expiry": { + "map": "function(doc) {\n if (doc.type != 'Identity') {\n return;\n }\n if (typeof doc.cert_fingerprints === \"object\") {\n for (fp in doc.cert_fingerprints) {\n if (doc.cert_fingerprints.hasOwnProperty(fp)) {\n emit(doc.cert_fingerprints[fp], fp);\n }\n }\n }\n}\n" + }, + "cert_expiry_by_fingerprint": { + "map": "function(doc) {\n if (doc.type != 'Identity') {\n return;\n }\n if (typeof doc.cert_fingerprints === \"object\") {\n for (fp in doc.cert_fingerprints) {\n if (doc.cert_fingerprints.hasOwnProperty(fp)) {\n emit(fp, doc.cert_fingerprints[fp]);\n }\n }\n }\n}\n" }, "disabled": { - "map": " function(doc) {\n if (doc.type != 'Identity') {\n return;\n }\n if (typeof doc.user_id === \"undefined\") {\n emit(doc._id, 1);\n }\n }\n" + "map": "function(doc) {\n if (doc.type != 'Identity') {\n return;\n }\n if (typeof doc.user_id === \"undefined\") {\n emit(doc._id, 1);\n }\n}\n" }, - "all": { - "map": " function(doc) {\n if (doc['type'] == 'Identity') {\n emit(doc._id, null);\n }\n }\n" + "pgp_key_by_email": { + "map": "function(doc) {\n if (doc.type != 'Identity') {\n return;\n }\n if (typeof doc.keys === \"object\") {\n emit(doc.address, doc.keys[\"pgp\"]);\n }\n}\n" + }, + "by_user_id": { + "map": " function(doc) {\n if ((doc['type'] == 'Identity') && (doc['user_id'] != null)) {\n emit(doc['user_id'], 1);\n }\n }\n", + "reduce": "_sum" + }, + "by_address": { + "map": " function(doc) {\n if ((doc['type'] == 'Identity') && (doc['address'] != null)) {\n emit(doc['address'], 1);\n }\n }\n", + "reduce": "_sum" } }, - "couchrest-hash": "e9004d70e26770c621a9667536429a68" + "couchrest-hash": "4a774c3f56122b655a314670403b27e2" }
\ No newline at end of file diff --git a/puppet/modules/site_couchdb/files/designs/messages/Message.json b/puppet/modules/site_couchdb/files/designs/messages/Message.json index 7bcd74c7..6a48fc4d 100644 --- a/puppet/modules/site_couchdb/files/designs/messages/Message.json +++ b/puppet/modules/site_couchdb/files/designs/messages/Message.json @@ -2,17 +2,17 @@ "_id": "_design/Message", "language": "javascript", "views": { - "by_user_ids_to_show_and_created_at": { - "map": "// not using at moment\n// call with something like Message.by_user_ids_to_show_and_created_at.startkey([user_id, start_date]).endkey([user_id,end_date])\nfunction (doc) {\n if (doc.type === 'Message' && doc.user_ids_to_show && Array.isArray(doc.user_ids_to_show)) {\n doc.user_ids_to_show.forEach(function (userId) {\n emit([userId, doc.created_at], 1);\n });\n }\n}\n", - "reduce": "function(key, values, rereduce) { return sum(values); }" - }, "by_user_ids_to_show": { "map": "function (doc) {\n if (doc.type === 'Message' && doc.user_ids_to_show && Array.isArray(doc.user_ids_to_show)) {\n doc.user_ids_to_show.forEach(function (userId) {\n emit(userId, 1);\n });\n }\n}\n", - "reduce": "function(key, values, rereduce) { return sum(values); }" + "reduce": " function(key, values, rereduce) {\n return sum(values);\n }\n" + }, + "by_user_ids_to_show_and_created_at": { + "map": "// not using at moment\n// call with something like Message.by_user_ids_to_show_and_created_at.startkey([user_id, start_date]).endkey([user_id,end_date])\nfunction (doc) {\n if (doc.type === 'Message' && doc.user_ids_to_show && Array.isArray(doc.user_ids_to_show)) {\n doc.user_ids_to_show.forEach(function (userId) {\n emit([userId, doc.created_at], 1);\n });\n }\n}\n", + "reduce": " function(key, values, rereduce) {\n return sum(values);\n }\n" }, "all": { "map": " function(doc) {\n if (doc['type'] == 'Message') {\n emit(doc._id, null);\n }\n }\n" } }, - "couchrest-hash": "0967e7cc5bb1e61edc1c085f6f0cecbf" + "couchrest-hash": "ba80168e51015d2678cad88fc6c5b986" }
\ No newline at end of file diff --git a/puppet/modules/site_couchdb/files/designs/tickets/Ticket.json b/puppet/modules/site_couchdb/files/designs/tickets/Ticket.json index 2c9408b8..578f632b 100644 --- a/puppet/modules/site_couchdb/files/designs/tickets/Ticket.json +++ b/puppet/modules/site_couchdb/files/designs/tickets/Ticket.json @@ -24,27 +24,27 @@ }, "by_includes_post_by_and_is_open_and_created_at": { "map": "function(doc) {\n var arr = {}\n if (doc['type'] == 'Ticket' && doc.comments) {\n doc.comments.forEach(function(comment){\n if (comment.posted_by && !arr[comment.posted_by]) {\n //don't add duplicates\n arr[comment.posted_by] = true;\n emit([comment.posted_by, doc.is_open, doc.created_at], 1);\n }\n });\n }\n}\n", - "reduce": "function(key, values, rereduce) { return sum(values); }" - }, - "by_includes_post_by_and_is_open_and_updated_at": { - "map": "function(doc) {\n var arr = {}\n if (doc['type'] == 'Ticket' && doc.comments) {\n doc.comments.forEach(function(comment){\n if (comment.posted_by && !arr[comment.posted_by]) {\n //don't add duplicates\n arr[comment.posted_by] = true;\n emit([comment.posted_by, doc.is_open, doc.updated_at], 1);\n }\n });\n }\n}\n", - "reduce": "function(key, values, rereduce) { return sum(values); }" - }, - "by_includes_post_by_and_updated_at": { - "map": "function(doc) {\n var arr = {}\n if (doc['type'] == 'Ticket' && doc.comments) {\n doc.comments.forEach(function(comment){\n if (comment.posted_by && !arr[comment.posted_by]) {\n //don't add duplicates\n arr[comment.posted_by] = true;\n emit([comment.posted_by, doc.updated_at], 1);\n }\n });\n }\n}\n", - "reduce": "function(key, values, rereduce) { return sum(values); }" + "reduce": " function(key, values, rereduce) {\n return sum(values);\n }\n" }, "by_includes_post_by": { "map": "// TODO: This view is only used in tests--should we keep it?\nfunction(doc) {\n var arr = {}\n if (doc['type'] == 'Ticket' && doc.comments) {\n doc.comments.forEach(function(comment){\n if (comment.posted_by && !arr[comment.posted_by]) {\n //don't add duplicates\n arr[comment.posted_by] = true;\n emit(comment.posted_by, 1);\n }\n });\n }\n}\n", - "reduce": "function(key, values, rereduce) { return sum(values); }" + "reduce": " function(key, values, rereduce) {\n return sum(values);\n }\n" + }, + "by_includes_post_by_and_is_open_and_updated_at": { + "map": "function(doc) {\n var arr = {}\n if (doc['type'] == 'Ticket' && doc.comments) {\n doc.comments.forEach(function(comment){\n if (comment.posted_by && !arr[comment.posted_by]) {\n //don't add duplicates\n arr[comment.posted_by] = true;\n emit([comment.posted_by, doc.is_open, doc.updated_at], 1);\n }\n });\n }\n}\n", + "reduce": " function(key, values, rereduce) {\n return sum(values);\n }\n" }, "by_includes_post_by_and_created_at": { "map": "function(doc) {\n var arr = {}\n if (doc['type'] == 'Ticket' && doc.comments) {\n doc.comments.forEach(function(comment){\n if (comment.posted_by && !arr[comment.posted_by]) {\n //don't add duplicates\n arr[comment.posted_by] = true;\n emit([comment.posted_by, doc.created_at], 1);\n }\n });\n }\n}\n", - "reduce": "function(key, values, rereduce) { return sum(values); }" + "reduce": " function(key, values, rereduce) {\n return sum(values);\n }\n" + }, + "by_includes_post_by_and_updated_at": { + "map": "function(doc) {\n var arr = {}\n if (doc['type'] == 'Ticket' && doc.comments) {\n doc.comments.forEach(function(comment){\n if (comment.posted_by && !arr[comment.posted_by]) {\n //don't add duplicates\n arr[comment.posted_by] = true;\n emit([comment.posted_by, doc.updated_at], 1);\n }\n });\n }\n}\n", + "reduce": " function(key, values, rereduce) {\n return sum(values);\n }\n" }, "all": { "map": " function(doc) {\n if (doc['type'] == 'Ticket') {\n emit(doc._id, null);\n }\n }\n" } }, - "couchrest-hash": "9978e2cbeacbe8622c2a7f103bf8130f" + "couchrest-hash": "b21eaeea8ea66bfda65581b1b7ce06af" }
\ No newline at end of file diff --git a/puppet/modules/site_couchdb/files/designs/users/User.json b/puppet/modules/site_couchdb/files/designs/users/User.json index 4089ad97..8a82cf4a 100644 --- a/puppet/modules/site_couchdb/files/designs/users/User.json +++ b/puppet/modules/site_couchdb/files/designs/users/User.json @@ -11,12 +11,12 @@ }, "by_created_at_and_one_month_warning_not_sent": { "map": "function (doc) {\n if ((doc['type'] == 'User') && (doc['created_at'] != null) && (doc['one_month_warning_sent'] == null)) {\n emit(doc['created_at'], 1);\n } \n}\n", - "reduce": "function(key, values, rereduce) { return sum(values); }" + "reduce": " function(key, values, rereduce) {\n return sum(values);\n }\n" }, "by_created_at": { "map": " function(doc) {\n if ((doc['type'] == 'User') && (doc['created_at'] != null)) {\n emit(doc['created_at'], 1);\n }\n }\n", "reduce": "_sum" } }, - "couchrest-hash": "61840ab3ec0f94ef8bbd6dd208db3b70" + "couchrest-hash": "d854607d299887a347e554176cb79e20" }
\ No newline at end of file diff --git a/puppet/modules/site_couchdb/manifests/master.pp b/puppet/modules/site_couchdb/manifests/master.pp index 5dab6325..c50ed364 100644 --- a/puppet/modules/site_couchdb/manifests/master.pp +++ b/puppet/modules/site_couchdb/manifests/master.pp @@ -7,5 +7,10 @@ class site_couchdb::master { pwhash_alg => $site_couchdb::couchdb_pwhash_alg } + # couchdb is not available in jessie, and the + # leap deb repo only hosts a wheeyz version. + # we install it therefore from unstable + include site_apt::sid_repo + include site_check_mk::agent::couchdb::master } diff --git a/puppet/modules/site_nagios/manifests/server.pp b/puppet/modules/site_nagios/manifests/server.pp index 60a471b7..5c833508 100644 --- a/puppet/modules/site_nagios/manifests/server.pp +++ b/puppet/modules/site_nagios/manifests/server.pp @@ -33,7 +33,7 @@ class site_nagios::server inherits nagios::base { include site_apache::common include site_webapp::common_vhost - include site_apache::module::headers + include apache::module::headers File ['nagios_htpasswd'] { source => undef, diff --git a/puppet/modules/site_nagios/manifests/server/apache.pp b/puppet/modules/site_nagios/manifests/server/apache.pp index 8dbc7e9b..82962e89 100644 --- a/puppet/modules/site_nagios/manifests/server/apache.pp +++ b/puppet/modules/site_nagios/manifests/server/apache.pp @@ -1,7 +1,25 @@ +# set up apache for nagios class site_nagios::server::apache { + include x509::variables + include site_config::x509::commercial::cert include site_config::x509::commercial::key include site_config::x509::commercial::ca + include apache::module::authn_file + # "AuthUserFile" + include apache::module::authz_user + # "AuthType Basic" + include apache::module::auth_basic + # "DirectoryIndex" + include apache::module::dir + include apache::module::php5 + include apache::module::cgi + + # apache >= 2.4, debian jessie + if ( $::lsbdistcodename == 'jessie' ) { + include apache::module::authn_core + } + } diff --git a/puppet/modules/site_postfix/templates/checks/helo_access.erb b/puppet/modules/site_postfix/templates/checks/helo_access.erb index bef3c11d..bac2c45a 100644 --- a/puppet/modules/site_postfix/templates/checks/helo_access.erb +++ b/puppet/modules/site_postfix/templates/checks/helo_access.erb @@ -18,4 +18,4 @@ # Reject anybody that HELO's as being in our own domain(s) # anyone who identifies themselves as us is a virus/spammer -<%= domain %> 554 You are not in domain <%= domain %> +<%= @domain %> 554 You are not in domain <%= @domain %> diff --git a/puppet/modules/site_sshd/manifests/init.pp b/puppet/modules/site_sshd/manifests/init.pp index 170be32c..be0d3368 100644 --- a/puppet/modules/site_sshd/manifests/init.pp +++ b/puppet/modules/site_sshd/manifests/init.pp @@ -1,3 +1,4 @@ +# configures sshd, mosh, authorized keys and known hosts class site_sshd { $ssh = hiera_hash('ssh') $ssh_config = $ssh['config'] @@ -49,16 +50,32 @@ class site_sshd { } } + # we cannot use the 'hardened' parameter because leap_cli uses an + # old net-ssh gem that is incompatible with the included + # "KexAlgorithms curve25519-sha256@libssh.org", + # see https://leap.se/code/issues/7591 + # therefore we don't use it here, but include all other options + # that would be applied by the 'hardened' parameter + # not all options are available on wheezy + if ( $::lsbdistcodename == 'wheezy' ) { + $tail_additional_options = 'Ciphers aes256-ctr +MACs hmac-sha2-512,hmac-sha2-256,hmac-ripemd160' + } else { + $tail_additional_options = 'Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes256-ctr +MACs hmac-sha2-512,hmac-sha2-256,hmac-ripemd160' + } + ## ## SSHD SERVER CONFIGURATION ## class { '::sshd': - manage_nagios => false, - ports => [ $ssh['port'] ], - use_pam => 'yes', - hardened_ssl => 'yes', - print_motd => 'no', - tcp_forwarding => $ssh_config['AllowTcpForwarding'], - manage_client => false + manage_nagios => false, + ports => [ $ssh['port'] ], + use_pam => 'yes', + print_motd => 'no', + tcp_forwarding => $ssh_config['AllowTcpForwarding'], + manage_client => false, + use_storedconfigs => false, + tail_additional_options => $tail_additional_options } } diff --git a/puppet/modules/site_webapp/manifests/apache.pp b/puppet/modules/site_webapp/manifests/apache.pp index ddd04a91..80c7b29b 100644 --- a/puppet/modules/site_webapp/manifests/apache.pp +++ b/puppet/modules/site_webapp/manifests/apache.pp @@ -1,3 +1,4 @@ +# configure apache and passenger to serve the webapp class site_webapp::apache { $web_api = hiera('api') @@ -11,10 +12,10 @@ class site_webapp::apache { $webapp_domain = $webapp['domain'] include site_apache::common - include site_apache::module::headers - include site_apache::module::alias - include site_apache::module::expires - include site_apache::module::removeip + include apache::module::headers + include apache::module::alias + include apache::module::expires + include apache::module::removeip include site_webapp::common_vhost class { 'passenger': use_munin => false } diff --git a/puppet/modules/site_webapp/manifests/hidden_service.pp b/puppet/modules/site_webapp/manifests/hidden_service.pp index 99a756ca..4cf7a8ca 100644 --- a/puppet/modules/site_webapp/manifests/hidden_service.pp +++ b/puppet/modules/site_webapp/manifests/hidden_service.pp @@ -4,10 +4,10 @@ class site_webapp::hidden_service { $tor_domain = "${hidden_service['address']}.onion" include site_apache::common - include site_apache::module::headers - include site_apache::module::alias - include site_apache::module::expires - include site_apache::module::removeip + include apache::module::headers + include apache::module::alias + include apache::module::expires + include apache::module::removeip include tor::daemon tor::daemon::hidden_service { 'webapp': ports => '80 127.0.0.1:80' } diff --git a/puppet/modules/site_webapp/templates/config.yml.erb b/puppet/modules/site_webapp/templates/config.yml.erb index 19ed6b7b..c2e9f3df 100644 --- a/puppet/modules/site_webapp/templates/config.yml.erb +++ b/puppet/modules/site_webapp/templates/config.yml.erb @@ -1,4 +1,4 @@ -<%- +<% cert_options = @webapp['client_certificates'] production = { "admins" => @webapp['admins'], @@ -32,4 +32,4 @@ end # # This file is generated by puppet. This file inherits from defaults.yml. # -<%= scope.function_sorted_yaml({"production" => production}) %> +<%= scope.function_sorted_yaml([{"production" => production}]) %> diff --git a/puppet/modules/sshd b/puppet/modules/sshd -Subproject 750a497758d94c2f5a6cad23cecc3dbde2d2f92 +Subproject 76f4f872f81209a52df2205fd88b5619df58f00 diff --git a/puppet/modules/unbound b/puppet/modules/unbound -Subproject 9997485b8a31abbe0cd1943d09995705c2c8146 +Subproject a26b91dfea3189e6777629fa00d54f51dc41f4d diff --git a/tests/helpers/client_side_db.py b/tests/helpers/client_side_db.py new file mode 100644 index 00000000..2f8c220f --- /dev/null +++ b/tests/helpers/client_side_db.py @@ -0,0 +1,167 @@ +import logging +import os +import tempfile +import getpass +import binascii +import json + +try: + import requests + import srp._pysrp as srp +except ImportError: + pass + +from twisted.internet.defer import inlineCallbacks + +from leap.soledad.client import Soledad + + +""" +Helper functions to give access to client-side Soledad database. +Copied over from soledad/scripts folder. +""" + +# create a logger +logger = logging.getLogger(__name__) + +# DEBUG: enable debug logs +# LOG_FORMAT = '%(asctime)s %(message)s' +# logging.basicConfig(format=LOG_FORMAT, level=logging.DEBUG) + + +safe_unhexlify = lambda x: binascii.unhexlify(x) if ( + len(x) % 2 == 0) else binascii.unhexlify('0' + x) + + +def _fail(reason): + logger.error('Fail: ' + reason) + exit(2) + + +def get_soledad_instance(uuid, passphrase, basedir, server_url, cert_file, + token): + # setup soledad info + logger.info('UUID is %s' % uuid) + logger.info('Server URL is %s' % server_url) + secrets_path = os.path.join( + basedir, '%s.secret' % uuid) + local_db_path = os.path.join( + basedir, '%s.db' % uuid) + # instantiate soledad + return Soledad( + uuid, + unicode(passphrase), + secrets_path=secrets_path, + local_db_path=local_db_path, + server_url=server_url, + cert_file=cert_file, + auth_token=token, + defer_encryption=True) + + +def _get_api_info(provider): + info = requests.get( + 'https://'+provider+'/provider.json', verify=False).json() + return info['api_uri'], info['api_version'] + + +def _login(username, passphrase, provider, api_uri, api_version): + usr = srp.User(username, passphrase, srp.SHA256, srp.NG_1024) + auth = None + try: + auth = _authenticate(api_uri, api_version, usr).json() + except requests.exceptions.ConnectionError: + _fail('Could not connect to server.') + if 'errors' in auth: + _fail(str(auth['errors'])) + return api_uri, api_version, auth + + +def _authenticate(api_uri, api_version, usr): + api_url = "%s/%s" % (api_uri, api_version) + session = requests.session() + uname, A = usr.start_authentication() + params = {'login': uname, 'A': binascii.hexlify(A)} + init = session.post( + api_url + '/sessions', data=params, verify=False).json() + if 'errors' in init: + _fail('test user not found') + M = usr.process_challenge( + safe_unhexlify(init['salt']), safe_unhexlify(init['B'])) + return session.put(api_url + '/sessions/' + uname, verify=False, + data={'client_auth': binascii.hexlify(M)}) + + +def _get_soledad_info(username, provider, passphrase, basedir): + api_uri, api_version = _get_api_info(provider) + auth = _login(username, passphrase, provider, api_uri, api_version) + # get soledad server url + service_url = '%s/%s/config/soledad-service.json' % \ + (api_uri, api_version) + soledad_hosts = requests.get(service_url, verify=False).json()['hosts'] + hostnames = soledad_hosts.keys() + # allow for choosing the host + host = hostnames[0] + if len(hostnames) > 1: + i = 1 + print "There are many available hosts:" + for h in hostnames: + print " (%d) %s.%s" % (i, h, provider) + i += 1 + choice = raw_input("Choose a host to use (default: 1): ") + if choice != '': + host = hostnames[int(choice) - 1] + server_url = 'https://%s:%d/user-%s' % \ + (soledad_hosts[host]['hostname'], soledad_hosts[host]['port'], + auth[2]['id']) + # get provider ca certificate + ca_cert = requests.get('https://%s/ca.crt' % provider, verify=False).text + cert_file = os.path.join(basedir, 'ca.crt') + with open(cert_file, 'w') as f: + f.write(ca_cert) + return auth[2]['id'], server_url, cert_file, auth[2]['token'] + + +def _get_passphrase(args): + passphrase = args.passphrase + if passphrase is None: + passphrase = getpass.getpass( + 'Password for %s@%s: ' % (args.username, args.provider)) + return passphrase + + +def _get_basedir(args): + basedir = args.basedir + if basedir is None: + basedir = tempfile.mkdtemp() + elif not os.path.isdir(basedir): + os.mkdir(basedir) + logger.info('Using %s as base directory.' % basedir) + return basedir + + +@inlineCallbacks +def _export_key(args, km, fname, private=False): + address = args.username + "@" + args.provider + pkey = yield km.get_key( + address, OpenPGPKey, private=private, fetch_remote=False) + with open(args.export_private_key, "w") as f: + f.write(pkey.key_data) + + +@inlineCallbacks +def _export_incoming_messages(soledad, directory): + yield soledad.create_index("by-incoming", "bool(incoming)") + docs = yield soledad.get_from_index("by-incoming", '1') + i = 1 + for doc in docs: + with open(os.path.join(directory, "message_%d.gpg" % i), "w") as f: + f.write(doc.content["_enc_json"]) + i += 1 + + +@inlineCallbacks +def _get_all_docs(soledad): + _, docs = yield soledad.get_all_docs() + for doc in docs: + print json.dumps(doc.content, indent=4) diff --git a/tests/helpers/os_helper.rb b/tests/helpers/os_helper.rb index aad67dda..da9ac843 100644 --- a/tests/helpers/os_helper.rb +++ b/tests/helpers/os_helper.rb @@ -9,7 +9,10 @@ class LeapTest output.each_line.map{|line| pid = line.split(' ')[0] process = line.gsub(/(#{pid} |\n)/, '') - if process =~ /pgrep --full --list-name/ + # filter out pgrep cmd itself + # on wheezy hosts, the "process" var contains the whole cmd including all parameters + # on jessie hosts, it only contains the first cmd (which is the default sheel invoked by 'sh') + if process =~ /^sh/ nil else {:pid => pid, :process => process} diff --git a/tests/helpers/soledad_sync.py b/tests/helpers/soledad_sync.py index 2fb865fc..a1cea069 100755 --- a/tests/helpers/soledad_sync.py +++ b/tests/helpers/soledad_sync.py @@ -1,78 +1,75 @@ #!/usr/bin/env python +""" +soledad_sync.py -# -# Test Soledad sync -# -# This script performs a slightly modified U1DB sync to the Soledad server and -# returns whether that sync was successful or not. -# -# It takes three arguments: -# -# uuid -- uuid of the user to sync -# token -- a valid session token -# server -- the url of the soledad server we should connect to -# -# For example: -# -# soledad_sync.py f6bef0586fcfdb8705e26a58f2d9e580 uYO-4ucEJFksJ6afjmcYwIyap2vW7bv6uLxk0w_RfCc https://199.119.112.9:2323/user-f6bef0586fcfdb8705e26a58f2d9e580 -# +This script exercises soledad synchronization. +Its exit code is 0 if the sync took place correctly, 1 otherwise. +It takes 5 arguments: + + uuid: uuid of the user to sync + token: a valid session token + server: the url of the soledad server we should connect to + cert_file: the file containing the certificate for the CA that signed the + cert for the soledad server. + password: the password for the user to sync + +__author__: kali@leap.se +""" import os import sys -import traceback import tempfile -import shutil -import u1db -from u1db.remote.http_target import HTTPSyncTarget +# This is needed because the twisted shipped with wheezy is too old +# to do proper ssl verification. +os.environ['SKIP_TWISTED_SSL_CHECK'] = '1' -# -# monkey patch U1DB's HTTPSyncTarget to perform token based auth -# +from twisted.internet import defer, reactor -def set_token_credentials(self, uuid, token): - self._creds = {'token': (uuid, token)} +from client_side_db import get_soledad_instance +from leap.common.events import flags -def _sign_request(self, method, url_query, params): - uuid, token = self._creds['token'] - auth = '%s:%s' % (uuid, token) - return [('Authorization', 'Token %s' % auth.encode('base64')[:-1])] +flags.set_events_enabled(False) -HTTPSyncTarget.set_token_credentials = set_token_credentials -HTTPSyncTarget._sign_request = _sign_request +NUMDOCS = 1 +USAGE = "Usage: %s uuid token server cert_file password" % sys.argv[0] -# -# Create a temporary local u1db replica and attempt to sync to it. -# Returns a failure message if something went wrong. -# -def soledad_sync(uuid, token, server): - tempdir = tempfile.mkdtemp() - try: - db = u1db.open(os.path.join(tempdir, '%s.db' % uuid), True) - creds = {'token': {'uuid': uuid, 'token': token}} - db.sync(server, creds=creds, autocreate=False) - finally: - shutil.rmtree(tempdir) - -# -# exit codes: -# -# 0 - OK -# 1 - WARNING -# 2 - ERROR -# +def bail(msg, exitcode): + print "[!] %s" % msg + sys.exit(exitcode) + + +def create_docs(soledad): + """ + Populates the soledad database with dummy messages, so we can exercise + sending payloads during the sync. + """ + deferreds = [] + for index in xrange(NUMDOCS): + deferreds.append(soledad.create_doc({'payload': 'dummy'})) + return defer.gatherResults(deferreds) + +# main program if __name__ == '__main__': - try: - uuid, token, server = sys.argv[1:] - result = soledad_sync(uuid, token, server) - if result is None: - exit(0) - else: - print(result) - exit(1) - except Exception as exc: - print(exc.message or str(exc)) - traceback.print_exc(file=sys.stdout) - exit(2) + + tempdir = tempfile.mkdtemp() + if len(sys.argv) < 6: + bail(USAGE, 2) + uuid, token, server, cert_file, passphrase = sys.argv[1:] + s = get_soledad_instance( + uuid, passphrase, tempdir, server, cert_file, token) + + def onSyncDone(sync_result): + print "SYNC_RESULT:", sync_result + s.close() + reactor.stop() + + def start_sync(): + d = create_docs(s) + d.addCallback(lambda _: s.sync()) + d.addCallback(onSyncDone) + + reactor.callWhenRunning(start_sync) + reactor.run() diff --git a/tests/white-box/mx.rb b/tests/white-box/mx.rb index 794a9a41..f49d2ab4 100644 --- a/tests/white-box/mx.rb +++ b/tests/white-box/mx.rb @@ -34,6 +34,9 @@ class Mx < LeapTest def test_03_Are_MX_daemons_running? assert_running 'leap_mx' assert_running '/usr/lib/postfix/master' + assert_running '/usr/sbin/postfwd' + assert_running 'postfwd2::cache' + assert_running 'postfwd2::policy' assert_running '/usr/sbin/unbound' pass end diff --git a/tests/white-box/network.rb b/tests/white-box/network.rb index acb5c5e6..382f857b 100644 --- a/tests/white-box/network.rb +++ b/tests/white-box/network.rb @@ -28,11 +28,18 @@ class Network < LeapTest def test_02_Is_stunnel_running? ignore unless $node['stunnel'] good_stunnel_pids = [] + release = `facter lsbmajdistrelease` + if release.to_i > 7 + # on jessie, there is only one stunnel proc running instead of 6 + expected = 1 + else + expected = 6 + end $node['stunnel']['clients'].each do |stunnel_type, stunnel_configs| stunnel_configs.each do |stunnel_name, stunnel_conf| config_file_name = "/etc/stunnel/#{stunnel_name}.conf" processes = pgrep(config_file_name) - assert_equal 6, processes.length, "There should be six stunnel processes running for `#{config_file_name}`" + assert_equal expected, processes.length, "There should be #{expected} stunnel processes running for `#{config_file_name}`" good_stunnel_pids += processes.map{|ps| ps[:pid]} assert port = stunnel_conf['accept_port'], 'Field `accept_port` must be present in `stunnel` property.' assert_tcp_socket('localhost', port) @@ -41,7 +48,7 @@ class Network < LeapTest $node['stunnel']['servers'].each do |stunnel_name, stunnel_conf| config_file_name = "/etc/stunnel/#{stunnel_name}.conf" processes = pgrep(config_file_name) - assert_equal 6, processes.length, "There should be six stunnel processes running for `#{config_file_name}`" + assert_equal expected, processes.length, "There should be #{expected} stunnel processes running for `#{config_file_name}`" good_stunnel_pids += processes.map{|ps| ps[:pid]} assert accept_port = stunnel_conf['accept_port'], "Field `accept` must be present in property `stunnel.servers.#{stunnel_name}`" assert_tcp_socket('localhost', accept_port) diff --git a/tests/white-box/webapp.rb b/tests/white-box/webapp.rb index 48507521..e689c143 100644 --- a/tests/white-box/webapp.rb +++ b/tests/white-box/webapp.rb @@ -41,6 +41,35 @@ class Webapp < LeapTest pass end + def test_05_Can_create_and_authenticate_and_delete_user_via_API? + if property('webapp.allow_registration') + assert_tmp_user + pass + else + skip "New user registrations are disabled." + end + end + + def test_06_Can_sync_Soledad? + return unless property('webapp.allow_registration') + soledad_config = property('definition_files.soledad_service') + if soledad_config && !soledad_config.empty? + soledad_server = pick_soledad_server(soledad_config) + if soledad_server + assert_tmp_user do |user| + command = File.expand_path "../../helpers/soledad_sync.py", __FILE__ + soledad_url = "https://#{soledad_server}/user-#{user.id}" + soledad_cert = "/usr/local/share/ca-certificates/leap_ca.crt" + assert_run "#{command} #{user.id} #{user.session_token} #{soledad_url} #{soledad_cert} #{user.password}" + assert_user_db_exists(user) + pass + end + end + else + skip 'No soledad service configuration' + end + end + private def url_options |