aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuilhem Moulin <guilhem@fripost.org>2022-02-23 22:30:45 +0100
committerGuilhem Moulin <guilhem@fripost.org>2022-02-23 23:43:58 +0100
commit2447861913835637bbf49d96728ce9ac6ab0ae22 (patch)
tree4f865a799547eb6b2a6728de37e65a6f07665b4e
parent4d36557a007f06196affe14afd1a2bd2a4945c44 (diff)
interimap, pullimap: Ensure DB and statefiles are created with mode 0600.
It wasn't the case for interimap(1), see https://bugs.debian.org/608604 … Fortunately we create $XDG_DATA_HOME/interimap with a secure mode, but there is no reason to have the DB world-readable. Since we can't rely on SQLITE_OPEN_CREATE for secure mode we use sysopen(,,O_CREAT,0600).
-rwxr-xr-xinterimap10
-rw-r--r--tests/db-exclusive-lock/t4
-rw-r--r--tests/db-no-create--watch/t2
-rw-r--r--tests/pullimap/t7
-rwxr-xr-xtests/run5
5 files changed, 21 insertions, 7 deletions
diff --git a/interimap b/interimap
index 9ba5d06..d4ff3fc 100755
--- a/interimap
+++ b/interimap
@@ -29,7 +29,7 @@ use Getopt::Long qw/:config posix_default no_ignore_case gnu_compat
bundling auto_version/;
use DBI ':sql_types';
use DBD::SQLite::Constants ':file_open';
-use Fcntl qw/F_GETFD F_SETFD FD_CLOEXEC/;
+use Fcntl qw/O_WRONLY O_CREAT O_EXCL F_GETFD F_SETFD FD_CLOEXEC/;
use List::Util 'first';
use lib "./lib";
@@ -160,6 +160,12 @@ $SIG{TERM} = sub { cleanup(); exit 0; };
# Open (and maybe create) the database
{
+ # don't auto-create in long-lived mode
+ unless ($CONFIG{watch} or -e $DBFILE) {
+ sysopen(my $fh, $DBFILE, O_WRONLY | O_CREAT | O_EXCL, 0600) or die "Can't create $DBFILE: $!";
+ close $fh or warn "close: $!";
+ }
+
my $dbi_data_source = "dbi:SQLite:dbname=".$DBFILE;
my %dbi_attrs = (
AutoCommit => 0,
@@ -167,8 +173,6 @@ $SIG{TERM} = sub { cleanup(); exit 0; };
sqlite_use_immediate_transaction => 1,
sqlite_open_flags => SQLITE_OPEN_READWRITE
);
- # don't auto-create in long-lived mode
- $dbi_attrs{sqlite_open_flags} |= SQLITE_OPEN_CREATE unless defined $CONFIG{watch};
$DBH = DBI::->connect($dbi_data_source, undef, undef, \%dbi_attrs);
$DBH->sqlite_busy_timeout(250);
diff --git a/tests/db-exclusive-lock/t b/tests/db-exclusive-lock/t
index 7cbe550..837d21b 100644
--- a/tests/db-exclusive-lock/t
+++ b/tests/db-exclusive-lock/t
@@ -10,7 +10,7 @@ sleep .5
# subsequent runs fail as we can't acquire the exclusive lock
! interimap || error
-grep -Ex "DBD::SQLite::db do failed: database is locked at (\S+/)?interimap line 177\." <"$STDERR" \
- || error "Is \$DBH->do(\"PRAGMA locking_mode = EXCLUSIVE\"); at line 177?"
+grep -Ex "DBD::SQLite::db do failed: database is locked at (\S+/)?interimap line 181\." <"$STDERR" \
+ || error "Is \$DBH->do(\"PRAGMA locking_mode = EXCLUSIVE\"); at line 181?"
# vim: set filetype=sh :
diff --git a/tests/db-no-create--watch/t b/tests/db-no-create--watch/t
index 7ac3d31..37fc6cb 100644
--- a/tests/db-no-create--watch/t
+++ b/tests/db-no-create--watch/t
@@ -1,6 +1,6 @@
! interimap --watch=60 || error
-grep -Ex "DBI connect\(.*\) failed: unable to open database file at (\S+/)?interimap line 173\." <"$STDERR" || error
+grep -Ex "DBI connect\(.*\) failed: unable to open database file at (\S+/)?interimap line 177\." <"$STDERR" || error
test \! -e "$XDG_DATA_HOME/interimap/remote.db" || error
# vim: set filetype=sh :
diff --git a/tests/pullimap/t b/tests/pullimap/t
index 0dfe634..7998cdc 100644
--- a/tests/pullimap/t
+++ b/tests/pullimap/t
@@ -6,6 +6,13 @@ step_start "\`pullimap --idle\` refuses to create the state file"
! pullimap --idle "remote" || error
step_done
+step_start "\`pullimap\` creates statefile with mode 0600"
+pullimap "remote" || error
+if ! st="$(stat -c"%#a" -- "$XDG_DATA_HOME/pullimap/remote")" || [ "$st" != "0600" ]; then
+ error "$XDG_DATA_HOME/pullimap/remote has mode $st != 0600"
+fi
+step_done
+
# compare mailboxes (can't compare the RFC 3501 TEXT as the LMTPd inconditionally
# adds a Return-Path: header -- and also Delivered-To: and Received: to by default)
list_mails_sha256() {
diff --git a/tests/run b/tests/run
index 230ca83..eed77df 100755
--- a/tests/run
+++ b/tests/run
@@ -228,13 +228,16 @@ _interimap_cmd() {
}
interimap_init() {
local u="${1-remote}"
- local db="$XDG_DATA_HOME/interimap/$u.db"
+ local db="$XDG_DATA_HOME/interimap/$u.db" st
local cfg="config${u#remote}"
test \! -e "$db" || error "Database already exists" 1
interimap --config "$cfg" || error "Couldn't initialize interimap" 1
test -f "$db" || error "Database is still missing" 1
grep -Fx "Creating new schema in database file $db" <"$STDERR" || error "DB wasn't created" 1
+ if ! st="$(stat -c"%#a" -- "$db")" || [ "$st" != "0600" ]; then
+ error "$db has mode $st != 0600" 1
+ fi
}
doveadm() {
if [ $# -le 2 ] || [ "$1" != "-u" ]; then