From 6017757bc079f4446aa77bc5c0855c52741280f4 Mon Sep 17 00:00:00 2001 From: Reinhard Tartler Date: Tue, 28 May 2019 07:20:50 -0400 Subject: New upstream version 0.13~~git20190527.g039c4a1 --- test/backupstorefix/testbackupstorefix.cpp | 8 +- .../testfiles/testbackupstorefix.pl.in | 16 +- test/basicserver/testbasicserver.cpp | 205 ++++++++++++- .../testfiles/seclevel2-sha1/bbackupd.conf | 196 +++++++++++++ .../seclevel2-sha1/bbackupd/1234567-csr.pem | 15 + .../seclevel2-sha1/bbackupd/1234567-key.pem | 27 ++ .../seclevel2-sha1/bbackupd/NotifySysadmin.sh | 70 +++++ .../testfiles/seclevel2-sha1/bbstored.conf | 23 ++ .../seclevel2-sha1/bbstored/localhost-csr.pem | 15 + .../seclevel2-sha1/bbstored/localhost-key.pem | 27 ++ .../seclevel2-sha1/ca/clients/1234567-cert.pem | 17 ++ .../seclevel2-sha1/ca/keys/clientRootCSR.pem | 15 + .../seclevel2-sha1/ca/keys/clientRootKey.pem | 27 ++ .../seclevel2-sha1/ca/keys/serverRootCSR.pem | 15 + .../seclevel2-sha1/ca/keys/serverRootKey.pem | 27 ++ .../testfiles/seclevel2-sha1/ca/roots/clientCA.pem | 18 ++ .../testfiles/seclevel2-sha1/ca/roots/clientCA.srl | 1 + .../testfiles/seclevel2-sha1/ca/roots/serverCA.pem | 18 ++ .../testfiles/seclevel2-sha1/ca/roots/serverCA.srl | 1 + .../seclevel2-sha1/ca/servers/localhost-cert.pem | 17 ++ .../testfiles/seclevel2-sha1/raidfile.conf | 10 + .../testfiles/seclevel2-sha256/bbackupd.conf | 196 +++++++++++++ .../seclevel2-sha256/bbackupd/1234567-csr.pem | 15 + .../seclevel2-sha256/bbackupd/1234567-key.pem | 27 ++ .../seclevel2-sha256/bbackupd/NotifySysadmin.sh | 70 +++++ .../testfiles/seclevel2-sha256/bbstored.conf | 23 ++ .../seclevel2-sha256/bbstored/localhost-csr.pem | 15 + .../seclevel2-sha256/bbstored/localhost-key.pem | 27 ++ .../seclevel2-sha256/ca/clients/1234567-cert.pem | 17 ++ .../seclevel2-sha256/ca/keys/clientRootCSR.pem | 15 + .../seclevel2-sha256/ca/keys/clientRootKey.pem | 27 ++ .../seclevel2-sha256/ca/keys/serverRootCSR.pem | 15 + .../seclevel2-sha256/ca/keys/serverRootKey.pem | 27 ++ .../seclevel2-sha256/ca/roots/clientCA.pem | 18 ++ .../seclevel2-sha256/ca/roots/clientCA.srl | 1 + .../seclevel2-sha256/ca/roots/serverCA.pem | 18 ++ .../seclevel2-sha256/ca/roots/serverCA.srl | 1 + .../ca/servers/localhost-cert-sha1.pem | 17 ++ .../seclevel2-sha256/ca/servers/localhost-cert.pem | 17 ++ .../testfiles/seclevel2-sha256/raidfile.conf | 10 + .../testfiles/srv3-insecure-daemon.conf | 9 + .../basicserver/testfiles/srv3-seclevel2-sha1.conf | 9 + .../testfiles/srv3-seclevel2-sha256.conf | 9 + test/basicserver/testfiles/srv4-noseclevel.conf | 5 + test/basicserver/testfiles/srv4-seclevel1.conf | 7 + .../testfiles/srv4-seclevel2-insecure.conf | 7 + .../testfiles/srv4-seclevel2-secure.conf | 7 + test/basicserver/testfiles/srv4.conf | 6 - test/bbackupd/testbbackupd.cpp | 320 ++++++++++++++++----- 49 files changed, 1612 insertions(+), 91 deletions(-) create mode 100644 test/basicserver/testfiles/seclevel2-sha1/bbackupd.conf create mode 100644 test/basicserver/testfiles/seclevel2-sha1/bbackupd/1234567-csr.pem create mode 100644 test/basicserver/testfiles/seclevel2-sha1/bbackupd/1234567-key.pem create mode 100755 test/basicserver/testfiles/seclevel2-sha1/bbackupd/NotifySysadmin.sh create mode 100644 test/basicserver/testfiles/seclevel2-sha1/bbstored.conf create mode 100644 test/basicserver/testfiles/seclevel2-sha1/bbstored/localhost-csr.pem create mode 100644 test/basicserver/testfiles/seclevel2-sha1/bbstored/localhost-key.pem create mode 100644 test/basicserver/testfiles/seclevel2-sha1/ca/clients/1234567-cert.pem create mode 100644 test/basicserver/testfiles/seclevel2-sha1/ca/keys/clientRootCSR.pem create mode 100644 test/basicserver/testfiles/seclevel2-sha1/ca/keys/clientRootKey.pem create mode 100644 test/basicserver/testfiles/seclevel2-sha1/ca/keys/serverRootCSR.pem create mode 100644 test/basicserver/testfiles/seclevel2-sha1/ca/keys/serverRootKey.pem create mode 100644 test/basicserver/testfiles/seclevel2-sha1/ca/roots/clientCA.pem create mode 100644 test/basicserver/testfiles/seclevel2-sha1/ca/roots/clientCA.srl create mode 100644 test/basicserver/testfiles/seclevel2-sha1/ca/roots/serverCA.pem create mode 100644 test/basicserver/testfiles/seclevel2-sha1/ca/roots/serverCA.srl create mode 100644 test/basicserver/testfiles/seclevel2-sha1/ca/servers/localhost-cert.pem create mode 100644 test/basicserver/testfiles/seclevel2-sha1/raidfile.conf create mode 100644 test/basicserver/testfiles/seclevel2-sha256/bbackupd.conf create mode 100644 test/basicserver/testfiles/seclevel2-sha256/bbackupd/1234567-csr.pem create mode 100644 test/basicserver/testfiles/seclevel2-sha256/bbackupd/1234567-key.pem create mode 100755 test/basicserver/testfiles/seclevel2-sha256/bbackupd/NotifySysadmin.sh create mode 100644 test/basicserver/testfiles/seclevel2-sha256/bbstored.conf create mode 100644 test/basicserver/testfiles/seclevel2-sha256/bbstored/localhost-csr.pem create mode 100644 test/basicserver/testfiles/seclevel2-sha256/bbstored/localhost-key.pem create mode 100644 test/basicserver/testfiles/seclevel2-sha256/ca/clients/1234567-cert.pem create mode 100644 test/basicserver/testfiles/seclevel2-sha256/ca/keys/clientRootCSR.pem create mode 100644 test/basicserver/testfiles/seclevel2-sha256/ca/keys/clientRootKey.pem create mode 100644 test/basicserver/testfiles/seclevel2-sha256/ca/keys/serverRootCSR.pem create mode 100644 test/basicserver/testfiles/seclevel2-sha256/ca/keys/serverRootKey.pem create mode 100644 test/basicserver/testfiles/seclevel2-sha256/ca/roots/clientCA.pem create mode 100644 test/basicserver/testfiles/seclevel2-sha256/ca/roots/clientCA.srl create mode 100644 test/basicserver/testfiles/seclevel2-sha256/ca/roots/serverCA.pem create mode 100644 test/basicserver/testfiles/seclevel2-sha256/ca/roots/serverCA.srl create mode 100644 test/basicserver/testfiles/seclevel2-sha256/ca/servers/localhost-cert-sha1.pem create mode 100644 test/basicserver/testfiles/seclevel2-sha256/ca/servers/localhost-cert.pem create mode 100644 test/basicserver/testfiles/seclevel2-sha256/raidfile.conf create mode 100644 test/basicserver/testfiles/srv3-insecure-daemon.conf create mode 100644 test/basicserver/testfiles/srv3-seclevel2-sha1.conf create mode 100644 test/basicserver/testfiles/srv3-seclevel2-sha256.conf create mode 100644 test/basicserver/testfiles/srv4-noseclevel.conf create mode 100644 test/basicserver/testfiles/srv4-seclevel1.conf create mode 100644 test/basicserver/testfiles/srv4-seclevel2-insecure.conf create mode 100644 test/basicserver/testfiles/srv4-seclevel2-secure.conf delete mode 100644 test/basicserver/testfiles/srv4.conf (limited to 'test') diff --git a/test/backupstorefix/testbackupstorefix.cpp b/test/backupstorefix/testbackupstorefix.cpp index 38492bd1..ac1d0c14 100644 --- a/test/backupstorefix/testbackupstorefix.cpp +++ b/test/backupstorefix/testbackupstorefix.cpp @@ -671,8 +671,12 @@ int test(int argc, const char *argv[]) char name[256]; while(::fgets(line, sizeof(line), f) != 0) { - TEST_THAT(::sscanf(line, "%x %s %s", &id, - flags, name) == 3); + if(StartsWith("WARNING: SSLSecurityLevel not set.", line)) + { + continue; + } + TEST_EQUAL_LINE(3, ::sscanf(line, "%x %s %s", &id, flags, name), + "Unexpected format in initial-listing.txt: <" << line << ">"); bool isDir = (::strcmp(flags, "-d---") == 0); //TRACE3("%x,%d,%s\n", id, isDir, name); MEMLEAKFINDER_NO_LEAKS; diff --git a/test/backupstorefix/testfiles/testbackupstorefix.pl.in b/test/backupstorefix/testfiles/testbackupstorefix.pl.in index fc807155..483087f7 100755 --- a/test/backupstorefix/testfiles/testbackupstorefix.pl.in +++ b/test/backupstorefix/testfiles/testbackupstorefix.pl.in @@ -148,18 +148,20 @@ elsif($ARGV[0] eq 'reroot') or die "can't open copy listing file"; my $err = 0; my $count = 0; - while() + while(my $line = ) { - print LISTING_COPY; - chomp; - s/\[FILENAME NOT ENCRYPTED\]//; - next if /^WARNING: \*\*\*\* BackupStoreFilename encoded with Clear encoding \*\*\*\*/; - my ($id,$type,$name) = split / /; + print LISTING_COPY $line; + chomp $line; + $line =~s/\[FILENAME NOT ENCRYPTED\]//; + next if $line =~ /^WARNING: \*\*\*\* BackupStoreFilename encoded with Clear encoding \*\*\*\*/; + next if $line =~ /^WARNING: SSLSecurityLevel not set./; + my ($id,$type,$name) = split / /, $line; $count++; if($name !~ /\Alost\+found0/) { # everything must be in a lost and found dir - $err = 1 + print "Expected '$name' to be in a lost+found directory, but it was not ($line)"; + $err = 1; } } close LISTING_COPY; diff --git a/test/basicserver/testbasicserver.cpp b/test/basicserver/testbasicserver.cpp index 6f2def54..9285dfc9 100644 --- a/test/basicserver/testbasicserver.cpp +++ b/test/basicserver/testbasicserver.cpp @@ -15,18 +15,17 @@ #include -#include "Test.h" -#include "Daemon.h" +#include "CollectInBufferStream.h" #include "Configuration.h" -#include "ServerStream.h" -#include "SocketStream.h" +#include "Daemon.h" #include "IOStreamGetLine.h" +#include "ServerControl.h" +#include "ServerStream.h" #include "ServerTLS.h" -#include "CollectInBufferStream.h" - +#include "SocketStream.h" +#include "Test.h" #include "TestContext.h" #include "autogen_TestProtocol.h" -#include "ServerControl.h" #include "MemLeakFindOn.h" @@ -98,7 +97,7 @@ void testservers_connection(SocketStream &rStream) while(!getline.IsEOF()) { std::string line; - while(!getline.GetLine(line)) + while(!getline.GetLine(line, false, SHORT_TIMEOUT)) ; if(line == "QUIT") { @@ -208,11 +207,16 @@ const ConfigurationVerify *testserver::GetConfigVerify() const } }; + static ConfigurationVerifyKey root_keys[] = + { + ssl_security_level_key, + }; + static ConfigurationVerify verify = { "root", /* mName */ verifyserver, /* mpSubConfigurations */ - 0, /* mpKeys */ + root_keys, // mpKeys ConfigTest_Exists | ConfigTest_LastEntry, 0 }; @@ -449,6 +453,151 @@ void TestStreamReceive(TestProtocolClient &protocol, int value, bool uncertainst TEST_THAT(count == (24273*3)); // over 64 k of data, definately } +bool test_security_level(int cert_level, int test_level, bool expect_failure_on_connect = false) +{ + int old_num_failures = num_failures; + + // Context first + TLSContext context; + if(cert_level == 0) + { + context.Initialise(false /* client */, + "testfiles/clientCerts.pem", + "testfiles/clientPrivKey.pem", + "testfiles/clientTrustedCAs.pem", + test_level); // SecurityLevel + } + else if(cert_level == 1) + { + context.Initialise(false /* client */, + "testfiles/seclevel2-sha1/ca/clients/1234567-cert.pem", + "testfiles/seclevel2-sha1/bbackupd/1234567-key.pem", + "testfiles/seclevel2-sha1/ca/roots/serverCA.pem", + test_level); // SecurityLevel + } + else if(cert_level == 2) + { + context.Initialise(false /* client */, + "testfiles/seclevel2-sha256/ca/clients/1234567-cert.pem", + "testfiles/seclevel2-sha256/bbackupd/1234567-key.pem", + "testfiles/seclevel2-sha256/ca/roots/serverCA.pem", + test_level); // SecurityLevel + } + else + { + TEST_FAIL_WITH_MESSAGE("No certificates generated for level " << cert_level); + return false; + } + + SocketStreamTLS conn; + + if(expect_failure_on_connect) + { + TEST_CHECK_THROWS( + conn.Open(context, Socket::TypeINET, "localhost", 2003), + ConnectionException, TLSPeerWeakCertificate); + } + else + { + conn.Open(context, Socket::TypeINET, "localhost", 2003); + } + + return (num_failures == old_num_failures); // no new failures -> good +} + +// Test the certificates that were distributed with the Box Backup source since ancient times, +// which have only 1024-bit keys, and thus fail with "ee key too small". +bool test_ancient_certificates() +{ + int old_num_failures = num_failures; + + // Level -1 (allow weaker, with warning) should pass with any certificates: + TEST_THAT(test_security_level(0, -1)); // cert_level, test_level + + // We do not test level 0 (system-wide default) because the system + // may have it set high, and our old certificate will not be usable + // in that case, and the user has no way to fix that, so it's not a + // useful test. + + // Level 1 (allow weaker, without a warning) should pass with any certificates: + TEST_THAT(test_security_level(0, 1)); // cert_level, test_level + +#ifdef HAVE_SSL_CTX_SET_SECURITY_LEVEL + // Level 2 (disallow weaker, without a warning) should NOT pass with old certificates: + TEST_CHECK_THROWS( + test_security_level(0, 2), // cert_level, test_level + ServerException, TLSServerWeakCertificate); +#else + // We have no way to increase the security level, so it should still pass: + test_security_level(0, 2); // cert_level, test_level +#endif + + return (num_failures == old_num_failures); // no new failures -> good +} + +// Test a set of more recent certificates, which have a longer key but are signed using the SHA1 +// algorithm instead of SHA256, which fail with "ca md too weak" instead. +bool test_old_certificates() +{ + int old_num_failures = num_failures; + + // Level -1 (allow weaker, with warning) should pass with any certificates: + TEST_THAT(test_security_level(1, -1)); // cert_level, test_level + + // We do not test level 0 (system-wide default) because the system + // may have it set high, and our old certificate will not be usable + // in that case, and the user has no way to fix that, so it's not a + // useful test. + + // Level 1 (allow weaker, without a warning) should pass with any certificates: + TEST_THAT(test_security_level(1, 1)); // cert_level, test_level + +#ifdef HAVE_SSL_CTX_SET_SECURITY_LEVEL + // Level 2 (disallow weaker, without a warning) should NOT pass with old certificates: + TEST_CHECK_THROWS( + test_security_level(1, 2), // cert_level, test_level + ServerException, TLSServerWeakCertificate); +#else + // We have no way to increase the security level, so it should still pass: + test_security_level(1, 2); // cert_level, test_level +#endif + + return (num_failures == old_num_failures); // no new failures -> good +} + + +bool test_new_certificates(bool expect_failure_level_2) +{ + int old_num_failures = num_failures; + + // Level -1 (allow weaker, with warning) should pass with any certificates: + TEST_THAT(test_security_level(2, -1)); // cert_level, test_level + + // Level 0 (system dependent). This will fail if the user (or their + // distro) sets the system-wide security level very high. We check + // this because *we* may need to update Box Backup if this happens + // again, as it did when Debian increased the default level. + // Newly generated certificates may need to be strengthened. + // And we may need to update the documentation. + TEST_THAT(test_security_level(2, 0)); // cert_level, test_level + + // Level 1 (allow weaker, without a warning) should pass with any certificates: + TEST_THAT(test_security_level(2, 1)); // cert_level, test_level + +#ifdef HAVE_SSL_CTX_SET_SECURITY_LEVEL + // Level 2 (disallow weaker, without a warning) should pass with new certificates, + // but might fail to connect to a peer with weak (insecure) certificates: + TEST_THAT(test_security_level(2, 2, expect_failure_level_2)); + // cert_level, test_level, expect_failure +#else + // We have no way to increase the security level, so it should not fail to connect to a + // daemon with weak certificates: + test_security_level(2, 2, false); // cert_level, test_level, expect_failure +#endif + + return (num_failures == old_num_failures); // no new failures -> good +} + int test(int argc, const char *argv[]) { @@ -644,6 +793,7 @@ int test(int argc, const char *argv[]) "testfiles/clientCerts.pem", "testfiles/clientPrivKey.pem", "testfiles/clientTrustedCAs.pem"); + // SecurityLevel == -1 by default (old security + warnings) SocketStreamTLS conn1; conn1.Open(context, Socket::TypeINET, "localhost", 2003); @@ -682,6 +832,11 @@ int test(int argc, const char *argv[]) TEST_THAT(ServerIsAlive(pid)); #endif + // Try testing with different security levels, check that the behaviour is + // as documented at: + // https://github.com/boxbackup/boxbackup/wiki/WeakSSLCertificates + TEST_THAT(test_ancient_certificates()); + // Kill it TEST_THAT(KillServer(pid)); ::sleep(1); @@ -691,6 +846,36 @@ int test(int argc, const char *argv[]) TestRemoteProcessMemLeaks("test-srv3.memleaks"); #endif } + + cmd = TEST_EXECUTABLE " --test-daemon-args="; + cmd += test_args; + cmd += " srv3 testfiles/srv3-seclevel2-sha1.conf"; + pid = LaunchServer(cmd, "testfiles/srv3.pid"); + + TEST_THAT(pid != -1 && pid != 0); + TEST_THAT(test_old_certificates()); + TEST_THAT(KillServer(pid)); + + cmd = TEST_EXECUTABLE " --test-daemon-args="; + cmd += test_args; + cmd += " srv3 testfiles/srv3-seclevel2-sha256.conf"; + pid = LaunchServer(cmd, "testfiles/srv3.pid"); + + TEST_THAT(pid != -1 && pid != 0); + TEST_THAT(test_new_certificates(false)); // !expect_failure_level_2 + TEST_THAT(KillServer(pid)); + + // Start a daemon using old, insecure certificates. We should get an error when we + // try to connect to it: + + cmd = TEST_EXECUTABLE " --test-daemon-args="; + cmd += test_args; + cmd += " srv3 testfiles/srv3-insecure-daemon.conf"; + pid = LaunchServer(cmd, "testfiles/srv3.pid"); + + TEST_THAT(pid != -1 && pid != 0); + TEST_THAT(test_new_certificates(true)); // expect_failure_level_2 + TEST_THAT(KillServer(pid)); } //protocolserver: @@ -698,7 +883,7 @@ int test(int argc, const char *argv[]) { std::string cmd = TEST_EXECUTABLE " --test-daemon-args="; cmd += test_args; - cmd += " srv4 testfiles/srv4.conf"; + cmd += " srv4 testfiles/srv4-seclevel1.conf"; int pid = LaunchServer(cmd, "testfiles/srv4.pid"); TEST_THAT(pid != -1 && pid != 0); diff --git a/test/basicserver/testfiles/seclevel2-sha1/bbackupd.conf b/test/basicserver/testfiles/seclevel2-sha1/bbackupd.conf new file mode 100644 index 00000000..eb37d9ab --- /dev/null +++ b/test/basicserver/testfiles/seclevel2-sha1/bbackupd.conf @@ -0,0 +1,196 @@ + +StoreHostname = localhost +AccountNumber = 0x1234567 +KeysFile = ./bbackupd/1234567-FileEncKeys.raw + +CertificateFile = ./bbackupd/1234567-cert.pem +PrivateKeyFile = ./bbackupd/1234567-key.pem +TrustedCAsFile = ./bbackupd/serverCA.pem +SSLSecurityLevel = 2 + +DataDirectory = /home/chris/boxbackup/test/basicserver/testfiles/seclevel2-sha1 + + +# This script is run whenever bbackupd changes state or encounters a +# problem which requires the system administrator to assist: +# +# 1) The store is full, and no more data can be uploaded. +# 2) Some files or directories were not readable. +# 3) A backup run starts or finishes. +# +# The default script emails the system administrator, except for backups +# starting and stopping, where it does nothing. + +NotifyScript = ./bbackupd/NotifySysadmin.sh + + +# The number of seconds between backup runs under normal conditions. To avoid +# cycles of load on the server, this time is randomly adjusted by a small +# percentage as the daemon runs. + +UpdateStoreInterval = 3600 + + +# The minimum age of a file, in seconds, that will be uploaded. Avoids +# repeated uploads of a file which is constantly being modified. + +MinimumFileAge = 21600 + + +# If a file is modified repeated, it won't be uploaded immediately in case +# it's modified again, due to the MinimumFileAge specified above. However, it +# should be uploaded eventually even if it is being modified repeatedly. This +# is how long we should wait, in seconds, after first noticing a change. +# (86400 seconds = 1 day) + +MaxUploadWait = 86400 + +# If the connection is idle for some time (e.g. over 10 minutes or 600 +# seconds, not sure exactly how long) then the server will give up and +# disconnect the client, resulting in Connection Protocol_Timeout errors +# on the server and TLSReadFailed or TLSWriteFailed errors on the client. +# Also, some firewalls and NAT gateways will kill idle connections after +# similar lengths of time. +# +# This can happen for example when most files are backed up already and +# don't need to be sent to the store again, while scanning a large +# directory, or while calculating diffs of a large file. To avoid this, +# KeepAliveTime specifies that special keep-alive messages should be sent +# when the connection is otherwise idle for a certain length of time, +# specified here in seconds. +# +# The default is that these messages are never sent, equivalent to setting +# this option to zero, but we recommend that all users enable this. + +KeepAliveTime = 120 + + +# Files above this size (in bytes) are tracked, and if they are renamed they will simply be +# renamed on the server, rather than being uploaded again. (64k - 1) + +FileTrackingSizeThreshold = 65535 + + +# The daemon does "changes only" uploads for files above this size (in bytes). +# Files less than it are uploaded whole without this extra processing. + +DiffingUploadSizeThreshold = 8192 + + +# The limit on how much time is spent diffing files, in seconds. Most files +# shouldn't take very long, but if you have really big files you can use this +# to limit the time spent diffing them. +# +# * Reduce if you are having problems with processor usage. +# +# * Increase if you have large files, and think the upload of changes is too +# large and you want bbackupd to spend more time searching for unchanged +# blocks. + +MaximumDiffingTime = 120 + + +# Uncomment this line to see exactly what the daemon is going when it's connected to the server. + +# ExtendedLogging = yes + + +# This specifies a program or script script which is run just before each +# sync, and ideally the full path to the interpreter. It will be run as the +# same user bbackupd is running as, usually root. +# +# The script must output (print) either "now" or a number to STDOUT (and a +# terminating newline, no quotes). +# +# If the result was "now", then the sync will happen. If it's a number, then +# no backup will happen for that number of seconds (bbackupd will pause) and +# then the script will be run again. +# +# Use this to temporarily stop bbackupd from syncronising or connecting to the +# store. For example, you could use this on a laptop to only backup when on a +# specific network, or when it has a working Internet connection. + +# SyncAllowScript = /path/to/intepreter/or/exe script-name parameters etc + + +# Where the command socket is created in the filesystem. + +CommandSocket = /home/chris/boxbackup/test/basicserver/testfiles/seclevel2-sha1/bbackupd.sock + +# Uncomment the StoreObjectInfoFile to enable the experimental archiving +# of the daemon's state (including client store marker and configuration) +# between backup runs. This saves time and increases efficiency when +# bbackupd is frequently stopped and started, since it removes the need +# to rescan all directories on the remote server. However, it is new and +# not yet heavily tested, so use with caution. + +# StoreObjectInfoFile = /home/chris/boxbackup/test/basicserver/testfiles/seclevel2-sha1/bbackupd.state + +Server +{ + PidFile = /home/chris/boxbackup/test/basicserver/testfiles/seclevel2-sha1/bbackupd.pid +} + + +# BackupLocations specifies which locations on disc should be backed up. Each +# directory is in the format +# +# name +# { +# Path = /path/of/directory +# (optional exclude directives) +# } +# +# 'name' is derived from the Path by the config script, but should merely be +# unique. +# +# The exclude directives are of the form +# +# [Exclude|AlwaysInclude][File|Dir][|sRegex] = regex or full pathname +# +# (The regex suffix is shown as 'sRegex' to make File or Dir plural) +# +# For example: +# +# ExcludeDir = /home/guest-user +# ExcludeFilesRegex = .(mp3|MP3)$ +# AlwaysIncludeFile = /home/username/veryimportant.mp3 +# +# This excludes the directory /home/guest-user from the backup along with all mp3 +# files, except one MP3 file in particular. +# +# In general, Exclude excludes a file or directory, unless the directory is +# explicitly mentioned in a AlwaysInclude directive. However, Box Backup +# does NOT scan inside excluded directories and will never back up an +# AlwaysIncluded file or directory inside an excluded directory or any +# subdirectory thereof. +# +# To back up a directory inside an excluded directory, use a configuration +# like this, to ensure that each directory in the path to the important +# files is included, but none of their contents will be backed up except +# the directories further down that path to the important one. +# +# ExcludeDirsRegex = ^/home/user/bigfiles/ +# ExcludeFilesRegex = ^/home/user/bigfiles/ +# AlwaysIncludeDir = /home/user/bigfiles/path +# AlwaysIncludeDir = /home/user/bigfiles/path/to +# AlwaysIncludeDir = /home/user/bigfiles/path/important +# AlwaysIncludeDir = /home/user/bigfiles/path/important/files +# AlwaysIncludeDirsRegex = ^/home/user/bigfiles/path/important/files/ +# AlwaysIncludeFilesRegex = ^/home/user/bigfiles/path/important/files/ +# +# If a directive ends in Regex, then it is a regular expression rather than a +# explicit full pathname. See +# +# man 7 re_format +# +# for the regex syntax on your platform. + +BackupLocations +{ + home-chris-boxbackup-test-basicserver-testfiles-seclevel2-sha1 + { + Path = /home/chris/boxbackup/test/basicserver/testfiles/seclevel2-sha1 + } +} + diff --git a/test/basicserver/testfiles/seclevel2-sha1/bbackupd/1234567-csr.pem b/test/basicserver/testfiles/seclevel2-sha1/bbackupd/1234567-csr.pem new file mode 100644 index 00000000..340116ed --- /dev/null +++ b/test/basicserver/testfiles/seclevel2-sha1/bbackupd/1234567-csr.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIICXjCCAUYCAQAwGTEXMBUGA1UEAwwOQkFDS1VQLTEyMzQ1NjcwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrSHZEUGZxLnDFr0B02Utd5rF6YwYmhzLG +WNBnC0FBrCN0qJgjEHpQ0jqMGA9vIvBuesYhBmk8hOyJFHNtJB8MJyeHvKSwdwlF +Isz+gr60RGAKj290nSdFgMvMgkdqz6Vg4R9t94fzhxjk/BJyNjr8r+64hffIOQmM +YlmADLX38BLRLAfbVVkq/bRgqBFtmvFYTZKl6of1jVSWQLcXGShWE45lc5Hpd+qv +DRjzsQukb3gJmKU4DMW1BCaS8W6v7R0MG/5CooiwMRrct8puH4IeIDrByBz/0mRP +fMPjR2qpjx4EmLRcC39lGVBTnXLYM1XGIYsX7f1ssYZZXSSajUp9AgMBAAGgADAN +BgkqhkiG9w0BAQUFAAOCAQEAbDRc2PW9WnUu7F1g/mWQW8aGhyzMcYTp28kVEtMC +dvvbNLFWtWPXktM9PjR6F+3QRQktdXwYXsTctmGL4vvSKFd66gw4HklGe+Opiiw/ +o9F6E2PAFzRYbMio7UYevs/RhktaJRkVyd81e8LtFHuUD3vqBY84NVeKwmxnbdoK +jzBj3x3COkLLiPTWjb+RgxnPWcNtXhLAcATZeCKBo4U0gvRL1NTMCslIumdhtD8h +BQOdEaSP2sB8o3mMEh8W5tgja4zWv1GszJK9sJNL/EZag331/++5H06yf8vPhQW7 +rqRHA33CUe7XiqAkXp+Rgq5W97qcKIlo4uKRzCsTYC/QUg== +-----END CERTIFICATE REQUEST----- diff --git a/test/basicserver/testfiles/seclevel2-sha1/bbackupd/1234567-key.pem b/test/basicserver/testfiles/seclevel2-sha1/bbackupd/1234567-key.pem new file mode 100644 index 00000000..9ee696ee --- /dev/null +++ b/test/basicserver/testfiles/seclevel2-sha1/bbackupd/1234567-key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAq0h2RFBmcS5wxa9AdNlLXeaxemMGJocyxljQZwtBQawjdKiY +IxB6UNI6jBgPbyLwbnrGIQZpPITsiRRzbSQfDCcnh7yksHcJRSLM/oK+tERgCo9v +dJ0nRYDLzIJHas+lYOEfbfeH84cY5PwScjY6/K/uuIX3yDkJjGJZgAy19/AS0SwH +21VZKv20YKgRbZrxWE2SpeqH9Y1UlkC3FxkoVhOOZXOR6Xfqrw0Y87ELpG94CZil +OAzFtQQmkvFur+0dDBv+QqKIsDEa3LfKbh+CHiA6wcgc/9JkT3zD40dqqY8eBJi0 +XAt/ZRlQU51y2DNVxiGLF+39bLGGWV0kmo1KfQIDAQABAoIBAHLetfI6uXlOW/M4 +BVJYKGNhQ8WAg69zHGpJRfrVYX5Zo62pI97gPifV1c3+lNtD41s0m4uqcQlVXAzS +2lZn0yqjV6+ApDJ0opLrM++8X4kmEgMDDwx2GNBUAFm3RY4slAzU7e8iAtsfz2JC +a1yNYiH1G3RE5FgzaGPt0Xg/DgqorT6uR5/jIzlSpqRse9sXG4/uGEmfkogMwvU+ +gmcMOs+Jm7HbLMIGxzBydNTFoup1YUVSCuIjdJBpWRCbBaeYeTSoQgdAPALtwJgz +v8quFaJOkJMKIaXOF+1VN8w5rPTJJdfHtYITz6i0V5A7qSHR5jckbm0UWcXnEdaZ +YvkKRUECgYEA4krb4xrXLuSbUv70dKXybyNxEFK+IVG6NZG4+iaW8B8oU8+q8FzM +HPYAdppYKkYrjslKWIOwZdTsYa4Z8U/uhmMv4OpcCq7nYv6W/g1N/AMd8pEJvV9m +EQ5hY1uMg3rgorYWGDyh3HcYl2q4/9EJiPKUVoZb9IPeO3Po3TgK8A8CgYEAwcTf +EHJVs5F2mnetRhETpC5IGUB9OKbPm+JR6+BNFsh1vaPosobfYOzO6PJm0H/z4jMN +n29oc1SAphUXegE6gbVO8/hd9S4OhTq8egFO9Y/BN3/lHUYe/RPs2BZ+Foh70PH7 +9l6K/UDrwJ458hBrFM/DCcjRRcw12GBPUZ8xkLMCgYEAlND8GDc/igQnLYajhs7X +R0V8hmqTxN+1YKNLjZ6xJoqm/68TUG0Ggok5NsY78tkgrg8sSFeaOu2y4m4Xe33A +dDpoczZMf24UlyKsc7iWL4RxPmMpj5NcUR0u6KN9Hb5CWl762seM/qqHzpQNw5ZZ ++ejlqp1DfeL21Axe+JRxhPsCgYEAiYEWtoocbRhd7RHeYWl+4bSCL4FHG2usyjdZ +4SREMFXCz/fACuiRHiwOTNqvwWf7ftqx4SFjIuylerZe+ZJjnWY3iAQJURME9OCQ +nZfOG46PE75rrVF0bi20lken5H+oNcdzAQtoYH2wjvj5r+CczKD/DDN45qoaz9jQ +kOCCgOcCgYBDeOUq+6UoZMmx1c/H4MnRWMpHu0hNfivDEeJMYkxLMA98clstohc7 +T4B4gaoCewJ5XVR72k+Oqgvy++d4g5EpRjFE8hVNjw7Vo3WP0+X5iI+TmBuLKh/c +Wl10t7jLE25vyLJs4nmQd4hav9gWMbP5l99sVq61DM6bMuRcQnyeIA== +-----END RSA PRIVATE KEY----- diff --git a/test/basicserver/testfiles/seclevel2-sha1/bbackupd/NotifySysadmin.sh b/test/basicserver/testfiles/seclevel2-sha1/bbackupd/NotifySysadmin.sh new file mode 100755 index 00000000..48e8cf8e --- /dev/null +++ b/test/basicserver/testfiles/seclevel2-sha1/bbackupd/NotifySysadmin.sh @@ -0,0 +1,70 @@ +#!/bin/sh + +# This script is run whenever bbackupd changes state or encounters a +# problem which requires the system administrator to assist: +# +# 1) The store is full, and no more data can be uploaded. +# 2) Some files or directories were not readable. +# 3) A backup run starts or finishes. +# +# The default script emails the system administrator, except for backups +# starting and stopping, where it does nothing. + +SUBJECT="BACKUP PROBLEM on host debian-unstable" +SENDTO="chris" + +if [ "$1" = "" ]; then + echo "Usage: $0 " >&2 + exit 2 +elif [ "$1" = store-full ]; then + sendmail: $SENDTO <" >&2 + exit 2 +elif [ "$1" = store-full ]; then + sendmail: $SENDTO < +#include +#include + #ifndef WIN32 #include #endif -#include -#include -#include -#include -#include - -#ifdef HAVE_SYS_WAIT_H - #include +#ifdef WIN32 + #include #endif -#ifdef HAVE_SYS_XATTR_H - #include - #include +#ifdef HAVE_PWD_H + #include #endif #ifdef HAVE_SIGNAL_H #include #endif -#ifdef WIN32 - #include -#endif - -#include +#include +#include #ifdef HAVE_SYSCALL #include #endif +#ifdef HAVE_SYS_WAIT_H + #include +#endif + +#ifdef HAVE_SYS_XATTR_H + #include + #include +#endif + +#include + #include "BackupClientCryptoKeys.h" #include "BackupClientContext.h" #include "BackupClientFileAttributes.h" @@ -96,7 +101,6 @@ #define TIME_TO_WAIT_FOR_BACKUP_OPERATION 12 #define SHORT_TIMEOUT 5000 #define BACKUP_ERROR_DELAY_SHORTENED 10 -#define DEFAULT_BBACKUPD_CONFIG_FILE "testfiles/bbackupd.conf" void wait_for_backup_operation(const char* message) { @@ -410,25 +414,9 @@ bool configure_bbackupd(BackupDaemon& bbackupd, const std::string& config_file) return true; } -bool kill_running_daemons() -{ - bool success = true; - - if(FileExists("testfiles/bbstored.pid")) - { - TEST_THAT_OR(KillServer("testfiles/bbstored.pid", true), success = false); - } - - if(FileExists("testfiles/bbackupd.pid")) - { - TEST_THAT_OR(KillServer("testfiles/bbackupd.pid", true), success = false); - } - - return success; -} - -bool setup_test_bbackupd(BackupDaemon& bbackupd, bool do_unpack_files = true, - bool do_start_bbstored = true) +bool prepare_test_with_client_daemon(BackupDaemon& bbackupd, bool do_unpack_files = true, + bool do_start_bbstored = true, + const std::string& bbackupd_conf_file = "testfiles/bbackupd.conf") { Timers::Cleanup(false); // don't throw exception if not initialised Timers::Init(); @@ -469,8 +457,7 @@ bool setup_test_bbackupd(BackupDaemon& bbackupd, bool do_unpack_files = true, #endif } - TEST_THAT_OR(configure_bbackupd(bbackupd, "testfiles/bbackupd.conf"), - FAIL); + TEST_THAT_OR(configure_bbackupd(bbackupd, bbackupd_conf_file), FAIL); spDaemon = &bbackupd; return true; } @@ -486,13 +473,13 @@ bool setup_test_bbackupd(BackupDaemon& bbackupd, bool do_unpack_files = true, #define SETUP_WITHOUT_FILES() \ SETUP_TEST_BBACKUPD(); \ BackupDaemon bbackupd; \ - TEST_THAT_OR(setup_test_bbackupd(bbackupd, false), FAIL); \ + TEST_THAT_OR(prepare_test_with_client_daemon(bbackupd, false), FAIL); \ TEST_THAT_OR(::mkdir("testfiles/TestDir1", 0755) == 0, FAIL); #define SETUP_WITH_BBSTORED() \ SETUP_TEST_BBACKUPD(); \ BackupDaemon bbackupd; \ - TEST_THAT_OR(setup_test_bbackupd(bbackupd), FAIL); + TEST_THAT_OR(prepare_test_with_client_daemon(bbackupd), FAIL); #define TEARDOWN_TEST_BBACKUPD() \ TEST_THAT(bbackupd_pid == 0 || StopClient()); \ @@ -983,15 +970,16 @@ bool test_entry_deleted(BackupStoreDirectory& rDir, return flags && BackupStoreDirectory::Entry::Flags_Deleted; } -bool compare(BackupQueries::ReturnCode::Type expected_status, +bool compare_external(BackupQueries::ReturnCode::Type expected_status, const std::string& bbackupquery_options = "", - const std::string& compare_options = "-acQ") + const std::string& compare_options = "-acQ", + const std::string& bbackupd_conf_file = "testfiles/bbackupd.conf") { std::string cmd = BBACKUPQUERY; cmd += " "; cmd += (expected_status == BackupQueries::ReturnCode::Compare_Same) ? "-Wwarning" : "-Werror"; - cmd += " -c testfiles/bbackupd.conf "; + cmd += " -c " + bbackupd_conf_file; cmd += " " + bbackupquery_options; cmd += " \"compare " + compare_options + "\" quit"; @@ -1007,7 +995,7 @@ bool compare(BackupQueries::ReturnCode::Type expected_status, return (returnValue == expected_system_result); } -bool compare_local(BackupQueries::ReturnCode::Type expected_status, +bool compare_in_process(BackupQueries::ReturnCode::Type expected_status, BackupProtocolCallable& client, const std::string& compare_options = "acQ") { @@ -1074,10 +1062,21 @@ bool touch_and_wait(const std::string& filename) TLSContext sTlsContext; -#define TEST_COMPARE(...) \ - TEST_THAT(compare(BackupQueries::ReturnCode::__VA_ARGS__)); -#define TEST_COMPARE_LOCAL(...) \ - TEST_THAT(compare_local(BackupQueries::ReturnCode::__VA_ARGS__)); +#define TEST_COMPARE(expected_status) \ + BOX_INFO("Running external compare, expecting " #expected_status); \ + TEST_THAT(compare_external(BackupQueries::ReturnCode::expected_status)); +#define TEST_COMPARE_EXTRA(expected_status, ...) \ + BOX_INFO("Running external compare, expecting " #expected_status); \ + TEST_THAT(compare_external(BackupQueries::ReturnCode::expected_status, __VA_ARGS__)); + +#define TEST_COMPARE_LOCAL(expected_status, client) \ + BOX_INFO("Running compare in-process, expecting " #expected_status); \ + TEST_THAT(compare_in_process(BackupQueries::ReturnCode::expected_status, client)); +#define TEST_COMPARE_LOCAL_EXTRA(expected_status, client, compare_options) \ + BOX_INFO("Running compare in-process, expecting " #expected_status); \ + TEST_THAT(compare_in_process(BackupQueries::ReturnCode::expected_status, client, \ + compare_options)); + bool search_for_file(const std::string& filename) { @@ -1458,7 +1457,7 @@ bool test_ssl_keepalives() KeepAliveBackupProtocolLocal connection(0x01234567, "test", "backup/01234567/", 0, false); MockBackupDaemon bbackupd(connection); - TEST_THAT_OR(setup_test_bbackupd(bbackupd), FAIL); + TEST_THAT_OR(prepare_test_with_client_daemon(bbackupd), FAIL); // Test that sending a keepalive actually works, when the timeout has expired, // but doesn't send anything at the beginning: @@ -1943,9 +1942,9 @@ bool test_bbackupd_exclusions() bbackupd.RunSyncNow(); TEST_THAT(!bbackupd.StorageLimitExceeded()); - // Check that the contents of the store are the same - // as the contents of the disc - TEST_COMPARE(Compare_Same, "-c testfiles/bbackupd-exclude.conf"); + // Check that the contents of the store are the same + // as the contents of the disc + TEST_COMPARE_EXTRA(Compare_Same, "-c testfiles/bbackupd-exclude.conf"); BOX_TRACE("done."); // BLOCK @@ -2055,7 +2054,7 @@ bool test_bbackupd_responds_to_connection_failure() MockBackupProtocolLocal client(0x01234567, "test", "backup/01234567/", 0, false); MockBackupDaemon bbackupd(client); - TEST_THAT_OR(setup_test_bbackupd(bbackupd, false, false), FAIL); + TEST_THAT_OR(prepare_test_with_client_daemon(bbackupd, false, false), FAIL); TEST_THAT(::system("rm -f testfiles/notifyran.store-full.*") == 0); std::auto_ptr apClientContext; @@ -2285,11 +2284,11 @@ bool test_read_only_dirs_can_be_restored() #endif bbackupd.RunSyncNow(); - TEST_COMPARE(Compare_Same, "", "-cEQ Test1 testfiles/TestDir1"); + TEST_COMPARE_EXTRA(Compare_Same, "", "-cEQ Test1 testfiles/TestDir1"); // check that we can restore it TEST_THAT(restore("Test1", "testfiles/restore1")); - TEST_COMPARE(Compare_Same, "", "-cEQ Test1 testfiles/restore1"); + TEST_COMPARE_EXTRA(Compare_Same, "", "-cEQ Test1 testfiles/restore1"); // Try a restore with just the remote directory name, // check that it uses the same name in the local @@ -2297,7 +2296,7 @@ bool test_read_only_dirs_can_be_restored() TEST_THAT(::mkdir("testfiles/restore-test", 0700) == 0); TEST_THAT(bbackupquery("\"lcd testfiles/restore-test\" " "\"restore Test1\"")); - TEST_COMPARE(Compare_Same, "", "-cEQ Test1 " + TEST_COMPARE_EXTRA(Compare_Same, "", "-cEQ Test1 " "testfiles/restore-test/Test1"); // put the permissions back to sensible values @@ -2507,7 +2506,7 @@ bool test_unicode_filenames_can_be_backed_up() // Check that bbackupquery can compare the dir when given // on the command line in system encoding. - TEST_COMPARE(Compare_Same, "", "-cEQ Test1/" + systemDirName + + TEST_COMPARE_EXTRA(Compare_Same, "", "-cEQ Test1/" + systemDirName + " testfiles/TestDir1/" + systemDirName); // Check that bbackupquery can restore the dir when given @@ -2516,7 +2515,7 @@ bool test_unicode_filenames_can_be_backed_up() "testfiles/restore-" + systemDirName)); // Compare to make sure it was restored properly. - TEST_COMPARE(Compare_Same, "", "-cEQ Test1/" + systemDirName + + TEST_COMPARE_EXTRA(Compare_Same, "", "-cEQ Test1/" + systemDirName + " testfiles/restore-" + systemDirName); std::string fileToUnlink = "testfiles/restore-" + @@ -2548,7 +2547,7 @@ bool test_unicode_filenames_can_be_backed_up() // Compare to make sure it was restored properly. The Get // command does restore attributes, so we don't need to // specify the -A option for this to succeed. - TEST_COMPARE(Compare_Same, "", "-cEQ Test1/" + systemDirName + + TEST_COMPARE_EXTRA(Compare_Same, "", "-cEQ Test1/" + systemDirName + " testfiles/restore-" + systemDirName); // Check that no read error has been reported yet @@ -2704,7 +2703,7 @@ bool test_delete_update_and_symlink_files() TEST_COMPARE(Compare_Same); // Try a quick compare, just for fun - TEST_COMPARE(Compare_Same, "", "-acqQ"); + TEST_COMPARE_EXTRA(Compare_Same, "", "-acqQ"); } TEARDOWN_TEST_BBACKUPD(); @@ -3193,8 +3192,8 @@ bool test_excluded_files_are_not_backed_up() BackupProtocolLocal2 client(0x01234567, "test", "backup/01234567/", 0, false); MockBackupDaemon bbackupd(client); - - TEST_THAT_OR(setup_test_bbackupd(bbackupd, + + TEST_THAT_OR(prepare_test_with_client_daemon(bbackupd, true, // do_unpack_files false // do_start_bbstored ), FAIL); @@ -3210,8 +3209,8 @@ bool test_excluded_files_are_not_backed_up() TEST_COMPARE_LOCAL(Compare_Same, client); // compare without exclusions, should find differences - // TEST_COMPARE(Compare_Different, "", "-acEQ"); - TEST_COMPARE_LOCAL(Compare_Different, client, "acEQ"); + // TEST_COMPARE_EXTRA(Compare_Different, "", "-acEQ"); + TEST_COMPARE_LOCAL_EXTRA(Compare_Different, client, "acEQ"); // check that the excluded files did not make it // into the store, and the included files did @@ -3614,7 +3613,7 @@ bool test_rename_operations() TEST_COMPARE(Compare_Same); // and again, but with quick flag - TEST_COMPARE(Compare_Same, "", "-acqQ"); + TEST_COMPARE_EXTRA(Compare_Same, "", "-acqQ"); // Rename some files -- one under the threshold, others above TEST_THAT(rename("testfiles/TestDir1/df324", @@ -3914,7 +3913,7 @@ bool test_restore_deleted_files() client.reset(); // Do a compare with the now undeleted files - TEST_COMPARE(Compare_Same, "", "-cEQ Test1/x1 " + TEST_COMPARE_EXTRA(Compare_Same, "", "-cEQ Test1/x1 " "testfiles/restore-Test1-x1-2"); } @@ -4039,6 +4038,194 @@ bool test_parse_syncallowscript_output() TEARDOWN_TEST_BBACKUPD(); } +bool check_output_log_file_for_ssl_security_level_warnings(const std::string& log_file_name, + const std::string& sentinel_value) +{ + int old_num_failures = num_failures; + + FileStream fs(log_file_name, O_RDONLY); + IOStreamGetLine getline(fs); + std::string line; + bool found_not_set = false, found_not_supported = false, found_sentinel = false; + + while(fs.StreamDataLeft()) + { + TEST_THAT(getline.GetLine(line, true, 30000)); // 30 seconds should be enough + TEST_THAT(line.size() >= 30); + if(line.size() < 30) + { + continue; + } + + if(StartsWith("SSLSecurityLevel not set. Your connection may not " + "be secure.", line.substr(30))) + { + found_not_set = true; + } + else if(StartsWith("SSLSecurityLevel is set, but this Box Backup " + "is not compiled with OpenSSL 1.1 or higher", line.substr(30))) + { + found_not_supported = true; + } + else if(StartsWith(sentinel_value, line.substr(30))) + { + found_sentinel = true; + break; + } + } + +#ifdef HAVE_SSL_CTX_SET_SECURITY_LEVEL + TEST_THAT(!found_not_set); // We should set it in bbackupd-config + TEST_THAT(!found_not_supported); // And this message should never be logged +#else + TEST_THAT(!found_not_supported); // We should not set it in bbackupd-config + TEST_THAT(!found_not_set); // And this message should never be logged +#endif + + TEST_THAT(found_sentinel); // Otherwise we're looking for the wrong thing! + + return (num_failures == old_num_failures); // no new failures -> good +} + + +bool test_bbackupd_config_script() +{ + SETUP_TEST_BBACKUPD(); + +#ifdef WIN32 + BOX_NOTICE("skipping test on this platform"); // TODO: write a PowerShell version +#else + char buf[PATH_MAX]; + if (getcwd(buf, sizeof(buf)) == NULL) + { + BOX_LOG_SYS_ERROR("getcwd"); + } + std::string current_dir = buf; + + TEST_THAT(mkdir("testfiles/tmp", 0777) == 0); + TEST_THAT(mkdir("testfiles/TestDir1", 0777) == 0); + + // Generate a new configuration for our test bbackupd, from scratch: + std::string cmd = "../../../bin/bbackupd/bbackupd-config " + + current_dir + "/testfiles/tmp " // config-dir + "lazy " // backup-mode + "12345 " // account-num + "localhost " + // server-hostname + current_dir + "/testfiles " + // working-dir + current_dir + "/testfiles/TestDir1"; // backup directories + TEST_RETURN(system(cmd.c_str()), 0) + + // Open the generated config file and add a StorePort line: + { + FileStream conf_file("testfiles/tmp/bbackupd.conf", O_WRONLY | O_APPEND); + conf_file.Write("StorePort = 22011\n"); + conf_file.Close(); + } + + // Generate a new configuration for our test bbstored, from scratch: + struct passwd *result = getpwuid(getuid()); + TEST_THAT_OR(result != NULL, FAIL); // failed to get username for current user + std::string username = result->pw_name; + + cmd = "../../../bin/bbstored/bbstored-config testfiles/tmp localhost " + username + " " + "testfiles/raidfile.conf"; + TEST_RETURN_COMMAND(system(cmd.c_str()), 0, cmd) + + cmd = "sed -i.orig -e 's/\\(ListenAddresses = inet:localhost\\)/\\1:22011/' " + "-e 's@PidFile = .*/run/bbstored.pid@PidFile = testfiles/bbstored.pid@' " + "testfiles/tmp/bbstored.conf"; + TEST_RETURN_COMMAND(system(cmd.c_str()), 0, cmd) + + // Create a server certificate authority, and sign the client and server certificates: + cmd = "../../../bin/bbstored/bbstored-certs testfiles/tmp/ca init"; + TEST_RETURN_COMMAND(system(cmd.c_str()), 0, cmd) + + cmd = "echo yes | ../../../bin/bbstored/bbstored-certs testfiles/tmp/ca sign " + "testfiles/tmp/bbackupd/12345-csr.pem"; + TEST_RETURN_COMMAND(system(cmd.c_str()), 0, cmd) + + cmd = "echo yes | ../../../bin/bbstored/bbstored-certs testfiles/tmp/ca sign-server " + "testfiles/tmp/bbstored/localhost-csr.pem"; + TEST_RETURN_COMMAND(system(cmd.c_str()), 0, cmd) + + // Copy the certificate files into the right places + cmd = "cp testfiles/tmp/ca/clients/12345-cert.pem testfiles/tmp/bbackupd"; + TEST_RETURN_COMMAND(system(cmd.c_str()), 0, cmd) + + cmd = "cp testfiles/tmp/ca/roots/serverCA.pem testfiles/tmp/bbackupd"; + TEST_RETURN_COMMAND(system(cmd.c_str()), 0, cmd) + + cmd = "cp testfiles/tmp/ca/servers/localhost-cert.pem testfiles/tmp/bbstored"; + TEST_RETURN_COMMAND(system(cmd.c_str()), 0, cmd) + + cmd = "cp testfiles/tmp/ca/roots/clientCA.pem testfiles/tmp/bbstored"; + TEST_RETURN(system(cmd.c_str()), 0) + + cmd = BBSTOREACCOUNTS " -c testfiles/tmp/bbstored.conf create 12345 0 1M 2M"; + TEST_RETURN_COMMAND(system(cmd.c_str()), 0, cmd) + + bbstored_pid = StartDaemon(bbstored_pid, BBSTORED " " + bbstored_args + + " -o testfiles/tmp/bbstored.log testfiles/tmp/bbstored.conf", "testfiles/bbstored.pid", + 22011); + + { + Capture capture; + Logging::TempLoggerGuard guard(&capture); + + BackupDaemon bbackupd; + TEST_THAT( + prepare_test_with_client_daemon( + bbackupd, + true, // do_unpack_files + false, // !do_start_bbstored + "testfiles/tmp/bbackupd.conf") + ); + + bbackupd.RunSyncNow(); + + std::vector messages = capture.GetMessages(); + TEST_THAT(!messages.empty()); + if (!messages.empty()) + { + bool found_not_set = false, found_not_supported = false; + for(std::vector::iterator i = messages.begin(); + i != messages.end(); i++) + { + if(StartsWith("SSLSecurityLevel not set. Your connection may not " + "be secure.", i->message)) + { + found_not_set = true; + } + else if(StartsWith("SSLSecurityLevel is set, but this Box Backup " + "is not compiled with OpenSSL 1.1 or higher", i->message)) + { + found_not_supported = true; + } + } + +#ifdef HAVE_SSL_CTX_SET_SECURITY_LEVEL + TEST_THAT(!found_not_set); // We should set it in bbackupd-config + TEST_THAT(!found_not_supported); // And this message should never be logged +#else + TEST_THAT(!found_not_supported); // We should not set it in bbackupd-config + TEST_THAT(!found_not_set); // And this message should never be logged +#endif + } + } + + TEST_THAT(compare_external(BackupQueries::ReturnCode::Compare_Same, + "-otestfiles/tmp/bbackupquery.log", "-acQ", "testfiles/tmp/bbackupd.conf")); + TEST_THAT(check_output_log_file_for_ssl_security_level_warnings("testfiles/tmp/bbackupquery.log", + "Connecting to store")); + TEST_THAT(check_output_log_file_for_ssl_security_level_warnings("testfiles/tmp/bbstored.log", + "Forked child process")); + + TEST_THAT(StopServer()); +#endif // !WIN32 + + TEARDOWN_TEST_BBACKUPD(); +} + int test(int argc, const char *argv[]) { // SSL library @@ -4104,6 +4291,7 @@ int test(int argc, const char *argv[]) TEST_THAT(test_backup_many_files()); TEST_THAT(test_parse_incomplete_command()); TEST_THAT(test_parse_syncallowscript_output()); + TEST_THAT(test_bbackupd_config_script()); TEST_THAT(kill_running_daemons()); -- cgit v1.2.3