summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Vagrantfile37
-rw-r--r--lib/leap_cli/commands/vagrant.rb4
-rw-r--r--puppet/lib/puppet/parser/functions/sorted_yaml.rb16
m---------puppet/modules/apache0
m---------puppet/modules/couchdb0
m---------puppet/modules/haproxy0
-rw-r--r--puppet/modules/leap_mx/manifests/init.pp24
-rw-r--r--puppet/modules/site_apache/manifests/common.pp20
-rw-r--r--puppet/modules/site_apache/manifests/module/alias.pp5
-rw-r--r--puppet/modules/site_apache/manifests/module/expires.pp4
-rw-r--r--puppet/modules/site_apache/manifests/module/headers.pp5
-rw-r--r--puppet/modules/site_apache/manifests/module/removeip.pp5
-rw-r--r--puppet/modules/site_apache/manifests/module/rewrite.pp5
-rw-r--r--puppet/modules/site_apache/templates/vhosts.d/api.conf.erb16
-rw-r--r--puppet/modules/site_apache/templates/vhosts.d/common.conf.erb25
-rw-r--r--puppet/modules/site_apt/manifests/init.pp16
-rw-r--r--puppet/modules/site_apt/manifests/leap_repo.pp4
-rw-r--r--puppet/modules/site_apt/manifests/sid_repo.pp11
-rw-r--r--puppet/modules/site_apt/templates/jessie/postfix.seeds1
-rw-r--r--puppet/modules/site_apt/templates/secondary.list2
-rw-r--r--puppet/modules/site_check_mk/manifests/agent/mx.pp7
-rw-r--r--puppet/modules/site_check_mk/manifests/server.pp13
-rw-r--r--puppet/modules/site_check_mk/templates/use_ssh.mk2
-rw-r--r--puppet/modules/site_config/manifests/packages/build_essential.pp4
-rw-r--r--puppet/modules/site_config/manifests/remove/files.pp14
-rw-r--r--puppet/modules/site_config/manifests/ruby.pp12
-rw-r--r--puppet/modules/site_config/manifests/ruby/dev.pp2
-rw-r--r--puppet/modules/site_couchdb/files/designs/identities/Identity.json32
-rw-r--r--puppet/modules/site_couchdb/files/designs/messages/Message.json12
-rw-r--r--puppet/modules/site_couchdb/files/designs/tickets/Ticket.json24
-rw-r--r--puppet/modules/site_couchdb/files/designs/users/User.json4
-rw-r--r--puppet/modules/site_couchdb/manifests/master.pp5
-rw-r--r--puppet/modules/site_nagios/manifests/server.pp2
-rw-r--r--puppet/modules/site_nagios/manifests/server/apache.pp18
-rw-r--r--puppet/modules/site_postfix/templates/checks/helo_access.erb2
-rw-r--r--puppet/modules/site_sshd/manifests/init.pp31
-rw-r--r--puppet/modules/site_webapp/manifests/apache.pp9
-rw-r--r--puppet/modules/site_webapp/manifests/hidden_service.pp8
-rw-r--r--puppet/modules/site_webapp/templates/config.yml.erb4
m---------puppet/modules/sshd0
m---------puppet/modules/unbound0
-rw-r--r--tests/helpers/client_side_db.py167
-rw-r--r--tests/helpers/os_helper.rb5
-rwxr-xr-xtests/helpers/soledad_sync.py123
-rw-r--r--tests/white-box/mx.rb3
-rw-r--r--tests/white-box/network.rb11
-rw-r--r--tests/white-box/webapp.rb29
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