summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--LICENSE.txt158
-rwxr-xr-xbin/bbackupd/bbackupd-config.in17
-rw-r--r--bin/bbackupquery/bbackupquery.cpp4
-rwxr-xr-xbin/bbstored/bbstored-certs.in8
-rwxr-xr-xbin/bbstored/bbstored-config.in17
-rw-r--r--contrib/windows/installer/bbackupd.conf.template352
-rwxr-xr-xcontrib/windows/installer/tools/InstallService.bat6
-rwxr-xr-xcontrib/windows/installer/tools/KillBackupProcess.bat6
-rwxr-xr-xcontrib/windows/installer/tools/QueryOutputAll.bat10
-rwxr-xr-xcontrib/windows/installer/tools/QueryOutputCurrent.bat10
-rwxr-xr-xcontrib/windows/installer/tools/ReloadConfig.bat6
-rwxr-xr-xcontrib/windows/installer/tools/RemoveService.bat6
-rwxr-xr-xcontrib/windows/installer/tools/RestartService.bat10
-rwxr-xr-xcontrib/windows/installer/tools/ShowUsage.bat6
-rwxr-xr-xcontrib/windows/installer/tools/StartService.bat6
-rwxr-xr-xcontrib/windows/installer/tools/StopService.bat6
-rwxr-xr-xcontrib/windows/installer/tools/Sync.bat6
-rw-r--r--docs/xsl-generic/highlighting/common.xsl124
-rw-r--r--docs/xsl-generic/highlighting/xslthl-config.xml22
-rw-r--r--docs/xsl-generic/html/highlight.xsl108
-rw-r--r--infrastructure/cmake/CMakeLists.txt19
-rwxr-xr-xinfrastructure/cmake/build/bin_bbackupd.vcxproj.user14
-rwxr-xr-xinfrastructure/cmake/build/bin_bbstored.vcxproj.user14
-rwxr-xr-xinfrastructure/cmake/build/test_backupstore.vcxproj.user16
-rwxr-xr-xinfrastructure/cmake/build/test_backupstorefix.vcxproj.user12
-rwxr-xr-xinfrastructure/cmake/build/test_bbackupd.vcxproj.user14
-rwxr-xr-xinfrastructure/cmake/build/test_common.vcxproj.user12
-rwxr-xr-xinfrastructure/cmake/build/test_httpserver.vcxproj.user12
-rwxr-xr-xinfrastructure/cmake/build/test_raidfile.vcxproj.user12
-rwxr-xr-xinfrastructure/cmake/msvc/bin_bbackupd.vcxproj.user14
-rwxr-xr-xinfrastructure/cmake/msvc/bin_bbstored.vcxproj.user14
-rwxr-xr-xinfrastructure/cmake/msvc/test_backupstore.vcxproj.user16
-rwxr-xr-xinfrastructure/cmake/msvc/test_backupstorefix.vcxproj.user12
-rwxr-xr-xinfrastructure/cmake/msvc/test_bbackupd.vcxproj.user14
-rwxr-xr-xinfrastructure/cmake/msvc/test_common.vcxproj.user12
-rwxr-xr-xinfrastructure/cmake/msvc/test_httpserver.vcxproj.user12
-rwxr-xr-xinfrastructure/cmake/msvc/test_raidfile.vcxproj.user12
-rw-r--r--infrastructure/cmake/windows/CMakeLists.txt13
-rw-r--r--infrastructure/m4/boxbackup_tests.m44
-rw-r--r--lib/backupclient/BackupDaemonConfigVerify.cpp9
-rw-r--r--lib/backupstore/BackupStoreCheck.cpp10
-rw-r--r--lib/backupstore/BackupStoreCheck2.cpp2
-rw-r--r--lib/backupstore/BackupStoreRefCountDatabase.cpp11
-rw-r--r--lib/backupstore/BackupStoreRefCountDatabase.h3
-rw-r--r--lib/backupstore/StoreTestUtils.cpp55
-rw-r--r--lib/backupstore/StoreTestUtils.h11
-rw-r--r--lib/bbackupd/BackupDaemon.cpp3
-rw-r--r--lib/common/BoxException.h3
-rw-r--r--lib/common/BoxPortsAndFiles.h.in4
-rw-r--r--lib/common/Configuration.cpp15
-rw-r--r--lib/common/Configuration.h1
-rw-r--r--lib/common/FileStream.h1
-rw-r--r--lib/common/Test.cpp138
-rw-r--r--lib/common/Test.h10
-rw-r--r--lib/server/ConnectionException.txt1
-rw-r--r--lib/server/Daemon.cpp4
-rw-r--r--lib/server/Daemon.h2
-rw-r--r--lib/server/ServerControl.cpp171
-rw-r--r--lib/server/ServerControl.h16
-rw-r--r--lib/server/ServerException.txt1
-rw-r--r--lib/server/ServerStream.h11
-rw-r--r--lib/server/ServerTLS.h9
-rw-r--r--lib/server/SocketStream.cpp4
-rw-r--r--lib/server/SocketStream.h1
-rw-r--r--lib/server/SocketStreamTLS.cpp51
-rw-r--r--lib/server/SocketStreamTLS.h3
-rw-r--r--lib/server/TLSContext.cpp72
-rw-r--r--lib/server/TLSContext.h3
-rwxr-xr-xlib/win32/getopt_long.cpp1092
-rwxr-xr-xlib/win32/messages.rc4
-rw-r--r--qdbm/VCmakefile496
-rw-r--r--qdbm/misc/VCmakefile-old338
-rw-r--r--qdbm/misc/win32check.bat222
-rw-r--r--qdbm/qdbm.def848
-rw-r--r--test/backupstorefix/testbackupstorefix.cpp8
-rwxr-xr-xtest/backupstorefix/testfiles/testbackupstorefix.pl.in16
-rw-r--r--test/basicserver/testbasicserver.cpp205
-rw-r--r--test/basicserver/testfiles/seclevel2-sha1/bbackupd.conf196
-rw-r--r--test/basicserver/testfiles/seclevel2-sha1/bbackupd/1234567-csr.pem15
-rw-r--r--test/basicserver/testfiles/seclevel2-sha1/bbackupd/1234567-key.pem27
-rwxr-xr-xtest/basicserver/testfiles/seclevel2-sha1/bbackupd/NotifySysadmin.sh70
-rw-r--r--test/basicserver/testfiles/seclevel2-sha1/bbstored.conf23
-rw-r--r--test/basicserver/testfiles/seclevel2-sha1/bbstored/localhost-csr.pem15
-rw-r--r--test/basicserver/testfiles/seclevel2-sha1/bbstored/localhost-key.pem27
-rw-r--r--test/basicserver/testfiles/seclevel2-sha1/ca/clients/1234567-cert.pem17
-rw-r--r--test/basicserver/testfiles/seclevel2-sha1/ca/keys/clientRootCSR.pem15
-rw-r--r--test/basicserver/testfiles/seclevel2-sha1/ca/keys/clientRootKey.pem27
-rw-r--r--test/basicserver/testfiles/seclevel2-sha1/ca/keys/serverRootCSR.pem15
-rw-r--r--test/basicserver/testfiles/seclevel2-sha1/ca/keys/serverRootKey.pem27
-rw-r--r--test/basicserver/testfiles/seclevel2-sha1/ca/roots/clientCA.pem18
-rw-r--r--test/basicserver/testfiles/seclevel2-sha1/ca/roots/clientCA.srl1
-rw-r--r--test/basicserver/testfiles/seclevel2-sha1/ca/roots/serverCA.pem18
-rw-r--r--test/basicserver/testfiles/seclevel2-sha1/ca/roots/serverCA.srl1
-rw-r--r--test/basicserver/testfiles/seclevel2-sha1/ca/servers/localhost-cert.pem17
-rw-r--r--test/basicserver/testfiles/seclevel2-sha1/raidfile.conf10
-rw-r--r--test/basicserver/testfiles/seclevel2-sha256/bbackupd.conf196
-rw-r--r--test/basicserver/testfiles/seclevel2-sha256/bbackupd/1234567-csr.pem15
-rw-r--r--test/basicserver/testfiles/seclevel2-sha256/bbackupd/1234567-key.pem27
-rwxr-xr-xtest/basicserver/testfiles/seclevel2-sha256/bbackupd/NotifySysadmin.sh70
-rw-r--r--test/basicserver/testfiles/seclevel2-sha256/bbstored.conf23
-rw-r--r--test/basicserver/testfiles/seclevel2-sha256/bbstored/localhost-csr.pem15
-rw-r--r--test/basicserver/testfiles/seclevel2-sha256/bbstored/localhost-key.pem27
-rw-r--r--test/basicserver/testfiles/seclevel2-sha256/ca/clients/1234567-cert.pem17
-rw-r--r--test/basicserver/testfiles/seclevel2-sha256/ca/keys/clientRootCSR.pem15
-rw-r--r--test/basicserver/testfiles/seclevel2-sha256/ca/keys/clientRootKey.pem27
-rw-r--r--test/basicserver/testfiles/seclevel2-sha256/ca/keys/serverRootCSR.pem15
-rw-r--r--test/basicserver/testfiles/seclevel2-sha256/ca/keys/serverRootKey.pem27
-rw-r--r--test/basicserver/testfiles/seclevel2-sha256/ca/roots/clientCA.pem18
-rw-r--r--test/basicserver/testfiles/seclevel2-sha256/ca/roots/clientCA.srl1
-rw-r--r--test/basicserver/testfiles/seclevel2-sha256/ca/roots/serverCA.pem18
-rw-r--r--test/basicserver/testfiles/seclevel2-sha256/ca/roots/serverCA.srl1
-rw-r--r--test/basicserver/testfiles/seclevel2-sha256/ca/servers/localhost-cert-sha1.pem17
-rw-r--r--test/basicserver/testfiles/seclevel2-sha256/ca/servers/localhost-cert.pem17
-rw-r--r--test/basicserver/testfiles/seclevel2-sha256/raidfile.conf10
-rw-r--r--test/basicserver/testfiles/srv3-insecure-daemon.conf9
-rw-r--r--test/basicserver/testfiles/srv3-seclevel2-sha1.conf9
-rw-r--r--test/basicserver/testfiles/srv3-seclevel2-sha256.conf9
-rw-r--r--test/basicserver/testfiles/srv4-noseclevel.conf (renamed from test/basicserver/testfiles/srv4.conf)1
-rw-r--r--test/basicserver/testfiles/srv4-seclevel1.conf7
-rw-r--r--test/basicserver/testfiles/srv4-seclevel2-insecure.conf7
-rw-r--r--test/basicserver/testfiles/srv4-seclevel2-secure.conf7
-rw-r--r--test/bbackupd/testbbackupd.cpp320
122 files changed, 4122 insertions, 2332 deletions
diff --git a/LICENSE.txt b/LICENSE.txt
index dd4e26e1..4f57a372 100644
--- a/LICENSE.txt
+++ b/LICENSE.txt
@@ -1,79 +1,79 @@
-Box Backup, http://www.boxbackup.org/
-
-Copyright (c) 2003-2015, Ben Summers and contributors.
-All rights reserved.
-
-The license of the code was changed on 23-Jan-2010 in order to meet the
-Fedora Project's definition of Free Software, and therefore allow inclusion
-in Fedora, Red Hat Linux and CentOS. This also solves a long-standing
-incompatibility with the GNU Readline library that prevented us from
-distributing Box Backup binaries compiled against that library. You can
-review our discussions of the change in the mailing list archives at:
-http://lists.boxbackup.org/pipermail/boxbackup/2010-January/000005.html
-
-Note that this project uses mixed licensing. Different parts of the project
-may be used and distributed under different licenses, as described below.
-The two licenses used are "Box Backup GPL" and a BSD-style license.
-
-For full details of the license, please read the included COPYING.txt file.
-
-Unless stated otherwise in the file, all files in the following directories
-fall under the "Box Backup GPL" license, described below:
-
-bin/bbackupctl
-bin/bbackupd
-bin/bbackupobjdump
-bin/bbackupquery
-bin/bbstoreaccounts
-bin/bbstored
-bin/s3simulator
-lib/backupclient
-lib/backupstore
-test/backupdiff
-test/backupstore
-test/backupstorefix
-test/backupstorepatch
-test/bbackupd
-contrib/bbadmin
-contrib/bbreporter
-contrib/cygwin
-contrib/debian
-contrib/mac_osx
-contrib/redhat
-contrib/rpm
-contrib/solaris
-contrib/suse
-contrib/windows
-distribution/boxbackup
-
-The "Box Backup GPL" license text may be found in the file
-LICENSE-GPL.txt, or online at:
-[https://www.boxbackup.org/svn/box/trunk/LICENSE-GPL.txt]
-
-Unless stated otherwise in the file, all files in the following directories
-are dual licensed under the BSD and GPL licenses. You may use and distribute
-them providing that you comply EITHER with the terms of the BSD license,
-OR the GPL license. It is not necessary to comply with both licenses,
-only one.
-
-lib/common
-lib/compress
-lib/crypto
-lib/httpserver
-lib/intercept
-lib/raidfile
-lib/server
-lib/win32
-test/basicserver
-test/common
-test/compress
-test/crypto
-test/httpserver
-test/raidfile
-test/win32
-infrastructure
-distribution
-
-The dual license text may be found in the file
-LICENSE-DUAL.txt, or online at:
-[https://www.boxbackup.org/svn/box/trunk/LICENSE-DUAL.txt]
+Box Backup, http://www.boxbackup.org/
+
+Copyright (c) 2003-2015, Ben Summers and contributors.
+All rights reserved.
+
+The license of the code was changed on 23-Jan-2010 in order to meet the
+Fedora Project's definition of Free Software, and therefore allow inclusion
+in Fedora, Red Hat Linux and CentOS. This also solves a long-standing
+incompatibility with the GNU Readline library that prevented us from
+distributing Box Backup binaries compiled against that library. You can
+review our discussions of the change in the mailing list archives at:
+http://lists.boxbackup.org/pipermail/boxbackup/2010-January/000005.html
+
+Note that this project uses mixed licensing. Different parts of the project
+may be used and distributed under different licenses, as described below.
+The two licenses used are "Box Backup GPL" and a BSD-style license.
+
+For full details of the license, please read the included COPYING.txt file.
+
+Unless stated otherwise in the file, all files in the following directories
+fall under the "Box Backup GPL" license, described below:
+
+bin/bbackupctl
+bin/bbackupd
+bin/bbackupobjdump
+bin/bbackupquery
+bin/bbstoreaccounts
+bin/bbstored
+bin/s3simulator
+lib/backupclient
+lib/backupstore
+test/backupdiff
+test/backupstore
+test/backupstorefix
+test/backupstorepatch
+test/bbackupd
+contrib/bbadmin
+contrib/bbreporter
+contrib/cygwin
+contrib/debian
+contrib/mac_osx
+contrib/redhat
+contrib/rpm
+contrib/solaris
+contrib/suse
+contrib/windows
+distribution/boxbackup
+
+The "Box Backup GPL" license text may be found in the file
+LICENSE-GPL.txt, or online at:
+[https://www.boxbackup.org/svn/box/trunk/LICENSE-GPL.txt]
+
+Unless stated otherwise in the file, all files in the following directories
+are dual licensed under the BSD and GPL licenses. You may use and distribute
+them providing that you comply EITHER with the terms of the BSD license,
+OR the GPL license. It is not necessary to comply with both licenses,
+only one.
+
+lib/common
+lib/compress
+lib/crypto
+lib/httpserver
+lib/intercept
+lib/raidfile
+lib/server
+lib/win32
+test/basicserver
+test/common
+test/compress
+test/crypto
+test/httpserver
+test/raidfile
+test/win32
+infrastructure
+distribution
+
+The dual license text may be found in the file
+LICENSE-DUAL.txt, or online at:
+[https://www.boxbackup.org/svn/box/trunk/LICENSE-DUAL.txt]
diff --git a/bin/bbackupd/bbackupd-config.in b/bin/bbackupd/bbackupd-config.in
index 1fc224c2..43f63b4e 100755
--- a/bin/bbackupd/bbackupd-config.in
+++ b/bin/bbackupd/bbackupd-config.in
@@ -169,7 +169,7 @@ if(!-f $private_key)
if(!-f $certificate_request)
{
die "Couldn't run openssl for CSR generation" unless
- open(CSR,"|openssl req -new -key $private_key -sha1 -out $certificate_request");
+ open(CSR,"|openssl req -new -key $private_key -sha256 -out $certificate_request");
print CSR <<__E;
.
.
@@ -317,6 +317,21 @@ NotifyScript = $notify_script
__E
+if("@HAVE_SSL_CTX_SET_SECURITY_LEVEL@" eq "1")
+{
+ print CONFIG <<__E;
+# Box Backup compiled with support for SSLSecurityLevel
+SSLSecurityLevel = 2
+__E
+}
+else
+{
+ print CONFIG <<__E;
+# Box Backup compiled without support for SSLSecurityLevel
+# SSLSecurityLevel = 2
+__E
+}
+
if($backup_mode eq 'lazy')
{
# lazy mode configuration
diff --git a/bin/bbackupquery/bbackupquery.cpp b/bin/bbackupquery/bbackupquery.cpp
index e10c48fe..aef26ddc 100644
--- a/bin/bbackupquery/bbackupquery.cpp
+++ b/bin/bbackupquery/bbackupquery.cpp
@@ -364,7 +364,9 @@ int main(int argc, const char *argv[])
std::string certFile(conf.GetKeyValue("CertificateFile"));
std::string keyFile(conf.GetKeyValue("PrivateKeyFile"));
std::string caFile(conf.GetKeyValue("TrustedCAsFile"));
- tlsContext.Initialise(false /* as client */, certFile.c_str(), keyFile.c_str(), caFile.c_str());
+ int ssl_security_level(conf.GetKeyValueInt("SSLSecurityLevel"));
+ tlsContext.Initialise(false /* as client */, certFile.c_str(), keyFile.c_str(),
+ caFile.c_str(), ssl_security_level);
// Initialise keys
BackupClientCryptoKeys_Setup(conf.GetKeyValue("KeysFile").c_str());
diff --git a/bin/bbstored/bbstored-certs.in b/bin/bbstored/bbstored-certs.in
index 00085662..10072a87 100755
--- a/bin/bbstored/bbstored-certs.in
+++ b/bin/bbstored/bbstored-certs.in
@@ -122,7 +122,7 @@ sub cmd_init_create_root
# make CSR
die "Couldn't run openssl for CSR generation" unless
- open(CSR,"|openssl req -new -key $key -sha1 -out $csr");
+ open(CSR,"|openssl req -new -key $key -sha256 -out $csr");
print CSR <<__E;
.
.
@@ -140,7 +140,7 @@ __E
die "Certificate request wasn't created.\n" unless -f $csr;
# sign it to make a self-signed root CA key
- if(system("openssl x509 -req -in $csr -sha1 -extensions v3_ca -signkey $key -out $cert -days $root_sign_period") != 0)
+ if(system("openssl x509 -req -in $csr -sha256 -extensions v3_ca -signkey $key -out $cert -days $root_sign_period") != 0)
{
die "Couldn't generate root certificate."
}
@@ -201,7 +201,7 @@ __E
my $out_cert = "$cert_dir/clients/$acc"."-cert.pem";
# sign it!
- if(system("openssl x509 -req -in $csr -sha1 -extensions usr_crt -CA $cert_dir/roots/clientCA.pem -CAkey $cert_dir/keys/clientRootKey.pem -out $out_cert -days $sign_period") != 0)
+ if(system("openssl x509 -req -in $csr -sha256 -extensions usr_crt -CA $cert_dir/roots/clientCA.pem -CAkey $cert_dir/keys/clientRootKey.pem -out $out_cert -days $sign_period") != 0)
{
die "Signing failed"
}
@@ -257,7 +257,7 @@ __E
my $out_cert = "$cert_dir/servers/$common_name"."-cert.pem";
# sign it!
- if(system("openssl x509 -req -in $csr -sha1 -extensions usr_crt -CA $cert_dir/roots/serverCA.pem -CAkey $cert_dir/keys/serverRootKey.pem -out $out_cert -days $sign_period") != 0)
+ if(system("openssl x509 -req -in $csr -sha256 -extensions usr_crt -CA $cert_dir/roots/serverCA.pem -CAkey $cert_dir/keys/serverRootKey.pem -out $out_cert -days $sign_period") != 0)
{
die "Signing failed"
}
diff --git a/bin/bbstored/bbstored-config.in b/bin/bbstored/bbstored-config.in
index 83305c4f..1efaf668 100755
--- a/bin/bbstored/bbstored-config.in
+++ b/bin/bbstored/bbstored-config.in
@@ -202,11 +202,24 @@ Server
CertificateFile = $certificate
PrivateKeyFile = $private_key
TrustedCAsFile = $ca_root_cert
-}
-
+__E
+if("@HAVE_SSL_CTX_SET_SECURITY_LEVEL@" eq "1")
+{
+ print CONFIG <<__E;
+ # Box Backup compiled with support for SSLSecurityLevel
+ SSLSecurityLevel = 2
__E
+}
+else
+{
+ print CONFIG <<__E;
+ # Box Backup compiled without support for SSLSecurityLevel
+ # SSLSecurityLevel = 2
+__E
+}
+print CONFIG "}\n";
close CONFIG;
# explain to the user what they need to do next
diff --git a/contrib/windows/installer/bbackupd.conf.template b/contrib/windows/installer/bbackupd.conf.template
index 969ca619..cf61e72e 100644
--- a/contrib/windows/installer/bbackupd.conf.template
+++ b/contrib/windows/installer/bbackupd.conf.template
@@ -1,176 +1,176 @@
-StoreHostname = @@ServerName@@
-AccountNumber = 0x@@AccountNo@@
-KeysFile = @@InstallDir@@/conf/@@AccountNo@@-FileEncKeys.raw
-
-CertificateFile = @@InstallDir@@/conf/@@AccountNo@@-cert.pem
-PrivateKeyFile = @@InstallDir@@/conf/@@AccountNo@@-key.pem
-TrustedCAsFile = @@InstallDir@@/conf/serverCA.pem
-
-DataDirectory = @@InstallDir@@/state
-
-
-# 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 = @@InstallDir@@/bin/NotifySysAdmin.vbs
-
-# 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 = @@CommandSocketNamedPipe@@
-
-# 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 = @@InstallDir@@/state/bbackupd.state
-
-Server
-{
- PidFile = @@InstallDir@@/state/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.
+StoreHostname = @@ServerName@@
+AccountNumber = 0x@@AccountNo@@
+KeysFile = @@InstallDir@@/conf/@@AccountNo@@-FileEncKeys.raw
+
+CertificateFile = @@InstallDir@@/conf/@@AccountNo@@-cert.pem
+PrivateKeyFile = @@InstallDir@@/conf/@@AccountNo@@-key.pem
+TrustedCAsFile = @@InstallDir@@/conf/serverCA.pem
+
+DataDirectory = @@InstallDir@@/state
+
+
+# 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 = @@InstallDir@@/bin/NotifySysAdmin.vbs
+
+# 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 = @@CommandSocketNamedPipe@@
+
+# 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 = @@InstallDir@@/state/bbackupd.state
+
+Server
+{
+ PidFile = @@InstallDir@@/state/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.
diff --git a/contrib/windows/installer/tools/InstallService.bat b/contrib/windows/installer/tools/InstallService.bat
index 80a342eb..94696440 100755
--- a/contrib/windows/installer/tools/InstallService.bat
+++ b/contrib/windows/installer/tools/InstallService.bat
@@ -1,3 +1,3 @@
-service.exe -i -S GigaLock
-echo off
-ping 192.168.254.254 -n 5 -w 1000 > nul
+service.exe -i -S GigaLock
+echo off
+ping 192.168.254.254 -n 5 -w 1000 > nul
diff --git a/contrib/windows/installer/tools/KillBackupProcess.bat b/contrib/windows/installer/tools/KillBackupProcess.bat
index 416d4a79..87343c57 100755
--- a/contrib/windows/installer/tools/KillBackupProcess.bat
+++ b/contrib/windows/installer/tools/KillBackupProcess.bat
@@ -1,3 +1,3 @@
-control.exe terminate
-echo off
-ping 192.168.254.254 -n 5 -w 1000 > nul
+control.exe terminate
+echo off
+ping 192.168.254.254 -n 5 -w 1000 > nul
diff --git a/contrib/windows/installer/tools/QueryOutputAll.bat b/contrib/windows/installer/tools/QueryOutputAll.bat
index 2ab30a72..c58b4ab6 100755
--- a/contrib/windows/installer/tools/QueryOutputAll.bat
+++ b/contrib/windows/installer/tools/QueryOutputAll.bat
@@ -1,5 +1,5 @@
-@ECHO OFF
-: o=old, d=deleted, s=size info, t=timestamp, r=recursive
-set Queryopts=-odstr
-::set Queryopts=-str
-query.exe "list %Queryopts%" quit > QueryOutputAllResults.txt
+@ECHO OFF
+: o=old, d=deleted, s=size info, t=timestamp, r=recursive
+set Queryopts=-odstr
+::set Queryopts=-str
+query.exe "list %Queryopts%" quit > QueryOutputAllResults.txt
diff --git a/contrib/windows/installer/tools/QueryOutputCurrent.bat b/contrib/windows/installer/tools/QueryOutputCurrent.bat
index d59ddbf1..2142b83f 100755
--- a/contrib/windows/installer/tools/QueryOutputCurrent.bat
+++ b/contrib/windows/installer/tools/QueryOutputCurrent.bat
@@ -1,5 +1,5 @@
-@ECHO OFF
-: o=old, d=deleted, s=size info, t=timestamp, r=recursive
-::set Queryopts=-odstr
-set Queryopts=-str
-query.exe "list %Queryopts%" quit > QueryOutputCurrentResults.txt
+@ECHO OFF
+: o=old, d=deleted, s=size info, t=timestamp, r=recursive
+::set Queryopts=-odstr
+set Queryopts=-str
+query.exe "list %Queryopts%" quit > QueryOutputCurrentResults.txt
diff --git a/contrib/windows/installer/tools/ReloadConfig.bat b/contrib/windows/installer/tools/ReloadConfig.bat
index 5fd44e83..911afb0a 100755
--- a/contrib/windows/installer/tools/ReloadConfig.bat
+++ b/contrib/windows/installer/tools/ReloadConfig.bat
@@ -1,3 +1,3 @@
-control.exe reload
-echo off
-ping 192.168.254.254 -n 8 -w 1000 > nul
+control.exe reload
+echo off
+ping 192.168.254.254 -n 8 -w 1000 > nul
diff --git a/contrib/windows/installer/tools/RemoveService.bat b/contrib/windows/installer/tools/RemoveService.bat
index 881ec5b1..193f272f 100755
--- a/contrib/windows/installer/tools/RemoveService.bat
+++ b/contrib/windows/installer/tools/RemoveService.bat
@@ -1,3 +1,3 @@
-@@SERVICEEXENAME@ -r -S GigaLock
-echo off
-ping 192.168.254.254 -n 5 -w 1000 > nul
+@@SERVICEEXENAME@ -r -S GigaLock
+echo off
+ping 192.168.254.254 -n 5 -w 1000 > nul
diff --git a/contrib/windows/installer/tools/RestartService.bat b/contrib/windows/installer/tools/RestartService.bat
index 77092a69..87a0a4ef 100755
--- a/contrib/windows/installer/tools/RestartService.bat
+++ b/contrib/windows/installer/tools/RestartService.bat
@@ -1,5 +1,5 @@
-net stop GigaLock
-ping 192.168.254.254 -n 2 -w 1000 > nul
-net start GigaLock
-echo off
-ping 192.168.254.254 -n 5 -w 1000 > nul
+net stop GigaLock
+ping 192.168.254.254 -n 2 -w 1000 > nul
+net start GigaLock
+echo off
+ping 192.168.254.254 -n 5 -w 1000 > nul
diff --git a/contrib/windows/installer/tools/ShowUsage.bat b/contrib/windows/installer/tools/ShowUsage.bat
index e6f69e9f..2ac0f37d 100755
--- a/contrib/windows/installer/tools/ShowUsage.bat
+++ b/contrib/windows/installer/tools/ShowUsage.bat
@@ -1,3 +1,3 @@
-query.exe usage quit
-ping 192.168.254.254 -n 10 -w 1000 > nul
-
+query.exe usage quit
+ping 192.168.254.254 -n 10 -w 1000 > nul
+
diff --git a/contrib/windows/installer/tools/StartService.bat b/contrib/windows/installer/tools/StartService.bat
index 1771238f..dc7dce7e 100755
--- a/contrib/windows/installer/tools/StartService.bat
+++ b/contrib/windows/installer/tools/StartService.bat
@@ -1,3 +1,3 @@
-net start GigaLock
-echo off
-ping 192.168.254.254 -n 5 -w 1000 > nul
+net start GigaLock
+echo off
+ping 192.168.254.254 -n 5 -w 1000 > nul
diff --git a/contrib/windows/installer/tools/StopService.bat b/contrib/windows/installer/tools/StopService.bat
index 8e70d68d..056cc69e 100755
--- a/contrib/windows/installer/tools/StopService.bat
+++ b/contrib/windows/installer/tools/StopService.bat
@@ -1,3 +1,3 @@
-net stop GigaLock
-echo off
-ping 192.168.254.254 -n 5 -w 1000 > nul
+net stop GigaLock
+echo off
+ping 192.168.254.254 -n 5 -w 1000 > nul
diff --git a/contrib/windows/installer/tools/Sync.bat b/contrib/windows/installer/tools/Sync.bat
index 30a04bec..0357070a 100755
--- a/contrib/windows/installer/tools/Sync.bat
+++ b/contrib/windows/installer/tools/Sync.bat
@@ -1,3 +1,3 @@
-control.exe sync
-echo off
-ping 192.168.254.254 -n 5 -w 1000 > nul
+control.exe sync
+echo off
+ping 192.168.254.254 -n 5 -w 1000 > nul
diff --git a/docs/xsl-generic/highlighting/common.xsl b/docs/xsl-generic/highlighting/common.xsl
index 32f1bbcf..23ac77ea 100644
--- a/docs/xsl-generic/highlighting/common.xsl
+++ b/docs/xsl-generic/highlighting/common.xsl
@@ -1,62 +1,62 @@
-<?xml version='1.0'?>
-<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
- xmlns:hl="java:net.sf.xslthl.ConnectorSaxon6"
- xmlns:exsl="http://exslt.org/common"
- exclude-result-prefixes="exsl hl"
- version='1.0'>
-
-<!-- ********************************************************************
- $Id: common.xsl 7266 2007-08-22 11:58:42Z xmldoc $
- ********************************************************************
-
- This file is part of the XSL DocBook Stylesheet distribution.
- See ../README or http://docbook.sf.net/release/xsl/current/ for
- and other information.
-
- ******************************************************************** -->
-
-<!-- You can override this template to do more complex mapping of
- language attribute to highlighter language ID (see xslthl-config.xml) -->
-<xsl:template name="language.to.xslthl">
- <xsl:param name="context"/>
-
- <xsl:choose>
- <xsl:when test="$context/@language != ''">
- <xsl:value-of select="$context/@language"/>
- </xsl:when>
- <xsl:when test="$highlight.default.language != ''">
- <xsl:value-of select="$highlight.default.language"/>
- </xsl:when>
- </xsl:choose>
-</xsl:template>
-
-<xsl:template name="apply-highlighting">
- <xsl:choose>
- <!-- Do we want syntax highlighting -->
- <xsl:when test="$highlight.source != 0 and function-available('hl:highlight')">
- <xsl:variable name="language">
- <xsl:call-template name="language.to.xslthl">
- <xsl:with-param name="context" select="."/>
- </xsl:call-template>
- </xsl:variable>
- <xsl:choose>
- <xsl:when test="$language != ''">
- <xsl:variable name="content">
- <xsl:apply-templates/>
- </xsl:variable>
- <xsl:apply-templates select="hl:highlight($language, exsl:node-set($content))"/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:apply-templates/>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:when>
- <!-- No syntax highlighting -->
- <xsl:otherwise>
- <xsl:apply-templates/>
- </xsl:otherwise>
- </xsl:choose>
-</xsl:template>
-
-</xsl:stylesheet>
-
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:hl="java:net.sf.xslthl.ConnectorSaxon6"
+ xmlns:exsl="http://exslt.org/common"
+ exclude-result-prefixes="exsl hl"
+ version='1.0'>
+
+<!-- ********************************************************************
+ $Id: common.xsl 7266 2007-08-22 11:58:42Z xmldoc $
+ ********************************************************************
+
+ This file is part of the XSL DocBook Stylesheet distribution.
+ See ../README or http://docbook.sf.net/release/xsl/current/ for
+ and other information.
+
+ ******************************************************************** -->
+
+<!-- You can override this template to do more complex mapping of
+ language attribute to highlighter language ID (see xslthl-config.xml) -->
+<xsl:template name="language.to.xslthl">
+ <xsl:param name="context"/>
+
+ <xsl:choose>
+ <xsl:when test="$context/@language != ''">
+ <xsl:value-of select="$context/@language"/>
+ </xsl:when>
+ <xsl:when test="$highlight.default.language != ''">
+ <xsl:value-of select="$highlight.default.language"/>
+ </xsl:when>
+ </xsl:choose>
+</xsl:template>
+
+<xsl:template name="apply-highlighting">
+ <xsl:choose>
+ <!-- Do we want syntax highlighting -->
+ <xsl:when test="$highlight.source != 0 and function-available('hl:highlight')">
+ <xsl:variable name="language">
+ <xsl:call-template name="language.to.xslthl">
+ <xsl:with-param name="context" select="."/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:choose>
+ <xsl:when test="$language != ''">
+ <xsl:variable name="content">
+ <xsl:apply-templates/>
+ </xsl:variable>
+ <xsl:apply-templates select="hl:highlight($language, exsl:node-set($content))"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:apply-templates/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:when>
+ <!-- No syntax highlighting -->
+ <xsl:otherwise>
+ <xsl:apply-templates/>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+</xsl:stylesheet>
+
diff --git a/docs/xsl-generic/highlighting/xslthl-config.xml b/docs/xsl-generic/highlighting/xslthl-config.xml
index 7c77f6fc..dd83aa77 100644
--- a/docs/xsl-generic/highlighting/xslthl-config.xml
+++ b/docs/xsl-generic/highlighting/xslthl-config.xml
@@ -1,11 +1,11 @@
-<?xml version='1.0'?>
-<xslthl-config>
- <highlighter id='java' file='./java-hl.xml' />
- <highlighter id='delphi' file='./delphi-hl.xml'/>
- <highlighter id='ini' file='./ini-hl.xml' />
- <highlighter id='php' file='./php-hl.xml' />
- <highlighter id='myxml' file='./myxml-hl.xml' />
- <highlighter id='m2' file='./m2-hl.xml' />
- <highlighter id='c' file='./c-hl.xml' />
- <namespace prefix="xslthl" uri="http://xslthl.sf.net" />
-</xslthl-config>
+<?xml version='1.0'?>
+<xslthl-config>
+ <highlighter id='java' file='./java-hl.xml' />
+ <highlighter id='delphi' file='./delphi-hl.xml'/>
+ <highlighter id='ini' file='./ini-hl.xml' />
+ <highlighter id='php' file='./php-hl.xml' />
+ <highlighter id='myxml' file='./myxml-hl.xml' />
+ <highlighter id='m2' file='./m2-hl.xml' />
+ <highlighter id='c' file='./c-hl.xml' />
+ <namespace prefix="xslthl" uri="http://xslthl.sf.net" />
+</xslthl-config>
diff --git a/docs/xsl-generic/html/highlight.xsl b/docs/xsl-generic/html/highlight.xsl
index 30f2153e..05896cd9 100644
--- a/docs/xsl-generic/html/highlight.xsl
+++ b/docs/xsl-generic/html/highlight.xsl
@@ -1,54 +1,54 @@
-<?xml version='1.0'?>
-<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
- xmlns:xslthl="http://xslthl.sf.net"
- exclude-result-prefixes="xslthl"
- version='1.0'>
-
-<!-- ********************************************************************
- $Id: highlight.xsl 7266 2007-08-22 11:58:42Z xmldoc $
- ********************************************************************
-
- This file is part of the XSL DocBook Stylesheet distribution.
- See ../README or http://docbook.sf.net/release/xsl/current/ for
- and other information.
-
- ******************************************************************** -->
-
-<xsl:template match='xslthl:keyword'>
- <b class="hl-keyword"><xsl:apply-templates/></b>
-</xsl:template>
-
-<xsl:template match='xslthl:string'>
- <b class="hl-string"><i style="color:red"><xsl:apply-templates/></i></b>
-</xsl:template>
-
-<xsl:template match='xslthl:comment'>
- <i class="hl-comment" style="color: silver"><xsl:apply-templates/></i>
-</xsl:template>
-
-<xsl:template match='xslthl:tag'>
- <b class="hl-tag" style="color: blue"><xsl:apply-templates/></b>
-</xsl:template>
-
-<xsl:template match='xslthl:attribute'>
- <span class="hl-attribute" style="color: blue"><xsl:apply-templates/></span>
-</xsl:template>
-
-<xsl:template match='xslthl:value'>
- <span class="hl-value" style="color: blue"><xsl:apply-templates/></span>
-</xsl:template>
-
-<xsl:template match='xslthl:html'>
- <b><i style="color: red"><xsl:apply-templates/></i></b>
-</xsl:template>
-
-<xsl:template match='xslthl:xslt'>
- <b style="color: blue"><xsl:apply-templates/></b>
-</xsl:template>
-
-<xsl:template match='xslthl:section'>
- <b><xsl:apply-templates/></b>
-</xsl:template>
-
-</xsl:stylesheet>
-
+<?xml version='1.0'?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:xslthl="http://xslthl.sf.net"
+ exclude-result-prefixes="xslthl"
+ version='1.0'>
+
+<!-- ********************************************************************
+ $Id: highlight.xsl 7266 2007-08-22 11:58:42Z xmldoc $
+ ********************************************************************
+
+ This file is part of the XSL DocBook Stylesheet distribution.
+ See ../README or http://docbook.sf.net/release/xsl/current/ for
+ and other information.
+
+ ******************************************************************** -->
+
+<xsl:template match='xslthl:keyword'>
+ <b class="hl-keyword"><xsl:apply-templates/></b>
+</xsl:template>
+
+<xsl:template match='xslthl:string'>
+ <b class="hl-string"><i style="color:red"><xsl:apply-templates/></i></b>
+</xsl:template>
+
+<xsl:template match='xslthl:comment'>
+ <i class="hl-comment" style="color: silver"><xsl:apply-templates/></i>
+</xsl:template>
+
+<xsl:template match='xslthl:tag'>
+ <b class="hl-tag" style="color: blue"><xsl:apply-templates/></b>
+</xsl:template>
+
+<xsl:template match='xslthl:attribute'>
+ <span class="hl-attribute" style="color: blue"><xsl:apply-templates/></span>
+</xsl:template>
+
+<xsl:template match='xslthl:value'>
+ <span class="hl-value" style="color: blue"><xsl:apply-templates/></span>
+</xsl:template>
+
+<xsl:template match='xslthl:html'>
+ <b><i style="color: red"><xsl:apply-templates/></i></b>
+</xsl:template>
+
+<xsl:template match='xslthl:xslt'>
+ <b style="color: blue"><xsl:apply-templates/></b>
+</xsl:template>
+
+<xsl:template match='xslthl:section'>
+ <b><xsl:apply-templates/></b>
+</xsl:template>
+
+</xsl:stylesheet>
+
diff --git a/infrastructure/cmake/CMakeLists.txt b/infrastructure/cmake/CMakeLists.txt
index 5116e7ff..b906e202 100644
--- a/infrastructure/cmake/CMakeLists.txt
+++ b/infrastructure/cmake/CMakeLists.txt
@@ -71,13 +71,6 @@ function(move_file_if_exists source_file dest_file)
endif()
endfunction()
-foreach(file_to_configure ${files_to_configure})
- configure_file("${base_dir}/${file_to_configure}.in" "${base_dir}/${file_to_configure}.out" @ONLY)
- replace_file_if_different(
- "${base_dir}/${file_to_configure}"
- "${base_dir}/${file_to_configure}.out")
-endforeach()
-
# If BOXBACKUP_VERSION is defined when running CMake (as the AppVeyor config does), use it
# as-is, since it contains the full version number, branch, and platform (Win32/Win64):
if(BOXBACKUP_VERSION)
@@ -375,6 +368,7 @@ file(WRITE "${boxconfig_h_file}" "// Auto-generated by CMake. Do not edit.\n")
if(WIN32)
target_link_libraries(lib_common PUBLIC ws2_32 gdi32)
+ list(APPEND CMAKE_REQUIRED_LIBRARIES ws2_32 gdi32)
endif()
# On Windows we want to statically link zlib to make debugging and distribution easier,
@@ -430,6 +424,7 @@ else()
endif()
include_directories(${OPENSSL_INCLUDE_DIR})
target_link_libraries(lib_crypto PUBLIC ${OPENSSL_LIBRARIES})
+list(APPEND CMAKE_REQUIRED_LIBRARIES ${OPENSSL_LIBRARIES})
# Link to PCRE
if (WIN32)
@@ -613,6 +608,9 @@ foreach(function_name ${detect_functions})
file(APPEND "${boxconfig_h_file}" "#cmakedefine HAVE_${platform_var_name}\n")
endforeach()
+check_function_exists(SSL_CTX_set_security_level HAVE_SSL_CTX_SET_SECURITY_LEVEL)
+file(APPEND "${boxconfig_h_file}" "#cmakedefine HAVE_SSL_CTX_SET_SECURITY_LEVEL\n")
+
check_symbol_exists(dirfd "dirent.h" HAVE_DECL_DIRFD)
file(APPEND "${boxconfig_h_file}" "#cmakedefine01 HAVE_DECL_DIRFD\n")
@@ -829,6 +827,13 @@ file(TO_NATIVE_PATH "${PERL_EXECUTABLE}" perl_executable_native)
string(REPLACE "\\" "\\\\" perl_path_escaped ${perl_executable_native})
target_compile_definitions(test_backupstorefix PRIVATE -DPERL_EXECUTABLE="${perl_path_escaped}")
+foreach(file_to_configure ${files_to_configure})
+ configure_file("${base_dir}/${file_to_configure}.in" "${base_dir}/${file_to_configure}.out" @ONLY)
+ replace_file_if_different(
+ "${base_dir}/${file_to_configure}"
+ "${base_dir}/${file_to_configure}.out")
+endforeach()
+
# Configure test timeouts:
# I've set the timeout to 4 times as long as it took to run on a particular run on Appveyor:
# https://ci.appveyor.com/project/qris/boxbackup/build/job/xm10itascygtu93j
diff --git a/infrastructure/cmake/build/bin_bbackupd.vcxproj.user b/infrastructure/cmake/build/bin_bbackupd.vcxproj.user
index 51928554..fa1f3d34 100755
--- a/infrastructure/cmake/build/bin_bbackupd.vcxproj.user
+++ b/infrastructure/cmake/build/bin_bbackupd.vcxproj.user
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <LocalDebuggerCommandArguments>testfiles\bbackupd.conf</LocalDebuggerCommandArguments>
- <LocalDebuggerWorkingDirectory>$(ProjectDir)\..\..\..\debug\test\bbackupd</LocalDebuggerWorkingDirectory>
- <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
- </PropertyGroup>
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <LocalDebuggerCommandArguments>testfiles\bbackupd.conf</LocalDebuggerCommandArguments>
+ <LocalDebuggerWorkingDirectory>$(ProjectDir)\..\..\..\debug\test\bbackupd</LocalDebuggerWorkingDirectory>
+ <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+ </PropertyGroup>
</Project> \ No newline at end of file
diff --git a/infrastructure/cmake/build/bin_bbstored.vcxproj.user b/infrastructure/cmake/build/bin_bbstored.vcxproj.user
index e48b8383..339cddee 100755
--- a/infrastructure/cmake/build/bin_bbstored.vcxproj.user
+++ b/infrastructure/cmake/build/bin_bbstored.vcxproj.user
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <LocalDebuggerCommandArguments>testfiles/bbstored.conf</LocalDebuggerCommandArguments>
- <LocalDebuggerWorkingDirectory>$(ProjectDir)\..\..\..\debug\test\backupstorefix</LocalDebuggerWorkingDirectory>
- <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
- </PropertyGroup>
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <LocalDebuggerCommandArguments>testfiles/bbstored.conf</LocalDebuggerCommandArguments>
+ <LocalDebuggerWorkingDirectory>$(ProjectDir)\..\..\..\debug\test\backupstorefix</LocalDebuggerWorkingDirectory>
+ <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+ </PropertyGroup>
</Project> \ No newline at end of file
diff --git a/infrastructure/cmake/build/test_backupstore.vcxproj.user b/infrastructure/cmake/build/test_backupstore.vcxproj.user
index 79ef7571..7d7b3158 100755
--- a/infrastructure/cmake/build/test_backupstore.vcxproj.user
+++ b/infrastructure/cmake/build/test_backupstore.vcxproj.user
@@ -1,9 +1,9 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <LocalDebuggerWorkingDirectory>$(ProjectDir)\..\..\..\debug\test\backupstore</LocalDebuggerWorkingDirectory>
- <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
- <LocalDebuggerCommandArguments>
- </LocalDebuggerCommandArguments>
- </PropertyGroup>
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <LocalDebuggerWorkingDirectory>$(ProjectDir)\..\..\..\debug\test\backupstore</LocalDebuggerWorkingDirectory>
+ <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+ <LocalDebuggerCommandArguments>
+ </LocalDebuggerCommandArguments>
+ </PropertyGroup>
</Project> \ No newline at end of file
diff --git a/infrastructure/cmake/build/test_backupstorefix.vcxproj.user b/infrastructure/cmake/build/test_backupstorefix.vcxproj.user
index c0895191..170fb496 100755
--- a/infrastructure/cmake/build/test_backupstorefix.vcxproj.user
+++ b/infrastructure/cmake/build/test_backupstorefix.vcxproj.user
@@ -1,7 +1,7 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <LocalDebuggerWorkingDirectory>$(ProjectDir)\..\..\..\debug\test\backupstorefix</LocalDebuggerWorkingDirectory>
- <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
- </PropertyGroup>
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <LocalDebuggerWorkingDirectory>$(ProjectDir)\..\..\..\debug\test\backupstorefix</LocalDebuggerWorkingDirectory>
+ <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+ </PropertyGroup>
</Project> \ No newline at end of file
diff --git a/infrastructure/cmake/build/test_bbackupd.vcxproj.user b/infrastructure/cmake/build/test_bbackupd.vcxproj.user
index 9ca2b5e9..ebf8c6a3 100755
--- a/infrastructure/cmake/build/test_bbackupd.vcxproj.user
+++ b/infrastructure/cmake/build/test_bbackupd.vcxproj.user
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <LocalDebuggerCommandArguments>-e test_basics</LocalDebuggerCommandArguments>
- <LocalDebuggerWorkingDirectory>$(ProjectDir)\..\..\..\debug\test\bbackupd</LocalDebuggerWorkingDirectory>
- <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
- </PropertyGroup>
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <LocalDebuggerCommandArguments>-e test_basics</LocalDebuggerCommandArguments>
+ <LocalDebuggerWorkingDirectory>$(ProjectDir)\..\..\..\debug\test\bbackupd</LocalDebuggerWorkingDirectory>
+ <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+ </PropertyGroup>
</Project> \ No newline at end of file
diff --git a/infrastructure/cmake/build/test_common.vcxproj.user b/infrastructure/cmake/build/test_common.vcxproj.user
index 7a375f10..e5854a80 100755
--- a/infrastructure/cmake/build/test_common.vcxproj.user
+++ b/infrastructure/cmake/build/test_common.vcxproj.user
@@ -1,7 +1,7 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <LocalDebuggerWorkingDirectory>$(ProjectDir)\..\..\..\debug\test\common</LocalDebuggerWorkingDirectory>
- <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
- </PropertyGroup>
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <LocalDebuggerWorkingDirectory>$(ProjectDir)\..\..\..\debug\test\common</LocalDebuggerWorkingDirectory>
+ <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+ </PropertyGroup>
</Project> \ No newline at end of file
diff --git a/infrastructure/cmake/build/test_httpserver.vcxproj.user b/infrastructure/cmake/build/test_httpserver.vcxproj.user
index b2da015c..ac1512a8 100755
--- a/infrastructure/cmake/build/test_httpserver.vcxproj.user
+++ b/infrastructure/cmake/build/test_httpserver.vcxproj.user
@@ -1,7 +1,7 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <LocalDebuggerWorkingDirectory>$(ProjectDir)\..\..\..\debug\test\httpserver</LocalDebuggerWorkingDirectory>
- <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
- </PropertyGroup>
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <LocalDebuggerWorkingDirectory>$(ProjectDir)\..\..\..\debug\test\httpserver</LocalDebuggerWorkingDirectory>
+ <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+ </PropertyGroup>
</Project> \ No newline at end of file
diff --git a/infrastructure/cmake/build/test_raidfile.vcxproj.user b/infrastructure/cmake/build/test_raidfile.vcxproj.user
index d2c2fc34..620aa4bb 100755
--- a/infrastructure/cmake/build/test_raidfile.vcxproj.user
+++ b/infrastructure/cmake/build/test_raidfile.vcxproj.user
@@ -1,7 +1,7 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <LocalDebuggerWorkingDirectory>$(ProjectDir)\..\..\..\debug\test\raidfile</LocalDebuggerWorkingDirectory>
- <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
- </PropertyGroup>
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <LocalDebuggerWorkingDirectory>$(ProjectDir)\..\..\..\debug\test\raidfile</LocalDebuggerWorkingDirectory>
+ <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+ </PropertyGroup>
</Project> \ No newline at end of file
diff --git a/infrastructure/cmake/msvc/bin_bbackupd.vcxproj.user b/infrastructure/cmake/msvc/bin_bbackupd.vcxproj.user
index 51928554..fa1f3d34 100755
--- a/infrastructure/cmake/msvc/bin_bbackupd.vcxproj.user
+++ b/infrastructure/cmake/msvc/bin_bbackupd.vcxproj.user
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <LocalDebuggerCommandArguments>testfiles\bbackupd.conf</LocalDebuggerCommandArguments>
- <LocalDebuggerWorkingDirectory>$(ProjectDir)\..\..\..\debug\test\bbackupd</LocalDebuggerWorkingDirectory>
- <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
- </PropertyGroup>
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <LocalDebuggerCommandArguments>testfiles\bbackupd.conf</LocalDebuggerCommandArguments>
+ <LocalDebuggerWorkingDirectory>$(ProjectDir)\..\..\..\debug\test\bbackupd</LocalDebuggerWorkingDirectory>
+ <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+ </PropertyGroup>
</Project> \ No newline at end of file
diff --git a/infrastructure/cmake/msvc/bin_bbstored.vcxproj.user b/infrastructure/cmake/msvc/bin_bbstored.vcxproj.user
index e48b8383..339cddee 100755
--- a/infrastructure/cmake/msvc/bin_bbstored.vcxproj.user
+++ b/infrastructure/cmake/msvc/bin_bbstored.vcxproj.user
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <LocalDebuggerCommandArguments>testfiles/bbstored.conf</LocalDebuggerCommandArguments>
- <LocalDebuggerWorkingDirectory>$(ProjectDir)\..\..\..\debug\test\backupstorefix</LocalDebuggerWorkingDirectory>
- <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
- </PropertyGroup>
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <LocalDebuggerCommandArguments>testfiles/bbstored.conf</LocalDebuggerCommandArguments>
+ <LocalDebuggerWorkingDirectory>$(ProjectDir)\..\..\..\debug\test\backupstorefix</LocalDebuggerWorkingDirectory>
+ <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+ </PropertyGroup>
</Project> \ No newline at end of file
diff --git a/infrastructure/cmake/msvc/test_backupstore.vcxproj.user b/infrastructure/cmake/msvc/test_backupstore.vcxproj.user
index 79ef7571..7d7b3158 100755
--- a/infrastructure/cmake/msvc/test_backupstore.vcxproj.user
+++ b/infrastructure/cmake/msvc/test_backupstore.vcxproj.user
@@ -1,9 +1,9 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <LocalDebuggerWorkingDirectory>$(ProjectDir)\..\..\..\debug\test\backupstore</LocalDebuggerWorkingDirectory>
- <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
- <LocalDebuggerCommandArguments>
- </LocalDebuggerCommandArguments>
- </PropertyGroup>
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <LocalDebuggerWorkingDirectory>$(ProjectDir)\..\..\..\debug\test\backupstore</LocalDebuggerWorkingDirectory>
+ <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+ <LocalDebuggerCommandArguments>
+ </LocalDebuggerCommandArguments>
+ </PropertyGroup>
</Project> \ No newline at end of file
diff --git a/infrastructure/cmake/msvc/test_backupstorefix.vcxproj.user b/infrastructure/cmake/msvc/test_backupstorefix.vcxproj.user
index c0895191..170fb496 100755
--- a/infrastructure/cmake/msvc/test_backupstorefix.vcxproj.user
+++ b/infrastructure/cmake/msvc/test_backupstorefix.vcxproj.user
@@ -1,7 +1,7 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <LocalDebuggerWorkingDirectory>$(ProjectDir)\..\..\..\debug\test\backupstorefix</LocalDebuggerWorkingDirectory>
- <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
- </PropertyGroup>
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <LocalDebuggerWorkingDirectory>$(ProjectDir)\..\..\..\debug\test\backupstorefix</LocalDebuggerWorkingDirectory>
+ <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+ </PropertyGroup>
</Project> \ No newline at end of file
diff --git a/infrastructure/cmake/msvc/test_bbackupd.vcxproj.user b/infrastructure/cmake/msvc/test_bbackupd.vcxproj.user
index 9ca2b5e9..ebf8c6a3 100755
--- a/infrastructure/cmake/msvc/test_bbackupd.vcxproj.user
+++ b/infrastructure/cmake/msvc/test_bbackupd.vcxproj.user
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <LocalDebuggerCommandArguments>-e test_basics</LocalDebuggerCommandArguments>
- <LocalDebuggerWorkingDirectory>$(ProjectDir)\..\..\..\debug\test\bbackupd</LocalDebuggerWorkingDirectory>
- <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
- </PropertyGroup>
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <LocalDebuggerCommandArguments>-e test_basics</LocalDebuggerCommandArguments>
+ <LocalDebuggerWorkingDirectory>$(ProjectDir)\..\..\..\debug\test\bbackupd</LocalDebuggerWorkingDirectory>
+ <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+ </PropertyGroup>
</Project> \ No newline at end of file
diff --git a/infrastructure/cmake/msvc/test_common.vcxproj.user b/infrastructure/cmake/msvc/test_common.vcxproj.user
index 7a375f10..e5854a80 100755
--- a/infrastructure/cmake/msvc/test_common.vcxproj.user
+++ b/infrastructure/cmake/msvc/test_common.vcxproj.user
@@ -1,7 +1,7 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <LocalDebuggerWorkingDirectory>$(ProjectDir)\..\..\..\debug\test\common</LocalDebuggerWorkingDirectory>
- <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
- </PropertyGroup>
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <LocalDebuggerWorkingDirectory>$(ProjectDir)\..\..\..\debug\test\common</LocalDebuggerWorkingDirectory>
+ <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+ </PropertyGroup>
</Project> \ No newline at end of file
diff --git a/infrastructure/cmake/msvc/test_httpserver.vcxproj.user b/infrastructure/cmake/msvc/test_httpserver.vcxproj.user
index b2da015c..ac1512a8 100755
--- a/infrastructure/cmake/msvc/test_httpserver.vcxproj.user
+++ b/infrastructure/cmake/msvc/test_httpserver.vcxproj.user
@@ -1,7 +1,7 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <LocalDebuggerWorkingDirectory>$(ProjectDir)\..\..\..\debug\test\httpserver</LocalDebuggerWorkingDirectory>
- <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
- </PropertyGroup>
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <LocalDebuggerWorkingDirectory>$(ProjectDir)\..\..\..\debug\test\httpserver</LocalDebuggerWorkingDirectory>
+ <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+ </PropertyGroup>
</Project> \ No newline at end of file
diff --git a/infrastructure/cmake/msvc/test_raidfile.vcxproj.user b/infrastructure/cmake/msvc/test_raidfile.vcxproj.user
index d2c2fc34..620aa4bb 100755
--- a/infrastructure/cmake/msvc/test_raidfile.vcxproj.user
+++ b/infrastructure/cmake/msvc/test_raidfile.vcxproj.user
@@ -1,7 +1,7 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <LocalDebuggerWorkingDirectory>$(ProjectDir)\..\..\..\debug\test\raidfile</LocalDebuggerWorkingDirectory>
- <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
- </PropertyGroup>
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <LocalDebuggerWorkingDirectory>$(ProjectDir)\..\..\..\debug\test\raidfile</LocalDebuggerWorkingDirectory>
+ <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+ </PropertyGroup>
</Project> \ No newline at end of file
diff --git a/infrastructure/cmake/windows/CMakeLists.txt b/infrastructure/cmake/windows/CMakeLists.txt
index 49a1ea4d..9657b5e7 100644
--- a/infrastructure/cmake/windows/CMakeLists.txt
+++ b/infrastructure/cmake/windows/CMakeLists.txt
@@ -20,9 +20,9 @@ set(OPENSSL_VERSION 1.1.0g)
set(OPENSSL_HASH SHA256=de4d501267da39310905cb6dc8c6121f7a2cad45a7707f76df828fe1b85073af)
# Version of PCRE to download, build, and compile Box Backup against:
-set(PCRE_VERSION 8.39)
-# Hash of pcre-${PCRE_VERSION}.tar.gz, to be verified after download:
-set(PCRE_HASH SHA256=ccdf7e788769838f8285b3ee672ed573358202305ee361cfec7a4a4fb005bbc7)
+set(PCRE_VERSION 8.42)
+# Hash of pcre-${PCRE_VERSION}.tar.bz2, to be verified after download:
+set(PCRE_HASH SHA256=2cd04b7c887808be030254e8d77de11d3fe9d4505c39d4b15d2664ffe8bf9301)
# Version of Boost to download, unpack, and compile Box Backup against:
set(BOOST_VERSION 1.62.0)
@@ -87,12 +87,11 @@ else()
endif()
ExternalProject_Add(pcre
- # Temporarily use SVN repo until the PCRE_STATIC issue in 8.40 is fixed:
- # https://vcs.pcre.org/pcre?view=revision&revision=1677
- SVN_REPOSITORY svn://vcs.exim.org/pcre/code/trunk
- SVN_REVISION -r 1677
+ URL "https://ftp.pcre.org/pub/pcre/pcre-${PCRE_VERSION}.tar.bz2"
+ URL_HASH ${PCRE_HASH}
DOWNLOAD_NO_PROGRESS 1
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${install_dir} ${SUB_CMAKE_EXTRA_ARGS}
+ -DPCRE_BUILD_PCREGREP=OFF
-DPCRE_SUPPORT_LIBREADLINE=OFF
-DPCRE_SUPPORT_LIBBZ2=OFF
# We need to build both versions, debug and release, because cmake requires both to be
diff --git a/infrastructure/m4/boxbackup_tests.m4 b/infrastructure/m4/boxbackup_tests.m4
index 86aa560a..61cd34c2 100644
--- a/infrastructure/m4/boxbackup_tests.m4
+++ b/infrastructure/m4/boxbackup_tests.m4
@@ -128,6 +128,7 @@ AC_CHECK_FUNCS([dlsym dladdr])
AC_SEARCH_LIBS([gethostbyname], [nsl socket resolv])
AC_SEARCH_LIBS([shutdown], [nsl socket resolv])
AX_CHECK_SSL(, [AC_MSG_ERROR([[OpenSSL is not installed but is required]])])
+AC_CHECK_DECLS([SSL_R_EE_KEY_TOO_SMALL],,, [[#include <openssl/ssl.h>]])
AC_ARG_ENABLE(
[old-ssl],
[AC_HELP_STRING([--enable-old-ssl],
@@ -142,7 +143,8 @@ AC_SEARCH_LIBS(
Upgrade or read the documentation for alternatives]])
fi
])
-
+AC_CHECK_FUNCS([SSL_CTX_set_security_level], [HAVE_SSL_CTX_SET_SECURITY_LEVEL=1])
+AC_SUBST([HAVE_SSL_CTX_SET_SECURITY_LEVEL])
### Checks for header files.
diff --git a/lib/backupclient/BackupDaemonConfigVerify.cpp b/lib/backupclient/BackupDaemonConfigVerify.cpp
index 865ee413..e28e26ff 100644
--- a/lib/backupclient/BackupDaemonConfigVerify.cpp
+++ b/lib/backupclient/BackupDaemonConfigVerify.cpp
@@ -8,10 +8,11 @@
// --------------------------------------------------------------------------
#include "Box.h"
+
+#include "BackupConstants.h"
#include "BackupDaemonConfigVerify.h"
-#include "Daemon.h"
#include "BoxPortsAndFiles.h"
-#include "BackupConstants.h"
+#include "Daemon.h"
#include "MemLeakFindOn.h"
@@ -148,7 +149,9 @@ static const ConfigurationVerifyKey verifyrootkeys[] =
ConfigTest_IsUint32),
ConfigurationVerifyKey("CertificateFile", 0),
ConfigurationVerifyKey("PrivateKeyFile", 0),
- ConfigurationVerifyKey("TrustedCAsFile", ConfigTest_LastEntry),
+ ConfigurationVerifyKey("TrustedCAsFile", 0),
+ ConfigurationVerifyKey("SSLSecurityLevel", ConfigTest_IsInt | ConfigTest_LastEntry,
+ BOX_DEFAULT_SSL_SECURITY_LEVEL),
};
const ConfigurationVerify BackupDaemonConfigVerify =
diff --git a/lib/backupstore/BackupStoreCheck.cpp b/lib/backupstore/BackupStoreCheck.cpp
index b53ebf6d..37e45b03 100644
--- a/lib/backupstore/BackupStoreCheck.cpp
+++ b/lib/backupstore/BackupStoreCheck.cpp
@@ -174,9 +174,17 @@ void BackupStoreCheck::Check()
try
{
+ // We should be able to load a reference to the old refcount database
+ // (read-only) at the same time that we have a reference to the new one
+ // (temporary) open but not yet committed.
std::auto_ptr<BackupStoreRefCountDatabase> apOldRefs =
BackupStoreRefCountDatabase::Load(account, false);
- mNumberErrorsFound += mapNewRefs->ReportChangesTo(*apOldRefs);
+
+ // If we have created a new lost+found directory (and thus allocated it a nonzero
+ // object ID) then it's not surprising that the previous refcount DB did not have
+ // a reference to this directory, and not an error, so ignore it.
+ mNumberErrorsFound += mapNewRefs->ReportChangesTo(*apOldRefs,
+ mLostAndFoundDirectoryID); // ignore_object_id
}
catch(BoxException &e)
{
diff --git a/lib/backupstore/BackupStoreCheck2.cpp b/lib/backupstore/BackupStoreCheck2.cpp
index 13831a09..3775cc4a 100644
--- a/lib/backupstore/BackupStoreCheck2.cpp
+++ b/lib/backupstore/BackupStoreCheck2.cpp
@@ -429,7 +429,7 @@ int64_t BackupStoreCheck::GetLostAndFoundDirID()
if(!mFixErrors)
{
// The result will never be used anyway if errors aren't being fixed
- return 1;
+ return 0;
}
// Load up the root directory
diff --git a/lib/backupstore/BackupStoreRefCountDatabase.cpp b/lib/backupstore/BackupStoreRefCountDatabase.cpp
index b2ea1abd..86da0943 100644
--- a/lib/backupstore/BackupStoreRefCountDatabase.cpp
+++ b/lib/backupstore/BackupStoreRefCountDatabase.cpp
@@ -347,17 +347,22 @@ bool BackupStoreRefCountDatabase::RemoveReference(int64_t ObjectID)
return (refcount > 0);
}
-int BackupStoreRefCountDatabase::ReportChangesTo(BackupStoreRefCountDatabase& rOldRefs)
+int BackupStoreRefCountDatabase::ReportChangesTo(BackupStoreRefCountDatabase& rOldRefs,
+ int64_t ignore_object_id)
{
int ErrorCount = 0;
int64_t MaxOldObjectId = rOldRefs.GetLastObjectIDUsed();
int64_t MaxNewObjectId = GetLastObjectIDUsed();
for (int64_t ObjectID = BACKUPSTORE_ROOT_DIRECTORY_ID;
- ObjectID < std::max(MaxOldObjectId, MaxNewObjectId);
+ ObjectID <= std::max(MaxOldObjectId, MaxNewObjectId);
ObjectID++)
{
- typedef BackupStoreRefCountDatabase::refcount_t refcount_t;
+ if(ObjectID == ignore_object_id)
+ {
+ continue;
+ }
+
refcount_t OldRefs = (ObjectID <= MaxOldObjectId) ?
rOldRefs.GetRefCount(ObjectID) : 0;
refcount_t NewRefs = (ObjectID <= MaxNewObjectId) ?
diff --git a/lib/backupstore/BackupStoreRefCountDatabase.h b/lib/backupstore/BackupStoreRefCountDatabase.h
index 915653a4..6c16516e 100644
--- a/lib/backupstore/BackupStoreRefCountDatabase.h
+++ b/lib/backupstore/BackupStoreRefCountDatabase.h
@@ -87,7 +87,8 @@ public:
void AddReference(int64_t ObjectID);
// RemoveReference returns false if refcount drops to zero
bool RemoveReference(int64_t ObjectID);
- int ReportChangesTo(BackupStoreRefCountDatabase& rOldRefs);
+ int ReportChangesTo(BackupStoreRefCountDatabase& rOldRefs,
+ int64_t ignore_object_id = 0);
private:
static std::string GetFilename(const BackupStoreAccountDatabase::Entry&
diff --git a/lib/backupstore/StoreTestUtils.cpp b/lib/backupstore/StoreTestUtils.cpp
index 2b773cb1..902552d5 100644
--- a/lib/backupstore/StoreTestUtils.cpp
+++ b/lib/backupstore/StoreTestUtils.cpp
@@ -54,7 +54,7 @@ bool delete_account()
}
std::vector<uint32_t> ExpectedRefCounts;
-int bbstored_pid = 0, bbackupd_pid = 0;
+int bbstored_pid = 0, bbackupd_pid = 0, s3simulator_pid = 0;
void set_refcount(int64_t ObjectID, uint32_t RefCount)
{
@@ -266,11 +266,11 @@ bool check_reference_counts()
return counts_ok;
}
-bool StartServer()
+bool StartServer(const std::string& daemon_args)
{
- bbstored_pid = StartDaemon(bbstored_pid,
- BBSTORED " " + bbstored_args + " testfiles/bbstored.conf",
- "testfiles/bbstored.pid");
+ const std::string& daemon_args_final(daemon_args.size() ? daemon_args : bbstored_args);
+ bbstored_pid = StartDaemon(bbstored_pid, BBSTORED " " + daemon_args_final +
+ " testfiles/bbstored.conf", "testfiles/bbstored.pid");
return bbstored_pid != 0;
}
@@ -282,11 +282,11 @@ bool StopServer(bool wait_for_process)
return result;
}
-bool StartClient(const std::string& bbackupd_conf_file)
+bool StartClient(const std::string& bbackupd_conf_file, const std::string& daemon_args)
{
- bbackupd_pid = StartDaemon(bbackupd_pid,
- BBACKUPD " " + bbackupd_args + " " + bbackupd_conf_file,
- "testfiles/bbackupd.pid");
+ const std::string& daemon_args_final(daemon_args.size() ? daemon_args : bbackupd_args);
+ bbackupd_pid = StartDaemon(bbackupd_pid, BBACKUPD " " + daemon_args_final + " -c " +
+ bbackupd_conf_file, "testfiles/bbackupd.pid");
return bbackupd_pid != 0;
}
@@ -298,3 +298,40 @@ bool StopClient(bool wait_for_process)
return result;
}
+bool StartSimulator()
+{
+ s3simulator_pid = StartDaemon(s3simulator_pid,
+ "../../bin/s3simulator/s3simulator " + bbstored_args +
+ " testfiles/s3simulator.conf", "testfiles/s3simulator.pid");
+ return s3simulator_pid != 0;
+}
+
+bool StopSimulator()
+{
+ bool result = StopDaemon(s3simulator_pid, "testfiles/s3simulator.pid",
+ "s3simulator.memleaks", true);
+ s3simulator_pid = 0;
+ return result;
+}
+
+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);
+ }
+
+ if(FileExists("testfiles/s3simulator.pid"))
+ {
+ TEST_THAT_OR(KillServer("testfiles/s3simulator.pid", true), success = false);
+ }
+
+ return success;
+}
diff --git a/lib/backupstore/StoreTestUtils.h b/lib/backupstore/StoreTestUtils.h
index b3faebb5..794fbd44 100644
--- a/lib/backupstore/StoreTestUtils.h
+++ b/lib/backupstore/StoreTestUtils.h
@@ -66,17 +66,24 @@ bool run_housekeeping_and_check_account();
bool check_reference_counts();
//! Starts the bbstored test server running, which must not already be running.
-bool StartServer();
+bool StartServer(const std::string& daemon_args = "");
//! Stops the currently running bbstored test server.
bool StopServer(bool wait_for_process = false);
//! Starts the bbackupd client running, which must not already be running.
-bool StartClient(const std::string& bbackupd_conf_file = "testfiles/bbackupd.conf");
+bool StartClient(const std::string& bbackupd_conf_file = "testfiles/bbackupd.conf",
+ const std::string& daemon_args = "");
//! Stops the currently running bbackupd client.
bool StopClient(bool wait_for_process = false);
+bool StartSimulator();
+
+bool StopSimulator();
+
+bool kill_running_daemons();
+
//! Creates the standard test account, for example after delete_account().
bool create_account(int soft, int hard);
diff --git a/lib/bbackupd/BackupDaemon.cpp b/lib/bbackupd/BackupDaemon.cpp
index 996c1919..d75aa381 100644
--- a/lib/bbackupd/BackupDaemon.cpp
+++ b/lib/bbackupd/BackupDaemon.cpp
@@ -579,8 +579,9 @@ void BackupDaemon::InitCrypto()
std::string certFile(conf.GetKeyValue("CertificateFile"));
std::string keyFile(conf.GetKeyValue("PrivateKeyFile"));
std::string caFile(conf.GetKeyValue("TrustedCAsFile"));
+ int ssl_security_level(conf.GetKeyValueInt("SSLSecurityLevel"));
mTlsContext.Initialise(false /* as client */, certFile.c_str(),
- keyFile.c_str(), caFile.c_str());
+ keyFile.c_str(), caFile.c_str(), ssl_security_level);
// Set up the keys for various things
BackupClientCryptoKeys_Setup(conf.GetKeyValue("KeysFile"));
diff --git a/lib/common/BoxException.h b/lib/common/BoxException.h
index 361f04e8..e3a2268a 100644
--- a/lib/common/BoxException.h
+++ b/lib/common/BoxException.h
@@ -34,6 +34,9 @@ public:
private:
};
+#define EXCEPTION_IS_TYPE(exception_obj, type, subtype) \
+ (exception_obj.GetType() == type::ExceptionType && \
+ exception_obj.GetSubType() == type::subtype)
#endif // BOXEXCEPTION__H
diff --git a/lib/common/BoxPortsAndFiles.h.in b/lib/common/BoxPortsAndFiles.h.in
index 047a828f..f63e614b 100644
--- a/lib/common/BoxPortsAndFiles.h.in
+++ b/lib/common/BoxPortsAndFiles.h.in
@@ -20,6 +20,10 @@
// directory within the RAIDFILE root for the backup store daemon
#define BOX_RAIDFILE_ROOT_BBSTORED "backup"
+// default security level if SSLSecurityLevel is not specified: see
+// https://github.com/boxbackup/boxbackup/wiki/WeakSSLCertificates
+const int BOX_DEFAULT_SSL_SECURITY_LEVEL = -1;
+
// configuration file paths
#ifdef WIN32
// no default config file path, use these macros to call
diff --git a/lib/common/Configuration.cpp b/lib/common/Configuration.cpp
index 8ce8d389..9860864a 100644
--- a/lib/common/Configuration.cpp
+++ b/lib/common/Configuration.cpp
@@ -470,6 +470,16 @@ int Configuration::GetKeyValueInt(const std::string& rKeyName) const
}
+int Configuration::GetKeyValueInt(const std::string& rKeyName, int default_value) const
+{
+ if(!KeyExists(rKeyName))
+ {
+ return default_value;
+ }
+ return GetKeyValueInt(rKeyName);
+}
+
+
// --------------------------------------------------------------------------
//
// Function
@@ -778,8 +788,7 @@ bool Configuration::Verify(const ConfigurationVerify &rVerify,
}
else if(pvkey->HasDefaultValue())
{
- mKeys[pvkey->Name()] =
- pvkey->DefaultValue();
+ mKeys[pvkey->Name()] = pvkey->DefaultValue();
}
}
@@ -922,5 +931,3 @@ bool Configuration::Verify(const ConfigurationVerify &rVerify,
return ok;
}
-
-
diff --git a/lib/common/Configuration.h b/lib/common/Configuration.h
index e6498e80..f9b5eb77 100644
--- a/lib/common/Configuration.h
+++ b/lib/common/Configuration.h
@@ -122,6 +122,7 @@ public:
bool KeyExists(const std::string& rKeyName) const;
const std::string &GetKeyValue(const std::string& rKeyName) const;
int GetKeyValueInt(const std::string& rKeyName) const;
+ int GetKeyValueInt(const std::string& rKeyName, int default_value) const;
uint32_t GetKeyValueUint32(const std::string& rKeyName) const;
bool GetKeyValueBool(const std::string& rKeyName) const;
std::vector<std::string> GetKeyNames() const;
diff --git a/lib/common/FileStream.h b/lib/common/FileStream.h
index 1426d8a2..26442212 100644
--- a/lib/common/FileStream.h
+++ b/lib/common/FileStream.h
@@ -42,6 +42,7 @@ public:
virtual pos_type BytesLeftToRead();
virtual void Write(const void *pBuffer, int NBytes,
int Timeout = IOStream::TimeOutInfinite);
+ using IOStream::Write;
virtual pos_type GetPosition() const;
virtual void Seek(IOStream::pos_type Offset, int SeekType);
virtual void Close();
diff --git a/lib/common/Test.cpp b/lib/common/Test.cpp
index 2c51cd61..3d1620a1 100644
--- a/lib/common/Test.cpp
+++ b/lib/common/Test.cpp
@@ -28,7 +28,7 @@
int num_tests_selected = 0;
int num_failures = 0;
-int old_failure_count = 0;
+static int old_failure_count = 0; // do not expose!
int first_fail_line;
std::string original_working_dir;
std::string first_fail_file;
@@ -97,6 +97,8 @@ bool setUp(const char* function_name)
if(StartsWith("TestDir", filename) ||
StartsWith("0_", filename) ||
filename == "accounts.txt" ||
+ filename == "bbackupd-data" ||
+ filename == "ca" ||
StartsWith("file", filename) ||
StartsWith("notifyran", filename) ||
StartsWith("notifyscript.tag", filename) ||
@@ -105,7 +107,9 @@ bool setUp(const char* function_name)
filename == "syncallowscript.control" ||
StartsWith("syncallowscript.notifyran.", filename) ||
filename == "test2.downloaded" ||
- EndsWith("testfile", filename))
+ EndsWith("testfile", filename) ||
+ filename == "tmp" ||
+ EndsWith(".qdbm", filename))
{
std::string filepath = std::string("testfiles\\") + filename;
@@ -201,7 +205,8 @@ bool setUp(const char* function_name)
"testfiles/restore* testfiles/bbackupd-data "
"testfiles/syncallowscript.control "
"testfiles/syncallowscript.notifyran.* "
- "testfiles/test2.downloaded"
+ "testfiles/test2.downloaded "
+ "testfiles/tmp "
) == 0);
TEST_THAT_THROWONFAIL(system("touch testfiles/accounts.txt") == 0);
#endif
@@ -382,133 +387,6 @@ int ReadPidFile(const char *pidFile)
return pid;
}
-int LaunchServer(const std::string& rCommandLine, const char *pidFile)
-{
- BOX_INFO("Starting server: " << rCommandLine);
-
-#ifdef WIN32
-
- PROCESS_INFORMATION procInfo;
-
- STARTUPINFO startInfo;
- startInfo.cb = sizeof(startInfo);
- startInfo.lpReserved = NULL;
- startInfo.lpDesktop = NULL;
- startInfo.lpTitle = NULL;
- startInfo.dwFlags = 0;
- startInfo.cbReserved2 = 0;
- startInfo.lpReserved2 = NULL;
-
- std::string cmd = ConvertPaths(rCommandLine);
- CHAR* tempCmd = strdup(cmd.c_str());
-
- DWORD result = CreateProcess
- (
- NULL, // lpApplicationName, naughty!
- tempCmd, // lpCommandLine
- NULL, // lpProcessAttributes
- NULL, // lpThreadAttributes
- false, // bInheritHandles
- 0, // dwCreationFlags
- NULL, // lpEnvironment
- NULL, // lpCurrentDirectory
- &startInfo, // lpStartupInfo
- &procInfo // lpProcessInformation
- );
-
- free(tempCmd);
-
- TEST_THAT_OR(result != 0,
- BOX_LOG_WIN_ERROR("Launch failed: " << rCommandLine);
- return -1;
- );
-
- CloseHandle(procInfo.hProcess);
- CloseHandle(procInfo.hThread);
-
- return WaitForServerStartup(pidFile, (int)procInfo.dwProcessId);
-
-#else // !WIN32
-
- TEST_THAT_OR(RunCommand(rCommandLine) == 0,
- TEST_FAIL_WITH_MESSAGE("Failed to start server: " << rCommandLine);
- return -1;
- )
-
- return WaitForServerStartup(pidFile, 0);
-
-#endif // WIN32
-}
-
-int WaitForServerStartup(const char *pidFile, int pidIfKnown)
-{
- #ifdef WIN32
- if (pidFile == NULL)
- {
- return pidIfKnown;
- }
- #else
- // on other platforms there is no other way to get
- // the PID, so a NULL pidFile doesn't make sense.
- ASSERT(pidFile != NULL);
- #endif
-
- // time for it to start up
- BOX_TRACE("Waiting for server to start");
-
- for (int i = 0; i < 15; i++)
- {
- if (TestFileNotEmpty(pidFile))
- {
- break;
- }
-
- if (pidIfKnown && !ServerIsAlive(pidIfKnown))
- {
- break;
- }
-
- ::sleep(1);
- }
-
- // on Win32 we can check whether the process is alive
- // without even checking the PID file
-
- if (pidIfKnown && !ServerIsAlive(pidIfKnown))
- {
- TEST_FAIL_WITH_MESSAGE("Server died!");
- return -1;
- }
-
- if (!TestFileNotEmpty(pidFile))
- {
- TEST_FAIL_WITH_MESSAGE("Server didn't save PID file");
- return -1;
- }
-
- BOX_TRACE("Server started");
-
- // wait a second for the pid to be written to the file
- ::sleep(1);
-
- // read pid file
- int pid = ReadPidFile(pidFile);
-
- // On Win32 we can check whether the PID in the pidFile matches
- // the one returned by the system, which it always should.
-
- if (pidIfKnown && pid != pidIfKnown)
- {
- BOX_ERROR("Server wrote wrong pid to file (" << pidFile <<
- "): expected " << pidIfKnown << " but found " <<
- pid);
- TEST_FAIL_WITH_MESSAGE("Server wrote wrong pid to file");
- return -1;
- }
-
- return pid;
-}
-
void TestRemoteProcessMemLeaksFunc(const char *filename,
const char* file, int line)
{
diff --git a/lib/common/Test.h b/lib/common/Test.h
index 4b5cef61..35443c29 100644
--- a/lib/common/Test.h
+++ b/lib/common/Test.h
@@ -23,6 +23,7 @@
#define BBACKUPQUERY "..\\..\\bin\\bbackupquery\\bbackupquery.exe"
#define BBSTOREACCOUNTS "..\\..\\bin\\bbstoreaccounts\\bbstoreaccounts.exe"
#define TEST_RETURN(actual, expected) TEST_EQUAL(expected, actual);
+#define TEST_RETURN_COMMAND(actual, expected, command) TEST_EQUAL_LINE(expected, actual, command);
#else
#define BBACKUPCTL "../../bin/bbackupctl/bbackupctl"
#define BBACKUPD "../../bin/bbackupd/bbackupd"
@@ -30,12 +31,16 @@
#define BBACKUPQUERY "../../bin/bbackupquery/bbackupquery"
#define BBSTOREACCOUNTS "../../bin/bbstoreaccounts/bbstoreaccounts"
#define TEST_RETURN(actual, expected) TEST_EQUAL((expected << 8), actual);
+#define TEST_RETURN_COMMAND(actual, expected, command) TEST_EQUAL_LINE((expected << 8), actual, command);
#endif
+#define DEFAULT_BBSTORED_CONFIG_FILE "testfiles/bbstored.conf"
+#define DEFAULT_BBACKUPD_CONFIG_FILE "testfiles/bbackupd.conf"
+#define DEFAULT_S3_CACHE_DIR "testfiles/bbackupd-cache"
+
extern int num_failures;
extern int first_fail_line;
extern int num_tests_selected;
-extern int old_failure_count;
extern std::string first_fail_file;
extern std::string bbackupd_args, bbstored_args, bbackupquery_args, test_args;
extern std::list<std::string> run_only_named_tests;
@@ -215,6 +220,7 @@ int finish_test_suite();
bool TestFileExists(const char *Filename);
bool TestDirExists(const char *Filename);
+bool TestFileNotEmpty(const char *Filename);
// -1 if doesn't exist
int TestGetFileSize(const std::string& Filename);
@@ -222,8 +228,6 @@ std::string ConvertPaths(const std::string& rOriginal);
int RunCommand(const std::string& rCommandLine);
bool ServerIsAlive(int pid);
int ReadPidFile(const char *pidFile);
-int LaunchServer(const std::string& rCommandLine, const char *pidFile);
-int WaitForServerStartup(const char *pidFile, int pidIfKnown);
#define TestRemoteProcessMemLeaks(filename) \
TestRemoteProcessMemLeaksFunc(filename, __FILE__, __LINE__)
diff --git a/lib/server/ConnectionException.txt b/lib/server/ConnectionException.txt
index 7dcaadeb..74390853 100644
--- a/lib/server/ConnectionException.txt
+++ b/lib/server/ConnectionException.txt
@@ -15,6 +15,7 @@ TLSNoPeerCertificate 36
TLSPeerCertificateInvalid 37 Check certification process
TLSClosedWhenWriting 38
TLSHandshakeTimedOut 39
+TLSPeerWeakCertificate 40 The peer's certificate is too weak for the current SSL Security Level, see https://github.com/boxbackup/boxbackup/wiki/WeakSSLCertificates
Protocol_Timeout 41 Probably a network issue between client and server.
Protocol_ObjTooBig 42
Protocol_BadCommandRecieved 44
diff --git a/lib/server/Daemon.cpp b/lib/server/Daemon.cpp
index d3c8441f..76141b6f 100644
--- a/lib/server/Daemon.cpp
+++ b/lib/server/Daemon.cpp
@@ -42,6 +42,7 @@
#include "autogen_ConnectionException.h"
#include "autogen_ServerException.h"
+#include "BoxPortsAndFiles.h"
#include "Configuration.h"
#include "Daemon.h"
#include "FileModificationTime.h"
@@ -52,6 +53,9 @@
#include "MemLeakFindOn.h"
+const ConfigurationVerifyKey ssl_security_level_key("SSLSecurityLevel",
+ ConfigTest_IsInt | ConfigTest_LastEntry, BOX_DEFAULT_SSL_SECURITY_LEVEL);
+
Daemon *Daemon::spDaemon = 0;
diff --git a/lib/server/Daemon.h b/lib/server/Daemon.h
index b5384918..60ce4507 100644
--- a/lib/server/Daemon.h
+++ b/lib/server/Daemon.h
@@ -121,5 +121,7 @@ private:
ConfigurationVerifyKey("LogFacility", 0), \
ConfigurationVerifyKey("User", ConfigTest_LastEntry)
+extern const ConfigurationVerifyKey ssl_security_level_key;
+
#endif // DAEMON__H
diff --git a/lib/server/ServerControl.cpp b/lib/server/ServerControl.cpp
index f1a718df..b6cadab3 100644
--- a/lib/server/ServerControl.cpp
+++ b/lib/server/ServerControl.cpp
@@ -18,7 +18,9 @@
#include "BoxTime.h"
#include "IOStreamGetLine.h"
#include "ServerControl.h"
+#include "SocketStream.h"
#include "Test.h"
+#include "autogen_ServerException.h"
#ifdef WIN32
@@ -227,7 +229,7 @@ bool KillServer(int pid, bool WaitForProcess)
return !ServerIsAlive(pid);
}
-bool KillServer(std::string pid_file, bool WaitForProcess)
+bool KillServer(const std::string& pid_file, bool WaitForProcess)
{
FileStream fs(pid_file);
IOStreamGetLine getline(fs);
@@ -251,11 +253,174 @@ bool KillServer(std::string pid_file, bool WaitForProcess)
return status;
}
-int StartDaemon(int current_pid, const std::string& cmd_line, const char* pid_file)
+int LaunchServer(const std::string& rCommandLine, const char *pidFile, int port,
+ const std::string& socket_path)
+{
+ BOX_INFO("Starting server: " << rCommandLine);
+
+#ifdef WIN32
+
+ // Use a Windows "Job Object" as a container for all our child
+ // processes. The test runner will create this job object when
+ // it starts, and close the handle (killing any running daemons)
+ // when it exits. This is the best way to avoid daemons hanging
+ // around and causing subsequent tests to fail, and/or the test
+ // runner to hang waiting for a daemon that will never terminate.
+
+ PROCESS_INFORMATION procInfo;
+
+ STARTUPINFO startInfo;
+ startInfo.cb = sizeof(startInfo);
+ startInfo.lpReserved = NULL;
+ startInfo.lpDesktop = NULL;
+ startInfo.lpTitle = NULL;
+ startInfo.dwFlags = 0;
+ startInfo.cbReserved2 = 0;
+ startInfo.lpReserved2 = NULL;
+
+ std::string cmd = ConvertPaths(rCommandLine);
+ CHAR* tempCmd = strdup(cmd.c_str());
+
+ DWORD result = CreateProcess
+ (
+ NULL, // lpApplicationName, naughty!
+ tempCmd, // lpCommandLine
+ NULL, // lpProcessAttributes
+ NULL, // lpThreadAttributes
+ false, // bInheritHandles
+ 0, // dwCreationFlags
+ NULL, // lpEnvironment
+ NULL, // lpCurrentDirectory
+ &startInfo, // lpStartupInfo
+ &procInfo // lpProcessInformation
+ );
+
+ free(tempCmd);
+
+ TEST_THAT_OR(result != 0,
+ BOX_LOG_WIN_ERROR("Failed to CreateProcess: " << rCommandLine);
+ return -1;
+ );
+
+ CloseHandle(procInfo.hProcess);
+ CloseHandle(procInfo.hThread);
+
+ return WaitForServerStartup(pidFile, (int)procInfo.dwProcessId, port, socket_path);
+
+#else // !WIN32
+
+ TEST_THAT_OR(RunCommand(rCommandLine) == 0,
+ TEST_FAIL_WITH_MESSAGE("Failed to start server: " << rCommandLine);
+ return -1;
+ )
+
+ return WaitForServerStartup(pidFile, 0, port, socket_path);
+
+#endif // WIN32
+}
+
+int WaitForServerStartup(const char *pidFile, int pidIfKnown, int port,
+ const std::string& socket_path)
+{
+#ifdef WIN32
+ if(pidFile == NULL && port == 0 && socket_path == "")
+ {
+ return pidIfKnown;
+ }
+#else
+ // On other platforms there is no other way to get the PID, so a NULL pidFile doesn't
+ // make sense.
+ ASSERT(pidFile != NULL);
+#endif
+
+ // time for it to start up
+ BOX_TRACE("Waiting for server to start");
+
+ for (int i = 150; i >= 0; i--)
+ {
+ if(i == 0)
+ {
+ // ran out of time waiting
+ TEST_FAIL_WITH_MESSAGE("Server didn't start within expected time");
+ return -1;
+ }
+
+ ShortSleep(MilliSecondsToBoxTime(100), false);
+
+ if(!TestFileNotEmpty(pidFile))
+ {
+ // Hasn't written a complete PID file yet, go round again
+ continue;
+ }
+
+ // Once we know what PID the process has/had, we can check if it has died during or
+ // shortly after startup:
+ if (pidIfKnown && !ServerIsAlive(pidIfKnown))
+ {
+ TEST_FAIL_WITH_MESSAGE("Server died!");
+ return -1;
+ }
+
+ if(port != 0 || socket_path != "")
+ {
+ try
+ {
+ if(port != 0)
+ {
+ SocketStream conn;
+ conn.Open(Socket::TypeINET, "localhost", port);
+ }
+
+ if(socket_path != "")
+ {
+ SocketStream conn;
+ conn.Open(Socket::TypeUNIX, socket_path);
+ }
+ }
+ catch(ServerException &e)
+ {
+ if(EXCEPTION_IS_TYPE(e, ServerException, SocketOpenError))
+ {
+ // not listening on port, go round again
+ continue;
+ }
+ else
+ {
+ // something bad happened, break
+ throw;
+ }
+ }
+ }
+
+ // All tests that we can do have passed, looks good!
+ break;
+ }
+
+ BOX_TRACE("Server started");
+
+ // read pid file
+ int pid = ReadPidFile(pidFile);
+
+ // On Win32 we can check whether the PID in the pidFile matches
+ // the one returned by the system, which it always should.
+ if (pidIfKnown && pid != pidIfKnown)
+ {
+ BOX_ERROR("Server wrote wrong pid to file (" << pidFile <<
+ "): expected " << pidIfKnown << " but found " <<
+ pid);
+ TEST_FAIL_WITH_MESSAGE("Server wrote wrong pid to file");
+ return -1;
+ }
+
+ return pid;
+}
+
+int StartDaemon(int current_pid, const std::string& cmd_line, const char* pid_file, int port,
+ const std::string& socket_path)
{
TEST_THAT_OR(current_pid == 0, return 0);
- int new_pid = LaunchServer(cmd_line, pid_file);
+ int new_pid = LaunchServer(cmd_line, pid_file, port, socket_path);
TEST_THAT_OR(new_pid != -1 && new_pid != 0, return 0);
::sleep(1);
diff --git a/lib/server/ServerControl.h b/lib/server/ServerControl.h
index be2464c1..28320491 100644
--- a/lib/server/ServerControl.h
+++ b/lib/server/ServerControl.h
@@ -4,11 +4,17 @@
#include "Test.h"
bool HUPServer(int pid);
-bool KillServer(int pid, bool WaitForProcess = false);
-bool KillServer(std::string pid_file, bool WaitForProcess = false);
-int StartDaemon(int current_pid, const std::string& cmd_line, const char* pid_file);
-bool StopDaemon(int current_pid, const std::string& pid_file,
- const std::string& memleaks_file, bool wait_for_process);
+bool KillServer(int pid, bool wait_for_process = false);
+bool KillServer(const std::string& pid_file, bool wait_for_process = false);
+bool KillServerInternal(int pid);
+int StartDaemon(int current_pid, const std::string& cmd_line, const char* pid_file, int port = 0,
+ const std::string& socket_path = "");
+bool StopDaemon(int current_pid, const std::string& pid_file, const std::string& memleaks_file,
+ bool wait_for_process);
+int LaunchServer(const std::string& rCommandLine, const char *pidFile, int port = 0,
+ const std::string& socket_path = "");
+int WaitForServerStartup(const char *pidFile, int pidIfKnown, int port = 0,
+ const std::string& socket_path = "");
#ifdef WIN32
#include "WinNamedPipeStream.h"
diff --git a/lib/server/ServerException.txt b/lib/server/ServerException.txt
index 474b4067..02fb379c 100644
--- a/lib/server/ServerException.txt
+++ b/lib/server/ServerException.txt
@@ -29,6 +29,7 @@ TLSSetCiphersFailed 28
SSLLibraryInitialisationError 29
TLSNoSSLObject 31
TLSAlreadyHandshaked 35
+TLSServerWeakCertificate 36 Our SSL certificate is too weak for the current SSL Security Level, see https://github.com/boxbackup/boxbackup/wiki/WeakSSLCertificates
SocketSetNonBlockingFailed 40
Protocol_BadUsage 43
Protocol_UnsuitableStreamTypeForSending 51
diff --git a/lib/server/ServerStream.h b/lib/server/ServerStream.h
index 3f6eed7e..db8beaf2 100644
--- a/lib/server/ServerStream.h
+++ b/lib/server/ServerStream.h
@@ -306,7 +306,16 @@ public:
#endif // !WIN32
// Just handle in this process
SetProcessTitle("handling");
- HandleConnection(connection);
+ try
+ {
+ HandleConnection(connection);
+ }
+ catch(BoxException &e)
+ {
+ BOX_ERROR("Error in child handler, terminating connection: "
+ "exception " << e.what() << "(" << e.GetType() << "/" <<
+ e.GetSubType() << ")");
+ }
SetProcessTitle("idle");
#ifndef WIN32
}
diff --git a/lib/server/ServerTLS.h b/lib/server/ServerTLS.h
index f748f4b2..6b53e860 100644
--- a/lib/server/ServerTLS.h
+++ b/lib/server/ServerTLS.h
@@ -10,6 +10,7 @@
#ifndef SERVERTLS__H
#define SERVERTLS__H
+#include "BoxPortsAndFiles.h"
#include "ServerStream.h"
#include "SocketStreamTLS.h"
#include "SSLLib.h"
@@ -52,8 +53,12 @@ public:
std::string certFile(serverconf.GetKeyValue("CertificateFile"));
std::string keyFile(serverconf.GetKeyValue("PrivateKeyFile"));
std::string caFile(serverconf.GetKeyValue("TrustedCAsFile"));
+
+ int ssl_security_level(serverconf.GetKeyValueInt("SSLSecurityLevel",
+ BOX_DEFAULT_SSL_SECURITY_LEVEL));
+
mContext.Initialise(true /* as server */, certFile.c_str(),
- keyFile.c_str(), caFile.c_str());
+ keyFile.c_str(), caFile.c_str(), ssl_security_level);
// Then do normal stream server stuff
ServerStream<SocketStreamTLS, Port, ListenBacklog,
@@ -75,6 +80,8 @@ private:
ConfigurationVerifyKey("CertificateFile", ConfigTest_Exists), \
ConfigurationVerifyKey("PrivateKeyFile", ConfigTest_Exists), \
ConfigurationVerifyKey("TrustedCAsFile", ConfigTest_Exists), \
+ ConfigurationVerifyKey("SSLSecurityLevel", ConfigTest_IsInt, \
+ BOX_DEFAULT_SSL_SECURITY_LEVEL), \
SERVERSTREAM_VERIFY_SERVER_KEYS(DEFAULT_ADDRESSES)
#endif // SERVERTLS__H
diff --git a/lib/server/SocketStream.cpp b/lib/server/SocketStream.cpp
index edb5e5b8..f8c6c85c 100644
--- a/lib/server/SocketStream.cpp
+++ b/lib/server/SocketStream.cpp
@@ -171,6 +171,10 @@ void SocketStream::Open(Socket::Type Type, const std::string& rName, int Port)
Socket::NameLookupToSockAddr(addr, sockDomain, Type, rName, Port,
addrLen);
+ std::ostringstream oss;
+ oss << rName << ":" << Port;
+ mPeerSocketDesc = oss.str();
+
// Create the socket
mSocketHandle = ::socket(sockDomain, SOCK_STREAM,
0 /* let OS choose protocol */);
diff --git a/lib/server/SocketStream.h b/lib/server/SocketStream.h
index fd57af8f..6b029387 100644
--- a/lib/server/SocketStream.h
+++ b/lib/server/SocketStream.h
@@ -114,6 +114,7 @@ private:
protected:
off_t mBytesRead;
off_t mBytesWritten;
+ std::string mPeerSocketDesc;
public:
off_t GetBytesRead() const {return mBytesRead;}
diff --git a/lib/server/SocketStreamTLS.cpp b/lib/server/SocketStreamTLS.cpp
index e6299bfa..fc9652b7 100644
--- a/lib/server/SocketStreamTLS.cpp
+++ b/lib/server/SocketStreamTLS.cpp
@@ -10,8 +10,7 @@
#include "Box.h"
#define TLS_CLASS_IMPLEMENTATION_CPP
-#include <openssl/ssl.h>
-#include <openssl/bio.h>
+
#include <errno.h>
#include <fcntl.h>
@@ -19,6 +18,10 @@
#include <poll.h>
#endif
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/ssl.h>
+
#include "autogen_ConnectionException.h"
#include "autogen_ServerException.h"
#include "BoxTime.h"
@@ -126,8 +129,8 @@ void SocketStreamTLS::Handshake(const TLSContext &rContext, bool IsServer)
mpBIO = ::BIO_new(::BIO_s_socket());
if(mpBIO == 0)
{
- CryptoUtils::LogError("creating socket bio");
- THROW_EXCEPTION(ServerException, TLSAllocationFailed)
+ THROW_EXCEPTION_MESSAGE(ServerException, TLSAllocationFailed,
+ "Failed to create SSL BIO: " << CryptoUtils::LogError("creating socket bio"));
}
tOSSocketHandle socket = GetSocketHandle();
@@ -137,8 +140,8 @@ void SocketStreamTLS::Handshake(const TLSContext &rContext, bool IsServer)
mpSSL = ::SSL_new(rContext.GetRawContext());
if(mpSSL == 0)
{
- CryptoUtils::LogError("creating SSL object");
- THROW_EXCEPTION(ServerException, TLSAllocationFailed)
+ THROW_EXCEPTION_MESSAGE(ServerException, TLSAllocationFailed,
+ "Failed to create SSL object: " << CryptoUtils::LogError("creating SSL object"));
}
// Make the socket non-blocking so timeouts on Read work
@@ -203,15 +206,43 @@ void SocketStreamTLS::Handshake(const TLSContext &rContext, bool IsServer)
default: // (and SSL_ERROR_ZERO_RETURN)
// Error occured
+#if HAVE_DECL_SSL_R_EE_KEY_TOO_SMALL
+ int err_reason = ERR_GET_REASON(ERR_peek_error());
+ const char *file, *data;
+ int line, flags;
+ ERR_peek_error_line_data(&file, &line, &data, &flags);
+ long verify_result = SSL_get_verify_result(mpSSL);
+
+ if(se == SSL_ERROR_SSL && verify_result == X509_V_ERR_CA_KEY_TOO_SMALL)
+ {
+ // Would be nice to use GetPeerCommonName() in these error messages,
+ // but since the certificate isn't trusted, that might be misleading,
+ // and it's not available to us anyway :(
+
+ THROW_EXCEPTION_MESSAGE(ConnectionException, TLSPeerWeakCertificate,
+ (IsServer ? "Failed to accept connection from" :
+ "Failed to connect to") << " " << mPeerSocketDesc <<
+ ": key too short for current security level");
+ }
+ else if(se == SSL_ERROR_SSL && verify_result == X509_V_ERR_CA_MD_TOO_WEAK)
+ {
+ THROW_EXCEPTION_MESSAGE(ConnectionException, TLSPeerWeakCertificate,
+ (IsServer ? "Failed to accept connection from" :
+ "Failed to connect to") << " " << mPeerSocketDesc <<
+ ": hash too weak for current security level");
+ }
+ else
+#endif // HAVE_DECL_SSL_R_EE_KEY_TOO_SMALL
if(IsServer)
{
- CryptoUtils::LogError("accepting connection");
- THROW_EXCEPTION(ConnectionException, TLSHandshakeFailed)
+ THROW_EXCEPTION_MESSAGE(ConnectionException, TLSHandshakeFailed,
+ "Failed to accept connection: " <<
+ CryptoUtils::LogError("accepting connection"));
}
else
{
- CryptoUtils::LogError("connecting");
- THROW_EXCEPTION(ConnectionException, TLSHandshakeFailed)
+ THROW_EXCEPTION_MESSAGE(ConnectionException, TLSHandshakeFailed,
+ "Failed to connect: " << CryptoUtils::LogError("connecting"));
}
}
}
diff --git a/lib/server/SocketStreamTLS.h b/lib/server/SocketStreamTLS.h
index 3fda98c1..8a793966 100644
--- a/lib/server/SocketStreamTLS.h
+++ b/lib/server/SocketStreamTLS.h
@@ -34,10 +34,11 @@ public:
SocketStreamTLS();
SocketStreamTLS(int socket);
~SocketStreamTLS();
+
private:
SocketStreamTLS(const SocketStreamTLS &rToCopy);
-public:
+public:
void Open(const TLSContext &rContext, Socket::Type Type,
const std::string& rName, int Port = 0);
void Handshake(const TLSContext &rContext, bool IsServer = false);
diff --git a/lib/server/TLSContext.cpp b/lib/server/TLSContext.cpp
index 1a6d4a53..9c01452b 100644
--- a/lib/server/TLSContext.cpp
+++ b/lib/server/TLSContext.cpp
@@ -10,10 +10,12 @@
#include "Box.h"
#define TLS_CLASS_IMPLEMENTATION_CPP
+#include <openssl/err.h>
#include <openssl/ssl.h>
#include "autogen_ConnectionException.h"
#include "autogen_ServerException.h"
+#include "BoxPortsAndFiles.h"
#include "CryptoUtils.h"
#include "SSLLib.h"
#include "TLSContext.h"
@@ -21,7 +23,7 @@
#include "MemLeakFindOn.h"
#define MAX_VERIFICATION_DEPTH 2
-#define CIPHER_LIST "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"
+#define CIPHER_LIST "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"
// Macros to allow compatibility with OpenSSL 1.0 and 1.1 APIs. See
// https://github.com/charybdis-ircd/charybdis/blob/release/3.5/libratbox/src/openssl_ratbox.h
@@ -71,7 +73,8 @@ TLSContext::~TLSContext()
// Created: 2003/08/06
//
// --------------------------------------------------------------------------
-void TLSContext::Initialise(bool AsServer, const char *CertificatesFile, const char *PrivateKeyFile, const char *TrustedCAsFile)
+void TLSContext::Initialise(bool AsServer, const char *CertificatesFile, const char *PrivateKeyFile,
+ const char *TrustedCAsFile, int SSLSecurityLevel)
{
if(mpContext != 0)
{
@@ -84,29 +87,65 @@ void TLSContext::Initialise(bool AsServer, const char *CertificatesFile, const c
THROW_EXCEPTION(ServerException, TLSAllocationFailed)
}
+#ifdef HAVE_SSL_CTX_SET_SECURITY_LEVEL
+ if(SSLSecurityLevel == -1)
+ {
+ BOX_WARNING("SSLSecurityLevel not set. Your connection may not be secure. "
+ "Please see https://github.com/boxbackup/boxbackup/wiki/WeakSSLCertificates "
+ "for details");
+ SSLSecurityLevel = 1; // Default for now. Unsafe, but we warned the user.
+ // TODO: upgrade to level 2 soon.
+ }
+
+ SSL_CTX_set_security_level(mpContext, SSLSecurityLevel);
+#else
+ if(SSLSecurityLevel != BOX_DEFAULT_SSL_SECURITY_LEVEL)
+ {
+ BOX_WARNING("SSLSecurityLevel is set, but this Box Backup is not compiled with "
+ "OpenSSL 1.1 or higher, so will be ignored (compiled with "
+ OPENSSL_VERSION_TEXT ")");
+ }
+#endif
+
// Setup our identity
if(::SSL_CTX_use_certificate_chain_file(mpContext, CertificatesFile) != 1)
{
- std::string msg = "loading certificates from ";
- msg += CertificatesFile;
- CryptoUtils::LogError(msg);
- THROW_EXCEPTION(ServerException, TLSLoadCertificatesFailed)
+#if HAVE_DECL_SSL_R_EE_KEY_TOO_SMALL
+ int err_reason = ERR_GET_REASON(ERR_peek_error());
+ if(err_reason == SSL_R_EE_KEY_TOO_SMALL)
+ {
+ THROW_EXCEPTION_MESSAGE(ServerException, TLSServerWeakCertificate,
+ "Failed to load certificates from " << CertificatesFile << ": "
+ "key too short for current security level");
+ }
+ else if(err_reason == SSL_R_CA_MD_TOO_WEAK)
+ {
+ THROW_EXCEPTION_MESSAGE(ServerException, TLSServerWeakCertificate,
+ "Failed to load certificates from " << CertificatesFile << ": "
+ "hash too weak for current security level");
+ }
+ else
+#endif // HAVE_DECL_SSL_R_EE_KEY_TOO_SMALL
+ {
+ THROW_EXCEPTION_MESSAGE(ServerException, TLSLoadCertificatesFailed,
+ "Failed to load certificates from " << CertificatesFile << ": " <<
+ CryptoUtils::LogError("loading certificates"));
+ }
}
+
if(::SSL_CTX_use_PrivateKey_file(mpContext, PrivateKeyFile, SSL_FILETYPE_PEM) != 1)
{
- std::string msg = "loading private key from ";
- msg += PrivateKeyFile;
- CryptoUtils::LogError(msg);
- THROW_EXCEPTION(ServerException, TLSLoadPrivateKeyFailed)
+ THROW_EXCEPTION_MESSAGE(ServerException, TLSLoadPrivateKeyFailed,
+ "Failed to load private key from " << PrivateKeyFile << ": " <<
+ CryptoUtils::LogError("loading private key"));
}
// Setup the identify of CAs we trust
if(::SSL_CTX_load_verify_locations(mpContext, TrustedCAsFile, NULL) != 1)
{
- std::string msg = "loading CA cert from ";
- msg += TrustedCAsFile;
- CryptoUtils::LogError(msg);
- THROW_EXCEPTION(ServerException, TLSLoadTrustedCAsFailed)
+ THROW_EXCEPTION_MESSAGE(ServerException, TLSLoadTrustedCAsFailed,
+ "Failed to load CA certificate from " << TrustedCAsFile << ": " <<
+ CryptoUtils::LogError("loading CA cert"));
}
// Setup options to require these certificates
@@ -117,8 +156,9 @@ void TLSContext::Initialise(bool AsServer, const char *CertificatesFile, const c
// Setup allowed ciphers
if(::SSL_CTX_set_cipher_list(mpContext, CIPHER_LIST) != 1)
{
- CryptoUtils::LogError("setting cipher list to " CIPHER_LIST);
- THROW_EXCEPTION(ServerException, TLSSetCiphersFailed)
+ THROW_EXCEPTION_MESSAGE(ServerException, TLSSetCiphersFailed,
+ "Failed to set cipher list to " << CIPHER_LIST << ": " <<
+ CryptoUtils::LogError("setting cipher list"));
}
}
diff --git a/lib/server/TLSContext.h b/lib/server/TLSContext.h
index f52f5457..6239d136 100644
--- a/lib/server/TLSContext.h
+++ b/lib/server/TLSContext.h
@@ -30,7 +30,8 @@ public:
private:
TLSContext(const TLSContext &);
public:
- void Initialise(bool AsServer, const char *CertificatesFile, const char *PrivateKeyFile, const char *TrustedCAsFile);
+ void Initialise(bool AsServer, const char *CertificatesFile, const char *PrivateKeyFile,
+ const char *TrustedCAsFile, int SSLSecurityLevel = -1);
SSL_CTX *GetRawContext() const;
private:
diff --git a/lib/win32/getopt_long.cpp b/lib/win32/getopt_long.cpp
index af2833a1..825de2a0 100755
--- a/lib/win32/getopt_long.cpp
+++ b/lib/win32/getopt_long.cpp
@@ -1,546 +1,546 @@
-/* $OpenBSD: getopt_long.c,v 1.20 2005/10/25 15:49:37 jmc Exp $ */
-/* $NetBSD: getopt_long.c,v 1.15 2002/01/31 22:43:40 tv Exp $ */
-// Adapted for Box Backup by Chris Wilson <chris+boxbackup@qwirx.com>
-
-/*
- * Copyright (c) 2002 Todd C. Miller <Todd.Miller@courtesan.com>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Sponsored in part by the Defense Advanced Research Projects
- * Agency (DARPA) and Air Force Research Laboratory, Air Force
- * Materiel Command, USAF, under agreement number F39502-99-1-0512.
- */
-/*-
- * Copyright (c) 2000 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Dieter Baron and Thomas Klausner.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-// #include "Box.h"
-#include "emu.h"
-
-#include <errno.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "box_getopt.h"
-
-#ifdef REPLACE_GETOPT // until end of file
-
-int opterr = 1; /* if error message should be printed */
-int optind = 1; /* index into parent argv vector */
-int optopt = '?'; /* character checked for validity */
-int optreset; /* reset getopt */
-char *optarg; /* argument associated with option */
-
-#define PRINT_ERROR ((opterr) && (*options != ':'))
-
-#define FLAG_PERMUTE 0x01 /* permute non-options to the end of argv */
-#define FLAG_ALLARGS 0x02 /* treat non-options as args to option "-1" */
-#define FLAG_LONGONLY 0x04 /* operate as getopt_long_only */
-
-/* return values */
-#define BADCH (int)'?'
-#define BADARG ((*options == ':') ? (int)':' : (int)'?')
-#define INORDER (int)1
-
-#define EMSG ""
-
-static void warnx(const char* fmt, ...)
-{
- va_list ap;
- va_start(ap, fmt);
- vfprintf(stderr, fmt, ap);
- va_end(ap);
- fprintf(stderr, "\n");
-}
-
-static int getopt_internal(int, char * const *, const char *,
- const struct option *, int *, int);
-static int parse_long_options(char * const *, const char *,
- const struct option *, int *, int);
-static int gcd(int, int);
-static void permute_args(int, int, int, char * const *);
-
-static char *place = EMSG; /* option letter processing */
-
-/* XXX: set optreset to 1 rather than these two */
-static int nonopt_start = -1; /* first non option argument (for permute) */
-static int nonopt_end = -1; /* first option after non options (for permute) */
-
-/* Error messages */
-static const char recargchar[] = "option requires an argument -- %c";
-static const char recargstring[] = "option requires an argument -- %s";
-static const char ambig[] = "ambiguous option -- %.*s";
-static const char noarg[] = "option doesn't take an argument -- %.*s";
-static const char illoptchar[] = "unknown option -- %c";
-static const char illoptstring[] = "unknown option -- %s";
-
-/*
- * Compute the greatest common divisor of a and b.
- */
-static int
-gcd(int a, int b)
-{
- int c;
-
- c = a % b;
- while (c != 0) {
- a = b;
- b = c;
- c = a % b;
- }
-
- return (b);
-}
-
-/*
- * Exchange the block from nonopt_start to nonopt_end with the block
- * from nonopt_end to opt_end (keeping the same order of arguments
- * in each block).
- */
-static void
-permute_args(int panonopt_start, int panonopt_end, int opt_end,
- char * const *nargv)
-{
- int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos;
- char *swap;
-
- /*
- * compute lengths of blocks and number and size of cycles
- */
- nnonopts = panonopt_end - panonopt_start;
- nopts = opt_end - panonopt_end;
- ncycle = gcd(nnonopts, nopts);
- cyclelen = (opt_end - panonopt_start) / ncycle;
-
- for (i = 0; i < ncycle; i++) {
- cstart = panonopt_end+i;
- pos = cstart;
- for (j = 0; j < cyclelen; j++) {
- if (pos >= panonopt_end)
- pos -= nnonopts;
- else
- pos += nopts;
- swap = nargv[pos];
- /* LINTED const cast */
- ((char **) nargv)[pos] = nargv[cstart];
- /* LINTED const cast */
- ((char **)nargv)[cstart] = swap;
- }
- }
-}
-
-/*
- * parse_long_options --
- * Parse long options in argc/argv argument vector.
- * Returns -1 if short_too is set and the option does not match long_options.
- */
-static int
-parse_long_options(char * const *nargv, const char *options,
- const struct option *long_options, int *idx, int short_too)
-{
- char *current_argv, *has_equal;
- size_t current_argv_len;
- int i, match;
-
- current_argv = place;
- match = -1;
-
- optind++;
-
- if ((has_equal = strchr(current_argv, '=')) != NULL) {
- /* argument found (--option=arg) */
- current_argv_len = has_equal - current_argv;
- has_equal++;
- } else
- current_argv_len = strlen(current_argv);
-
- for (i = 0; long_options[i].name; i++) {
- /* find matching long option */
- if (strncmp(current_argv, long_options[i].name,
- current_argv_len))
- continue;
-
- if (strlen(long_options[i].name) == current_argv_len) {
- /* exact match */
- match = i;
- break;
- }
- /*
- * If this is a known short option, don't allow
- * a partial match of a single character.
- */
- if (short_too && current_argv_len == 1)
- continue;
-
- if (match == -1) /* partial match */
- match = i;
- else {
- /* ambiguous abbreviation */
- if (PRINT_ERROR)
- warnx(ambig, (int)current_argv_len,
- current_argv);
- optopt = 0;
- return (BADCH);
- }
- }
- if (match != -1) { /* option found */
- if (long_options[match].has_arg == no_argument
- && has_equal) {
- if (PRINT_ERROR)
- warnx(noarg, (int)current_argv_len,
- current_argv);
- /*
- * XXX: GNU sets optopt to val regardless of flag
- */
- if (long_options[match].flag == NULL)
- optopt = long_options[match].val;
- else
- optopt = 0;
- return (BADARG);
- }
- if (long_options[match].has_arg == required_argument ||
- long_options[match].has_arg == optional_argument) {
- if (has_equal)
- optarg = has_equal;
- else if (long_options[match].has_arg ==
- required_argument) {
- /*
- * optional argument doesn't use next nargv
- */
- optarg = nargv[optind++];
- }
- }
- if ((long_options[match].has_arg == required_argument)
- && (optarg == NULL)) {
- /*
- * Missing argument; leading ':' indicates no error
- * should be generated.
- */
- if (PRINT_ERROR)
- warnx(recargstring,
- current_argv);
- /*
- * XXX: GNU sets optopt to val regardless of flag
- */
- if (long_options[match].flag == NULL)
- optopt = long_options[match].val;
- else
- optopt = 0;
- --optind;
- return (BADARG);
- }
- } else { /* unknown option */
- if (short_too) {
- --optind;
- return (-1);
- }
- if (PRINT_ERROR)
- warnx(illoptstring, current_argv);
- optopt = 0;
- return (BADCH);
- }
- if (idx)
- *idx = match;
- if (long_options[match].flag) {
- *long_options[match].flag = long_options[match].val;
- return (0);
- } else
- return (long_options[match].val);
-}
-
-/*
- * getopt_internal --
- * Parse argc/argv argument vector. Called by user level routines.
- */
-static int
-getopt_internal(int nargc, char * const *nargv, const char *options,
- const struct option *long_options, int *idx, int flags)
-{
- const char * oli; /* option letter list index */
- int optchar, short_too;
- static int posixly_correct = -1;
-
- if (options == NULL)
- return (-1);
-
- /*
- * Disable GNU extensions if POSIXLY_CORRECT is set or options
- * string begins with a '+'.
- */
- if (posixly_correct == -1)
- posixly_correct = (getenv("POSIXLY_CORRECT") != NULL);
- if (posixly_correct || *options == '+')
- flags &= ~FLAG_PERMUTE;
- else if (*options == '-')
- flags |= FLAG_ALLARGS;
- if (*options == '+' || *options == '-')
- options++;
-
- /*
- * XXX Some GNU programs (like cvs) set optind to 0 instead of
- * XXX using optreset. Work around this braindamage.
- */
- if (optind == 0)
- optind = optreset = 1;
-
- optarg = NULL;
- if (optreset)
- nonopt_start = nonopt_end = -1;
-start:
- if (optreset || !*place) { /* update scanning pointer */
- optreset = 0;
- if (optind >= nargc) { /* end of argument vector */
- place = EMSG;
- if (nonopt_end != -1) {
- /* do permutation, if we have to */
- permute_args(nonopt_start, nonopt_end,
- optind, nargv);
- optind -= nonopt_end - nonopt_start;
- }
- else if (nonopt_start != -1) {
- /*
- * If we skipped non-options, set optind
- * to the first of them.
- */
- optind = nonopt_start;
- }
- nonopt_start = nonopt_end = -1;
- return (-1);
- }
- if (*(place = nargv[optind]) != '-' ||
- (place[1] == '\0' && strchr(options, '-') == NULL)) {
- place = EMSG; /* found non-option */
- if (flags & FLAG_ALLARGS) {
- /*
- * GNU extension:
- * return non-option as argument to option 1
- */
- optarg = nargv[optind++];
- return (INORDER);
- }
- if (!(flags & FLAG_PERMUTE)) {
- /*
- * If no permutation wanted, stop parsing
- * at first non-option.
- */
- return (-1);
- }
- /* do permutation */
- if (nonopt_start == -1)
- nonopt_start = optind;
- else if (nonopt_end != -1) {
- permute_args(nonopt_start, nonopt_end,
- optind, nargv);
- nonopt_start = optind -
- (nonopt_end - nonopt_start);
- nonopt_end = -1;
- }
- optind++;
- /* process next argument */
- goto start;
- }
- if (nonopt_start != -1 && nonopt_end == -1)
- nonopt_end = optind;
-
- /*
- * If we have "-" do nothing, if "--" we are done.
- */
- if (place[1] != '\0' && *++place == '-' && place[1] == '\0') {
- optind++;
- place = EMSG;
- /*
- * We found an option (--), so if we skipped
- * non-options, we have to permute.
- */
- if (nonopt_end != -1) {
- permute_args(nonopt_start, nonopt_end,
- optind, nargv);
- optind -= nonopt_end - nonopt_start;
- }
- nonopt_start = nonopt_end = -1;
- return (-1);
- }
- }
-
- /*
- * Check long options if:
- * 1) we were passed some
- * 2) the arg is not just "-"
- * 3) either the arg starts with -- we are getopt_long_only()
- */
- if (long_options != NULL && place != nargv[optind] &&
- (*place == '-' || (flags & FLAG_LONGONLY))) {
- short_too = 0;
- if (*place == '-')
- place++; /* --foo long option */
- else if (*place != ':' && strchr(options, *place) != NULL)
- short_too = 1; /* could be short option too */
-
- optchar = parse_long_options(nargv, options, long_options,
- idx, short_too);
- if (optchar != -1) {
- place = EMSG;
- return (optchar);
- }
- }
-
- if ((optchar = (int)*place++) == (int)':' ||
- optchar == (int)'-' && *place != '\0' ||
- (oli = strchr(options, optchar)) == NULL) {
- /*
- * If the user specified "-" and '-' isn't listed in
- * options, return -1 (non-option) as per POSIX.
- * Otherwise, it is an unknown option character (or ':').
- */
- if (optchar == (int)'-' && *place == '\0')
- return (-1);
- if (!*place)
- ++optind;
- if (PRINT_ERROR)
- warnx(illoptchar, optchar);
- optopt = optchar;
- return (BADCH);
- }
- if (long_options != NULL && optchar == 'W' && oli[1] == ';') {
- /* -W long-option */
- if (*place) /* no space */
- /* NOTHING */;
- else if (++optind >= nargc) { /* no arg */
- place = EMSG;
- if (PRINT_ERROR)
- warnx(recargchar, optchar);
- optopt = optchar;
- return (BADARG);
- } else /* white space */
- place = nargv[optind];
- optchar = parse_long_options(nargv, options, long_options,
- idx, 0);
- place = EMSG;
- return (optchar);
- }
- if (*++oli != ':') { /* doesn't take argument */
- if (!*place)
- ++optind;
- } else { /* takes (optional) argument */
- optarg = NULL;
- if (*place) /* no white space */
- optarg = place;
- /* XXX: disable test for :: if PC? (GNU doesn't) */
- else if (oli[1] != ':') { /* arg not optional */
- if (++optind >= nargc) { /* no arg */
- place = EMSG;
- if (PRINT_ERROR)
- warnx(recargchar, optchar);
- optopt = optchar;
- return (BADARG);
- } else
- optarg = nargv[optind];
- } else if (!(flags & FLAG_PERMUTE)) {
- /*
- * If permutation is disabled, we can accept an
- * optional arg separated by whitespace so long
- * as it does not start with a dash (-).
- */
- if (optind + 1 < nargc && *nargv[optind + 1] != '-')
- optarg = nargv[++optind];
- }
- place = EMSG;
- ++optind;
- }
- /* dump back option letter */
- return (optchar);
-}
-
-/*
- * getopt --
- * Parse argc/argv argument vector.
- *
- * [eventually this will replace the BSD getopt]
- */
-int
-getopt(int nargc, char * const *nargv, const char *options)
-{
-
- /*
- * We don't pass FLAG_PERMUTE to getopt_internal() since
- * the BSD getopt(3) (unlike GNU) has never done this.
- *
- * Furthermore, since many privileged programs call getopt()
- * before dropping privileges it makes sense to keep things
- * as simple (and bug-free) as possible.
- */
- return (getopt_internal(nargc, nargv, options, NULL, NULL, 0));
-}
-
-/*
- * getopt_long --
- * Parse argc/argv argument vector.
- */
-int
-getopt_long(int nargc, char * const *nargv, const char *options,
- const struct option *long_options, int *idx)
-{
-
- return (getopt_internal(nargc, nargv, options, long_options, idx,
- FLAG_PERMUTE));
-}
-
-/*
- * getopt_long_only --
- * Parse argc/argv argument vector.
- */
-int
-getopt_long_only(int nargc, char * const *nargv, const char *options,
- const struct option *long_options, int *idx)
-{
-
- return (getopt_internal(nargc, nargv, options, long_options, idx,
- FLAG_PERMUTE|FLAG_LONGONLY));
-}
-
-#endif // REPLACE_GETOPT
+/* $OpenBSD: getopt_long.c,v 1.20 2005/10/25 15:49:37 jmc Exp $ */
+/* $NetBSD: getopt_long.c,v 1.15 2002/01/31 22:43:40 tv Exp $ */
+// Adapted for Box Backup by Chris Wilson <chris+boxbackup@qwirx.com>
+
+/*
+ * Copyright (c) 2002 Todd C. Miller <Todd.Miller@courtesan.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
+ */
+/*-
+ * Copyright (c) 2000 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Dieter Baron and Thomas Klausner.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// #include "Box.h"
+#include "emu.h"
+
+#include <errno.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "box_getopt.h"
+
+#ifdef REPLACE_GETOPT // until end of file
+
+int opterr = 1; /* if error message should be printed */
+int optind = 1; /* index into parent argv vector */
+int optopt = '?'; /* character checked for validity */
+int optreset; /* reset getopt */
+char *optarg; /* argument associated with option */
+
+#define PRINT_ERROR ((opterr) && (*options != ':'))
+
+#define FLAG_PERMUTE 0x01 /* permute non-options to the end of argv */
+#define FLAG_ALLARGS 0x02 /* treat non-options as args to option "-1" */
+#define FLAG_LONGONLY 0x04 /* operate as getopt_long_only */
+
+/* return values */
+#define BADCH (int)'?'
+#define BADARG ((*options == ':') ? (int)':' : (int)'?')
+#define INORDER (int)1
+
+#define EMSG ""
+
+static void warnx(const char* fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ fprintf(stderr, "\n");
+}
+
+static int getopt_internal(int, char * const *, const char *,
+ const struct option *, int *, int);
+static int parse_long_options(char * const *, const char *,
+ const struct option *, int *, int);
+static int gcd(int, int);
+static void permute_args(int, int, int, char * const *);
+
+static char *place = EMSG; /* option letter processing */
+
+/* XXX: set optreset to 1 rather than these two */
+static int nonopt_start = -1; /* first non option argument (for permute) */
+static int nonopt_end = -1; /* first option after non options (for permute) */
+
+/* Error messages */
+static const char recargchar[] = "option requires an argument -- %c";
+static const char recargstring[] = "option requires an argument -- %s";
+static const char ambig[] = "ambiguous option -- %.*s";
+static const char noarg[] = "option doesn't take an argument -- %.*s";
+static const char illoptchar[] = "unknown option -- %c";
+static const char illoptstring[] = "unknown option -- %s";
+
+/*
+ * Compute the greatest common divisor of a and b.
+ */
+static int
+gcd(int a, int b)
+{
+ int c;
+
+ c = a % b;
+ while (c != 0) {
+ a = b;
+ b = c;
+ c = a % b;
+ }
+
+ return (b);
+}
+
+/*
+ * Exchange the block from nonopt_start to nonopt_end with the block
+ * from nonopt_end to opt_end (keeping the same order of arguments
+ * in each block).
+ */
+static void
+permute_args(int panonopt_start, int panonopt_end, int opt_end,
+ char * const *nargv)
+{
+ int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos;
+ char *swap;
+
+ /*
+ * compute lengths of blocks and number and size of cycles
+ */
+ nnonopts = panonopt_end - panonopt_start;
+ nopts = opt_end - panonopt_end;
+ ncycle = gcd(nnonopts, nopts);
+ cyclelen = (opt_end - panonopt_start) / ncycle;
+
+ for (i = 0; i < ncycle; i++) {
+ cstart = panonopt_end+i;
+ pos = cstart;
+ for (j = 0; j < cyclelen; j++) {
+ if (pos >= panonopt_end)
+ pos -= nnonopts;
+ else
+ pos += nopts;
+ swap = nargv[pos];
+ /* LINTED const cast */
+ ((char **) nargv)[pos] = nargv[cstart];
+ /* LINTED const cast */
+ ((char **)nargv)[cstart] = swap;
+ }
+ }
+}
+
+/*
+ * parse_long_options --
+ * Parse long options in argc/argv argument vector.
+ * Returns -1 if short_too is set and the option does not match long_options.
+ */
+static int
+parse_long_options(char * const *nargv, const char *options,
+ const struct option *long_options, int *idx, int short_too)
+{
+ char *current_argv, *has_equal;
+ size_t current_argv_len;
+ int i, match;
+
+ current_argv = place;
+ match = -1;
+
+ optind++;
+
+ if ((has_equal = strchr(current_argv, '=')) != NULL) {
+ /* argument found (--option=arg) */
+ current_argv_len = has_equal - current_argv;
+ has_equal++;
+ } else
+ current_argv_len = strlen(current_argv);
+
+ for (i = 0; long_options[i].name; i++) {
+ /* find matching long option */
+ if (strncmp(current_argv, long_options[i].name,
+ current_argv_len))
+ continue;
+
+ if (strlen(long_options[i].name) == current_argv_len) {
+ /* exact match */
+ match = i;
+ break;
+ }
+ /*
+ * If this is a known short option, don't allow
+ * a partial match of a single character.
+ */
+ if (short_too && current_argv_len == 1)
+ continue;
+
+ if (match == -1) /* partial match */
+ match = i;
+ else {
+ /* ambiguous abbreviation */
+ if (PRINT_ERROR)
+ warnx(ambig, (int)current_argv_len,
+ current_argv);
+ optopt = 0;
+ return (BADCH);
+ }
+ }
+ if (match != -1) { /* option found */
+ if (long_options[match].has_arg == no_argument
+ && has_equal) {
+ if (PRINT_ERROR)
+ warnx(noarg, (int)current_argv_len,
+ current_argv);
+ /*
+ * XXX: GNU sets optopt to val regardless of flag
+ */
+ if (long_options[match].flag == NULL)
+ optopt = long_options[match].val;
+ else
+ optopt = 0;
+ return (BADARG);
+ }
+ if (long_options[match].has_arg == required_argument ||
+ long_options[match].has_arg == optional_argument) {
+ if (has_equal)
+ optarg = has_equal;
+ else if (long_options[match].has_arg ==
+ required_argument) {
+ /*
+ * optional argument doesn't use next nargv
+ */
+ optarg = nargv[optind++];
+ }
+ }
+ if ((long_options[match].has_arg == required_argument)
+ && (optarg == NULL)) {
+ /*
+ * Missing argument; leading ':' indicates no error
+ * should be generated.
+ */
+ if (PRINT_ERROR)
+ warnx(recargstring,
+ current_argv);
+ /*
+ * XXX: GNU sets optopt to val regardless of flag
+ */
+ if (long_options[match].flag == NULL)
+ optopt = long_options[match].val;
+ else
+ optopt = 0;
+ --optind;
+ return (BADARG);
+ }
+ } else { /* unknown option */
+ if (short_too) {
+ --optind;
+ return (-1);
+ }
+ if (PRINT_ERROR)
+ warnx(illoptstring, current_argv);
+ optopt = 0;
+ return (BADCH);
+ }
+ if (idx)
+ *idx = match;
+ if (long_options[match].flag) {
+ *long_options[match].flag = long_options[match].val;
+ return (0);
+ } else
+ return (long_options[match].val);
+}
+
+/*
+ * getopt_internal --
+ * Parse argc/argv argument vector. Called by user level routines.
+ */
+static int
+getopt_internal(int nargc, char * const *nargv, const char *options,
+ const struct option *long_options, int *idx, int flags)
+{
+ const char * oli; /* option letter list index */
+ int optchar, short_too;
+ static int posixly_correct = -1;
+
+ if (options == NULL)
+ return (-1);
+
+ /*
+ * Disable GNU extensions if POSIXLY_CORRECT is set or options
+ * string begins with a '+'.
+ */
+ if (posixly_correct == -1)
+ posixly_correct = (getenv("POSIXLY_CORRECT") != NULL);
+ if (posixly_correct || *options == '+')
+ flags &= ~FLAG_PERMUTE;
+ else if (*options == '-')
+ flags |= FLAG_ALLARGS;
+ if (*options == '+' || *options == '-')
+ options++;
+
+ /*
+ * XXX Some GNU programs (like cvs) set optind to 0 instead of
+ * XXX using optreset. Work around this braindamage.
+ */
+ if (optind == 0)
+ optind = optreset = 1;
+
+ optarg = NULL;
+ if (optreset)
+ nonopt_start = nonopt_end = -1;
+start:
+ if (optreset || !*place) { /* update scanning pointer */
+ optreset = 0;
+ if (optind >= nargc) { /* end of argument vector */
+ place = EMSG;
+ if (nonopt_end != -1) {
+ /* do permutation, if we have to */
+ permute_args(nonopt_start, nonopt_end,
+ optind, nargv);
+ optind -= nonopt_end - nonopt_start;
+ }
+ else if (nonopt_start != -1) {
+ /*
+ * If we skipped non-options, set optind
+ * to the first of them.
+ */
+ optind = nonopt_start;
+ }
+ nonopt_start = nonopt_end = -1;
+ return (-1);
+ }
+ if (*(place = nargv[optind]) != '-' ||
+ (place[1] == '\0' && strchr(options, '-') == NULL)) {
+ place = EMSG; /* found non-option */
+ if (flags & FLAG_ALLARGS) {
+ /*
+ * GNU extension:
+ * return non-option as argument to option 1
+ */
+ optarg = nargv[optind++];
+ return (INORDER);
+ }
+ if (!(flags & FLAG_PERMUTE)) {
+ /*
+ * If no permutation wanted, stop parsing
+ * at first non-option.
+ */
+ return (-1);
+ }
+ /* do permutation */
+ if (nonopt_start == -1)
+ nonopt_start = optind;
+ else if (nonopt_end != -1) {
+ permute_args(nonopt_start, nonopt_end,
+ optind, nargv);
+ nonopt_start = optind -
+ (nonopt_end - nonopt_start);
+ nonopt_end = -1;
+ }
+ optind++;
+ /* process next argument */
+ goto start;
+ }
+ if (nonopt_start != -1 && nonopt_end == -1)
+ nonopt_end = optind;
+
+ /*
+ * If we have "-" do nothing, if "--" we are done.
+ */
+ if (place[1] != '\0' && *++place == '-' && place[1] == '\0') {
+ optind++;
+ place = EMSG;
+ /*
+ * We found an option (--), so if we skipped
+ * non-options, we have to permute.
+ */
+ if (nonopt_end != -1) {
+ permute_args(nonopt_start, nonopt_end,
+ optind, nargv);
+ optind -= nonopt_end - nonopt_start;
+ }
+ nonopt_start = nonopt_end = -1;
+ return (-1);
+ }
+ }
+
+ /*
+ * Check long options if:
+ * 1) we were passed some
+ * 2) the arg is not just "-"
+ * 3) either the arg starts with -- we are getopt_long_only()
+ */
+ if (long_options != NULL && place != nargv[optind] &&
+ (*place == '-' || (flags & FLAG_LONGONLY))) {
+ short_too = 0;
+ if (*place == '-')
+ place++; /* --foo long option */
+ else if (*place != ':' && strchr(options, *place) != NULL)
+ short_too = 1; /* could be short option too */
+
+ optchar = parse_long_options(nargv, options, long_options,
+ idx, short_too);
+ if (optchar != -1) {
+ place = EMSG;
+ return (optchar);
+ }
+ }
+
+ if ((optchar = (int)*place++) == (int)':' ||
+ optchar == (int)'-' && *place != '\0' ||
+ (oli = strchr(options, optchar)) == NULL) {
+ /*
+ * If the user specified "-" and '-' isn't listed in
+ * options, return -1 (non-option) as per POSIX.
+ * Otherwise, it is an unknown option character (or ':').
+ */
+ if (optchar == (int)'-' && *place == '\0')
+ return (-1);
+ if (!*place)
+ ++optind;
+ if (PRINT_ERROR)
+ warnx(illoptchar, optchar);
+ optopt = optchar;
+ return (BADCH);
+ }
+ if (long_options != NULL && optchar == 'W' && oli[1] == ';') {
+ /* -W long-option */
+ if (*place) /* no space */
+ /* NOTHING */;
+ else if (++optind >= nargc) { /* no arg */
+ place = EMSG;
+ if (PRINT_ERROR)
+ warnx(recargchar, optchar);
+ optopt = optchar;
+ return (BADARG);
+ } else /* white space */
+ place = nargv[optind];
+ optchar = parse_long_options(nargv, options, long_options,
+ idx, 0);
+ place = EMSG;
+ return (optchar);
+ }
+ if (*++oli != ':') { /* doesn't take argument */
+ if (!*place)
+ ++optind;
+ } else { /* takes (optional) argument */
+ optarg = NULL;
+ if (*place) /* no white space */
+ optarg = place;
+ /* XXX: disable test for :: if PC? (GNU doesn't) */
+ else if (oli[1] != ':') { /* arg not optional */
+ if (++optind >= nargc) { /* no arg */
+ place = EMSG;
+ if (PRINT_ERROR)
+ warnx(recargchar, optchar);
+ optopt = optchar;
+ return (BADARG);
+ } else
+ optarg = nargv[optind];
+ } else if (!(flags & FLAG_PERMUTE)) {
+ /*
+ * If permutation is disabled, we can accept an
+ * optional arg separated by whitespace so long
+ * as it does not start with a dash (-).
+ */
+ if (optind + 1 < nargc && *nargv[optind + 1] != '-')
+ optarg = nargv[++optind];
+ }
+ place = EMSG;
+ ++optind;
+ }
+ /* dump back option letter */
+ return (optchar);
+}
+
+/*
+ * getopt --
+ * Parse argc/argv argument vector.
+ *
+ * [eventually this will replace the BSD getopt]
+ */
+int
+getopt(int nargc, char * const *nargv, const char *options)
+{
+
+ /*
+ * We don't pass FLAG_PERMUTE to getopt_internal() since
+ * the BSD getopt(3) (unlike GNU) has never done this.
+ *
+ * Furthermore, since many privileged programs call getopt()
+ * before dropping privileges it makes sense to keep things
+ * as simple (and bug-free) as possible.
+ */
+ return (getopt_internal(nargc, nargv, options, NULL, NULL, 0));
+}
+
+/*
+ * getopt_long --
+ * Parse argc/argv argument vector.
+ */
+int
+getopt_long(int nargc, char * const *nargv, const char *options,
+ const struct option *long_options, int *idx)
+{
+
+ return (getopt_internal(nargc, nargv, options, long_options, idx,
+ FLAG_PERMUTE));
+}
+
+/*
+ * getopt_long_only --
+ * Parse argc/argv argument vector.
+ */
+int
+getopt_long_only(int nargc, char * const *nargv, const char *options,
+ const struct option *long_options, int *idx)
+{
+
+ return (getopt_internal(nargc, nargv, options, long_options, idx,
+ FLAG_PERMUTE|FLAG_LONGONLY));
+}
+
+#endif // REPLACE_GETOPT
diff --git a/lib/win32/messages.rc b/lib/win32/messages.rc
index 116522b7..0885a897 100755
--- a/lib/win32/messages.rc
+++ b/lib/win32/messages.rc
@@ -1,2 +1,2 @@
-LANGUAGE 0x9,0x1
-1 11 MSG00001.bin
+LANGUAGE 0x9,0x1
+1 11 MSG00001.bin
diff --git a/qdbm/VCmakefile b/qdbm/VCmakefile
index 210a98ff..e37275c9 100644
--- a/qdbm/VCmakefile
+++ b/qdbm/VCmakefile
@@ -1,248 +1,248 @@
-# Makefile to build QDBM using Microsoft Visual C++
-
-
-
-#================================================================
-# Setting variables
-#================================================================
-
-
-# VC++ directory
-VCPATH = C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7
-
-# User options
-YOUR_CLFLAGS =
-YOUR_LIBFLAGS =
-YOUR_LINKFLAGS=
-
-# Configurations
-!IF "$(CFG)" == "ld"
-!MESSAGE Build using static debug configuration
-BASE_FLAGS = /MLd /W3 /ZI /Od /FD /GZ /Fo"$(OUTDIR)\\" /Fd"$(OUTDIR)\\"
-BASE_DEFS = /D_DEBUG /D__DEBUG__
-OUTDIR = .\tmp_ld
-LIB_APPEND = _ld
-EXE_APPEND = _ld
-!ELSEIF "$(CFG)" == "l"
-!MESSAGE Build using static release configuration
-BASE_DEFS = /DNDEBUG
-BASE_FLAGS = /ML /W3 /O2 /FD /Fo"$(OUTDIR)\\" /Fd"$(OUTDIR)\\"
-OUTDIR = .\tmp_l
-LIB_APPEND = _l
-EXE_APPEND = _l
-!ELSEIF "$(CFG)" == "td"
-!MESSAGE Build using static threaded debug configuration
-BASE_FLAGS = /MTd /W3 /ZI /Od /FD /GZ /Fo"$(OUTDIR)\\" /Fd"$(OUTDIR)\\"
-BASE_DEFS = /D_DEBUG /D__DEBUG__
-OUTDIR = .\tmp_td
-LIB_APPEND = _td
-EXE_APPEND = _td
-!ELSEIF "$(CFG)" == "t"
-!MESSAGE Build using static threaded release configuration
-BASE_DEFS = /DNDEBUG
-BASE_FLAGS = /MT /W3 /O2 /FD /Fo"$(OUTDIR)\\" /Fd"$(OUTDIR)\\"
-OUTDIR = .\tmp_t
-LIB_APPEND = _t
-EXE_APPEND = _t
-!ELSEIF "$(CFG)" == "dd"
-!MESSAGE Build using dynamic threaded debug configuration
-BASE_FLAGS = /MDd /W3 /ZI /Od /FD /GZ /Fo"$(OUTDIR)\\" /Fd"$(OUTDIR)\\"
-BASE_DEFS = /D_DEBUG /D__DEBUG__
-OUTDIR = .\tmp_dd
-LIB_APPEND = _dd
-EXE_APPEND = _dd
-!ELSE
-!MESSAGE Build using dynamic threaded release configuration
-BASE_DEFS = /DNDEBUG
-BASE_FLAGS = /MD /W3 /O2 /FD /Fo"$(OUTDIR)\\" /Fd"$(OUTDIR)\\"
-OUTDIR = .\tmp
-LIB_APPEND =
-EXE_APPEND =
-!ENDIF
-
-# Building binaries
-CLFLAGS = /I "$(VCPATH)\Include" /I "$(VCPATH)\PlatformSDK\Include" /I "." \
- /nologo $(YOUR_CLFLAGS) $(BASE_FLAGS) $(BASE_DEFS) /D_CRT_SECURE_NO_DEPRECATE=1
-LIBFLAGS = /libpath:"$(VCPATH)\lib" /libpath:"$(VCPATH)\PlatformSDK\Lib" /libpath:"." \
- /nologo $(YOUR_LIBFLAGS)
-LINKFLAGS = /libpath:"$(VCPATH)\lib" /libpath:"$(VCPATH)\PlatformSDK\Lib" /libpath:"." \
- /nologo $(YOUR_LINKFLAGS)
-
-# Targets
-MYLIBS = qdbm$(LIB_APPEND).dll qdbm$(LIB_APPEND).lib qdbm$(LIB_APPEND)_static.lib
-LIBOBJS = $(OUTDIR)\depot.obj $(OUTDIR)\curia.obj $(OUTDIR)\relic.obj \
- $(OUTDIR)\hovel.obj $(OUTDIR)\cabin.obj $(OUTDIR)\villa.obj \
- $(OUTDIR)\vista.obj $(OUTDIR)\odeum.obj $(OUTDIR)\myconf.obj
-MYBINS = dpmgr$(EXE_APPEND).exe dptest$(EXE_APPEND).exe dptsv$(EXE_APPEND).exe \
- crmgr$(EXE_APPEND).exe crtest$(EXE_APPEND).exe crtsv$(EXE_APPEND).exe \
- rlmgr$(EXE_APPEND).exe rltest$(EXE_APPEND).exe hvmgr$(EXE_APPEND).exe \
- hvtest$(EXE_APPEND).exe cbtest$(EXE_APPEND).exe cbcodec$(EXE_APPEND).exe \
- vlmgr$(EXE_APPEND).exe vltest$(EXE_APPEND).exe vltsv$(EXE_APPEND).exe \
- odmgr$(EXE_APPEND).exe odtest$(EXE_APPEND).exe odidx$(EXE_APPEND).exe
-
-
-
-#================================================================
-# Suffix rules
-#================================================================
-
-
-.SUFFIXES :
-.SUFFIXES : .c .obj
-
-.c{$(OUTDIR)}.obj :
- cl /c $(CLFLAGS) $<
-
-.c.obj:
- cl /c $(CLFLAGS) $<
-
-
-
-#================================================================
-# Actions
-#================================================================
-
-
-all : $(OUTDIR) $(MYLIBS) $(MYBINS)
-
-
-allcfg:
- nmake /NOLOGO /f VCmakefile CFG=ld
- nmake /NOLOGO /f VCmakefile CFG=l
- nmake /NOLOGO /f VCmakefile CFG=td
- nmake /NOLOGO /f VCmakefile CFG=t
- nmake /NOLOGO /f VCmakefile CFG=dd
- nmake /NOLOGO /f VCmakefile
-
-
-clean :
- -rd tmp_ld /S /Q > NUL: 2>&1
- -rd tmp_l /S /Q > NUL: 2>&1
- -rd tmp_td /S /Q > NUL: 2>&1
- -rd tmp_t /S /Q > NUL: 2>&1
- -rd tmp_dd /S /Q > NUL: 2>&1
- -rd tmp /S /Q > NUL: 2>&1
- -del *.obj *.lib *.dll *.exp *.exe casket /F /Q > NUL: 2>&1
-
-
-"$(OUTDIR)" :
- if not exist "$(OUTDIR)/" mkdir "$(OUTDIR)"
-
-
-
-#================================================================
-# Building binaries
-#================================================================
-
-
-qdbm$(LIB_APPEND).dll : $(LIBOBJS) qdbm.def
- link /DLL /DEF:qdbm.def $(LINKFLAGS) /OUT:$@ /IMPLIB:qdbm$(LIB_APPEND).lib $(LIBOBJS)
-
-
-qdbm$(LIB_APPEND).lib : qdbm$(LIB_APPEND).dll
-
-
-qdbm$(LIB_APPEND)_static.lib : $(LIBOBJS)
- lib $(LIBFLAGS) /OUT:$@ $(LIBOBJS)
-
-
-dpmgr$(EXE_APPEND).exe : $(OUTDIR)\dpmgr.obj qdbm$(LIB_APPEND).lib
- link $(LINKFLAGS) /OUT:$@ $(OUTDIR)\dpmgr.obj qdbm$(LIB_APPEND).lib
-
-
-dptest$(EXE_APPEND).exe : $(OUTDIR)\dptest.obj qdbm$(LIB_APPEND).lib
- link $(LINKFLAGS) /OUT:$@ $(OUTDIR)\dptest.obj qdbm$(LIB_APPEND).lib
-
-
-dptsv$(EXE_APPEND).exe : $(OUTDIR)\dptsv.obj qdbm$(LIB_APPEND).lib
- link $(LINKFLAGS) /OUT:$@ $(OUTDIR)\dptsv.obj qdbm$(LIB_APPEND).lib
-
-
-crmgr$(EXE_APPEND).exe : $(OUTDIR)\crmgr.obj qdbm$(LIB_APPEND).lib
- link $(LINKFLAGS) /OUT:$@ $(OUTDIR)\crmgr.obj qdbm$(LIB_APPEND).lib
-
-
-crtest$(EXE_APPEND).exe : $(OUTDIR)\crtest.obj qdbm$(LIB_APPEND).lib
- link $(LINKFLAGS) /OUT:$@ $(OUTDIR)\crtest.obj qdbm$(LIB_APPEND).lib
-
-
-crtsv$(EXE_APPEND).exe : $(OUTDIR)\crtsv.obj qdbm$(LIB_APPEND).lib
- link $(LINKFLAGS) /OUT:$@ $(OUTDIR)\crtsv.obj qdbm$(LIB_APPEND).lib
-
-
-rlmgr$(EXE_APPEND).exe : $(OUTDIR)\rlmgr.obj qdbm$(LIB_APPEND).lib
- link $(LINKFLAGS) /OUT:$@ $(OUTDIR)\rlmgr.obj qdbm$(LIB_APPEND).lib
-
-
-rltest$(EXE_APPEND).exe : $(OUTDIR)\rltest.obj qdbm$(LIB_APPEND).lib
- link $(LINKFLAGS) /OUT:$@ $(OUTDIR)\rltest.obj qdbm$(LIB_APPEND).lib
-
-
-hvmgr$(EXE_APPEND).exe : $(OUTDIR)\hvmgr.obj qdbm$(LIB_APPEND).lib
- link $(LINKFLAGS) /OUT:$@ $(OUTDIR)\hvmgr.obj qdbm$(LIB_APPEND).lib
-
-
-hvtest$(EXE_APPEND).exe : $(OUTDIR)\hvtest.obj qdbm$(LIB_APPEND).lib
- link $(LINKFLAGS) /OUT:$@ $(OUTDIR)\hvtest.obj qdbm$(LIB_APPEND).lib
-
-
-cbtest$(EXE_APPEND).exe : $(OUTDIR)\cbtest.obj qdbm$(LIB_APPEND).lib
- link $(LINKFLAGS) /OUT:$@ $(OUTDIR)\cbtest.obj qdbm$(LIB_APPEND).lib
-
-
-cbcodec$(EXE_APPEND).exe : $(OUTDIR)\cbcodec.obj qdbm$(LIB_APPEND).lib
- link $(LINKFLAGS) /OUT:$@ $(OUTDIR)\cbcodec.obj qdbm$(LIB_APPEND).lib
-
-
-vlmgr$(EXE_APPEND).exe : $(OUTDIR)\vlmgr.obj qdbm$(LIB_APPEND).lib
- link $(LINKFLAGS) /OUT:$@ $(OUTDIR)\vlmgr.obj qdbm$(LIB_APPEND).lib
-
-
-vltest$(EXE_APPEND).exe : $(OUTDIR)\vltest.obj qdbm$(LIB_APPEND).lib
- link $(LINKFLAGS) /OUT:$@ $(OUTDIR)\vltest.obj qdbm$(LIB_APPEND).lib
-
-
-vltsv$(EXE_APPEND).exe : $(OUTDIR)\vltsv.obj qdbm$(LIB_APPEND).lib
- link $(LINKFLAGS) /OUT:$@ $(OUTDIR)\vltsv.obj qdbm$(LIB_APPEND).lib
-
-
-odmgr$(EXE_APPEND).exe : $(OUTDIR)\odmgr.obj qdbm$(LIB_APPEND).lib
- link $(LINKFLAGS) /OUT:$@ $(OUTDIR)\odmgr.obj qdbm$(LIB_APPEND).lib
-
-
-odtest$(EXE_APPEND).exe : $(OUTDIR)\odtest.obj qdbm$(LIB_APPEND).lib
- link $(LINKFLAGS) /OUT:$@ $(OUTDIR)\odtest.obj qdbm$(LIB_APPEND).lib
-
-
-odidx$(EXE_APPEND).exe : $(OUTDIR)\odidx.obj qdbm$(LIB_APPEND).lib
- link $(LINKFLAGS) /OUT:$@ $(OUTDIR)\odidx.obj qdbm$(LIB_APPEND).lib
-
-
-$(OUTDIR)\depot.obj $(OUTDIR)\dpmgr.obj $(OUTDIR)\dptest.obj $(OUTDIR)\dptsv.obj : \
- depot.h myconf.h
-
-$(OUTDIR)\curia.obj $(OUTDIR)\crmgr.obj $(OUTDIR)\crtest.obj $(OUTDIR)\crtsv.obj : \
- curia.h depot.h myconf.h
-
-$(OUTDIR)\relic.obj $(OUTDIR)\rlmgr.obj $(OUTDIR)\rltest.obj : \
- relic.h depot.h myconf.h
-
-$(OUTDIR)\hovel.obj $(OUTDIR)\hvmgr.obj $(OUTDIR)\hvtest.obj : \
- hovel.h depot.h curia.h myconf.h
-
-$(OUTDIR)\cabin.obj $(OUTDIR)\cbtest.obj $(OUTDIR)\cbcodec.obj : \
- cabin.h myconf.h
-
-$(OUTDIR)\villa.obj $(OUTDIR)\vlmgr.obj $(OUTDIR)\vltest.obj $(OUTDIR)\vltsv.obj : \
- villa.h depot.h cabin.h myconf.h
-
-$(OUTDIR)\vista.obj : vista.h villa.h depot.h curia.h cabin.h myconf.h
-
-$(OUTDIR)\odeum.obj $(OUTDIR)\odmgr.obj $(OUTDIR)\odtest.obj $(OUTDIR)\odidx.obj : \
- odeum.h depot.h curia.h cabin.h villa.h myconf.h
-
-$(OUTDIR)\myconf.obj : myconf.h
-
-
-
-# END OF FILE
+# Makefile to build QDBM using Microsoft Visual C++
+
+
+
+#================================================================
+# Setting variables
+#================================================================
+
+
+# VC++ directory
+VCPATH = C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7
+
+# User options
+YOUR_CLFLAGS =
+YOUR_LIBFLAGS =
+YOUR_LINKFLAGS=
+
+# Configurations
+!IF "$(CFG)" == "ld"
+!MESSAGE Build using static debug configuration
+BASE_FLAGS = /MLd /W3 /ZI /Od /FD /GZ /Fo"$(OUTDIR)\\" /Fd"$(OUTDIR)\\"
+BASE_DEFS = /D_DEBUG /D__DEBUG__
+OUTDIR = .\tmp_ld
+LIB_APPEND = _ld
+EXE_APPEND = _ld
+!ELSEIF "$(CFG)" == "l"
+!MESSAGE Build using static release configuration
+BASE_DEFS = /DNDEBUG
+BASE_FLAGS = /ML /W3 /O2 /FD /Fo"$(OUTDIR)\\" /Fd"$(OUTDIR)\\"
+OUTDIR = .\tmp_l
+LIB_APPEND = _l
+EXE_APPEND = _l
+!ELSEIF "$(CFG)" == "td"
+!MESSAGE Build using static threaded debug configuration
+BASE_FLAGS = /MTd /W3 /ZI /Od /FD /GZ /Fo"$(OUTDIR)\\" /Fd"$(OUTDIR)\\"
+BASE_DEFS = /D_DEBUG /D__DEBUG__
+OUTDIR = .\tmp_td
+LIB_APPEND = _td
+EXE_APPEND = _td
+!ELSEIF "$(CFG)" == "t"
+!MESSAGE Build using static threaded release configuration
+BASE_DEFS = /DNDEBUG
+BASE_FLAGS = /MT /W3 /O2 /FD /Fo"$(OUTDIR)\\" /Fd"$(OUTDIR)\\"
+OUTDIR = .\tmp_t
+LIB_APPEND = _t
+EXE_APPEND = _t
+!ELSEIF "$(CFG)" == "dd"
+!MESSAGE Build using dynamic threaded debug configuration
+BASE_FLAGS = /MDd /W3 /ZI /Od /FD /GZ /Fo"$(OUTDIR)\\" /Fd"$(OUTDIR)\\"
+BASE_DEFS = /D_DEBUG /D__DEBUG__
+OUTDIR = .\tmp_dd
+LIB_APPEND = _dd
+EXE_APPEND = _dd
+!ELSE
+!MESSAGE Build using dynamic threaded release configuration
+BASE_DEFS = /DNDEBUG
+BASE_FLAGS = /MD /W3 /O2 /FD /Fo"$(OUTDIR)\\" /Fd"$(OUTDIR)\\"
+OUTDIR = .\tmp
+LIB_APPEND =
+EXE_APPEND =
+!ENDIF
+
+# Building binaries
+CLFLAGS = /I "$(VCPATH)\Include" /I "$(VCPATH)\PlatformSDK\Include" /I "." \
+ /nologo $(YOUR_CLFLAGS) $(BASE_FLAGS) $(BASE_DEFS) /D_CRT_SECURE_NO_DEPRECATE=1
+LIBFLAGS = /libpath:"$(VCPATH)\lib" /libpath:"$(VCPATH)\PlatformSDK\Lib" /libpath:"." \
+ /nologo $(YOUR_LIBFLAGS)
+LINKFLAGS = /libpath:"$(VCPATH)\lib" /libpath:"$(VCPATH)\PlatformSDK\Lib" /libpath:"." \
+ /nologo $(YOUR_LINKFLAGS)
+
+# Targets
+MYLIBS = qdbm$(LIB_APPEND).dll qdbm$(LIB_APPEND).lib qdbm$(LIB_APPEND)_static.lib
+LIBOBJS = $(OUTDIR)\depot.obj $(OUTDIR)\curia.obj $(OUTDIR)\relic.obj \
+ $(OUTDIR)\hovel.obj $(OUTDIR)\cabin.obj $(OUTDIR)\villa.obj \
+ $(OUTDIR)\vista.obj $(OUTDIR)\odeum.obj $(OUTDIR)\myconf.obj
+MYBINS = dpmgr$(EXE_APPEND).exe dptest$(EXE_APPEND).exe dptsv$(EXE_APPEND).exe \
+ crmgr$(EXE_APPEND).exe crtest$(EXE_APPEND).exe crtsv$(EXE_APPEND).exe \
+ rlmgr$(EXE_APPEND).exe rltest$(EXE_APPEND).exe hvmgr$(EXE_APPEND).exe \
+ hvtest$(EXE_APPEND).exe cbtest$(EXE_APPEND).exe cbcodec$(EXE_APPEND).exe \
+ vlmgr$(EXE_APPEND).exe vltest$(EXE_APPEND).exe vltsv$(EXE_APPEND).exe \
+ odmgr$(EXE_APPEND).exe odtest$(EXE_APPEND).exe odidx$(EXE_APPEND).exe
+
+
+
+#================================================================
+# Suffix rules
+#================================================================
+
+
+.SUFFIXES :
+.SUFFIXES : .c .obj
+
+.c{$(OUTDIR)}.obj :
+ cl /c $(CLFLAGS) $<
+
+.c.obj:
+ cl /c $(CLFLAGS) $<
+
+
+
+#================================================================
+# Actions
+#================================================================
+
+
+all : $(OUTDIR) $(MYLIBS) $(MYBINS)
+
+
+allcfg:
+ nmake /NOLOGO /f VCmakefile CFG=ld
+ nmake /NOLOGO /f VCmakefile CFG=l
+ nmake /NOLOGO /f VCmakefile CFG=td
+ nmake /NOLOGO /f VCmakefile CFG=t
+ nmake /NOLOGO /f VCmakefile CFG=dd
+ nmake /NOLOGO /f VCmakefile
+
+
+clean :
+ -rd tmp_ld /S /Q > NUL: 2>&1
+ -rd tmp_l /S /Q > NUL: 2>&1
+ -rd tmp_td /S /Q > NUL: 2>&1
+ -rd tmp_t /S /Q > NUL: 2>&1
+ -rd tmp_dd /S /Q > NUL: 2>&1
+ -rd tmp /S /Q > NUL: 2>&1
+ -del *.obj *.lib *.dll *.exp *.exe casket /F /Q > NUL: 2>&1
+
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/" mkdir "$(OUTDIR)"
+
+
+
+#================================================================
+# Building binaries
+#================================================================
+
+
+qdbm$(LIB_APPEND).dll : $(LIBOBJS) qdbm.def
+ link /DLL /DEF:qdbm.def $(LINKFLAGS) /OUT:$@ /IMPLIB:qdbm$(LIB_APPEND).lib $(LIBOBJS)
+
+
+qdbm$(LIB_APPEND).lib : qdbm$(LIB_APPEND).dll
+
+
+qdbm$(LIB_APPEND)_static.lib : $(LIBOBJS)
+ lib $(LIBFLAGS) /OUT:$@ $(LIBOBJS)
+
+
+dpmgr$(EXE_APPEND).exe : $(OUTDIR)\dpmgr.obj qdbm$(LIB_APPEND).lib
+ link $(LINKFLAGS) /OUT:$@ $(OUTDIR)\dpmgr.obj qdbm$(LIB_APPEND).lib
+
+
+dptest$(EXE_APPEND).exe : $(OUTDIR)\dptest.obj qdbm$(LIB_APPEND).lib
+ link $(LINKFLAGS) /OUT:$@ $(OUTDIR)\dptest.obj qdbm$(LIB_APPEND).lib
+
+
+dptsv$(EXE_APPEND).exe : $(OUTDIR)\dptsv.obj qdbm$(LIB_APPEND).lib
+ link $(LINKFLAGS) /OUT:$@ $(OUTDIR)\dptsv.obj qdbm$(LIB_APPEND).lib
+
+
+crmgr$(EXE_APPEND).exe : $(OUTDIR)\crmgr.obj qdbm$(LIB_APPEND).lib
+ link $(LINKFLAGS) /OUT:$@ $(OUTDIR)\crmgr.obj qdbm$(LIB_APPEND).lib
+
+
+crtest$(EXE_APPEND).exe : $(OUTDIR)\crtest.obj qdbm$(LIB_APPEND).lib
+ link $(LINKFLAGS) /OUT:$@ $(OUTDIR)\crtest.obj qdbm$(LIB_APPEND).lib
+
+
+crtsv$(EXE_APPEND).exe : $(OUTDIR)\crtsv.obj qdbm$(LIB_APPEND).lib
+ link $(LINKFLAGS) /OUT:$@ $(OUTDIR)\crtsv.obj qdbm$(LIB_APPEND).lib
+
+
+rlmgr$(EXE_APPEND).exe : $(OUTDIR)\rlmgr.obj qdbm$(LIB_APPEND).lib
+ link $(LINKFLAGS) /OUT:$@ $(OUTDIR)\rlmgr.obj qdbm$(LIB_APPEND).lib
+
+
+rltest$(EXE_APPEND).exe : $(OUTDIR)\rltest.obj qdbm$(LIB_APPEND).lib
+ link $(LINKFLAGS) /OUT:$@ $(OUTDIR)\rltest.obj qdbm$(LIB_APPEND).lib
+
+
+hvmgr$(EXE_APPEND).exe : $(OUTDIR)\hvmgr.obj qdbm$(LIB_APPEND).lib
+ link $(LINKFLAGS) /OUT:$@ $(OUTDIR)\hvmgr.obj qdbm$(LIB_APPEND).lib
+
+
+hvtest$(EXE_APPEND).exe : $(OUTDIR)\hvtest.obj qdbm$(LIB_APPEND).lib
+ link $(LINKFLAGS) /OUT:$@ $(OUTDIR)\hvtest.obj qdbm$(LIB_APPEND).lib
+
+
+cbtest$(EXE_APPEND).exe : $(OUTDIR)\cbtest.obj qdbm$(LIB_APPEND).lib
+ link $(LINKFLAGS) /OUT:$@ $(OUTDIR)\cbtest.obj qdbm$(LIB_APPEND).lib
+
+
+cbcodec$(EXE_APPEND).exe : $(OUTDIR)\cbcodec.obj qdbm$(LIB_APPEND).lib
+ link $(LINKFLAGS) /OUT:$@ $(OUTDIR)\cbcodec.obj qdbm$(LIB_APPEND).lib
+
+
+vlmgr$(EXE_APPEND).exe : $(OUTDIR)\vlmgr.obj qdbm$(LIB_APPEND).lib
+ link $(LINKFLAGS) /OUT:$@ $(OUTDIR)\vlmgr.obj qdbm$(LIB_APPEND).lib
+
+
+vltest$(EXE_APPEND).exe : $(OUTDIR)\vltest.obj qdbm$(LIB_APPEND).lib
+ link $(LINKFLAGS) /OUT:$@ $(OUTDIR)\vltest.obj qdbm$(LIB_APPEND).lib
+
+
+vltsv$(EXE_APPEND).exe : $(OUTDIR)\vltsv.obj qdbm$(LIB_APPEND).lib
+ link $(LINKFLAGS) /OUT:$@ $(OUTDIR)\vltsv.obj qdbm$(LIB_APPEND).lib
+
+
+odmgr$(EXE_APPEND).exe : $(OUTDIR)\odmgr.obj qdbm$(LIB_APPEND).lib
+ link $(LINKFLAGS) /OUT:$@ $(OUTDIR)\odmgr.obj qdbm$(LIB_APPEND).lib
+
+
+odtest$(EXE_APPEND).exe : $(OUTDIR)\odtest.obj qdbm$(LIB_APPEND).lib
+ link $(LINKFLAGS) /OUT:$@ $(OUTDIR)\odtest.obj qdbm$(LIB_APPEND).lib
+
+
+odidx$(EXE_APPEND).exe : $(OUTDIR)\odidx.obj qdbm$(LIB_APPEND).lib
+ link $(LINKFLAGS) /OUT:$@ $(OUTDIR)\odidx.obj qdbm$(LIB_APPEND).lib
+
+
+$(OUTDIR)\depot.obj $(OUTDIR)\dpmgr.obj $(OUTDIR)\dptest.obj $(OUTDIR)\dptsv.obj : \
+ depot.h myconf.h
+
+$(OUTDIR)\curia.obj $(OUTDIR)\crmgr.obj $(OUTDIR)\crtest.obj $(OUTDIR)\crtsv.obj : \
+ curia.h depot.h myconf.h
+
+$(OUTDIR)\relic.obj $(OUTDIR)\rlmgr.obj $(OUTDIR)\rltest.obj : \
+ relic.h depot.h myconf.h
+
+$(OUTDIR)\hovel.obj $(OUTDIR)\hvmgr.obj $(OUTDIR)\hvtest.obj : \
+ hovel.h depot.h curia.h myconf.h
+
+$(OUTDIR)\cabin.obj $(OUTDIR)\cbtest.obj $(OUTDIR)\cbcodec.obj : \
+ cabin.h myconf.h
+
+$(OUTDIR)\villa.obj $(OUTDIR)\vlmgr.obj $(OUTDIR)\vltest.obj $(OUTDIR)\vltsv.obj : \
+ villa.h depot.h cabin.h myconf.h
+
+$(OUTDIR)\vista.obj : vista.h villa.h depot.h curia.h cabin.h myconf.h
+
+$(OUTDIR)\odeum.obj $(OUTDIR)\odmgr.obj $(OUTDIR)\odtest.obj $(OUTDIR)\odidx.obj : \
+ odeum.h depot.h curia.h cabin.h villa.h myconf.h
+
+$(OUTDIR)\myconf.obj : myconf.h
+
+
+
+# END OF FILE
diff --git a/qdbm/misc/VCmakefile-old b/qdbm/misc/VCmakefile-old
index 8cd55467..94ececb9 100644
--- a/qdbm/misc/VCmakefile-old
+++ b/qdbm/misc/VCmakefile-old
@@ -1,169 +1,169 @@
-# Makefile to build QDBM using Microsoft Visual C++
-
-
-
-#================================================================
-# Setting Variables
-#================================================================
-
-
-# Targets
-MYLIBS = qdbm.lib
-LIBOBJS = depot.obj curia.obj relic.obj hovel.obj \
- cabin.obj villa.obj vista.obj odeum.obj myconf.obj
-MYBINS = dpmgr.exe dptest.exe dptsv.exe crmgr.exe crtest.exe crtsv.exe \
- rlmgr.exe rltest.exe hvmgr.exe hvtest.exe cbtest.exe cbcodec.exe \
- vlmgr.exe vltest.exe vltsv.exe odmgr.exe odtest.exe odidx.exe
-
-# VC++ directory
-VCPATH = C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7
-
-# Building binaries
-CLFLAGS = /I "$(VCPATH)\Include" /I "$(VCPATH)\PlatformSDK\Include" /I "." /O2 /nologo
-LIBFLAGS = /libpath:"$(VCPATH)\lib" /libpath:"$(VCPATH)\PlatformSDK\Lib" /libpath:"." /nologo
-LINKFLAGS = /libpath:"$(VCPATH)\lib" /libpath:"$(VCPATH)\PlatformSDK\Lib" /libpath:"." /nologo
-
-
-
-#================================================================
-# Suffix rules
-#================================================================
-
-
-.SUFFIXES :
-.SUFFIXES : .c .obj
-
-.c.obj :
- cl /c $(CLFLAGS) $<
-
-
-
-#================================================================
-# Actions
-#================================================================
-
-
-all : $(MYLIBS) $(MYBINS)
-
-
-clean :
- del *.obj *.lib *.dll *.exp *.exe
-
-
-
-#================================================================
-# Building binaries
-#================================================================
-
-
-qdbm.lib : $(LIBOBJS)
- lib $(LIBFLAGS) /OUT:$@ $(LIBOBJS)
-
-
-dpmgr.exe : dpmgr.obj qdbm.lib
- link $(LINKFLAGS) /OUT:$@ dpmgr.obj qdbm.lib
-
-
-dptest.exe : dptest.obj qdbm.lib
- link $(LINKFLAGS) /OUT:$@ dptest.obj qdbm.lib
-
-
-dptsv.exe : dptsv.obj qdbm.lib
- link $(LINKFLAGS) /OUT:$@ dptsv.obj qdbm.lib
-
-
-crmgr.exe : crmgr.obj qdbm.lib
- link $(LINKFLAGS) /OUT:$@ crmgr.obj qdbm.lib
-
-
-crtest.exe : crtest.obj qdbm.lib
- link $(LINKFLAGS) /OUT:$@ crtest.obj qdbm.lib
-
-
-crtsv.exe : crtsv.obj qdbm.lib
- link $(LINKFLAGS) /OUT:$@ crtsv.obj qdbm.lib
-
-
-rlmgr.exe : rlmgr.obj qdbm.lib
- link $(LINKFLAGS) /OUT:$@ rlmgr.obj qdbm.lib
-
-
-rltest.exe : rltest.obj qdbm.lib
- link $(LINKFLAGS) /OUT:$@ rltest.obj qdbm.lib
-
-
-hvmgr.exe : hvmgr.obj qdbm.lib
- link $(LINKFLAGS) /OUT:$@ hvmgr.obj qdbm.lib
-
-
-hvtest.exe : hvtest.obj qdbm.lib
- link $(LINKFLAGS) /OUT:$@ hvtest.obj qdbm.lib
-
-
-cbtest.exe : cbtest.obj qdbm.lib
- link $(LINKFLAGS) /OUT:$@ cbtest.obj qdbm.lib
-
-
-cbcodec.exe : cbcodec.obj qdbm.lib
- link $(LINKFLAGS) /OUT:$@ cbcodec.obj qdbm.lib
-
-
-vlmgr.exe : vlmgr.obj qdbm.lib
- link $(LINKFLAGS) /OUT:$@ vlmgr.obj qdbm.lib
-
-
-vltest.exe : vltest.obj qdbm.lib
- link $(LINKFLAGS) /OUT:$@ vltest.obj qdbm.lib
-
-
-vltsv.exe : vltsv.obj qdbm.lib
- link $(LINKFLAGS) /OUT:$@ vltsv.obj qdbm.lib
-
-
-odmgr.exe : odmgr.obj qdbm.lib
- link $(LINKFLAGS) /OUT:$@ odmgr.obj qdbm.lib
-
-
-odtest.exe : odtest.obj qdbm.lib
- link $(LINKFLAGS) /OUT:$@ odtest.obj qdbm.lib
-
-
-odidx.exe : odidx.obj qdbm.lib
- link $(LINKFLAGS) /OUT:$@ odidx.obj qdbm.lib
-
-
-depot.obj : depot.h myconf.h
-
-curia.obj : depot.h curia.h myconf.h
-
-relic.obj : depot.h relic.h myconf.h
-
-hovel.obj : depot.h curia.h hovel.h myconf.h
-
-cabin.obj : cabin.h myconf.h
-
-villa.obj : depot.h cabin.h villa.h myconf.h
-
-vista.obj : depot.h curia.h cabin.h villa.h vista.h myconf.h
-
-odeum.obj : depot.h curia.h cabin.h villa.h myconf.h
-
-myconf.obj : myconf.h
-
-dpmgr.obj dptest.obj dptsv.obj : depot.h cabin.h
-
-crmgr.obj crtest.obj crtsv.obj : depot.h curia.h cabin.h
-
-rlmgr.obj rltest.obj : depot.h relic.h cabin.h
-
-hvmgr.obj hvtest.obj : depot.h curia.h hovel.h cabin.h
-
-cbtest.obj cbcodec.obj : cabin.h
-
-vlmgr.obj vltest.obj vltsv.obj : depot.h cabin.h villa.h
-
-odmgr.obj odtest.obj odidx.obj : depot.h curia.h cabin.h villa.h odeum.h
-
-
-
-# END OF FILE
+# Makefile to build QDBM using Microsoft Visual C++
+
+
+
+#================================================================
+# Setting Variables
+#================================================================
+
+
+# Targets
+MYLIBS = qdbm.lib
+LIBOBJS = depot.obj curia.obj relic.obj hovel.obj \
+ cabin.obj villa.obj vista.obj odeum.obj myconf.obj
+MYBINS = dpmgr.exe dptest.exe dptsv.exe crmgr.exe crtest.exe crtsv.exe \
+ rlmgr.exe rltest.exe hvmgr.exe hvtest.exe cbtest.exe cbcodec.exe \
+ vlmgr.exe vltest.exe vltsv.exe odmgr.exe odtest.exe odidx.exe
+
+# VC++ directory
+VCPATH = C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7
+
+# Building binaries
+CLFLAGS = /I "$(VCPATH)\Include" /I "$(VCPATH)\PlatformSDK\Include" /I "." /O2 /nologo
+LIBFLAGS = /libpath:"$(VCPATH)\lib" /libpath:"$(VCPATH)\PlatformSDK\Lib" /libpath:"." /nologo
+LINKFLAGS = /libpath:"$(VCPATH)\lib" /libpath:"$(VCPATH)\PlatformSDK\Lib" /libpath:"." /nologo
+
+
+
+#================================================================
+# Suffix rules
+#================================================================
+
+
+.SUFFIXES :
+.SUFFIXES : .c .obj
+
+.c.obj :
+ cl /c $(CLFLAGS) $<
+
+
+
+#================================================================
+# Actions
+#================================================================
+
+
+all : $(MYLIBS) $(MYBINS)
+
+
+clean :
+ del *.obj *.lib *.dll *.exp *.exe
+
+
+
+#================================================================
+# Building binaries
+#================================================================
+
+
+qdbm.lib : $(LIBOBJS)
+ lib $(LIBFLAGS) /OUT:$@ $(LIBOBJS)
+
+
+dpmgr.exe : dpmgr.obj qdbm.lib
+ link $(LINKFLAGS) /OUT:$@ dpmgr.obj qdbm.lib
+
+
+dptest.exe : dptest.obj qdbm.lib
+ link $(LINKFLAGS) /OUT:$@ dptest.obj qdbm.lib
+
+
+dptsv.exe : dptsv.obj qdbm.lib
+ link $(LINKFLAGS) /OUT:$@ dptsv.obj qdbm.lib
+
+
+crmgr.exe : crmgr.obj qdbm.lib
+ link $(LINKFLAGS) /OUT:$@ crmgr.obj qdbm.lib
+
+
+crtest.exe : crtest.obj qdbm.lib
+ link $(LINKFLAGS) /OUT:$@ crtest.obj qdbm.lib
+
+
+crtsv.exe : crtsv.obj qdbm.lib
+ link $(LINKFLAGS) /OUT:$@ crtsv.obj qdbm.lib
+
+
+rlmgr.exe : rlmgr.obj qdbm.lib
+ link $(LINKFLAGS) /OUT:$@ rlmgr.obj qdbm.lib
+
+
+rltest.exe : rltest.obj qdbm.lib
+ link $(LINKFLAGS) /OUT:$@ rltest.obj qdbm.lib
+
+
+hvmgr.exe : hvmgr.obj qdbm.lib
+ link $(LINKFLAGS) /OUT:$@ hvmgr.obj qdbm.lib
+
+
+hvtest.exe : hvtest.obj qdbm.lib
+ link $(LINKFLAGS) /OUT:$@ hvtest.obj qdbm.lib
+
+
+cbtest.exe : cbtest.obj qdbm.lib
+ link $(LINKFLAGS) /OUT:$@ cbtest.obj qdbm.lib
+
+
+cbcodec.exe : cbcodec.obj qdbm.lib
+ link $(LINKFLAGS) /OUT:$@ cbcodec.obj qdbm.lib
+
+
+vlmgr.exe : vlmgr.obj qdbm.lib
+ link $(LINKFLAGS) /OUT:$@ vlmgr.obj qdbm.lib
+
+
+vltest.exe : vltest.obj qdbm.lib
+ link $(LINKFLAGS) /OUT:$@ vltest.obj qdbm.lib
+
+
+vltsv.exe : vltsv.obj qdbm.lib
+ link $(LINKFLAGS) /OUT:$@ vltsv.obj qdbm.lib
+
+
+odmgr.exe : odmgr.obj qdbm.lib
+ link $(LINKFLAGS) /OUT:$@ odmgr.obj qdbm.lib
+
+
+odtest.exe : odtest.obj qdbm.lib
+ link $(LINKFLAGS) /OUT:$@ odtest.obj qdbm.lib
+
+
+odidx.exe : odidx.obj qdbm.lib
+ link $(LINKFLAGS) /OUT:$@ odidx.obj qdbm.lib
+
+
+depot.obj : depot.h myconf.h
+
+curia.obj : depot.h curia.h myconf.h
+
+relic.obj : depot.h relic.h myconf.h
+
+hovel.obj : depot.h curia.h hovel.h myconf.h
+
+cabin.obj : cabin.h myconf.h
+
+villa.obj : depot.h cabin.h villa.h myconf.h
+
+vista.obj : depot.h curia.h cabin.h villa.h vista.h myconf.h
+
+odeum.obj : depot.h curia.h cabin.h villa.h myconf.h
+
+myconf.obj : myconf.h
+
+dpmgr.obj dptest.obj dptsv.obj : depot.h cabin.h
+
+crmgr.obj crtest.obj crtsv.obj : depot.h curia.h cabin.h
+
+rlmgr.obj rltest.obj : depot.h relic.h cabin.h
+
+hvmgr.obj hvtest.obj : depot.h curia.h hovel.h cabin.h
+
+cbtest.obj cbcodec.obj : cabin.h
+
+vlmgr.obj vltest.obj vltsv.obj : depot.h cabin.h villa.h
+
+odmgr.obj odtest.obj odidx.obj : depot.h curia.h cabin.h villa.h odeum.h
+
+
+
+# END OF FILE
diff --git a/qdbm/misc/win32check.bat b/qdbm/misc/win32check.bat
index 63dae180..4d6aebf4 100644
--- a/qdbm/misc/win32check.bat
+++ b/qdbm/misc/win32check.bat
@@ -1,111 +1,111 @@
-dptest write casket 50000 5000
-if errorlevel 1 goto error
-dptest read casket
-if errorlevel 1 goto error
-dptest read -wb casket
-if errorlevel 1 goto error
-dptest rcat casket 50000 50 500 32 32
-if errorlevel 1 goto error
-dptest combo casket
-if errorlevel 1 goto error
-dptest wicked casket 5000
-if errorlevel 1 goto error
-del /Q casket
-
-crtest write casket 50000 500 10
-if errorlevel 1 goto error
-crtest read casket
-if errorlevel 1 goto error
-crtest read -wb casket
-if errorlevel 1 goto error
-crtest rcat casket 50000 5 10 500 32 32
-if errorlevel 1 goto error
-crtest combo casket
-if errorlevel 1 goto error
-crtest wicked casket 5000
-if errorlevel 1 goto error
-rd /S /Q casket
-
-crtest write -lob casket 1000 50 10
-if errorlevel 1 goto error
-crtest read -lob casket
-if errorlevel 1 goto error
-rd /S /Q casket
-
-rltest write casket 50000
-if errorlevel 1 goto error
-rltest read casket 50000
-if errorlevel 1 goto error
-del /Q casket*
-
-hvtest write casket 50000
-if errorlevel 1 goto error
-hvtest read casket 50000
-if errorlevel 1 goto error
-del /Q casket
-
-hvtest write -qdbm casket 50000
-if errorlevel 1 goto error
-hvtest read -qdbm casket 50000
-if errorlevel 1 goto error
-rd /S /Q casket
-
-cbtest sort 5000
-if errorlevel 1 goto error
-cbtest strstr 500
-if errorlevel 1 goto error
-cbtest list 50000
-if errorlevel 1 goto error
-cbtest map 50000
-if errorlevel 1 goto error
-cbtest wicked 5000
-if errorlevel 1 goto error
-cbtest misc
-if errorlevel 1 goto error
-
-vltest write -tune 25 64 32 32 casket 50000
-if errorlevel 1 goto error
-vltest read casket
-if errorlevel 1 goto error
-vltest rdup -tune 25 64 256 256 casket 50000 50000
-if errorlevel 1 goto error
-vltest combo casket
-if errorlevel 1 goto error
-vltest wicked casket 5000
-if errorlevel 1 goto error
-del /Q casket
-
-vltest write -int -cz -tune 25 64 32 32 casket 50000
-if errorlevel 1 goto error
-vltest read -int casket
-if errorlevel 1 goto error
-vltest rdup -int -cz -tune 25 64 256 256 casket 50000 50000
-if errorlevel 1 goto error
-vltest combo -cz casket
-if errorlevel 1 goto error
-vltest wicked -cz casket 5000
-if errorlevel 1 goto error
-del /Q casket
-
-odtest write casket 500 50 5000
-if errorlevel 1 goto error
-odtest read casket
-if errorlevel 1 goto error
-odtest combo casket
-if errorlevel 1 goto error
-odtest wicked casket 500
-if errorlevel 1 goto error
-rd /S /Q casket
-
-@echo off
-echo #================================
-echo # SUCCESS
-echo #================================
-goto :EOF
-
-:error
-@echo off
-echo #================================
-echo # ERROR
-echo #================================
-goto :EOF
+dptest write casket 50000 5000
+if errorlevel 1 goto error
+dptest read casket
+if errorlevel 1 goto error
+dptest read -wb casket
+if errorlevel 1 goto error
+dptest rcat casket 50000 50 500 32 32
+if errorlevel 1 goto error
+dptest combo casket
+if errorlevel 1 goto error
+dptest wicked casket 5000
+if errorlevel 1 goto error
+del /Q casket
+
+crtest write casket 50000 500 10
+if errorlevel 1 goto error
+crtest read casket
+if errorlevel 1 goto error
+crtest read -wb casket
+if errorlevel 1 goto error
+crtest rcat casket 50000 5 10 500 32 32
+if errorlevel 1 goto error
+crtest combo casket
+if errorlevel 1 goto error
+crtest wicked casket 5000
+if errorlevel 1 goto error
+rd /S /Q casket
+
+crtest write -lob casket 1000 50 10
+if errorlevel 1 goto error
+crtest read -lob casket
+if errorlevel 1 goto error
+rd /S /Q casket
+
+rltest write casket 50000
+if errorlevel 1 goto error
+rltest read casket 50000
+if errorlevel 1 goto error
+del /Q casket*
+
+hvtest write casket 50000
+if errorlevel 1 goto error
+hvtest read casket 50000
+if errorlevel 1 goto error
+del /Q casket
+
+hvtest write -qdbm casket 50000
+if errorlevel 1 goto error
+hvtest read -qdbm casket 50000
+if errorlevel 1 goto error
+rd /S /Q casket
+
+cbtest sort 5000
+if errorlevel 1 goto error
+cbtest strstr 500
+if errorlevel 1 goto error
+cbtest list 50000
+if errorlevel 1 goto error
+cbtest map 50000
+if errorlevel 1 goto error
+cbtest wicked 5000
+if errorlevel 1 goto error
+cbtest misc
+if errorlevel 1 goto error
+
+vltest write -tune 25 64 32 32 casket 50000
+if errorlevel 1 goto error
+vltest read casket
+if errorlevel 1 goto error
+vltest rdup -tune 25 64 256 256 casket 50000 50000
+if errorlevel 1 goto error
+vltest combo casket
+if errorlevel 1 goto error
+vltest wicked casket 5000
+if errorlevel 1 goto error
+del /Q casket
+
+vltest write -int -cz -tune 25 64 32 32 casket 50000
+if errorlevel 1 goto error
+vltest read -int casket
+if errorlevel 1 goto error
+vltest rdup -int -cz -tune 25 64 256 256 casket 50000 50000
+if errorlevel 1 goto error
+vltest combo -cz casket
+if errorlevel 1 goto error
+vltest wicked -cz casket 5000
+if errorlevel 1 goto error
+del /Q casket
+
+odtest write casket 500 50 5000
+if errorlevel 1 goto error
+odtest read casket
+if errorlevel 1 goto error
+odtest combo casket
+if errorlevel 1 goto error
+odtest wicked casket 500
+if errorlevel 1 goto error
+rd /S /Q casket
+
+@echo off
+echo #================================
+echo # SUCCESS
+echo #================================
+goto :EOF
+
+:error
+@echo off
+echo #================================
+echo # ERROR
+echo #================================
+goto :EOF
diff --git a/qdbm/qdbm.def b/qdbm/qdbm.def
index 4c10e49e..6445b384 100644
--- a/qdbm/qdbm.def
+++ b/qdbm/qdbm.def
@@ -1,424 +1,424 @@
-EXPORTS
- VL_CMPDEC = VL_CMPDEC DATA
- VL_CMPINT = VL_CMPINT DATA
- VL_CMPLEX = VL_CMPLEX DATA
- VL_CMPNUM = VL_CMPNUM DATA
- VST_CMPDEC = VST_CMPDEC DATA
- VST_CMPINT = VST_CMPINT DATA
- VST_CMPLEX = VST_CMPLEX DATA
- VST_CMPNUM = VST_CMPNUM DATA
- cbfatalfunc = cbfatalfunc DATA
- dpdbgfd = dpdbgfd DATA
- dpisreentrant = dpisreentrant DATA
- dpsysname = dpsysname DATA
- dpversion = dpversion DATA
- gdbm_version = gdbm_version DATA
- odcachebnum = odcachebnum DATA
- odcachesiz = odcachesiz DATA
- odindexbnum = odindexbnum DATA
- odindexdnum = odindexdnum DATA
- odotcb = odotcb DATA
- cbbasedecode = cbbasedecode
- cbbaseencode = cbbaseencode
- cbbzdecode = cbbzdecode
- cbbzencode = cbbzencode
- cbcalendar = cbcalendar
- cbcsvcells = cbcsvcells
- cbcsvescape = cbcsvescape
- cbcsvrows = cbcsvrows
- cbcsvunescape = cbcsvunescape
- cbdatestrhttp = cbdatestrhttp
- cbdatestrwww = cbdatestrwww
- cbdatumcat = cbdatumcat
- cbdatumclose = cbdatumclose
- cbdatumdup = cbdatumdup
- cbdatumopen = cbdatumopen
- cbdatumopenbuf = cbdatumopenbuf
- cbdatumprintf = cbdatumprintf
- cbdatumptr = cbdatumptr
- cbdatumsetbuf = cbdatumsetbuf
- cbdatumsetsize = cbdatumsetsize
- cbdatumsize = cbdatumsize
- cbdatumtomalloc = cbdatumtomalloc
- cbdayofweek = cbdayofweek
- cbdeflate = cbdeflate
- cbdirlist = cbdirlist
- cbencname = cbencname
- cbfilestat = cbfilestat
- cbfree = cbfree
- cbgetcrc = cbgetcrc
- cbggcsweep = cbggcsweep
- cbglobalgc = cbglobalgc
- cbgzdecode = cbgzdecode
- cbgzencode = cbgzencode
- cbheapclose = cbheapclose
- cbheapdup = cbheapdup
- cbheapinsert = cbheapinsert
- cbheapnum = cbheapnum
- cbheapopen = cbheapopen
- cbheaptomalloc = cbheaptomalloc
- cbheapval = cbheapval
- cbhsort = cbhsort
- cbiconv = cbiconv
- cbinflate = cbinflate
- cbisort = cbisort
- cbjetlag = cbjetlag
- cblistbsearch = cblistbsearch
- cblistclose = cblistclose
- cblistdump = cblistdump
- cblistdup = cblistdup
- cblistinsert = cblistinsert
- cblistload = cblistload
- cblistlsearch = cblistlsearch
- cblistnum = cblistnum
- cblistopen = cblistopen
- cblistover = cblistover
- cblistpop = cblistpop
- cblistpush = cblistpush
- cblistpushbuf = cblistpushbuf
- cblistremove = cblistremove
- cblistshift = cblistshift
- cblistsort = cblistsort
- cblistunshift = cblistunshift
- cblistval = cblistval
- cblzodecode = cblzodecode
- cblzoencode = cblzoencode
- cbmalloc = cbmalloc
- cbmapclose = cbmapclose
- cbmapdump = cbmapdump
- cbmapdup = cbmapdup
- cbmapget = cbmapget
- cbmapiterinit = cbmapiterinit
- cbmapiternext = cbmapiternext
- cbmapiterval = cbmapiterval
- cbmapkeys = cbmapkeys
- cbmapload = cbmapload
- cbmaploadone = cbmaploadone
- cbmapmove = cbmapmove
- cbmapopen = cbmapopen
- cbmapopenex = cbmapopenex
- cbmapout = cbmapout
- cbmapput = cbmapput
- cbmapputcat = cbmapputcat
- cbmaprnum = cbmaprnum
- cbmapvals = cbmapvals
- cbmemdup = cbmemdup
- cbmimebreak = cbmimebreak
- cbmimedecode = cbmimedecode
- cbmimeencode = cbmimeencode
- cbmimeparts = cbmimeparts
- cbmyfatal = cbmyfatal
- cbproctime = cbproctime
- cbqsort = cbqsort
- cbquotedecode = cbquotedecode
- cbquoteencode = cbquoteencode
- cbreadfile = cbreadfile
- cbreadlines = cbreadlines
- cbrealloc = cbrealloc
- cbremove = cbremove
- cbreplace = cbreplace
- cbsplit = cbsplit
- cbsprintf = cbsprintf
- cbssort = cbssort
- cbstdiobin = cbstdiobin
- cbstrbwimatch = cbstrbwimatch
- cbstrbwmatch = cbstrbwmatch
- cbstrcountutf = cbstrcountutf
- cbstrcututf = cbstrcututf
- cbstrfwimatch = cbstrfwimatch
- cbstrfwmatch = cbstrfwmatch
- cbstricmp = cbstricmp
- cbstrmktime = cbstrmktime
- cbstrsqzspc = cbstrsqzspc
- cbstrstrbm = cbstrstrbm
- cbstrstrkmp = cbstrstrkmp
- cbstrtolower = cbstrtolower
- cbstrtoupper = cbstrtoupper
- cbstrtrim = cbstrtrim
- cburlbreak = cburlbreak
- cburldecode = cburldecode
- cburlencode = cburlencode
- cburlresolve = cburlresolve
- cbvmemavail = cbvmemavail
- cbwritefile = cbwritefile
- cbxmlattrs = cbxmlattrs
- cbxmlbreak = cbxmlbreak
- cbxmlescape = cbxmlescape
- cbxmlunescape = cbxmlunescape
- crbnum = crbnum
- crbusenum = crbusenum
- crclose = crclose
- crexportdb = crexportdb
- crfatalerror = crfatalerror
- crfsiz = crfsiz
- crfsizd = crfsizd
- crget = crget
- crgetflags = crgetflags
- crgetlob = crgetlob
- crgetlobfd = crgetlobfd
- crgetwb = crgetwb
- crimportdb = crimportdb
- crinode = crinode
- criterinit = criterinit
- criternext = criternext
- crmemflush = crmemflush
- crmemsync = crmemsync
- crmtime = crmtime
- crname = crname
- cropen = cropen
- croptimize = croptimize
- crout = crout
- croutlob = croutlob
- crput = crput
- crputlob = crputlob
- crremove = crremove
- crrepair = crrepair
- crrnum = crrnum
- crrnumlob = crrnumlob
- crsetalign = crsetalign
- crsetfbpsiz = crsetfbpsiz
- crsetflags = crsetflags
- crsnaffle = crsnaffle
- crsync = crsync
- crvsiz = crvsiz
- crvsizlob = crvsizlob
- crwritable = crwritable
- dbm_clearerr = dbm_clearerr
- dbm_close = dbm_close
- dbm_delete = dbm_delete
- dbm_dirfno = dbm_dirfno
- dbm_error = dbm_error
- dbm_fetch = dbm_fetch
- dbm_firstkey = dbm_firstkey
- dbm_nextkey = dbm_nextkey
- dbm_open = dbm_open
- dbm_pagfno = dbm_pagfno
- dbm_rdonly = dbm_rdonly
- dbm_store = dbm_store
- dpbnum = dpbnum
- dpbusenum = dpbusenum
- dpclose = dpclose
- dpecodeptr = dpecodeptr
- dpecodeset = dpecodeset
- dperrmsg = dperrmsg
- dpexportdb = dpexportdb
- dpfatalerror = dpfatalerror
- dpfdesc = dpfdesc
- dpfsiz = dpfsiz
- dpget = dpget
- dpgetflags = dpgetflags
- dpgetwb = dpgetwb
- dpimportdb = dpimportdb
- dpinnerhash = dpinnerhash
- dpinode = dpinode
- dpiterinit = dpiterinit
- dpiternext = dpiternext
- dpmemflush = dpmemflush
- dpmemsync = dpmemsync
- dpmtime = dpmtime
- dpname = dpname
- dpopen = dpopen
- dpoptimize = dpoptimize
- dpout = dpout
- dpouterhash = dpouterhash
- dpprimenum = dpprimenum
- dpput = dpput
- dpremove = dpremove
- dprepair = dprepair
- dprnum = dprnum
- dpsetalign = dpsetalign
- dpsetfbpsiz = dpsetfbpsiz
- dpsetflags = dpsetflags
- dpsnaffle = dpsnaffle
- dpsync = dpsync
- dpvsiz = dpvsiz
- dpwritable = dpwritable
- gdbm_close = gdbm_close
- gdbm_delete = gdbm_delete
- gdbm_errnoptr = gdbm_errnoptr
- gdbm_exists = gdbm_exists
- gdbm_fdesc = gdbm_fdesc
- gdbm_fetch = gdbm_fetch
- gdbm_firstkey = gdbm_firstkey
- gdbm_nextkey = gdbm_nextkey
- gdbm_open = gdbm_open
- gdbm_open2 = gdbm_open2
- gdbm_reorganize = gdbm_reorganize
- gdbm_setopt = gdbm_setopt
- gdbm_store = gdbm_store
- gdbm_strerror = gdbm_strerror
- gdbm_sync = gdbm_sync
- odanalyzetext = odanalyzetext
- odbnum = odbnum
- odbreaktext = odbreaktext
- odbusenum = odbusenum
- odcheck = odcheck
- odclose = odclose
- oddnum = oddnum
- oddocaddattr = oddocaddattr
- oddocaddword = oddocaddword
- oddocawords = oddocawords
- oddocclose = oddocclose
- oddocgetattr = oddocgetattr
- oddocid = oddocid
- oddocnwords = oddocnwords
- oddocopen = oddocopen
- oddocscores = oddocscores
- oddocuri = oddocuri
- odfatalerror = odfatalerror
- odfsiz = odfsiz
- odget = odget
- odgetbyid = odgetbyid
- odgetidbyuri = odgetidbyuri
- odidbdocs = odidbdocs
- odidbindex = odidbindex
- odidbrdocs = odidbrdocs
- odinode = odinode
- oditerinit = oditerinit
- oditernext = oditernext
- odlogarithm = odlogarithm
- odmerge = odmerge
- odmtime = odmtime
- odname = odname
- odnormalizeword = odnormalizeword
- odopen = odopen
- odoptimize = odoptimize
- odout = odout
- odoutbyid = odoutbyid
- odpairsand = odpairsand
- odpairsnotand = odpairsnotand
- odpairsor = odpairsor
- odpairssort = odpairssort
- odput = odput
- odquery = odquery
- odremove = odremove
- odsearch = odsearch
- odsearchdnum = odsearchdnum
- odsetcharclass = odsetcharclass
- odsetotcb = odsetotcb
- odsettuning = odsettuning
- odsquareroot = odsquareroot
- odsync = odsync
- odvecabsolute = odvecabsolute
- odvecinnerproduct = odvecinnerproduct
- odvectorcosine = odvectorcosine
- odwnum = odwnum
- odwritable = odwritable
- vlclose = vlclose
- vlcrdnumptr = vlcrdnumptr
- vlcurfirst = vlcurfirst
- vlcurjump = vlcurjump
- vlcurkey = vlcurkey
- vlcurkeycache = vlcurkeycache
- vlcurlast = vlcurlast
- vlcurnext = vlcurnext
- vlcurout = vlcurout
- vlcurprev = vlcurprev
- vlcurput = vlcurput
- vlcurval = vlcurval
- vlcurvalcache = vlcurvalcache
- vlexportdb = vlexportdb
- vlfatalerror = vlfatalerror
- vlfsiz = vlfsiz
- vlget = vlget
- vlgetcache = vlgetcache
- vlgetcat = vlgetcat
- vlgetflags = vlgetflags
- vlgetlist = vlgetlist
- vlimportdb = vlimportdb
- vlinode = vlinode
- vllnum = vllnum
- vlmemflush = vlmemflush
- vlmemsync = vlmemsync
- vlmtime = vlmtime
- vlmulcurclose = vlmulcurclose
- vlmulcurfirst = vlmulcurfirst
- vlmulcurjump = vlmulcurjump
- vlmulcurkey = vlmulcurkey
- vlmulcurkeycache = vlmulcurkeycache
- vlmulcurlast = vlmulcurlast
- vlmulcurnext = vlmulcurnext
- vlmulcuropen = vlmulcuropen
- vlmulcurprev = vlmulcurprev
- vlmulcurval = vlmulcurval
- vlmulcurvalcache = vlmulcurvalcache
- vlname = vlname
- vlnnum = vlnnum
- vlopen = vlopen
- vloptimize = vloptimize
- vlout = vlout
- vloutlist = vloutlist
- vlput = vlput
- vlputlist = vlputlist
- vlremove = vlremove
- vlrepair = vlrepair
- vlrnum = vlrnum
- vlsetfbpsiz = vlsetfbpsiz
- vlsetflags = vlsetflags
- vlsettuning = vlsettuning
- vlsync = vlsync
- vltranabort = vltranabort
- vltranbegin = vltranbegin
- vltrancommit = vltrancommit
- vlvnum = vlvnum
- vlvsiz = vlvsiz
- vlwritable = vlwritable
- vstclose = vstclose
- vstcrdnumptr = vstcrdnumptr
- vstcurfirst = vstcurfirst
- vstcurjump = vstcurjump
- vstcurkey = vstcurkey
- vstcurkeycache = vstcurkeycache
- vstcurlast = vstcurlast
- vstcurnext = vstcurnext
- vstcurout = vstcurout
- vstcurprev = vstcurprev
- vstcurput = vstcurput
- vstcurval = vstcurval
- vstcurvalcache = vstcurvalcache
- vstexportdb = vstexportdb
- vstfatalerror = vstfatalerror
- vstfsiz = vstfsiz
- vstget = vstget
- vstgetcache = vstgetcache
- vstgetcat = vstgetcat
- vstgetflags = vstgetflags
- vstgetlist = vstgetlist
- vstimportdb = vstimportdb
- vstinode = vstinode
- vstlnum = vstlnum
- vstmemflush = vstmemflush
- vstmemsync = vstmemsync
- vstmtime = vstmtime
- vstmulcurclose = vstmulcurclose
- vstmulcurfirst = vstmulcurfirst
- vstmulcurjump = vstmulcurjump
- vstmulcurkey = vstmulcurkey
- vstmulcurkeycache = vstmulcurkeycache
- vstmulcurlast = vstmulcurlast
- vstmulcurnext = vstmulcurnext
- vstmulcuropen = vstmulcuropen
- vstmulcurprev = vstmulcurprev
- vstmulcurval = vstmulcurval
- vstmulcurvalcache = vstmulcurvalcache
- vstname = vstname
- vstnnum = vstnnum
- vstopen = vstopen
- vstoptimize = vstoptimize
- vstout = vstout
- vstoutlist = vstoutlist
- vstput = vstput
- vstputlist = vstputlist
- vstremove = vstremove
- vstrepair = vstrepair
- vstrnum = vstrnum
- vstsetfbpsiz = vstsetfbpsiz
- vstsetflags = vstsetflags
- vstsettuning = vstsettuning
- vstsync = vstsync
- vsttranabort = vsttranabort
- vsttranbegin = vsttranbegin
- vsttrancommit = vsttrancommit
- vstvnum = vstvnum
- vstvsiz = vstvsiz
- vstwritable = vstwritable
+EXPORTS
+ VL_CMPDEC = VL_CMPDEC DATA
+ VL_CMPINT = VL_CMPINT DATA
+ VL_CMPLEX = VL_CMPLEX DATA
+ VL_CMPNUM = VL_CMPNUM DATA
+ VST_CMPDEC = VST_CMPDEC DATA
+ VST_CMPINT = VST_CMPINT DATA
+ VST_CMPLEX = VST_CMPLEX DATA
+ VST_CMPNUM = VST_CMPNUM DATA
+ cbfatalfunc = cbfatalfunc DATA
+ dpdbgfd = dpdbgfd DATA
+ dpisreentrant = dpisreentrant DATA
+ dpsysname = dpsysname DATA
+ dpversion = dpversion DATA
+ gdbm_version = gdbm_version DATA
+ odcachebnum = odcachebnum DATA
+ odcachesiz = odcachesiz DATA
+ odindexbnum = odindexbnum DATA
+ odindexdnum = odindexdnum DATA
+ odotcb = odotcb DATA
+ cbbasedecode = cbbasedecode
+ cbbaseencode = cbbaseencode
+ cbbzdecode = cbbzdecode
+ cbbzencode = cbbzencode
+ cbcalendar = cbcalendar
+ cbcsvcells = cbcsvcells
+ cbcsvescape = cbcsvescape
+ cbcsvrows = cbcsvrows
+ cbcsvunescape = cbcsvunescape
+ cbdatestrhttp = cbdatestrhttp
+ cbdatestrwww = cbdatestrwww
+ cbdatumcat = cbdatumcat
+ cbdatumclose = cbdatumclose
+ cbdatumdup = cbdatumdup
+ cbdatumopen = cbdatumopen
+ cbdatumopenbuf = cbdatumopenbuf
+ cbdatumprintf = cbdatumprintf
+ cbdatumptr = cbdatumptr
+ cbdatumsetbuf = cbdatumsetbuf
+ cbdatumsetsize = cbdatumsetsize
+ cbdatumsize = cbdatumsize
+ cbdatumtomalloc = cbdatumtomalloc
+ cbdayofweek = cbdayofweek
+ cbdeflate = cbdeflate
+ cbdirlist = cbdirlist
+ cbencname = cbencname
+ cbfilestat = cbfilestat
+ cbfree = cbfree
+ cbgetcrc = cbgetcrc
+ cbggcsweep = cbggcsweep
+ cbglobalgc = cbglobalgc
+ cbgzdecode = cbgzdecode
+ cbgzencode = cbgzencode
+ cbheapclose = cbheapclose
+ cbheapdup = cbheapdup
+ cbheapinsert = cbheapinsert
+ cbheapnum = cbheapnum
+ cbheapopen = cbheapopen
+ cbheaptomalloc = cbheaptomalloc
+ cbheapval = cbheapval
+ cbhsort = cbhsort
+ cbiconv = cbiconv
+ cbinflate = cbinflate
+ cbisort = cbisort
+ cbjetlag = cbjetlag
+ cblistbsearch = cblistbsearch
+ cblistclose = cblistclose
+ cblistdump = cblistdump
+ cblistdup = cblistdup
+ cblistinsert = cblistinsert
+ cblistload = cblistload
+ cblistlsearch = cblistlsearch
+ cblistnum = cblistnum
+ cblistopen = cblistopen
+ cblistover = cblistover
+ cblistpop = cblistpop
+ cblistpush = cblistpush
+ cblistpushbuf = cblistpushbuf
+ cblistremove = cblistremove
+ cblistshift = cblistshift
+ cblistsort = cblistsort
+ cblistunshift = cblistunshift
+ cblistval = cblistval
+ cblzodecode = cblzodecode
+ cblzoencode = cblzoencode
+ cbmalloc = cbmalloc
+ cbmapclose = cbmapclose
+ cbmapdump = cbmapdump
+ cbmapdup = cbmapdup
+ cbmapget = cbmapget
+ cbmapiterinit = cbmapiterinit
+ cbmapiternext = cbmapiternext
+ cbmapiterval = cbmapiterval
+ cbmapkeys = cbmapkeys
+ cbmapload = cbmapload
+ cbmaploadone = cbmaploadone
+ cbmapmove = cbmapmove
+ cbmapopen = cbmapopen
+ cbmapopenex = cbmapopenex
+ cbmapout = cbmapout
+ cbmapput = cbmapput
+ cbmapputcat = cbmapputcat
+ cbmaprnum = cbmaprnum
+ cbmapvals = cbmapvals
+ cbmemdup = cbmemdup
+ cbmimebreak = cbmimebreak
+ cbmimedecode = cbmimedecode
+ cbmimeencode = cbmimeencode
+ cbmimeparts = cbmimeparts
+ cbmyfatal = cbmyfatal
+ cbproctime = cbproctime
+ cbqsort = cbqsort
+ cbquotedecode = cbquotedecode
+ cbquoteencode = cbquoteencode
+ cbreadfile = cbreadfile
+ cbreadlines = cbreadlines
+ cbrealloc = cbrealloc
+ cbremove = cbremove
+ cbreplace = cbreplace
+ cbsplit = cbsplit
+ cbsprintf = cbsprintf
+ cbssort = cbssort
+ cbstdiobin = cbstdiobin
+ cbstrbwimatch = cbstrbwimatch
+ cbstrbwmatch = cbstrbwmatch
+ cbstrcountutf = cbstrcountutf
+ cbstrcututf = cbstrcututf
+ cbstrfwimatch = cbstrfwimatch
+ cbstrfwmatch = cbstrfwmatch
+ cbstricmp = cbstricmp
+ cbstrmktime = cbstrmktime
+ cbstrsqzspc = cbstrsqzspc
+ cbstrstrbm = cbstrstrbm
+ cbstrstrkmp = cbstrstrkmp
+ cbstrtolower = cbstrtolower
+ cbstrtoupper = cbstrtoupper
+ cbstrtrim = cbstrtrim
+ cburlbreak = cburlbreak
+ cburldecode = cburldecode
+ cburlencode = cburlencode
+ cburlresolve = cburlresolve
+ cbvmemavail = cbvmemavail
+ cbwritefile = cbwritefile
+ cbxmlattrs = cbxmlattrs
+ cbxmlbreak = cbxmlbreak
+ cbxmlescape = cbxmlescape
+ cbxmlunescape = cbxmlunescape
+ crbnum = crbnum
+ crbusenum = crbusenum
+ crclose = crclose
+ crexportdb = crexportdb
+ crfatalerror = crfatalerror
+ crfsiz = crfsiz
+ crfsizd = crfsizd
+ crget = crget
+ crgetflags = crgetflags
+ crgetlob = crgetlob
+ crgetlobfd = crgetlobfd
+ crgetwb = crgetwb
+ crimportdb = crimportdb
+ crinode = crinode
+ criterinit = criterinit
+ criternext = criternext
+ crmemflush = crmemflush
+ crmemsync = crmemsync
+ crmtime = crmtime
+ crname = crname
+ cropen = cropen
+ croptimize = croptimize
+ crout = crout
+ croutlob = croutlob
+ crput = crput
+ crputlob = crputlob
+ crremove = crremove
+ crrepair = crrepair
+ crrnum = crrnum
+ crrnumlob = crrnumlob
+ crsetalign = crsetalign
+ crsetfbpsiz = crsetfbpsiz
+ crsetflags = crsetflags
+ crsnaffle = crsnaffle
+ crsync = crsync
+ crvsiz = crvsiz
+ crvsizlob = crvsizlob
+ crwritable = crwritable
+ dbm_clearerr = dbm_clearerr
+ dbm_close = dbm_close
+ dbm_delete = dbm_delete
+ dbm_dirfno = dbm_dirfno
+ dbm_error = dbm_error
+ dbm_fetch = dbm_fetch
+ dbm_firstkey = dbm_firstkey
+ dbm_nextkey = dbm_nextkey
+ dbm_open = dbm_open
+ dbm_pagfno = dbm_pagfno
+ dbm_rdonly = dbm_rdonly
+ dbm_store = dbm_store
+ dpbnum = dpbnum
+ dpbusenum = dpbusenum
+ dpclose = dpclose
+ dpecodeptr = dpecodeptr
+ dpecodeset = dpecodeset
+ dperrmsg = dperrmsg
+ dpexportdb = dpexportdb
+ dpfatalerror = dpfatalerror
+ dpfdesc = dpfdesc
+ dpfsiz = dpfsiz
+ dpget = dpget
+ dpgetflags = dpgetflags
+ dpgetwb = dpgetwb
+ dpimportdb = dpimportdb
+ dpinnerhash = dpinnerhash
+ dpinode = dpinode
+ dpiterinit = dpiterinit
+ dpiternext = dpiternext
+ dpmemflush = dpmemflush
+ dpmemsync = dpmemsync
+ dpmtime = dpmtime
+ dpname = dpname
+ dpopen = dpopen
+ dpoptimize = dpoptimize
+ dpout = dpout
+ dpouterhash = dpouterhash
+ dpprimenum = dpprimenum
+ dpput = dpput
+ dpremove = dpremove
+ dprepair = dprepair
+ dprnum = dprnum
+ dpsetalign = dpsetalign
+ dpsetfbpsiz = dpsetfbpsiz
+ dpsetflags = dpsetflags
+ dpsnaffle = dpsnaffle
+ dpsync = dpsync
+ dpvsiz = dpvsiz
+ dpwritable = dpwritable
+ gdbm_close = gdbm_close
+ gdbm_delete = gdbm_delete
+ gdbm_errnoptr = gdbm_errnoptr
+ gdbm_exists = gdbm_exists
+ gdbm_fdesc = gdbm_fdesc
+ gdbm_fetch = gdbm_fetch
+ gdbm_firstkey = gdbm_firstkey
+ gdbm_nextkey = gdbm_nextkey
+ gdbm_open = gdbm_open
+ gdbm_open2 = gdbm_open2
+ gdbm_reorganize = gdbm_reorganize
+ gdbm_setopt = gdbm_setopt
+ gdbm_store = gdbm_store
+ gdbm_strerror = gdbm_strerror
+ gdbm_sync = gdbm_sync
+ odanalyzetext = odanalyzetext
+ odbnum = odbnum
+ odbreaktext = odbreaktext
+ odbusenum = odbusenum
+ odcheck = odcheck
+ odclose = odclose
+ oddnum = oddnum
+ oddocaddattr = oddocaddattr
+ oddocaddword = oddocaddword
+ oddocawords = oddocawords
+ oddocclose = oddocclose
+ oddocgetattr = oddocgetattr
+ oddocid = oddocid
+ oddocnwords = oddocnwords
+ oddocopen = oddocopen
+ oddocscores = oddocscores
+ oddocuri = oddocuri
+ odfatalerror = odfatalerror
+ odfsiz = odfsiz
+ odget = odget
+ odgetbyid = odgetbyid
+ odgetidbyuri = odgetidbyuri
+ odidbdocs = odidbdocs
+ odidbindex = odidbindex
+ odidbrdocs = odidbrdocs
+ odinode = odinode
+ oditerinit = oditerinit
+ oditernext = oditernext
+ odlogarithm = odlogarithm
+ odmerge = odmerge
+ odmtime = odmtime
+ odname = odname
+ odnormalizeword = odnormalizeword
+ odopen = odopen
+ odoptimize = odoptimize
+ odout = odout
+ odoutbyid = odoutbyid
+ odpairsand = odpairsand
+ odpairsnotand = odpairsnotand
+ odpairsor = odpairsor
+ odpairssort = odpairssort
+ odput = odput
+ odquery = odquery
+ odremove = odremove
+ odsearch = odsearch
+ odsearchdnum = odsearchdnum
+ odsetcharclass = odsetcharclass
+ odsetotcb = odsetotcb
+ odsettuning = odsettuning
+ odsquareroot = odsquareroot
+ odsync = odsync
+ odvecabsolute = odvecabsolute
+ odvecinnerproduct = odvecinnerproduct
+ odvectorcosine = odvectorcosine
+ odwnum = odwnum
+ odwritable = odwritable
+ vlclose = vlclose
+ vlcrdnumptr = vlcrdnumptr
+ vlcurfirst = vlcurfirst
+ vlcurjump = vlcurjump
+ vlcurkey = vlcurkey
+ vlcurkeycache = vlcurkeycache
+ vlcurlast = vlcurlast
+ vlcurnext = vlcurnext
+ vlcurout = vlcurout
+ vlcurprev = vlcurprev
+ vlcurput = vlcurput
+ vlcurval = vlcurval
+ vlcurvalcache = vlcurvalcache
+ vlexportdb = vlexportdb
+ vlfatalerror = vlfatalerror
+ vlfsiz = vlfsiz
+ vlget = vlget
+ vlgetcache = vlgetcache
+ vlgetcat = vlgetcat
+ vlgetflags = vlgetflags
+ vlgetlist = vlgetlist
+ vlimportdb = vlimportdb
+ vlinode = vlinode
+ vllnum = vllnum
+ vlmemflush = vlmemflush
+ vlmemsync = vlmemsync
+ vlmtime = vlmtime
+ vlmulcurclose = vlmulcurclose
+ vlmulcurfirst = vlmulcurfirst
+ vlmulcurjump = vlmulcurjump
+ vlmulcurkey = vlmulcurkey
+ vlmulcurkeycache = vlmulcurkeycache
+ vlmulcurlast = vlmulcurlast
+ vlmulcurnext = vlmulcurnext
+ vlmulcuropen = vlmulcuropen
+ vlmulcurprev = vlmulcurprev
+ vlmulcurval = vlmulcurval
+ vlmulcurvalcache = vlmulcurvalcache
+ vlname = vlname
+ vlnnum = vlnnum
+ vlopen = vlopen
+ vloptimize = vloptimize
+ vlout = vlout
+ vloutlist = vloutlist
+ vlput = vlput
+ vlputlist = vlputlist
+ vlremove = vlremove
+ vlrepair = vlrepair
+ vlrnum = vlrnum
+ vlsetfbpsiz = vlsetfbpsiz
+ vlsetflags = vlsetflags
+ vlsettuning = vlsettuning
+ vlsync = vlsync
+ vltranabort = vltranabort
+ vltranbegin = vltranbegin
+ vltrancommit = vltrancommit
+ vlvnum = vlvnum
+ vlvsiz = vlvsiz
+ vlwritable = vlwritable
+ vstclose = vstclose
+ vstcrdnumptr = vstcrdnumptr
+ vstcurfirst = vstcurfirst
+ vstcurjump = vstcurjump
+ vstcurkey = vstcurkey
+ vstcurkeycache = vstcurkeycache
+ vstcurlast = vstcurlast
+ vstcurnext = vstcurnext
+ vstcurout = vstcurout
+ vstcurprev = vstcurprev
+ vstcurput = vstcurput
+ vstcurval = vstcurval
+ vstcurvalcache = vstcurvalcache
+ vstexportdb = vstexportdb
+ vstfatalerror = vstfatalerror
+ vstfsiz = vstfsiz
+ vstget = vstget
+ vstgetcache = vstgetcache
+ vstgetcat = vstgetcat
+ vstgetflags = vstgetflags
+ vstgetlist = vstgetlist
+ vstimportdb = vstimportdb
+ vstinode = vstinode
+ vstlnum = vstlnum
+ vstmemflush = vstmemflush
+ vstmemsync = vstmemsync
+ vstmtime = vstmtime
+ vstmulcurclose = vstmulcurclose
+ vstmulcurfirst = vstmulcurfirst
+ vstmulcurjump = vstmulcurjump
+ vstmulcurkey = vstmulcurkey
+ vstmulcurkeycache = vstmulcurkeycache
+ vstmulcurlast = vstmulcurlast
+ vstmulcurnext = vstmulcurnext
+ vstmulcuropen = vstmulcuropen
+ vstmulcurprev = vstmulcurprev
+ vstmulcurval = vstmulcurval
+ vstmulcurvalcache = vstmulcurvalcache
+ vstname = vstname
+ vstnnum = vstnnum
+ vstopen = vstopen
+ vstoptimize = vstoptimize
+ vstout = vstout
+ vstoutlist = vstoutlist
+ vstput = vstput
+ vstputlist = vstputlist
+ vstremove = vstremove
+ vstrepair = vstrepair
+ vstrnum = vstrnum
+ vstsetfbpsiz = vstsetfbpsiz
+ vstsetflags = vstsetflags
+ vstsettuning = vstsettuning
+ vstsync = vstsync
+ vsttranabort = vsttranabort
+ vsttranbegin = vsttranbegin
+ vsttrancommit = vsttrancommit
+ vstvnum = vstvnum
+ vstvsiz = vstvsiz
+ vstwritable = vstwritable
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(<LISTING>)
+ while(my $line = <LISTING>)
{
- 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 <typeinfo>
-#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 <store-full|read-error|backup-ok|backup-error|backup-start|backup-finish>" >&2
+ exit 2
+elif [ "$1" = store-full ]; then
+ sendmail: $SENDTO <<EOM
+Subject: $SUBJECT (store full)
+To: $SENDTO
+
+
+The store account for debian-unstable is full.
+
+=============================
+FILES ARE NOT BEING BACKED UP
+=============================
+
+Please adjust the limits on account 1234567 on server localhost.
+
+EOM
+elif [ "$1" = read-error ]; then
+sendmail: $SENDTO <<EOM
+Subject: $SUBJECT (read errors)
+To: $SENDTO
+
+
+Errors occured reading some files or directories for backup on debian-unstable.
+
+===================================
+THESE FILES ARE NOT BEING BACKED UP
+===================================
+
+Check the logs on debian-unstable for the files and directories which caused
+these errors, and take appropriate action.
+
+Other files are being backed up.
+
+EOM
+elif [ "$1" = backup-start -o "$1" = backup-finish -o "$1" = backup-ok ]; then
+ # do nothing by default
+ true
+else
+sendmail: $SENDTO <<EOM
+Subject: $SUBJECT (unknown)
+To: $SENDTO
+
+
+The backup daemon on debian-unstable reported an unknown error ($1).
+
+==========================
+FILES MAY NOT BE BACKED UP
+==========================
+
+Please check the logs on debian-unstable.
+
+EOM
+fi
diff --git a/test/basicserver/testfiles/seclevel2-sha1/bbstored.conf b/test/basicserver/testfiles/seclevel2-sha1/bbstored.conf
new file mode 100644
index 00000000..25425dfa
--- /dev/null
+++ b/test/basicserver/testfiles/seclevel2-sha1/bbstored.conf
@@ -0,0 +1,23 @@
+
+RaidFileConf = ./raidfile.conf
+AccountDatabase = ./bbstored/accounts.txt
+
+# Uncomment this line to see exactly what commands are being received from clients.
+# ExtendedLogging = yes
+
+# scan all accounts for files which need deleting every 15 minutes.
+
+TimeBetweenHousekeeping = 900
+
+Server
+{
+ PidFile = /var/run/bbstored.pid
+ User = chris
+ ListenAddresses = inet:localhost
+ CertificateFile = ./bbstored/localhost-cert.pem
+ PrivateKeyFile = ./bbstored/localhost-key.pem
+ TrustedCAsFile = ./bbstored/clientCA.pem
+ SSLSecurityLevel = 2
+}
+
+
diff --git a/test/basicserver/testfiles/seclevel2-sha1/bbstored/localhost-csr.pem b/test/basicserver/testfiles/seclevel2-sha1/bbstored/localhost-csr.pem
new file mode 100644
index 00000000..db9fe3f7
--- /dev/null
+++ b/test/basicserver/testfiles/seclevel2-sha1/bbstored/localhost-csr.pem
@@ -0,0 +1,15 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIICWTCCAUECAQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0B
+AQEFAAOCAQ8AMIIBCgKCAQEAyzNFMI4BCpd/vGvPseb8U/NZYDQZ6nV7nFwDPsyr
+/yoUBQz7/gEAFP9Zo+8C9h89N2dPuxVNgylybiXO1icy8NsH+xkTtJXPSqi/Q87M
+36V5/k7wfF6Kx9ayuB2e1xg844fuY3llYacOyoA1NWP3DaQP+MztxuvKqK4JnodU
+oqysEK3DF4F1qFSHh1fum5nY+GBPaZjhn6ns/prQP8De6bctEjUAEYSKqUjNJpYa
+sP0KqFH8CoY1ZGa/f5n0CZ/9VT5N+Nm0TA1HwX2QeH0h1yp/LH52tD6/8T9XqgK4
+iuekRol6dkj63jXPnVSK4NSFksTzJsQCABOUz4kXKZucQQIDAQABoAAwDQYJKoZI
+hvcNAQEFBQADggEBACN8kdjf8P/OBMVytAKxWlXDAtG5A8qZz4e+aNM4JfXF//fP
+pS5c+m0rpt6aop4N5n5MWyL54eJlhh+yyNdm2RmHvybJKHLTRCPzP3gtHaVZ4v2V
+xWbDW+LuLMhDp70Ci1/CGWv+fQ2jmKPAtXGcbIsvjI+swLRtJDTwNV6B/dbS5QyF
+6n8O+pSLS6l7vsXginavB+VLAWWdtCbZAgId9Io0BePN/LpVb2bLgzGfzBInSCFl
+4bBN3dqC7nFkXdk+EXseA0L1NYUpXZoperzxMgDG74IMPwIomkb3elNP7xpz3Zgg
+Y5xwL05H5Jj5aW3Ao9mY3LKK8ZmAQnljOsyQsKc=
+-----END CERTIFICATE REQUEST-----
diff --git a/test/basicserver/testfiles/seclevel2-sha1/bbstored/localhost-key.pem b/test/basicserver/testfiles/seclevel2-sha1/bbstored/localhost-key.pem
new file mode 100644
index 00000000..885892b3
--- /dev/null
+++ b/test/basicserver/testfiles/seclevel2-sha1/bbstored/localhost-key.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEAyzNFMI4BCpd/vGvPseb8U/NZYDQZ6nV7nFwDPsyr/yoUBQz7
+/gEAFP9Zo+8C9h89N2dPuxVNgylybiXO1icy8NsH+xkTtJXPSqi/Q87M36V5/k7w
+fF6Kx9ayuB2e1xg844fuY3llYacOyoA1NWP3DaQP+MztxuvKqK4JnodUoqysEK3D
+F4F1qFSHh1fum5nY+GBPaZjhn6ns/prQP8De6bctEjUAEYSKqUjNJpYasP0KqFH8
+CoY1ZGa/f5n0CZ/9VT5N+Nm0TA1HwX2QeH0h1yp/LH52tD6/8T9XqgK4iuekRol6
+dkj63jXPnVSK4NSFksTzJsQCABOUz4kXKZucQQIDAQABAoIBACvo7mCprwvs5QuA
+eKdG9OvnQD8LwzXpIUcOkxz0+Y3wN9dHkQS4jp36+BH2yjsJUR8x0gbpeZCIWlP3
+E5Uvb1Cg5D6ckqeJX/wQLxSmEZualJwhztHxVCgO+xvSOsrcT/wTGa6hQwkxIn8b
+6WOaMH7gHxtynUdJGMgOo8GAGQf1yVganOo8hk/jARjln3Cyg+0018a8P0bZHI5L
+2EJgXSvVo5N4s0sVxMTDUX80YMmpH5M1duCYRitJwZCDMg5xOjootvfzw9pDD40/
+JsQHxdCfotDEBOVym7mKqxOUowwA+8vKG5yOkG7Fb7QmO9UkujqBCQs7n9q+0wj5
+3OV872ECgYEA+YwqJ+vk8EK6Eo4ZJmYNhreKDtfTCiv4CRpxWimyf8fShhPSpcur
+JSMl7OLuJhqsWIoGs5v1QSMhaSckLVq5lSZ7czVyC/ZFmhXN8LmfdYJ3LuSfEhG/
+ma9c2qXXC9EbTgdRg5lFSIugBFEHv+656Jn6Oj4hN/V8bd0EDgSY7Q0CgYEA0HRR
+esMH2YSGztoauzl0FmOHrH53diTpCNBzh2ZEwQgHcTbHK3VfDqN0bsUx4SwZW/Wj
+o7elnrBDHdVa8LMbUq7DH5YzRnfbGJHcKhUCTI3eT0wfpKvnyptIwRaKozS313rx
++5ZePf51krnYTs6p73Nvu7ALUwTLLi57PZQKJwUCgYB2B0JlEWB99sF1RzpD/B7H
+qgWlUZUiiXtOKvCT+YbQgx1ihvupqTPwY7hrW0XSRelgEyBqUQhl34zM5FNrFC8U
+iVf4PL4NRFTVNRzrj5AJD0T5q+5EqJpbwSKE081rbGKivDlkqdioIEn14LFuqSXL
+CxDb/UjO49APUmq5ipkd/QKBgQCfSxPsrNb1yMk/jvn4coochchq72WYudH+c1Sl
+dmg53knZoROISTPvusbB0x0vxgRG+qom9LKyVl2jkaPh5eyOPZBMNfpO8k5SMzw8
+SDuuhocIr9JKgzco44swSmp9F08ZchEywZCY7TepfS0n49OGcP9EPN4afcJKMyjo
+QJWVhQKBgH47nr45MgQJIoeUzmDPL/N9jAlG4+MvfsGvZxtGeRij68TYFStPEccO
+GJH09GQZgxvz8YbamC4KEA67PlwOdm/4ITs4HAE+tX6gaYeXG8XTw/azQdx0ZhXu
+EIhyRvSeCfXq/hi4Qef2yIx3YLarPXw1E38Xtl0MOl+yGg827Imt
+-----END RSA PRIVATE KEY-----
diff --git a/test/basicserver/testfiles/seclevel2-sha1/ca/clients/1234567-cert.pem b/test/basicserver/testfiles/seclevel2-sha1/ca/clients/1234567-cert.pem
new file mode 100644
index 00000000..d3f3acba
--- /dev/null
+++ b/test/basicserver/testfiles/seclevel2-sha1/ca/clients/1234567-cert.pem
@@ -0,0 +1,17 @@
+-----BEGIN CERTIFICATE-----
+MIICsTCCAZkCAQEwDQYJKoZIhvcNAQEFBQAwJDEiMCAGA1UEAwwZQmFja3VwIHN5
+c3RlbSBjbGllbnQgcm9vdDAeFw0xOTA0MjgyMDU3NDBaFw0zMzAxMDQyMDU3NDBa
+MBkxFzAVBgNVBAMMDkJBQ0tVUC0xMjM0NTY3MIIBIjANBgkqhkiG9w0BAQEFAAOC
+AQ8AMIIBCgKCAQEAq0h2RFBmcS5wxa9AdNlLXeaxemMGJocyxljQZwtBQawjdKiY
+IxB6UNI6jBgPbyLwbnrGIQZpPITsiRRzbSQfDCcnh7yksHcJRSLM/oK+tERgCo9v
+dJ0nRYDLzIJHas+lYOEfbfeH84cY5PwScjY6/K/uuIX3yDkJjGJZgAy19/AS0SwH
+21VZKv20YKgRbZrxWE2SpeqH9Y1UlkC3FxkoVhOOZXOR6Xfqrw0Y87ELpG94CZil
+OAzFtQQmkvFur+0dDBv+QqKIsDEa3LfKbh+CHiA6wcgc/9JkT3zD40dqqY8eBJi0
+XAt/ZRlQU51y2DNVxiGLF+39bLGGWV0kmo1KfQIDAQABMA0GCSqGSIb3DQEBBQUA
+A4IBAQBvwLWvNs2FhwNhjCA0A4r6hbKcdZDqmHT+EJpf1Os/f5A1fTah5u2UvNiQ
+jYkI7u5dds/pSRDQ+1itbq2ltHq59QolMDN80xbrqgW2SCYIzBqR5i+plIIlGaM+
+Cih9QUrbZO1qBSA9nvuqFOGdi4tca+rkkuogWWNsngEydS32EmcI/cTcrubMKnYT
+aW3+z46D42uZwljlhjnDDRbbvwpqd1h4NPbJcadelZnG3fsO0MCWi8LLp8Sepot7
+oDoseZ55JtYSjQuLFzfvgbvdkl/AQS1J+0Tjf2pq1zjIJmZ8qCuCP694z2BzRMTp
+y0vJrXoCFTpVaNZZJx+x8ZqKjp3J
+-----END CERTIFICATE-----
diff --git a/test/basicserver/testfiles/seclevel2-sha1/ca/keys/clientRootCSR.pem b/test/basicserver/testfiles/seclevel2-sha1/ca/keys/clientRootCSR.pem
new file mode 100644
index 00000000..e5bb872b
--- /dev/null
+++ b/test/basicserver/testfiles/seclevel2-sha1/ca/keys/clientRootCSR.pem
@@ -0,0 +1,15 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIICaTCCAVECAQAwJDEiMCAGA1UEAwwZQmFja3VwIHN5c3RlbSBjbGllbnQgcm9v
+dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMcxnm27tjpmhPdI23hV
+VLerRKdYRutug9EaVwoegRzsnx/+6vBrnXQFbqenA2MR9yMhje+CJqZJcKoEyN6o
+hSuv2vpMUOxLquUjhzv184rxp8dVcz1E6zpnxo5vJw8NoxN65SEjMKxFcO8e/RwQ
+Pb8Yot1wEantMZKUu9qQ45lPCJH1VdPES09D6yMc62P7gOkybR4MZE7t2Wm9Bbx6
+H3Ag9OaSuYJOhf3614SvZQFmUlr07X/RFGsAixXi7CWqMjPKZDpG0PALVnKeKrfj
+5gftcEUVVh2jRtfwN7DcTQu1f0Cv3Ixvv7T0lOK1BXGt5S8/l1RLeCNkzzIDyyEM
+92UCAwEAAaAAMA0GCSqGSIb3DQEBBQUAA4IBAQB9d+4iZAtngEGpbtuHEhWssZKP
+fisCUA+XokqrQ5Bw8wpE/zh4WHBfKDE0mrXARiJABKJqTVUI/fI9cGVWvRj17yxv
+aIuZdYsZgAWhy6U2u0I8Kyul4URnDJq+JiqKOwYDjduZRi6axsjqVoWqeyRn0M1o
+05d5O+TzS6uH9JhdYzpBeQVRweH4Dq374ApJu55RW+RQ7CpFQpW1cCqm3nMybNoM
+uMMDTXeV09jh8DE63VE5GLi2N9/DaAD8VrrGuZWRFUhEvxHe8Qs8gCX7ep+9rUlS
++Vn0880ItjjBRQwDaSkJqQaGL0Wq4eBSTx9WcvIer9XFfwUYKOFVIPwQqDqn
+-----END CERTIFICATE REQUEST-----
diff --git a/test/basicserver/testfiles/seclevel2-sha1/ca/keys/clientRootKey.pem b/test/basicserver/testfiles/seclevel2-sha1/ca/keys/clientRootKey.pem
new file mode 100644
index 00000000..0ccfd83c
--- /dev/null
+++ b/test/basicserver/testfiles/seclevel2-sha1/ca/keys/clientRootKey.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEAxzGebbu2OmaE90jbeFVUt6tEp1hG626D0RpXCh6BHOyfH/7q
+8GuddAVup6cDYxH3IyGN74ImpklwqgTI3qiFK6/a+kxQ7Euq5SOHO/XzivGnx1Vz
+PUTrOmfGjm8nDw2jE3rlISMwrEVw7x79HBA9vxii3XARqe0xkpS72pDjmU8IkfVV
+08RLT0PrIxzrY/uA6TJtHgxkTu3Zab0FvHofcCD05pK5gk6F/frXhK9lAWZSWvTt
+f9EUawCLFeLsJaoyM8pkOkbQ8AtWcp4qt+PmB+1wRRVWHaNG1/A3sNxNC7V/QK/c
+jG+/tPSU4rUFca3lLz+XVEt4I2TPMgPLIQz3ZQIDAQABAoIBAQC1TQJIGmw4J4uq
+j5PCqNgc/DPWpNCYBNTRg8npGe6mZvBGbP1lqm17Zl5bFfZNO9LXFPldH/cRrxJu
+jUBO+M+M/divrLqS+CQpvvadqrTqqBzvn2TuRUZcuIvOpHjGiMD/QAJA8QiiI+ow
+muIBov6wajoClrhdE9jk858vxmSB6gE4czdTrXvZQXC+9EyuaqrLQeTuJbz1JNGN
+jR61iSZWBfI6Ige+PSKpIQW/pU1+2QHyUNhTqN9V8Cxw0tVnOCZxNlWbXIaqsowa
+s4lzfYVvK1NsHitX3wIRJv3gPt3JYN8VIwpq86w1CDxvmEQUuj6VYGDj1n278z4h
+4CaZGNFBAoGBAP/b++wVZ1D0glBRhXghCMqGi/bzBySD+XDzd2DwVRM6jkX4Krof
+MPflg2AMGXOvYYEoDtNWPHYzLts45zpOY111DA4OKqLL1QgTOOtjjd4b/+AaQOKt
+m/Gvr9WFdqCjtO2rcv4546nB4M6bf6umHqoeKK947mi08jmW9VvZhaC5AoGBAMdN
+qIYmnR17s9He9/jgU9zfp+21fC9GSDI9MrdaGP9E4EAeg95Sn3ppplzVeIW+c2b/
+0MuhdbR2dn7JoXcJKlO2qcadvsRWURvR0ofWbjcKoKdAHlShsNIfT8cWfk7E1DL3
+04JTWFcLA7M5RkdT9y2/N4NNKAZ37ZWO10r5jz4NAoGAXWh8gmYV//IkGRqJ9Z9p
+zDZupst20hf0Ww4niRZ0mL6J7nV5c9WrVPVPjyMbr6ZZnIN5ViJnlGd/Nb2CfUDc
++eOfcQou+pwbvAT4hMclpe7m7XPoOFlVU1jmgrdk5aSeix5KrxGHUhRb9FHEvG+7
+RjQYemdV8pgMzoWUMeIp7NECgYB/39rN3/6UySbR9E6EF2KXZ8T2Jqh8KIrv+QYO
+UDeTqVx8p1eSkM6UGy9LhwfiQBUJM/+Cd6Du3ccfiD0aA/5tYdjCf7nDfWJjCBgd
+Yb6rgB0d0mzjfi7WUpK8OTlnTrCb1xiVGOaoSn/gQVJPN5dzeamjjCCvLcl5WQHX
+sBFxDQKBgAYnvJcaXYiyDW2fpdKodzf0AwPBaR2yUJsO2Zm2RpigrpAkpSo5lk5N
+GTWEbWUeENlgapQot5pxKbX07wSpifG3eAULusJuwd9+Ys04GZMYR9T+JXxjLQq7
+hxlWFoj/8o8zh5tGWocqvmTgIiFngwLpHRFStrAhmFSWtHlsgruV
+-----END RSA PRIVATE KEY-----
diff --git a/test/basicserver/testfiles/seclevel2-sha1/ca/keys/serverRootCSR.pem b/test/basicserver/testfiles/seclevel2-sha1/ca/keys/serverRootCSR.pem
new file mode 100644
index 00000000..5b6688f4
--- /dev/null
+++ b/test/basicserver/testfiles/seclevel2-sha1/ca/keys/serverRootCSR.pem
@@ -0,0 +1,15 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIICaTCCAVECAQAwJDEiMCAGA1UEAwwZQmFja3VwIHN5c3RlbSBzZXJ2ZXIgcm9v
+dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMmT9t4A51xpeJ3h6ddg
+l2wYFYSp2YdquKX85hipesYp0EIlrPHDdHXFjDS50ZhI62+2hxr/qCtSWwsAiNoK
+xSopXMVd6BO6eYPM0KqW4BMnqsKewv39uDiIHVQblB/3/4nd2Jx3sxGIdFivCDuo
+nqYm4BT5vEvHWG1Z+FtGqdPGZk4UG53Rx6ewHCYwpXUgCxJE814fruw+aWXPI0U3
+QYCgehOTP5+zcONaFP9aSVd5GXqCtF+MgZYSSK4exL33gKsaDXwhiTJ2IgOs4YpN
+HG4fu/ct4ppwArHvaHMuLKS6IgFjCHYCqMD/N2+ZpszPWzI5KGprfHZxl0uTLGTd
+HdsCAwEAAaAAMA0GCSqGSIb3DQEBBQUAA4IBAQCflWlk+xCivLP+EK8oh0VCuTo2
+qLMuPOR8GU+gVUN1z68T4j/ZsI0NKox++9NOzGwTE/cSpN+nfLNdhPwOM+TrRtS/
+iDrTSDMSVK4SjIQ9iEaINbfOZOv52l9vkyCR/u0TrnnkjXknzU9ZQmnDvj2e8K/B
+lq7LjvxeMxvLeZKfISr5XGcnUvhGcJkG6Cdkk6OIYUL7oDmBjS3IBzNTVTVmMB/U
+fHMURt/+ljmYKwNN8J7bG8nsMc/UnqqSLqBpPovup/+Ol8pbAjPNaLrQTz5PrN/k
+0PwqzbSJ52HEQY+kwpWLpx47p8ArQhD+YTaCUxyqzBWAI573rMdiAh/ZKVVi
+-----END CERTIFICATE REQUEST-----
diff --git a/test/basicserver/testfiles/seclevel2-sha1/ca/keys/serverRootKey.pem b/test/basicserver/testfiles/seclevel2-sha1/ca/keys/serverRootKey.pem
new file mode 100644
index 00000000..21dfb204
--- /dev/null
+++ b/test/basicserver/testfiles/seclevel2-sha1/ca/keys/serverRootKey.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEAyZP23gDnXGl4neHp12CXbBgVhKnZh2q4pfzmGKl6xinQQiWs
+8cN0dcWMNLnRmEjrb7aHGv+oK1JbCwCI2grFKilcxV3oE7p5g8zQqpbgEyeqwp7C
+/f24OIgdVBuUH/f/id3YnHezEYh0WK8IO6iepibgFPm8S8dYbVn4W0ap08ZmThQb
+ndHHp7AcJjCldSALEkTzXh+u7D5pZc8jRTdBgKB6E5M/n7Nw41oU/1pJV3kZeoK0
+X4yBlhJIrh7EvfeAqxoNfCGJMnYiA6zhik0cbh+79y3imnACse9ocy4spLoiAWMI
+dgKowP83b5mmzM9bMjkoamt8dnGXS5MsZN0d2wIDAQABAoIBAQCKVJ3+74PV6RM6
+1YORp9mB9m0d4ylCQryAPDLzDasRPjSKkCxEpKrQ/0YeEL6C0NewjAPfRT50rEmK
+HU3Mw8NWEZh2YOEYWMl25yDzUCJpQrluYWDSyECZmt71jw9xeNDGHZW+mm4qRAgD
+q+nsduSYhOkVu+O55Q0Lzcgfaziz+KNlZNFyjQpyrwCoj9lssL+ZYfhFZV2OnPof
+QLQpCEmrqzFaE9oFDjXxRkvmEBgtxPqSHNg2ZoFuVRAwcal8WHJbf7twCyQKB4i4
+UFV/SX70qw4pfX53rfUoxUNEJgnnJIpOV0q2N/FO3CPYMjvdSoqkhbaIa2D4c37h
+8aB0HCjxAoGBAPukpme3nRy7ybr5P8XomkIy+36sH8hLRoDZCNnz8UJa1OmrA8tG
+yKch9vlBMDXjzDQ0Uq8OFSjFN7uQF5zLx4UU2eL/ptEWEmDpPZui7YmI5Ep/ZK4k
+reK4op0tJ2fy7Fhq6IoBKvUVN3waWXzmObq77IKIQ5t1Z+MyfHEAtvKHAoGBAM0R
+aXluyt3+RwOE2RdlwgSDnHYNvKAUfmkOIVprFEb13LQABbna5BmNIa/rZ+RDtNza
+2/Tzqpmq8OVQkF9ATqjba+Y6GAoDwaAcvVwDrjoYtlI8zjnFEhhgVl455QlEZc5O
+qxOPYx4Kt60Cc6ee8L9gPvJUIAQLyyCjv1IWYQsNAoGBANWkPALiSGkUpXgwFIyZ
+ph192zb4OyN5hSnvGSyxhqqnIwwfPOFf/wqmM1/6kEuwUrYflfM5KY2rol2DQAjG
+mWXLBhFKqv3ol0Hfw4ZXFQQnTGpTLc8LJPXPe3+lzkbaXv3SBgrkYuwgTzL1y/PW
+Ijz/PxSzS3K4grLJMg1eZfQRAoGAOuatbPutuWW38ALQeC/6MmG7Jw17CF/aj0JH
+wjjPcjJcWjdHbcK5kb0/18+934qzAFy8oPb8IXdACh3B2hoWfdnIfDBjhzzc+KhI
+m41TFczTUXu1oFJCiE3jgN0QNEE5HLDr4opk5dQePctefN7iN5XlfqU7LO5WQeHG
+qkVTSmECgYB+pEKVBHyKyJtdnWhrVr8vhlJH7fh6VUkL4gnuoiFcfPn2gyw6UX7E
+9tls3aoxx47jvaJuoaNjiaT8ZZ4C0mx/L7XNHxiQHRb89nPC+WvapplDw+1XA0JK
+k/JenbDUXuEPrdoJh30lwwYqNBEJTstFbYILDhbaw4Ud6hRUrIfQOA==
+-----END RSA PRIVATE KEY-----
diff --git a/test/basicserver/testfiles/seclevel2-sha1/ca/roots/clientCA.pem b/test/basicserver/testfiles/seclevel2-sha1/ca/roots/clientCA.pem
new file mode 100644
index 00000000..79df3946
--- /dev/null
+++ b/test/basicserver/testfiles/seclevel2-sha1/ca/roots/clientCA.pem
@@ -0,0 +1,18 @@
+-----BEGIN CERTIFICATE-----
+MIICzzCCAbcCFDMFGbY+8snuTNZA311AVJo5GvwmMA0GCSqGSIb3DQEBBQUAMCQx
+IjAgBgNVBAMMGUJhY2t1cCBzeXN0ZW0gY2xpZW50IHJvb3QwHhcNMTkwNDI4MjA1
+NzM1WhcNMzgwMTE4MjA1NzM1WjAkMSIwIAYDVQQDDBlCYWNrdXAgc3lzdGVtIGNs
+aWVudCByb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxzGebbu2
+OmaE90jbeFVUt6tEp1hG626D0RpXCh6BHOyfH/7q8GuddAVup6cDYxH3IyGN74Im
+pklwqgTI3qiFK6/a+kxQ7Euq5SOHO/XzivGnx1VzPUTrOmfGjm8nDw2jE3rlISMw
+rEVw7x79HBA9vxii3XARqe0xkpS72pDjmU8IkfVV08RLT0PrIxzrY/uA6TJtHgxk
+Tu3Zab0FvHofcCD05pK5gk6F/frXhK9lAWZSWvTtf9EUawCLFeLsJaoyM8pkOkbQ
+8AtWcp4qt+PmB+1wRRVWHaNG1/A3sNxNC7V/QK/cjG+/tPSU4rUFca3lLz+XVEt4
+I2TPMgPLIQz3ZQIDAQABMA0GCSqGSIb3DQEBBQUAA4IBAQCUifYeul9/GHa2LV6/
+k9ZKOjcSmmDud8sTwfum3CuHLb9ODcKMaNz/vzPYeVyN7MZvXJIAqxaxrrToye46
+pDRQnguPNI5XU+Vb2l3Xvm7WBRGcxkAInkYBB7GwxmfffPS9/JrdPzxD6h3z8IOT
+jwzULNmNDse7Wf1hrgS1qKcCzJA1b1rLnZcrU+z3OUvLiR/8Bo/IuwXZVoNqDdq7
+NzrqYT4x0J4P5PuBQHPB/fHMFDc1HoCgLG9b42th71kDoxG7IH2r02FzVjF8qIvD
+eQes3VbI7BDT/f0L2r1FHcA7FVRUqTWnEWby/PjTZiRCSPKUG7RqAplrOKmk9JuN
+PkkW
+-----END CERTIFICATE-----
diff --git a/test/basicserver/testfiles/seclevel2-sha1/ca/roots/clientCA.srl b/test/basicserver/testfiles/seclevel2-sha1/ca/roots/clientCA.srl
new file mode 100644
index 00000000..8a0f05e1
--- /dev/null
+++ b/test/basicserver/testfiles/seclevel2-sha1/ca/roots/clientCA.srl
@@ -0,0 +1 @@
+01
diff --git a/test/basicserver/testfiles/seclevel2-sha1/ca/roots/serverCA.pem b/test/basicserver/testfiles/seclevel2-sha1/ca/roots/serverCA.pem
new file mode 100644
index 00000000..31ae4ecd
--- /dev/null
+++ b/test/basicserver/testfiles/seclevel2-sha1/ca/roots/serverCA.pem
@@ -0,0 +1,18 @@
+-----BEGIN CERTIFICATE-----
+MIICzzCCAbcCFGAQPLcwEruVZrE+h1tmI7s9CffgMA0GCSqGSIb3DQEBBQUAMCQx
+IjAgBgNVBAMMGUJhY2t1cCBzeXN0ZW0gc2VydmVyIHJvb3QwHhcNMTkwNDI4MjA1
+NzM1WhcNMzgwMTE4MjA1NzM1WjAkMSIwIAYDVQQDDBlCYWNrdXAgc3lzdGVtIHNl
+cnZlciByb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyZP23gDn
+XGl4neHp12CXbBgVhKnZh2q4pfzmGKl6xinQQiWs8cN0dcWMNLnRmEjrb7aHGv+o
+K1JbCwCI2grFKilcxV3oE7p5g8zQqpbgEyeqwp7C/f24OIgdVBuUH/f/id3YnHez
+EYh0WK8IO6iepibgFPm8S8dYbVn4W0ap08ZmThQbndHHp7AcJjCldSALEkTzXh+u
+7D5pZc8jRTdBgKB6E5M/n7Nw41oU/1pJV3kZeoK0X4yBlhJIrh7EvfeAqxoNfCGJ
+MnYiA6zhik0cbh+79y3imnACse9ocy4spLoiAWMIdgKowP83b5mmzM9bMjkoamt8
+dnGXS5MsZN0d2wIDAQABMA0GCSqGSIb3DQEBBQUAA4IBAQCHI5RDuqx9hu0anQRC
+dREc+3agRxq4C+Fo0mrsF1CWooO9lGyWvJqygiBGqOSjMi3D8AoyQXhxcvf1EniP
+CHCpqlP+h+6qILbtBizTTtHhceTpXiU5Se/yJvm9814jJrXVp10akShXzBlc4W/2
+O0NX6b1B0De2z+YJydB+meZws7wgGD3eZCBr2uF2seYTNitKmNfUfq9UXxxCKcMu
+eeRzWGM1UDFaRbN7FKNo6YpUE21olZEjxF8xOfyuWOYxv8qNTck89SurOwj4as/o
+CLJLVQ7i/keqt1XXXOSpp46CkRoEmmuxHuql44dToQOLZH1RcZLOMHSPO3OdNo5Z
+o2Do
+-----END CERTIFICATE-----
diff --git a/test/basicserver/testfiles/seclevel2-sha1/ca/roots/serverCA.srl b/test/basicserver/testfiles/seclevel2-sha1/ca/roots/serverCA.srl
new file mode 100644
index 00000000..8a0f05e1
--- /dev/null
+++ b/test/basicserver/testfiles/seclevel2-sha1/ca/roots/serverCA.srl
@@ -0,0 +1 @@
+01
diff --git a/test/basicserver/testfiles/seclevel2-sha1/ca/servers/localhost-cert.pem b/test/basicserver/testfiles/seclevel2-sha1/ca/servers/localhost-cert.pem
new file mode 100644
index 00000000..c3c6459b
--- /dev/null
+++ b/test/basicserver/testfiles/seclevel2-sha1/ca/servers/localhost-cert.pem
@@ -0,0 +1,17 @@
+-----BEGIN CERTIFICATE-----
+MIICrDCCAZQCAQEwDQYJKoZIhvcNAQEFBQAwJDEiMCAGA1UEAwwZQmFja3VwIHN5
+c3RlbSBzZXJ2ZXIgcm9vdDAeFw0xOTA0MjgyMDU3MzhaFw0zMzAxMDQyMDU3Mzha
+MBQxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
+AQoCggEBAMszRTCOAQqXf7xrz7Hm/FPzWWA0Gep1e5xcAz7Mq/8qFAUM+/4BABT/
+WaPvAvYfPTdnT7sVTYMpcm4lztYnMvDbB/sZE7SVz0qov0POzN+lef5O8HxeisfW
+srgdntcYPOOH7mN5ZWGnDsqANTVj9w2kD/jM7cbryqiuCZ6HVKKsrBCtwxeBdahU
+h4dX7puZ2PhgT2mY4Z+p7P6a0D/A3um3LRI1ABGEiqlIzSaWGrD9CqhR/AqGNWRm
+v3+Z9Amf/VU+TfjZtEwNR8F9kHh9Idcqfyx+drQ+v/E/V6oCuIrnpEaJenZI+t41
+z51UiuDUhZLE8ybEAgATlM+JFymbnEECAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA
+dYM0WTSCb0AN6eGhlbyNsENnUwLYjDE7ojVD2pY0Ab4ik04DIfTm5piqEkz5HBaI
+1ZIEtYlImnvQ9cax1m+8LrVS2tflPpZ0CqWT+In7EncuI1lONZJfYELITDgU3LWx
+FEfNQJaOv0Uc8u8GG29d22a50/jTfZr20puM7mYQkLaUJLHgoTImYg6M8W3Ggkyt
+DO/yrtPUWm424wCYx+f3DgOrraFtiRLdqUpy5+bRqmzTuEFMAARqt4uudF6MR36n
+hBIXg1jYKGrZMLwi60vfdtwe+zpAV/7SRGLbekhB6iAcVIXuom2aD7rlIcJHW/wd
+hk9u7ie0JVDdu0R4I5Z9vw==
+-----END CERTIFICATE-----
diff --git a/test/basicserver/testfiles/seclevel2-sha1/raidfile.conf b/test/basicserver/testfiles/seclevel2-sha1/raidfile.conf
new file mode 100644
index 00000000..6e235b24
--- /dev/null
+++ b/test/basicserver/testfiles/seclevel2-sha1/raidfile.conf
@@ -0,0 +1,10 @@
+
+disc0
+{
+ SetNumber = 0
+ BlockSize = 1024
+ Dir0 = .
+ Dir1 = .
+ Dir2 = .
+}
+
diff --git a/test/basicserver/testfiles/seclevel2-sha256/bbackupd.conf b/test/basicserver/testfiles/seclevel2-sha256/bbackupd.conf
new file mode 100644
index 00000000..671a13ac
--- /dev/null
+++ b/test/basicserver/testfiles/seclevel2-sha256/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
+
+
+# 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/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/bbackupd.state
+
+Server
+{
+ PidFile = /home/chris/boxbackup/test/basicserver/testfiles/seclevel2/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
+ {
+ Path = /home/chris/boxbackup/test/basicserver/testfiles/seclevel2
+ }
+}
+
diff --git a/test/basicserver/testfiles/seclevel2-sha256/bbackupd/1234567-csr.pem b/test/basicserver/testfiles/seclevel2-sha256/bbackupd/1234567-csr.pem
new file mode 100644
index 00000000..4f228021
--- /dev/null
+++ b/test/basicserver/testfiles/seclevel2-sha256/bbackupd/1234567-csr.pem
@@ -0,0 +1,15 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIICXjCCAUYCAQAwGTEXMBUGA1UEAwwOQkFDS1VQLTEyMzQ1NjcwggEiMA0GCSqG
+SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDeKRy4ppAb1cByCRkt2f1j+6iv7AWdF92p
+nPlzXPbLhP/edfuyVPFyBY46p+z6j4p9TrccMjUi4RPMx6dqyL2/o3Qzg3PhoHPq
+2fexEkrBSJ1bbL6hXjadzE53wiONj/8nSzFyzqR3/IhKNM0ssR10cqq64VgoiWOR
+GHYTTEbQy1k9WvoReC+diTEqIDBLif1EQJ+c/3iUopqtaVZWNS1LV5DX/u2Y1anX
+gO1s8jQaYlTtyNZyOi9lwXYXj4mH0mil2Hfh3IKD6GqB4HpFDUZ0/NHFRDvjdwfW
+4RTad55l8dWparOyie/QzFRj6Ua1746FsbUw2pERdmHAMshLpxkNAgMBAAGgADAN
+BgkqhkiG9w0BAQsFAAOCAQEAuW/o02Ga2yICJSJIrq44T+dIddakxhUPfIvAEWXs
+7Cap9qzmBNOAfzFqvbdVgsqC9/WCnpumf9ZpjkXvUy/6EB77HbtiJAXukT2DvFbo
+7mvbuh10YGv/AdZxLR2tMXmk9YqV6kgXdXFn18u8Vv35aYa4hru5q16m9QVhkeW+
+UAJCsjhYVISVWW5Pss5mgL058viMHt3T5X3+2ybMdsfLe5BfRbsPxnFClKfBg6QS
+3yH5JxQdfJlg64z4uQNHNbsWJ5mRBPEYawZ2ge+HmWb6xnuGLR3Dg5ZbbB0hvAO6
+kw7sZ1at9bX+MWz7rTvgKyxFXcGVXZ40/UQlgfzMiLEAHg==
+-----END CERTIFICATE REQUEST-----
diff --git a/test/basicserver/testfiles/seclevel2-sha256/bbackupd/1234567-key.pem b/test/basicserver/testfiles/seclevel2-sha256/bbackupd/1234567-key.pem
new file mode 100644
index 00000000..e5b132b6
--- /dev/null
+++ b/test/basicserver/testfiles/seclevel2-sha256/bbackupd/1234567-key.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEA3ikcuKaQG9XAcgkZLdn9Y/uor+wFnRfdqZz5c1z2y4T/3nX7
+slTxcgWOOqfs+o+KfU63HDI1IuETzMenasi9v6N0M4Nz4aBz6tn3sRJKwUidW2y+
+oV42ncxOd8IjjY//J0sxcs6kd/yISjTNLLEddHKquuFYKIljkRh2E0xG0MtZPVr6
+EXgvnYkxKiAwS4n9RECfnP94lKKarWlWVjUtS1eQ1/7tmNWp14DtbPI0GmJU7cjW
+cjovZcF2F4+Jh9Jopdh34dyCg+hqgeB6RQ1GdPzRxUQ743cH1uEU2neeZfHVqWqz
+sonv0MxUY+lGte+OhbG1MNqREXZhwDLIS6cZDQIDAQABAoIBAF1cH5LFhGf+ItqJ
+Ukh/hEnBFzme0RkcT22Y5weA+MG8SZ6eLEDcC38kMIobya3eJo/URYUW4FehCKYU
+/RkV9Q+UzB9dzZPyzuPR55JFIp8pOd+SymWb5w3XLt6K+k/iRJKpucUKa/l0aX3t
+xI9UexFVosPYMSkP24S9J9miQ1w4X8D1laJPi5KWrbdzDZxy5geoNmS0veQl6mRf
+91Owxsa15wQpxNoVesAiGbrHb5ljMsBovYgljRL6rqA9THXPXfcDkWkabfGai/kD
+AktxqPGUELxjD7gSO5G4ygCcGTeIEJbOfwgDtr59V518kVzwVNAxOKb7lfDM/l4D
+v0H3liECgYEA+nh1RjwOm2db+yW0hQ2DTCA84by2AyKP7nCwD7CjrGaXrm7zfQ+U
+VqSgpDg+xH9/Caa9P1n6zSZSEiXrCePQL6UsREj8sd+st7Uah9eQOc3vywxizGN6
+VMqqmctn+gKKxkmv8T6YtWblDDqOA/7yYlCaH0l7WUO+HKAl7MhaGgUCgYEA4xCo
+2bGwbaT7lLdFtOU2+erM2lbA4NzBkR7Mjpq16JiPPFdSF680XBRL0uNR0r2GFucM
+gG8Z+ktV1QosY22546Z3fl7+jcyZC4uramDicpAxnmEGIdPnqIkEPhZzKvV0uRGj
+tXs2qnJ9ztK7hf+PRwdQEvqCNLkoy+pQPG/bSWkCgYAvH36g6ietYTLS+3MNHU+4
+gNAzgDeWO2hs6dKWARuqEdszvDgfLVExQ+PdQZ+9hGc4P6CXTKx88Fq8g1nHEI9Y
+h3DeoAS6ymRKY85MBGhkF7SntPrZjVW0ojSansQ/Kz9EsxRhBO/iISuys0mIwuyD
+RrrYbBDC6JXZ+N9pvwAEqQKBgQCI4DgI0pY54iRN55S7kRjs2l+Wlok6g5ijtF82
+74gMqDpf83tnD5SOlSWIAMQIN3snPyxIF7EfMl6RR8quPSy7UFPj97uXGuh/DzjL
+rY+T49wlTvN1XNnevIm0K7BNCx3LmhiHg7jWUqIIFPw5sG5cMMpSRnRK9/rhwWOQ
+qxUTUQKBgQDYUi6255mUI23dYxCyY7P6rIcGiKqhiAJ5HbGShMFhpA94WS3m6YmJ
+sQTip0kykY168klOcRqt8y3RLS5UB1aYBMYvtFuk5wbUcuXFeGcIsuUIZeR3iueg
+G0MEhf9hgmBK/xkpfoiLJ+E0hFHqER57N6KCuEK0NWC1Vgqo8X79MQ==
+-----END RSA PRIVATE KEY-----
diff --git a/test/basicserver/testfiles/seclevel2-sha256/bbackupd/NotifySysadmin.sh b/test/basicserver/testfiles/seclevel2-sha256/bbackupd/NotifySysadmin.sh
new file mode 100755
index 00000000..48e8cf8e
--- /dev/null
+++ b/test/basicserver/testfiles/seclevel2-sha256/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 <store-full|read-error|backup-ok|backup-error|backup-start|backup-finish>" >&2
+ exit 2
+elif [ "$1" = store-full ]; then
+ sendmail: $SENDTO <<EOM
+Subject: $SUBJECT (store full)
+To: $SENDTO
+
+
+The store account for debian-unstable is full.
+
+=============================
+FILES ARE NOT BEING BACKED UP
+=============================
+
+Please adjust the limits on account 1234567 on server localhost.
+
+EOM
+elif [ "$1" = read-error ]; then
+sendmail: $SENDTO <<EOM
+Subject: $SUBJECT (read errors)
+To: $SENDTO
+
+
+Errors occured reading some files or directories for backup on debian-unstable.
+
+===================================
+THESE FILES ARE NOT BEING BACKED UP
+===================================
+
+Check the logs on debian-unstable for the files and directories which caused
+these errors, and take appropriate action.
+
+Other files are being backed up.
+
+EOM
+elif [ "$1" = backup-start -o "$1" = backup-finish -o "$1" = backup-ok ]; then
+ # do nothing by default
+ true
+else
+sendmail: $SENDTO <<EOM
+Subject: $SUBJECT (unknown)
+To: $SENDTO
+
+
+The backup daemon on debian-unstable reported an unknown error ($1).
+
+==========================
+FILES MAY NOT BE BACKED UP
+==========================
+
+Please check the logs on debian-unstable.
+
+EOM
+fi
diff --git a/test/basicserver/testfiles/seclevel2-sha256/bbstored.conf b/test/basicserver/testfiles/seclevel2-sha256/bbstored.conf
new file mode 100644
index 00000000..25425dfa
--- /dev/null
+++ b/test/basicserver/testfiles/seclevel2-sha256/bbstored.conf
@@ -0,0 +1,23 @@
+
+RaidFileConf = ./raidfile.conf
+AccountDatabase = ./bbstored/accounts.txt
+
+# Uncomment this line to see exactly what commands are being received from clients.
+# ExtendedLogging = yes
+
+# scan all accounts for files which need deleting every 15 minutes.
+
+TimeBetweenHousekeeping = 900
+
+Server
+{
+ PidFile = /var/run/bbstored.pid
+ User = chris
+ ListenAddresses = inet:localhost
+ CertificateFile = ./bbstored/localhost-cert.pem
+ PrivateKeyFile = ./bbstored/localhost-key.pem
+ TrustedCAsFile = ./bbstored/clientCA.pem
+ SSLSecurityLevel = 2
+}
+
+
diff --git a/test/basicserver/testfiles/seclevel2-sha256/bbstored/localhost-csr.pem b/test/basicserver/testfiles/seclevel2-sha256/bbstored/localhost-csr.pem
new file mode 100644
index 00000000..b3ff3f1f
--- /dev/null
+++ b/test/basicserver/testfiles/seclevel2-sha256/bbstored/localhost-csr.pem
@@ -0,0 +1,15 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIICWTCCAUECAQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0B
+AQEFAAOCAQ8AMIIBCgKCAQEA9Uk3V+oultps1qwaJwo+w332tal2trjr5LCXoTuX
+UrO4+xJIBYKC2D7a+Nl2VUZw+Kr6UEI/wc7ROwM84s9l1jCZ5iXVrz/8XHYJvJXw
+uw3IDQESFbxZsrNg0FC8U7GEtVlCRnVr6B2RkciPkDXK3TVqdf43fv4rripPSE/d
+4hbAq/uPd5LZNUQdy6yFsMywG4cSqiaHw3hg4aLgF6EKXj29s8IFTiNhM1h8XrCB
+i0MfyCIq2jHVM1/ZRL10HA6cMvu/2E+ofrLETl6FlTzyC4WFQBqv0onFmKFIM5bt
+AVIok/NIWX5vpk1rqGnSOuW/6lhUO4yczExZadgDwx7YiwIDAQABoAAwDQYJKoZI
+hvcNAQEFBQADggEBAJVk9eAleSiTsV3Pdq3L01WEyndnmpbU1FcExJWg5xb95xbX
+Ojxi6g/NhBodAWl6GHJEUTQ+eJHrZ/hTLD6ZHeX9CGxmxOIvpKJCoOiQU7zamLaq
+K6aP8BoG21h2MccnbKlrSFF/c89SzH78r2fgWpUqFUCxobemKfvUbdHSaNlOWxh9
+yO3q1P/ZK0wl/V0CG9kdkUfpl9OLATilBiJayrpX92Ef/U6JkX3ZFEG9vTGBSXXU
+5QQM7BrPDgMsaTNDv9N1oPCVrUKfQ7Ts2pTEKU/oMA8fYZKX2GFZ/LDXj4C7clQ4
+LJakbh26NhrohTjecHvJCxIDAk2xLipwmXLmVoU=
+-----END CERTIFICATE REQUEST-----
diff --git a/test/basicserver/testfiles/seclevel2-sha256/bbstored/localhost-key.pem b/test/basicserver/testfiles/seclevel2-sha256/bbstored/localhost-key.pem
new file mode 100644
index 00000000..c6acc692
--- /dev/null
+++ b/test/basicserver/testfiles/seclevel2-sha256/bbstored/localhost-key.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEA9Uk3V+oultps1qwaJwo+w332tal2trjr5LCXoTuXUrO4+xJI
+BYKC2D7a+Nl2VUZw+Kr6UEI/wc7ROwM84s9l1jCZ5iXVrz/8XHYJvJXwuw3IDQES
+FbxZsrNg0FC8U7GEtVlCRnVr6B2RkciPkDXK3TVqdf43fv4rripPSE/d4hbAq/uP
+d5LZNUQdy6yFsMywG4cSqiaHw3hg4aLgF6EKXj29s8IFTiNhM1h8XrCBi0MfyCIq
+2jHVM1/ZRL10HA6cMvu/2E+ofrLETl6FlTzyC4WFQBqv0onFmKFIM5btAVIok/NI
+WX5vpk1rqGnSOuW/6lhUO4yczExZadgDwx7YiwIDAQABAoIBAGc/FF6bIlU5R8rs
+0m1QcK7VHL3GwUOUfybZ9llVvhJ/uANm5I39K5peislor9ihN/hT791MpY2swoF2
+kXBfIFySRJWNo26LHmzE+sA41QXHfUeMBdLEX3VK8Bt/gGYyOMwk8DK8RlmD6LxW
+kaeAHQ4T5+YWxcFct4IuKQUlKR565lHr6LRDaYmlDHzjksi/fx0ceMlD/RBje7YD
+HXPDdetNkSBvpHEcH2lINnrY0kBb5HQv57ipOdA8MfQ+Xf06SjqjhA6ZUOdsMjsn
+QVleXQsT1HQ5Ji///JbqVL5j68qkjza2HroyXgOgQdu+fuksHTXvMjvAnW7/z3u2
+SpUd6WECgYEA/aBM7DKWeQdzlRCfosgv6SZ+ME0Lt5oBaHbbUYizi8DuylB196MJ
+xnP1QLa7MAYna6ASxDXIClqxG4x+d4lHpErmbYR4F0pa8/9teSbtUw3OXGe9ahZy
+HcpK3LSVV5ns8CjRsclNX86cn/Gxubw48gxjcjIA4qKUJv9KxCSAdoMCgYEA95Tu
+qhkXDGhBSSTqs51K8mHbTS4CrpCK6+5J++NP7AT4t2IHIaaQ7DtttAI9xFvwxD9U
+zFP2/lZVq1KSFATAoDhItUoC0SMlaFcrIxsIyq/UOqTTluf3in29rFHq3UN1rz9M
+X90Tfl5EhUvruVJOiJ5iYt97DJeVgOlWkU7qt1kCgYACEwWOCPviEYWIepJTqn95
+0K7HhlnKLqBEUnSIvi15vyI01WOhmtvBm8EtvlDZm7NG1hBROn9gVk2MhCGkqKLF
+XTd1PdgdmKYVyMkEbKUUQNCnQNHzxCs6wyTJmVB/XurpK+xLH/JaDj6JsFhbxIZS
+tHc7v9zx/ZJonz3lTMcgMQKBgG+WPqOHv22mJ5ax/t6JjFgGZvM4Q5kuKI8BzXKs
+Fz+HVhpBInm2Oydd+aniQLiZv8CT0sJtLaugeehHxPMk2TTdaVfcTby5HIkUkKq3
+6pR//yWXWI5xao6O8cgS+8pSN16PJvsmBz0ze6qgd1QFlsPYrvtlQm6Ae6+oe43u
+hbexAoGBAIKGmPAoQsBPEWkSs3nWyAPDHQ45NBoB23G0j01amf11Y/sQWhH+Mqfp
+mcU40xr/XwMlTVgALfW1Q048ftJ4D2oYPsUEG3Yiayqe8epl6V55QjGMpdEe/+mQ
+5VpndGimuUwxr9cyNShn6dngEg6D0hXfNqu4NFmt/2PH3x0D8eer
+-----END RSA PRIVATE KEY-----
diff --git a/test/basicserver/testfiles/seclevel2-sha256/ca/clients/1234567-cert.pem b/test/basicserver/testfiles/seclevel2-sha256/ca/clients/1234567-cert.pem
new file mode 100644
index 00000000..e1cb932c
--- /dev/null
+++ b/test/basicserver/testfiles/seclevel2-sha256/ca/clients/1234567-cert.pem
@@ -0,0 +1,17 @@
+-----BEGIN CERTIFICATE-----
+MIICsTCCAZkCAQEwDQYJKoZIhvcNAQELBQAwJDEiMCAGA1UEAwwZQmFja3VwIHN5
+c3RlbSBjbGllbnQgcm9vdDAeFw0xOTA0MjgyMDUxNTlaFw0zMzAxMDQyMDUxNTla
+MBkxFzAVBgNVBAMMDkJBQ0tVUC0xMjM0NTY3MIIBIjANBgkqhkiG9w0BAQEFAAOC
+AQ8AMIIBCgKCAQEA3ikcuKaQG9XAcgkZLdn9Y/uor+wFnRfdqZz5c1z2y4T/3nX7
+slTxcgWOOqfs+o+KfU63HDI1IuETzMenasi9v6N0M4Nz4aBz6tn3sRJKwUidW2y+
+oV42ncxOd8IjjY//J0sxcs6kd/yISjTNLLEddHKquuFYKIljkRh2E0xG0MtZPVr6
+EXgvnYkxKiAwS4n9RECfnP94lKKarWlWVjUtS1eQ1/7tmNWp14DtbPI0GmJU7cjW
+cjovZcF2F4+Jh9Jopdh34dyCg+hqgeB6RQ1GdPzRxUQ743cH1uEU2neeZfHVqWqz
+sonv0MxUY+lGte+OhbG1MNqREXZhwDLIS6cZDQIDAQABMA0GCSqGSIb3DQEBCwUA
+A4IBAQAEpEobzo6qm+GJw3Jgi7Gc/XBVBbib5Tp7fH0oyyzX7sSnbUWNUYNHLjMH
+CFFmeNsj2/x4P7JFK2shVy7lRnBt6RUi5zLtQyjhEF8OqV1rxb74hQHl4+7CiRUP
+Q1SRTJpdbdDwwAzd5UyDTAX3Glg73krDEHY+k0UCr0kczqcffVzgNmCklMzrCzZk
+Nz9KkUF+cMkFDz/5BRBj6I4M9b5ebkVYM32Gz0mAh/G/DcL5KGzWPL9KJ31pgkAP
+P8yrvZe2HwscKTJKnAK78M+75zzNv3539/V3y55lNNiyKF2q9Up4k3BE5PY9LDFJ
+fVZvMdAltZlFV1tlZksrsRoq3jsc
+-----END CERTIFICATE-----
diff --git a/test/basicserver/testfiles/seclevel2-sha256/ca/keys/clientRootCSR.pem b/test/basicserver/testfiles/seclevel2-sha256/ca/keys/clientRootCSR.pem
new file mode 100644
index 00000000..c4d2be66
--- /dev/null
+++ b/test/basicserver/testfiles/seclevel2-sha256/ca/keys/clientRootCSR.pem
@@ -0,0 +1,15 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIICaTCCAVECAQAwJDEiMCAGA1UEAwwZQmFja3VwIHN5c3RlbSBjbGllbnQgcm9v
+dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKWLP1hzvhUgHs8gp6+w
+v3aIbsEHXjWOKfTpB4u+eubM4oA9XtXT0NiCLZQPy2BAtIOkazJ6sae6w2Qq2naj
+MDyTBclAgok3TLVI6whMkgxdB878uaKQb3sk7xg6yNI6iI7S70cTRM9JKF8ZPBMZ
+6ftPgoPooe1ka2kFTjhNgE6jO/DjAyWGpf7Q4cb2ELBdgrU+ehbz4Zz0hHZ0Ts5p
+KO8SxEkBX4FRP4sUkbuDM92UNcxyBxlrLg21ktDlIciftef9J94qQyx5HnotMWWp
+rj4Zi2mA8/i14op90CXPq/figj8zYkPyyx9KytKDSKcGgByxjNMBWzIAZ17doRgq
+1KkCAwEAAaAAMA0GCSqGSIb3DQEBCwUAA4IBAQBVUqpA7BizyLkDut8sLYI4qyJA
+8Os+6IiSDyjyjf3C/hTbrbA31mtF0g3gbZFXnehVhop04zQYy3071OBYzuMx+/2F
+olylk7HWrScaKE0MDSSamfVTlSGiO2P+zPg32WKoZsOPPjSyrGF/l+A4TlTQJmFK
+SgapRRQVm3VDlkWO77c4EjpqoREPeSHVt+0m2490BY7aUT+kRlXl2nViSV52SS5j
+EDnb4N/9t60NRS2zaLtAr0DcRWemR+PzVKqKdNyhXdCeieQ9xzGGHK1vXpW/6kCo
+OHi/Xt4MHkt3hHxQQKOrK5dcsoqP9WxlnwOuuy9m9mVH4HUhi+S0KFtOytoX
+-----END CERTIFICATE REQUEST-----
diff --git a/test/basicserver/testfiles/seclevel2-sha256/ca/keys/clientRootKey.pem b/test/basicserver/testfiles/seclevel2-sha256/ca/keys/clientRootKey.pem
new file mode 100644
index 00000000..c81b607b
--- /dev/null
+++ b/test/basicserver/testfiles/seclevel2-sha256/ca/keys/clientRootKey.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEApYs/WHO+FSAezyCnr7C/dohuwQdeNY4p9OkHi7565szigD1e
+1dPQ2IItlA/LYEC0g6RrMnqxp7rDZCradqMwPJMFyUCCiTdMtUjrCEySDF0Hzvy5
+opBveyTvGDrI0jqIjtLvRxNEz0koXxk8Exnp+0+Cg+ih7WRraQVOOE2ATqM78OMD
+JYal/tDhxvYQsF2CtT56FvPhnPSEdnROzmko7xLESQFfgVE/ixSRu4Mz3ZQ1zHIH
+GWsuDbWS0OUhyJ+15/0n3ipDLHkeei0xZamuPhmLaYDz+LXiin3QJc+r9+KCPzNi
+Q/LLH0rK0oNIpwaAHLGM0wFbMgBnXt2hGCrUqQIDAQABAoIBAFOJ4X2RaureOq3r
+nLNcTkJStxFR1ojQJPwiXFx40yyFWAe+8IyXR1z61GVTUx5PiMilwDLJF7280b1K
+otQbpcvrpY/ZrgXwkhUppvGZMlpq1/XsMwGGQbuy97USdSUhxKfOalFDuAWitWzI
+HzjEav8XMJXAX3acpldpBgADnCwSA5izEfwt2oGNtcYTHjxG4tR96UvgAxbVbxrU
+jg6zd0/Q7eI4MGYc5l2mGFcbAUbeqCOQmTB8eQY9cdXCotXgQSa2EKEt1aG7dEbA
+omwwm8+hGYIX4i/E3crFHO5qlbQqtqktvic1Axj3I4NEy+a4Gpja3y6k8gY4TWbS
+4+0BZMECgYEA2o6mRCyDNI13VhRdlAO6VDSAdf//8EMeMrANvAGl70de0Ri10ZL6
+GdJLx31le94tVa5Dy+Qi9d9eYci9qIjMK1kUrLcVgvF63tbbOSpz37gESJe+wJYc
+xEW2eGRTUwHoYVqRjEi36kAKeWL4mxXeqzJE/ZUQZt2felr4dBJPyBsCgYEAweeS
+vV5TJsPlEazUZcRA2dMY8JG9tD1JFVVrlSC4xnLBOEXsC4dw74RsOhoMr69lBn6X
+xwcKtzsrx/s9NHI1s2AJXlz310Uj+gRB6/6foyyQDOtijfweZpm3zUNY5OwQ1VBZ
+M9J1YVI6xaa3BehQ0PHvx4U/WM9oFMc0upXaaosCgYEAmfo+MXGazn+MP90BQLKP
+p5uFlZzSWBcxQ0y9oGMY4MdLicz667e89Ewwj09NHEOfdOndYdxMtSS1ffbLh904
+2qFb64LhaOtwQWbl9BRwpoEio3IlNdGMWssyjwc/nQ+PBGeme0sQJ70OpA6ST9DM
+m5hC+tT2RUKGhNFqkXwFMVkCgYBY3Jlg82ND9q55xSypXqEhsh5R0ViQyy08+6KL
++yzytRBbi5+7QNy+x38ZuWpq8QRpT4abDV0Zz6Imybqo2FZH2BEzD4P9QZBVObJE
+RrI+A2QYp57I1uvPtU6IYP7SGmU0fNgEacSlTxvkDJz/thGjT9zFIQmA17wpGYnO
+oHIyNQKBgEbA0apflhYExq2OZP3mjUM7Baf8MhGylUFnND68YKEr2aR5ihYuWxME
+yLSGIDORaVQBiVklze9MXPvJv6WF0nE3VrR5j0AsSoAF0MZBcCJcn5bod0pFRZXG
+PkxibqTmzJXJjGRuAKxbNR2+WFxKqc2hsev3hwOSXKYH4DbdCxQg
+-----END RSA PRIVATE KEY-----
diff --git a/test/basicserver/testfiles/seclevel2-sha256/ca/keys/serverRootCSR.pem b/test/basicserver/testfiles/seclevel2-sha256/ca/keys/serverRootCSR.pem
new file mode 100644
index 00000000..b204952d
--- /dev/null
+++ b/test/basicserver/testfiles/seclevel2-sha256/ca/keys/serverRootCSR.pem
@@ -0,0 +1,15 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIICaTCCAVECAQAwJDEiMCAGA1UEAwwZQmFja3VwIHN5c3RlbSBzZXJ2ZXIgcm9v
+dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANMqKzGuRMYTGC4GtM4Y
+sa/EcpfgdRDt1V54c7Qjarfz/6Uvb7dn+21IDgnSMImnBzKuE11KBS2WAPPSxyF9
+Z+rNlry38pAVprnVv40dAUaohShxrkzgIYlZ866RonFYQ9mujMdynzGHB0jKH66T
+/enqFhEYzOuBcHyb7obgX+HmT95yAVhm6TvMuF8FR5CvrSqdnj141qJWdRmNeXH/
+Eonz1mcFizHRuFZ0ymxjoegwxQkeSnoYyH2vUh3RkQ/iNZPhu9DdDjgZ6Z0m8mUc
+xMGqtwTqiYS8KEcAHvcEPoS44BO1aGTnJEwhABTLuEkTPCXl1HkRoq50ts+Cr9w6
+vu8CAwEAAaAAMA0GCSqGSIb3DQEBCwUAA4IBAQAhVOO7/mqt2AWFaOlMrXICPm5n
+judbMjQhOzaTmYr+Tb2lDlsQyiSm/EONpjC1F8PP6ig3oK8dzmIn9/qLOau6xM2Y
+JiaTTJXRX+/JC/AaZvvaiA0etc2JwAcfBijAudEKivA/qKh01SvCgB+IEx5rlR6S
+TPjLRO4ygig3qGHeHUsiPBzR4PZA669Is3/P4W8pIlDbCQHI91brQV4TlHJET2V5
++y4et7ZduWvS6yEn29aiPq5UT36kWtJ9rhBFIiu2oUNnDiL7YUDIbdsl0I9LDPjw
+equwfb+dwjjO/bFQKB1RX4j5jUXj25bpe9FdB6iy36+3tLd1a0Oh4j6SEn2n
+-----END CERTIFICATE REQUEST-----
diff --git a/test/basicserver/testfiles/seclevel2-sha256/ca/keys/serverRootKey.pem b/test/basicserver/testfiles/seclevel2-sha256/ca/keys/serverRootKey.pem
new file mode 100644
index 00000000..7eb1ac20
--- /dev/null
+++ b/test/basicserver/testfiles/seclevel2-sha256/ca/keys/serverRootKey.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEA0yorMa5ExhMYLga0zhixr8Ryl+B1EO3VXnhztCNqt/P/pS9v
+t2f7bUgOCdIwiacHMq4TXUoFLZYA89LHIX1n6s2WvLfykBWmudW/jR0BRqiFKHGu
+TOAhiVnzrpGicVhD2a6Mx3KfMYcHSMofrpP96eoWERjM64FwfJvuhuBf4eZP3nIB
+WGbpO8y4XwVHkK+tKp2ePXjWolZ1GY15cf8SifPWZwWLMdG4VnTKbGOh6DDFCR5K
+ehjIfa9SHdGRD+I1k+G70N0OOBnpnSbyZRzEwaq3BOqJhLwoRwAe9wQ+hLjgE7Vo
+ZOckTCEAFMu4SRM8JeXUeRGirnS2z4Kv3Dq+7wIDAQABAoIBADUc0ih40MuRWe+Z
+uDhudaLkIn6Y8lkDuTs9yLxyfBEwygheWhcjjFX8XauStqqo3GKe7jf0ukCxDiRF
+y9hclpq0g0mMavJav8jWPovb08pV8Mgvb8veRBEsEuLBtr4TmV1TTg2MgwYOFIL2
+c+mRR7hiLJK4TjKeKBDvl5tNLFDBC/2clHXnLCRb8rOKqwmseoPavi992QZ7+Yyq
+n0Dx5DOpr1cOcJEr4va8Sornd3LjLuNMjm7XzgIryR5pvLM0ns8Fy2ihyKl7Hd3s
+ek9c5fh0jbhz6s28K8laWm9bhozdMQ12y1U5z0PJV+VOwTX/M9UCK1+CpvmjTim5
+NeD93QECgYEA924yXRdUXpOlxJifJ49n88gytHOVcgitrdlZNCAE7aKdYcQW7VSY
+7IjUyXH/Mi2zlWKpXYGllOoDW71PhLiMuEtaNfLdToXgHEMGvj+vGw9ZRqs6HY2w
+wGyOrxg5VcSOfSpAom4gCGRqxWhHtY/rzFOy7oZePJuRbjcqrAeGQmECgYEA2npt
+dGHwp20S5tyd7n1H6Fe2m1t/vjxGsGFfwbFggGIu9lVQxgAQiimzHgBDOjSzs163
+PmuWWUDmHllB9AmJw4wrbAyiHNOmdi4rgY0ez5G6Q9sviFQeFJZzHhe6G1+CcafL
++oSU+Ej7zznMpyU85vcxFz70JvRZ4BeD0PtZI08CgYEAsXEGjzoG2Fh8PdPR91Xh
+j7NXoY9ucjwFCbLgRQBdaGoBAbbVVlgf3yl1qA2nnL2nlw8NNLCgJX348JZ/60dK
+K3Rmel/0E7bwdHQg5tjW48oLFSIAaGdPhX+Uh78QhxCRuvNNLO9a64nQBEf3fR58
+VKkFngcgl8hc8DSB1qMCxqECgYAOZ54J219DmrRxVkBvdgEkt4vJqHm+sDi07mai
+3bAQJukTwsJFm8F7ao5tvvSvxMPIYslQK0XJcrb5b0ci8PINW5ONVzPlFKtYBWlG
+7GgIpYITcUMsCOfG0bibVlMl9OEj3z1ash0kVaOMoTH2H0VpsQiikLsGSnwWg1Zk
+k/3njwKBgD6Nu6kj4BSWGZacLtePJQzxlsnYiDm9SSmrtqJ1lnpbqo4/Zp5bCHS9
+qMOUv+Hcwpsb3IYI8np1ekZfKi7xFXcRjxKRYnDURQgQKwPeHZ06ht7X0DdTXuiY
+K97byeb9hks3QNE1k1EuXue7IXS657Fq5IZrN+NQ6vkqq/X7e91X
+-----END RSA PRIVATE KEY-----
diff --git a/test/basicserver/testfiles/seclevel2-sha256/ca/roots/clientCA.pem b/test/basicserver/testfiles/seclevel2-sha256/ca/roots/clientCA.pem
new file mode 100644
index 00000000..a9302167
--- /dev/null
+++ b/test/basicserver/testfiles/seclevel2-sha256/ca/roots/clientCA.pem
@@ -0,0 +1,18 @@
+-----BEGIN CERTIFICATE-----
+MIICzzCCAbcCFAiy3jWfhXnxRqZJCbjzFQzsU3p/MA0GCSqGSIb3DQEBCwUAMCQx
+IjAgBgNVBAMMGUJhY2t1cCBzeXN0ZW0gY2xpZW50IHJvb3QwHhcNMTkwNDI4MjA1
+MTU1WhcNMzgwMTE4MjA1MTU1WjAkMSIwIAYDVQQDDBlCYWNrdXAgc3lzdGVtIGNs
+aWVudCByb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApYs/WHO+
+FSAezyCnr7C/dohuwQdeNY4p9OkHi7565szigD1e1dPQ2IItlA/LYEC0g6RrMnqx
+p7rDZCradqMwPJMFyUCCiTdMtUjrCEySDF0Hzvy5opBveyTvGDrI0jqIjtLvRxNE
+z0koXxk8Exnp+0+Cg+ih7WRraQVOOE2ATqM78OMDJYal/tDhxvYQsF2CtT56FvPh
+nPSEdnROzmko7xLESQFfgVE/ixSRu4Mz3ZQ1zHIHGWsuDbWS0OUhyJ+15/0n3ipD
+LHkeei0xZamuPhmLaYDz+LXiin3QJc+r9+KCPzNiQ/LLH0rK0oNIpwaAHLGM0wFb
+MgBnXt2hGCrUqQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQAvHW8APi1lhEguSXDc
+X/k5ETL1YJzlEfIn4HKL7kcKo5IOdyHaIigGCWM7atwKeGBtTRl8CTY4wt1L7d+A
+LDzF07MlKL/KiX1yPw9ZzHBhKNLYgmKsRL5cgW/YLYEAGD0lTwW7llsqZ40jJ1+X
+CWomYEzVpGW76MprYge4Oj+4PRXaZikkn7pzlZVcGJbzr1Q+JaFNLRkAMPK4pRXj
+AOSLQpIuc0DzftzC8tHbyLMifrHYdibHaujsvu1mV4NeYhO63ZB8S5Xyz1JlpsEQ
+rieLH1/9dnWue7yBCpI+QMRq+zK92HxiCCaM0d6xpSsbI5IawkqmoWj9gYol0EnX
+ImLj
+-----END CERTIFICATE-----
diff --git a/test/basicserver/testfiles/seclevel2-sha256/ca/roots/clientCA.srl b/test/basicserver/testfiles/seclevel2-sha256/ca/roots/clientCA.srl
new file mode 100644
index 00000000..8a0f05e1
--- /dev/null
+++ b/test/basicserver/testfiles/seclevel2-sha256/ca/roots/clientCA.srl
@@ -0,0 +1 @@
+01
diff --git a/test/basicserver/testfiles/seclevel2-sha256/ca/roots/serverCA.pem b/test/basicserver/testfiles/seclevel2-sha256/ca/roots/serverCA.pem
new file mode 100644
index 00000000..e26b6e1a
--- /dev/null
+++ b/test/basicserver/testfiles/seclevel2-sha256/ca/roots/serverCA.pem
@@ -0,0 +1,18 @@
+-----BEGIN CERTIFICATE-----
+MIICzzCCAbcCFFv62JnwctULelqlEY+sZTPEb7ekMA0GCSqGSIb3DQEBCwUAMCQx
+IjAgBgNVBAMMGUJhY2t1cCBzeXN0ZW0gc2VydmVyIHJvb3QwHhcNMTkwNDI4MjA1
+MTU1WhcNMzgwMTE4MjA1MTU1WjAkMSIwIAYDVQQDDBlCYWNrdXAgc3lzdGVtIHNl
+cnZlciByb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0yorMa5E
+xhMYLga0zhixr8Ryl+B1EO3VXnhztCNqt/P/pS9vt2f7bUgOCdIwiacHMq4TXUoF
+LZYA89LHIX1n6s2WvLfykBWmudW/jR0BRqiFKHGuTOAhiVnzrpGicVhD2a6Mx3Kf
+MYcHSMofrpP96eoWERjM64FwfJvuhuBf4eZP3nIBWGbpO8y4XwVHkK+tKp2ePXjW
+olZ1GY15cf8SifPWZwWLMdG4VnTKbGOh6DDFCR5KehjIfa9SHdGRD+I1k+G70N0O
+OBnpnSbyZRzEwaq3BOqJhLwoRwAe9wQ+hLjgE7VoZOckTCEAFMu4SRM8JeXUeRGi
+rnS2z4Kv3Dq+7wIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQAI6THIONT6lgNq3Bvg
+TCBqkBA1W/k372Pktt6IDFW44dT0J9/oq2o6ZNHycpKS3VwS4C05XbU/v5hE/k2O
+Cu3/y3en+dJIv4Wl2JTPaSRF/4J46sXNtizVAJDKoE3ZHt1viCjsWyllGXoaavce
+fWYppf3g6ImhyAkzlCfyVph2F0vmLZL41K3C040e+GpXdzG1Yy1+2USPhz0Ch+kd
+jqIErNp9OnPRd1yRb1YD+dQ7Wei5vB3OXMk3UQiG9AJ2qmxlEem5lTSpt9fTvWfU
+OAjTynvWbHTULjxvOeenW7cD5ILSr2zVDYQ53KTWjP9NfmsQTAFzkqJztPpB2A0o
+CKG2
+-----END CERTIFICATE-----
diff --git a/test/basicserver/testfiles/seclevel2-sha256/ca/roots/serverCA.srl b/test/basicserver/testfiles/seclevel2-sha256/ca/roots/serverCA.srl
new file mode 100644
index 00000000..9e22bcb8
--- /dev/null
+++ b/test/basicserver/testfiles/seclevel2-sha256/ca/roots/serverCA.srl
@@ -0,0 +1 @@
+02
diff --git a/test/basicserver/testfiles/seclevel2-sha256/ca/servers/localhost-cert-sha1.pem b/test/basicserver/testfiles/seclevel2-sha256/ca/servers/localhost-cert-sha1.pem
new file mode 100644
index 00000000..19b6ed62
--- /dev/null
+++ b/test/basicserver/testfiles/seclevel2-sha256/ca/servers/localhost-cert-sha1.pem
@@ -0,0 +1,17 @@
+-----BEGIN CERTIFICATE-----
+MIICrDCCAZQCAQIwDQYJKoZIhvcNAQEFBQAwJDEiMCAGA1UEAwwZQmFja3VwIHN5
+c3RlbSBzZXJ2ZXIgcm9vdDAeFw0xOTA0MjkxOTI3NDRaFw0zMzAxMDUxOTI3NDRa
+MBQxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
+AQoCggEBAPVJN1fqLpbabNasGicKPsN99rWpdra46+Swl6E7l1KzuPsSSAWCgtg+
+2vjZdlVGcPiq+lBCP8HO0TsDPOLPZdYwmeYl1a8//Fx2CbyV8LsNyA0BEhW8WbKz
+YNBQvFOxhLVZQkZ1a+gdkZHIj5A1yt01anX+N37+K64qT0hP3eIWwKv7j3eS2TVE
+HcushbDMsBuHEqomh8N4YOGi4BehCl49vbPCBU4jYTNYfF6wgYtDH8giKtox1TNf
+2US9dBwOnDL7v9hPqH6yxE5ehZU88guFhUAar9KJxZihSDOW7QFSKJPzSFl+b6ZN
+a6hp0jrlv+pYVDuMnMxMWWnYA8Me2IsCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA
+E8KZNWzkbNwhcVEHR34IxVYPy1uppI/jtVOsQGGSVC1UscAWyGiQWPxqMhwYxsVn
+gz7QYj1oKye1VRuJNTekARvBRFZzWhAi0qGlpiC5yilZB8IlhYUABmgPjg+PuhAF
+xSd+IGVlm/+sisClsPG9DpesyK6+C2ukpVXyaXWR+1/IrQuUpWKLT1pPamVH3zWK
+anT+62bbk0XuxsVqCkGx+aPLesCHAfTNuAxWfkbXXcA+HoGNy3IpmpJGhyCnf1je
+eL6Wf6sAY44y7wQlwHimbi4kOge+UFLIKkqhHSDO2pzyPc02Gs1bBRd94+v2z5h7
+OkIcTqwiJLjLLIWV4WsdwA==
+-----END CERTIFICATE-----
diff --git a/test/basicserver/testfiles/seclevel2-sha256/ca/servers/localhost-cert.pem b/test/basicserver/testfiles/seclevel2-sha256/ca/servers/localhost-cert.pem
new file mode 100644
index 00000000..40ce8cbf
--- /dev/null
+++ b/test/basicserver/testfiles/seclevel2-sha256/ca/servers/localhost-cert.pem
@@ -0,0 +1,17 @@
+-----BEGIN CERTIFICATE-----
+MIICrDCCAZQCAQEwDQYJKoZIhvcNAQELBQAwJDEiMCAGA1UEAwwZQmFja3VwIHN5
+c3RlbSBzZXJ2ZXIgcm9vdDAeFw0xOTA0MjgyMDUxNTdaFw0zMzAxMDQyMDUxNTda
+MBQxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
+AQoCggEBAPVJN1fqLpbabNasGicKPsN99rWpdra46+Swl6E7l1KzuPsSSAWCgtg+
+2vjZdlVGcPiq+lBCP8HO0TsDPOLPZdYwmeYl1a8//Fx2CbyV8LsNyA0BEhW8WbKz
+YNBQvFOxhLVZQkZ1a+gdkZHIj5A1yt01anX+N37+K64qT0hP3eIWwKv7j3eS2TVE
+HcushbDMsBuHEqomh8N4YOGi4BehCl49vbPCBU4jYTNYfF6wgYtDH8giKtox1TNf
+2US9dBwOnDL7v9hPqH6yxE5ehZU88guFhUAar9KJxZihSDOW7QFSKJPzSFl+b6ZN
+a6hp0jrlv+pYVDuMnMxMWWnYA8Me2IsCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEA
+fu1wVNuZLkO0e8+oYAnznL7oknE8QJGAd/P2/MqgfsnBXHS0UVl+5L8DQdvCBarr
+vDO/CVL9/ZGj30CipA556cz1pYDtx5TV2GLtfKHKJhoftbgswmt1pPowIIa8zlBA
+SOERy2ooXGnrA5kii+fifkiWy1R0FmJTKZ2jX41Xq60FwXWX7cyCq/xRI+V08HrY
+mNJ2rmAjyWpWZpPNOtQ/SYIX1s2KoPw4XMxfiP5fiMOl3RqEVBkW0h9Hxikl8wKY
+EmA/ESm1F6lnRXvGXWDGQIFCRf2Rv0KlPvNPA/GLZMr0ibYIjc4KnIxKFg//GQF3
+LUYpyJyToT8hE49ypG18mQ==
+-----END CERTIFICATE-----
diff --git a/test/basicserver/testfiles/seclevel2-sha256/raidfile.conf b/test/basicserver/testfiles/seclevel2-sha256/raidfile.conf
new file mode 100644
index 00000000..6e235b24
--- /dev/null
+++ b/test/basicserver/testfiles/seclevel2-sha256/raidfile.conf
@@ -0,0 +1,10 @@
+
+disc0
+{
+ SetNumber = 0
+ BlockSize = 1024
+ Dir0 = .
+ Dir1 = .
+ Dir2 = .
+}
+
diff --git a/test/basicserver/testfiles/srv3-insecure-daemon.conf b/test/basicserver/testfiles/srv3-insecure-daemon.conf
new file mode 100644
index 00000000..09cf352d
--- /dev/null
+++ b/test/basicserver/testfiles/srv3-insecure-daemon.conf
@@ -0,0 +1,9 @@
+Server
+{
+ PidFile = testfiles/srv3.pid
+ ListenAddresses = inet:localhost,unix:testfiles/srv3.sock
+ CertificateFile = testfiles/seclevel2-sha256/ca/servers/localhost-cert-sha1.pem
+ PrivateKeyFile = testfiles/seclevel2-sha256/bbstored/localhost-key.pem
+ TrustedCAsFile = testfiles/seclevel2-sha256/ca/roots/clientCA.pem
+}
+
diff --git a/test/basicserver/testfiles/srv3-seclevel2-sha1.conf b/test/basicserver/testfiles/srv3-seclevel2-sha1.conf
new file mode 100644
index 00000000..93c0f99f
--- /dev/null
+++ b/test/basicserver/testfiles/srv3-seclevel2-sha1.conf
@@ -0,0 +1,9 @@
+Server
+{
+ PidFile = testfiles/srv3.pid
+ ListenAddresses = inet:localhost,unix:testfiles/srv3.sock
+ CertificateFile = testfiles/seclevel2-sha1/ca/servers/localhost-cert.pem
+ PrivateKeyFile = testfiles/seclevel2-sha1/bbstored/localhost-key.pem
+ TrustedCAsFile = testfiles/seclevel2-sha1/ca/roots/clientCA.pem
+}
+
diff --git a/test/basicserver/testfiles/srv3-seclevel2-sha256.conf b/test/basicserver/testfiles/srv3-seclevel2-sha256.conf
new file mode 100644
index 00000000..58c267d4
--- /dev/null
+++ b/test/basicserver/testfiles/srv3-seclevel2-sha256.conf
@@ -0,0 +1,9 @@
+Server
+{
+ PidFile = testfiles/srv3.pid
+ ListenAddresses = inet:localhost,unix:testfiles/srv3.sock
+ CertificateFile = testfiles/seclevel2-sha256/ca/servers/localhost-cert.pem
+ PrivateKeyFile = testfiles/seclevel2-sha256/bbstored/localhost-key.pem
+ TrustedCAsFile = testfiles/seclevel2-sha256/ca/roots/clientCA.pem
+}
+
diff --git a/test/basicserver/testfiles/srv4.conf b/test/basicserver/testfiles/srv4-noseclevel.conf
index f05dff75..db22e95f 100644
--- a/test/basicserver/testfiles/srv4.conf
+++ b/test/basicserver/testfiles/srv4-noseclevel.conf
@@ -3,4 +3,3 @@ Server
PidFile = testfiles/srv4.pid
ListenAddresses = unix:testfiles/srv4.sock,inet:localhost
}
-
diff --git a/test/basicserver/testfiles/srv4-seclevel1.conf b/test/basicserver/testfiles/srv4-seclevel1.conf
new file mode 100644
index 00000000..cd90566c
--- /dev/null
+++ b/test/basicserver/testfiles/srv4-seclevel1.conf
@@ -0,0 +1,7 @@
+Server
+{
+ PidFile = testfiles/srv4.pid
+ ListenAddresses = unix:testfiles/srv4.sock,inet:localhost
+}
+
+SSLSecurityLevel = 1
diff --git a/test/basicserver/testfiles/srv4-seclevel2-insecure.conf b/test/basicserver/testfiles/srv4-seclevel2-insecure.conf
new file mode 100644
index 00000000..5d8b1149
--- /dev/null
+++ b/test/basicserver/testfiles/srv4-seclevel2-insecure.conf
@@ -0,0 +1,7 @@
+Server
+{
+ PidFile = testfiles/srv4.pid
+ ListenAddresses = unix:testfiles/srv4.sock,inet:localhost
+}
+
+SSLSecurityLevel = 2
diff --git a/test/basicserver/testfiles/srv4-seclevel2-secure.conf b/test/basicserver/testfiles/srv4-seclevel2-secure.conf
new file mode 100644
index 00000000..5d8b1149
--- /dev/null
+++ b/test/basicserver/testfiles/srv4-seclevel2-secure.conf
@@ -0,0 +1,7 @@
+Server
+{
+ PidFile = testfiles/srv4.pid
+ ListenAddresses = unix:testfiles/srv4.sock,inet:localhost
+}
+
+SSLSecurityLevel = 2
diff --git a/test/bbackupd/testbbackupd.cpp b/test/bbackupd/testbbackupd.cpp
index cc602f22..deff53e2 100644
--- a/test/bbackupd/testbbackupd.cpp
+++ b/test/bbackupd/testbbackupd.cpp
@@ -12,39 +12,44 @@
// do not include MinGW's dirent.h on Win32,
// as we override some of it in lib/win32.
+#include <limits.h>
+#include <stdio.h>
+#include <string.h>
+
#ifndef WIN32
#include <dirent.h>
#endif
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <limits.h>
-#include <string.h>
-
-#ifdef HAVE_SYS_WAIT_H
- #include <sys/wait.h>
+#ifdef WIN32
+ #include <process.h>
#endif
-#ifdef HAVE_SYS_XATTR_H
- #include <cerrno>
- #include <sys/xattr.h>
+#ifdef HAVE_PWD_H
+ #include <pwd.h>
#endif
#ifdef HAVE_SIGNAL_H
#include <signal.h>
#endif
-#ifdef WIN32
- #include <process.h>
-#endif
-
-#include <map>
+#include <sys/stat.h>
+#include <sys/types.h>
#ifdef HAVE_SYSCALL
#include <sys/syscall.h>
#endif
+#ifdef HAVE_SYS_WAIT_H
+ #include <sys/wait.h>
+#endif
+
+#ifdef HAVE_SYS_XATTR_H
+ #include <cerrno>
+ #include <sys/xattr.h>
+#endif
+
+#include <map>
+
#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<BackupClientContext> 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<Capture::Message> messages = capture.GetMessages();
+ TEST_THAT(!messages.empty());
+ if (!messages.empty())
+ {
+ bool found_not_set = false, found_not_supported = false;
+ for(std::vector<Capture::Message>::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());