diff options
-rw-r--r-- | apt-pkg/contrib/fileutl.cc | 27 | ||||
-rwxr-xr-x | debian/apt.systemd.daily | 67 | ||||
-rw-r--r-- | test/libapt/openmaybeclearsignedfile_test.cc | 51 |
3 files changed, 91 insertions, 54 deletions
diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc index d3764d003..f8f7a478c 100644 --- a/apt-pkg/contrib/fileutl.cc +++ b/apt-pkg/contrib/fileutl.cc @@ -43,6 +43,7 @@ #include <signal.h> #include <stdarg.h> #include <stddef.h> +#include <stdio.h> #include <sys/select.h> #include <sys/stat.h> #include <sys/time.h> @@ -928,17 +929,31 @@ bool ExecWait(pid_t Pid,const char *Name,bool Reap) // StartsWithGPGClearTextSignature - Check if a file is Pgp/GPG clearsigned /*{{{*/ bool StartsWithGPGClearTextSignature(string const &FileName) { - static const char* SIGMSG = "-----BEGIN PGP SIGNED MESSAGE-----\n"; - char buffer[strlen(SIGMSG)+1]; FILE* gpg = fopen(FileName.c_str(), "r"); - if (gpg == NULL) + if (gpg == nullptr) return false; - char const * const test = fgets(buffer, sizeof(buffer), gpg); - fclose(gpg); - if (test == NULL || strcmp(buffer, SIGMSG) != 0) + char * lineptr = nullptr; + size_t n = 0; + errno = 0; + ssize_t const result = getline(&lineptr, &n, gpg); + if (errno != 0) + { + _error->Errno("getline", "Could not read from %s", FileName.c_str()); + fclose(gpg); + free(lineptr); return false; + } + fclose(gpg); + _strrstrip(lineptr); + static const char* SIGMSG = "-----BEGIN PGP SIGNED MESSAGE-----"; + if (result == -1 || strcmp(lineptr, SIGMSG) != 0) + { + free(lineptr); + return false; + } + free(lineptr); return true; } /*}}}*/ diff --git a/debian/apt.systemd.daily b/debian/apt.systemd.daily index 40b6692ec..b532bd151 100755 --- a/debian/apt.systemd.daily +++ b/debian/apt.systemd.daily @@ -78,19 +78,19 @@ check_stamp() stamp="$1" interval="$2" - if [ $interval = always ]; then + if [ "$interval" = always ]; then debug_echo "check_stamp: ignoring time stamp file, interval set to always" # treat as enough time has passed return 0 fi - if [ $interval -eq 0 ]; then + if [ "$interval" -eq 0 ]; then debug_echo "check_stamp: interval=0" # treat as no time has passed return 1 fi - if [ ! -f $stamp ]; then + if [ ! -f "$stamp" ]; then debug_echo "check_stamp: missing time stamp file: $stamp." # treat as enough time has passed return 0 @@ -98,7 +98,7 @@ check_stamp() # compare midnight today to midnight the day the stamp was updated stamp_file="$stamp" - stamp=$(date --date=$(date -r $stamp_file --iso-8601) +%s 2>/dev/null) + stamp=$(date --date="$(date -r "$stamp_file" --iso-8601)" +%s 2>/dev/null) if [ "$?" != "0" ]; then # Due to some timezones returning 'invalid date' for midnight on # certain dates (e.g. America/Sao_Paulo), if date returns with error @@ -108,7 +108,7 @@ check_stamp() return 0 fi - now=$(date --date=$(date --iso-8601) +%s 2>/dev/null) + now=$(date --date="$(date --iso-8601)" +%s 2>/dev/null) if [ "$?" != "0" ]; then # As above, due to some timezones returning 'invalid date' for midnight # on certain dates (e.g. America/Sao_Paulo), if date returns with error @@ -116,7 +116,7 @@ check_stamp() return 0 fi - delta=$(($now-$stamp)) + delta=$((now-stamp)) # Calculate the interval in seconds depending on the unit specified if [ "${interval%s}" != "$interval" ] ; then @@ -135,7 +135,7 @@ check_stamp() debug_echo "check_stamp: interval=$interval, now=$now, stamp=$stamp, delta=$delta (sec)" # remove timestamps a day (or more) in the future and force re-check - if [ $stamp -gt $(($now+86400)) ]; then + if [ "$stamp" -gt $((now+86400)) ]; then echo "WARNING: file $stamp_file has a timestamp in the future: $stamp" rm -f "$stamp_file" return 0 @@ -151,7 +151,7 @@ check_stamp() update_stamp() { stamp="$1" - touch $stamp + touch "$stamp" } # we check here if autoclean was enough sizewise @@ -192,11 +192,11 @@ check_size_constraints() # check size if [ ! $MaxSize -eq 0 ]; then # maxSize is in MB - MaxSize=$(($MaxSize*1024)) + MaxSize=$((MaxSize*1024)) #get current time - now=$(date --date=$(date --iso-8601) +%s) - MinAge=$(($MinAge*24*60*60)) + now=$(date --date="$(date --iso-8601)" +%s) + MinAge=$((MinAge*24*60*60)) # reverse-sort by mtime for file in $(ls -rt $Cache/*.deb 2>/dev/null); do @@ -211,12 +211,12 @@ check_size_constraints() # check for MinAge of the file if [ $MinAge -ne 0 ]; then # check both ctime and mtime - mtime=$(stat -c %Y $file) - ctime=$(stat -c %Z $file) - if [ $mtime -gt $ctime ]; then - delta=$(($now-$mtime)) + mtime=$(stat -c %Y "$file") + ctime=$(stat -c %Z "$file") + if [ "$mtime" -gt "$ctime" ]; then + delta=$((now-mtime)) else - delta=$(($now-$ctime)) + delta=$((now-ctime)) fi if [ $delta -le $MinAge ]; then debug_echo "skip remove by archive size: $file, delta=$delta < $MinAge" @@ -224,7 +224,7 @@ check_size_constraints() else # delete oldest file debug_echo "remove by archive size: $file, delta=$delta >= $MinAge (sec), size=$size >= $MaxSize" - rm -f $file + rm -f "$file" fi fi done @@ -235,10 +235,10 @@ check_size_constraints() do_cache_backup() { BackupArchiveInterval="$1" - if [ $BackupArchiveInterval = always ]; then + if [ "$BackupArchiveInterval" = always ]; then : - elif [ $BackupArchiveInterval -eq 0 ]; then - return + elif [ "$BackupArchiveInterval" -eq 0 ]; then + return fi # Set default values and normalize @@ -273,20 +273,20 @@ do_cache_backup() CacheArchive="$(basename "${Cache}")" test -n "${CacheArchive}" || CacheArchive="archives" BackX="${Back}${CacheArchive}/" - for x in $(seq 0 1 $((${BackupLevel}-1))); do + for x in $(seq 0 1 $((BackupLevel-1))); do eval "Back${x}=${Back}${x}/" done # backup after n-days if archive contents changed. # (This uses hardlink to save disk space) BACKUP_ARCHIVE_STAMP=/var/lib/apt/periodic/backup-archive-stamp - if check_stamp $BACKUP_ARCHIVE_STAMP $BackupArchiveInterval; then - if [ $({(cd $Cache 2>/dev/null; find . -name "*.deb"); (cd $Back0 2>/dev/null;find . -name "*.deb") ;}| sort|uniq -u|wc -l) -ne 0 ]; then + if check_stamp $BACKUP_ARCHIVE_STAMP "$BackupArchiveInterval"; then + if [ $({ (cd $Cache 2>/dev/null; find . -name "*.deb"); (cd $Back0 2>/dev/null;find . -name "*.deb") ;}| sort|uniq -u|wc -l) -ne 0 ]; then mkdir -p $Back - rm -rf $Back$((${BackupLevel}-1)) - for y in $(seq $((${BackupLevel}-1)) -1 1); do + rm -rf $Back$((BackupLevel-1)) + for y in $(seq $((BackupLevel-1)) -1 1); do eval BackY=${Back}$y - eval BackZ=${Back}$(($y-1)) + eval BackZ=${Back}$((y-1)) if [ -e $BackZ ]; then mv -f $BackZ $BackY ; fi @@ -306,7 +306,7 @@ debug_echo() { # Display message if $VERBOSE >= 1 if [ "$VERBOSE" -ge 1 ]; then - echo $1 1>&2 + echo "$1" 1>&2 fi } @@ -428,7 +428,7 @@ elif [ $UpdateInterval -eq 0 ] && exit 0 fi -if [ "$1" = "update" -o -z "$1" ] ; then +if [ "$1" = "update" ] || [ -z "$1" ] ; then # deal with BackupArchiveInterval do_cache_backup $BackupArchiveInterval @@ -445,15 +445,6 @@ if [ "$1" = "update" -o -z "$1" ] ; then if check_stamp $UPDATE_STAMP $UpdateInterval; then if eval apt-get $XAPTOPT -y update $XSTDERR; then debug_echo "download updated metadata (success)." - if which dbus-send >/dev/null 2>&1 && pidof dbus-daemon >/dev/null 2>&1; then - if dbus-send --system / app.apt.dbus.updated boolean:true ; then - debug_echo "send dbus signal (success)" - else - debug_echo "send dbus signal (error)" - fi - else - debug_echo "dbus signal not send (command not available)" - fi update_stamp $UPDATE_STAMP UPDATED=1 else @@ -491,7 +482,7 @@ if [ "$1" = "update" -o -z "$1" ] ; then fi fi -if [ "$1" = "install" -o -z "$1" ] ; then +if [ "$1" = "install" ] || [ -z "$1" ] ; then # auto upgrade all upgradeable packages UPGRADE_STAMP=/var/lib/apt/periodic/upgrade-stamp if which unattended-upgrade >/dev/null 2>&1 && check_stamp $UPGRADE_STAMP $UnattendedUpgradeInterval; then diff --git a/test/libapt/openmaybeclearsignedfile_test.cc b/test/libapt/openmaybeclearsignedfile_test.cc index 40735812d..1f63fb8fc 100644 --- a/test/libapt/openmaybeclearsignedfile_test.cc +++ b/test/libapt/openmaybeclearsignedfile_test.cc @@ -33,7 +33,7 @@ TEST(OpenMaybeClearSignedFileTest,SimpleSignedFile) "JQt/+gJCPxHUJphy8sccBKhW29CLELJIIafvU30E1nWn9szh2Xjq\n" "=TB1F\n" "-----END PGP SIGNATURE-----\n"); - + EXPECT_TRUE(StartsWithGPGClearTextSignature(tempfile)); EXPECT_TRUE(OpenMaybeClearSignedFile(tempfile, fd)); if (tempfile.empty() == false) unlink(tempfile.c_str()); @@ -64,7 +64,7 @@ TEST(OpenMaybeClearSignedFileTest,WhitespaceSignedFile) "JQt/+gJCPxHUJphy8sccBKhW29CLELJIIafvU30E1nWn9szh2Xjq \n" "=TB1F \n" "-----END PGP SIGNATURE-----"); - + EXPECT_TRUE(StartsWithGPGClearTextSignature(tempfile)); EXPECT_TRUE(OpenMaybeClearSignedFile(tempfile, fd)); if (tempfile.empty() == false) unlink(tempfile.c_str()); @@ -100,7 +100,7 @@ TEST(OpenMaybeClearSignedFileTest,SignedFileWithContentHeaders) "JQt/+gJCPxHUJphy8sccBKhW29CLELJIIafvU30E1nWn9szh2Xjq\n" "=TB1F\n" "-----END PGP SIGNATURE-----\n"); - + EXPECT_TRUE(StartsWithGPGClearTextSignature(tempfile)); EXPECT_TRUE(OpenMaybeClearSignedFile(tempfile, fd)); if (tempfile.empty() == false) unlink(tempfile.c_str()); @@ -142,7 +142,7 @@ TEST(OpenMaybeClearSignedFileTest,SignedFileWithTwoSignatures) "ASc9hsAZRG0xHuRU0F94V/XrkWw8QYAobJ/yxvs4L0EuA4optbSqawDB\n" "=CP8j\n" "-----END PGP SIGNATURE-----\n"); - + EXPECT_TRUE(StartsWithGPGClearTextSignature(tempfile)); EXPECT_TRUE(OpenMaybeClearSignedFile(tempfile, fd)); if (tempfile.empty() == false) unlink(tempfile.c_str()); @@ -188,8 +188,8 @@ TEST(OpenMaybeClearSignedFileTest,TwoSimpleSignedFile) "JQt/+gJCPxHUJphy8sccBKhW29CLELJIIafvU30E1nWn9szh2Xjq\n" "=TB1F\n" "-----END PGP SIGNATURE-----"); - EXPECT_TRUE(_error->empty()); + EXPECT_TRUE(StartsWithGPGClearTextSignature(tempfile)); EXPECT_TRUE(OpenMaybeClearSignedFile(tempfile, fd)); if (tempfile.empty() == false) unlink(tempfile.c_str()); @@ -211,7 +211,7 @@ TEST(OpenMaybeClearSignedFileTest,UnsignedFile) std::string tempfile; FileFd fd; createTemporaryFile("unsignedfile", fd, &tempfile, "Test"); - + EXPECT_FALSE(StartsWithGPGClearTextSignature(tempfile)); EXPECT_TRUE(OpenMaybeClearSignedFile(tempfile, fd)); if (tempfile.empty() == false) unlink(tempfile.c_str()); @@ -242,7 +242,7 @@ TEST(OpenMaybeClearSignedFileTest,GarbageTop) "JQt/+gJCPxHUJphy8sccBKhW29CLELJIIafvU30E1nWn9szh2Xjq\n" "=TB1F\n" "-----END PGP SIGNATURE-----\n"); - + EXPECT_FALSE(StartsWithGPGClearTextSignature(tempfile)); EXPECT_TRUE(_error->empty()); EXPECT_TRUE(OpenMaybeClearSignedFile(tempfile, fd)); if (tempfile.empty() == false) @@ -260,6 +260,37 @@ TEST(OpenMaybeClearSignedFileTest,GarbageTop) EXPECT_EQ("Clearsigned file '" + tempfile + "' does not start with a signed message block.", msg); } +TEST(OpenMaybeClearSignedFileTest,GarbageHeader) +{ + std::string tempfile; + FileFd fd; + createTemporaryFile("garbageheader", fd, &tempfile, "-----BEGIN PGP SIGNED MESSAGE----- Garbage\n" +"Hash: SHA512\n" +"\n" +"Test\n" +"-----BEGIN PGP SIGNATURE-----\n" +"\n" +"iQFEBAEBCgAuFiEENKjp0Y2zIPNn6OqgWpDRQdusja4FAlhT7+kQHGpvZUBleGFt\n" +"cGxlLm9yZwAKCRBakNFB26yNrjvEB/9/e3jA1l0fvPafx9LEXcH8CLpUFQK7ra9l\n" +"3M4YAH4JKQlTG1be7ixruBRlCTh3YiSs66fKMeJeUYoxA2HPhvbGFEjQFAxunEYg\n" +"X/LBKv1mQWa+Q34P5GBjK8kQdLCN+yJAiUErmWNQG3GPninrxsC9tY5jcWvHeP1k\n" +"V7N3MLnNqzXaCJM24mnKidC5IDadUdQ8qC8c3rjUexQ8vBz0eucH56jbqV5oOcvx\n" +"pjlW965dCPIf3OI8q6J7bIOjyY+u/PTcVlqPq3TUz/ti6RkVbKpLH0D4ll3lUTns\n" +"JQt/+gJCPxHUJphy8sccBKhW29CLELJIIafvU30E1nWn9szh2Xjq\n" +"=TB1F\n" +"-----END PGP SIGNATURE-----\n"); + EXPECT_FALSE(StartsWithGPGClearTextSignature(tempfile)); + // beware: the file will be successfully opened as unsigned file + EXPECT_TRUE(OpenMaybeClearSignedFile(tempfile, fd)); + if (tempfile.empty() == false) + unlink(tempfile.c_str()); + EXPECT_TRUE(fd.IsOpen()); + char buffer[100]; + EXPECT_TRUE(fd.ReadLine(buffer, sizeof(buffer))); + EXPECT_STREQ(buffer, "-----BEGIN PGP SIGNED MESSAGE----- Garbage\n"); + EXPECT_FALSE(fd.Eof()); +} + TEST(OpenMaybeClearSignedFileTest,GarbageBottom) { std::string tempfile; @@ -280,7 +311,7 @@ TEST(OpenMaybeClearSignedFileTest,GarbageBottom) "=TB1F\n" "-----END PGP SIGNATURE-----\n" "Garbage"); - + EXPECT_TRUE(StartsWithGPGClearTextSignature(tempfile)); EXPECT_TRUE(_error->empty()); EXPECT_TRUE(OpenMaybeClearSignedFile(tempfile, fd)); if (tempfile.empty() == false) @@ -306,7 +337,7 @@ TEST(OpenMaybeClearSignedFileTest,BogusNoSig) "Hash: SHA512\n" "\n" "Test"); - + EXPECT_TRUE(StartsWithGPGClearTextSignature(tempfile)); EXPECT_TRUE(_error->empty()); EXPECT_FALSE(OpenMaybeClearSignedFile(tempfile, fd)); if (tempfile.empty() == false) @@ -328,7 +359,7 @@ TEST(OpenMaybeClearSignedFileTest,BogusSigStart) "\n" "Test\n" "-----BEGIN PGP SIGNATURE-----"); - + EXPECT_TRUE(StartsWithGPGClearTextSignature(tempfile)); EXPECT_TRUE(_error->empty()); EXPECT_FALSE(OpenMaybeClearSignedFile(tempfile, fd)); if (tempfile.empty() == false) |