From 2447861913835637bbf49d96728ce9ac6ab0ae22 Mon Sep 17 00:00:00 2001 From: Guilhem Moulin Date: Wed, 23 Feb 2022 22:30:45 +0100 Subject: interimap, pullimap: Ensure DB and statefiles are created with mode 0600. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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). --- interimap | 10 +++++++--- tests/db-exclusive-lock/t | 4 ++-- tests/db-no-create--watch/t | 2 +- tests/pullimap/t | 7 +++++++ tests/run | 5 ++++- 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 -- cgit v1.2.3