aboutsummaryrefslogtreecommitdiff
#define _XOPEN_SOURCE 600

#include "config.h"

#include <cerrno>
#include <algorithm>
#include <vector>
#include <map>

#include <strings.h> // for strcasecmp

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>
#include <fcntl.h>

#include "archive.hh"
#include "util.hh"


namespace nix {

static string archiveVersion1 = "nix-archive-1";

static string caseHackSuffix = "~nix~case~hack~";

PathFilter defaultPathFilter;


static void dumpContents(const Path & path, size_t size,
    Sink & sink)
{
    writeString("contents", sink);
    writeLongLong(size, sink);

    AutoCloseFD fd = open(path.c_str(), O_RDONLY);
    if (fd == -1) throw SysError(format("opening file `%1%'") % path);

    unsigned char buf[65536];
    size_t left = size;

    while (left > 0) {
        size_t n = left > sizeof(buf) ? sizeof(buf) : left;
        readFull(fd, buf, n);
        left -= n;
        sink(buf, n);
    }

    writePadding(size, sink);
}


static void dump(const Path & path, Sink & sink, PathFilter & filter)
{
    struct stat st;
    if (lstat(path.c_str(), &st))
        throw SysError(format("getting attributes of path `%1%'") % path);

    writeString("(", sink);

    if (S_ISREG(st.st_mode)) {
        writeString("type", sink);
        writeString("regular", sink);
        if (st.st_mode & S_IXUSR) {
            writeString("executable", sink);
            writeString("", sink);
        }
        dumpContents(path, (size_t) st.st_size, sink);
    }

    else if (S_ISDIR(st.st_mode)) {
        writeString("type", sink);
        writeString("directory", sink);

        /* If we're on a case-insensitive system like Mac OS X, undo
           the case hack applied by restorePath(). */
        std::map<string, string> unhacked;
        for (auto & i : readDirectory(path))
	    unhacked[i.name] = i.name;

        for (auto & i : unhacked)
            if (filter(path + "/" + i.first)) {
                writeString("entry", sink);
                writeString("(", sink);
                writeString("name", sink);
                writeString(i.first, sink);
                writeString("node", sink);
                dump(path + "/" + i.second, sink, filter);
                writeString(")", sink);
            }
    }

    else if (S_ISLNK(st.st_mode)) {
        writeString("type", sink);
        writeString("symlink", sink);
        writeString("target", sink);
        writeString(readLink(path), sink);
    }

    else throw Error(format("file `%1%' has an unsupported type") % path);

    writeString(")", sink);
}


void dumpPath(const Path & path, Sink & sink, PathFilter & filter)
{
    writeString(archiveVersion1, sink);
    dump(path, sink, filter);
}


static SerialisationError badArchive(string s)
{
    return SerialisationError("bad archive: " + s);
}


#if 0
static void skipGeneric(Source & source)
{
    if (readString(source) == "(") {
        while (readString(source) != ")")
            skipGeneric(source);
    }
}
#endif


static void parseContents(ParseSink & sink, Source & source, const Path & path)
{
    unsigned long long size = readLongLong(source);

    sink.preallocateContents(size);

    unsigned long long left = size;
    unsigned char buf[65536];

    while (left) {
        checkInterrupt();
        unsigned int n = sizeof(buf);
        if ((unsigned long long) n > left) n = left;
        source(buf, n);
        sink.receiveContents(buf, n);
        left -= n;
    }

    readPadding(size, source);
}


struct CaseInsensitiveCompare
{
    bool operator() (const string & a, const string & b) const
    {
        return strcasecmp(a.c_str(), b.c_str()) < 0;
    }
};


static void parse(ParseSink & sink, Source & source, const Path & path)
{
    string s;

    s = readString(source);
    if (s != "(") throw badArchive("expected open tag");

    enum { tpUnknown, tpRegular, tpDirectory, tpSymlink } type = tpUnknown;

    std::map<Path, int, CaseInsensitiveCompare> names;

    while (1) {
        checkInterrupt();

        s = readString(source);

        if (s == ")") {
            break;
        }

        else if (s == "type") {
            if (type != tpUnknown)
                throw badArchive("multiple type fields");
            string t = readString(source);

            if (t == "regular") {
                type = tpRegular;
                sink.createRegularFile(path);
            }

            else if (t == "directory") {
                sink.createDirectory(path);
                type = tpDirectory;
            }

            else if (t == "symlink") {
                type = tpSymlink;
            }

            else throw badArchive("unknown file type " + t);

        }

        else if (s == "contents" && type == tpRegular) {
            parseContents(sink, source, path);
        }

        else if (s == "executable" && type == tpRegular) {
            readString(source);
            sink.isExecutable();
        }

        else if (s == "entry" && type == tpDirectory) {
            string name, prevName;

            s = readString(source);
            if (s != "(") throw badArchive("expected open tag");

            while (1) {
                checkInterrupt();

                s = readString(source);

                if (s == ")") {
                    break;
                } else if (s == "name") {
                    name = readString(source);
                    if (name.empty() || name == "." || name == ".." || name.find('/') != string::npos || name.find((char) 0) != string::npos)
                        throw Error(format("NAR contains invalid file name `%1%'") % name);
                    if (name <= prevName)
                        throw Error("NAR directory is not sorted");
                    prevName = name;
                } else if (s == "node") {
                    if (s.empty()) throw badArchive("entry name missing");
                    parse(sink, source, path + "/" + name);
                } else
                    throw badArchive("unknown field " + s);
            }
        }

        else if (s == "target" && type == tpSymlink) {
            string target = readString(source);
            sink.createSymlink(path, target);
        }

        else
            throw badArchive("unknown field " + s);
    }
}


void parseDump(ParseSink & sink, Source & source)
{
    string version;
    try {
        version = readString(source);
    } catch (SerialisationError & e) {
        /* This generally means the integer at the start couldn't be
           decoded.  Ignore and throw the exception below. */
    }
    if (version != archiveVersion1)
        throw badArchive("input doesn't look like a normalized archive");
    parse(sink, source, "");
}


struct RestoreSink : ParseSink
{
    Path dstPath;
    AutoCloseFD fd;

    void createDirectory(const Path & path)
    {
        Path p = dstPath + path;
        if (mkdir(p.c_str(), 0777) == -1)
            throw SysError(format("creating directory `%1%'") % p);
    };

    void createRegularFile(const Path & path)
    {
        Path p = dstPath + path;
        fd.close();
        fd = open(p.c_str(), O_CREAT | O_EXCL | O_WRONLY, 0666);
        if (fd == -1) throw SysError(format("creating file `%1%'") % p);
    }

    void isExecutable()
    {
        struct stat st;
        if (fstat(fd, &st) == -1)
            throw SysError("fstat");
        if (fchmod(fd, st.st_mode | (S_IXUSR | S_IXGRP | S_IXOTH)) == -1)
            throw SysError("fchmod");
    }

    void preallocateContents(unsigned long long len)
    {
#if HAVE_POSIX_FALLOCATE
        if (len) {
            errno = posix_fallocate(fd, 0, len);
            /* Note that EINVAL may indicate that the underlying
               filesystem doesn't support preallocation (e.g. on
               OpenSolaris).  Since preallocation is just an
               optimisation, ignore it. */
            if (errno && errno != EINVAL)
                throw SysError(format("preallocating file of %1% bytes") % len);
        }
#endif
    }

    void receiveContents(unsigned char * data, unsigned int len)
    {
        writeFull(fd, data, len);
    }

    void createSymlink(const Path & path, const string & target)
    {
        Path p = dstPath + path;
        nix::createSymlink(target, p);
    }
};


void restorePath(const Path & path, Source & source)
{
    RestoreSink sink;
    sink.dstPath = path;
    parseDump(sink, source);
}


}
9'>gnu: mullvadbrowser: Update to 13.0.16....Fixes CVEs 2024-5702, 2024-5688, 2024-5690, 2024-5691, 2024-5692, 2024-5693, 2024-5696 and 2024-5700. See the Mozilla Foundation Security advisory <https://www.mozilla.org/en-US/security/advisories/mfsa2024-26/> for details. * gnu/packages/mullvad-browsers.scm (%mullvadbrowser-locales): Update changesets. (%mullvadbrowser-build-date): Update to 20240510190000. (%mullvadbrowser-version): Update to 13.0.16. (%mullvadbrowser-firefox-version): Update to 115.12.0esr-13.0-1-build1. (mullvadbrowser-translation-base): Update to f28525699864f4e3d764c354130bd898ce5b20aa. (mullvadbrowser-translation-specific): Update to bff8092bbe5ae93b2c162ade300d739b2cd9e92d. Signed-off-by: Christopher Baines <mail@cbaines.net> Change-Id: I66d61606c496bffc0dbbbdfcc0df8cbf18af5887 André Batista 2024-06-06gnu: make-torbrowser: Use current ffmpeg version....torbrowser and mullvadbrowser are now based on v. 115 and can link to current ffmpeg. * gnu/packages/tor-browsers.scm (make-torbrowser): Use ffmpeg rather than ffmpeg-5. Signed-off-by: Christopher Baines <mail@cbaines.net> Change-Id: Ifba8d2a58f21aba1abe6b3c5daf9cb57b07386f6 André Batista 2024-05-30gnu: torbrowser: Fix typo in description....* gnu/packages/tor-browsers.scm (make-torbrowser)[description]: Fix typo changing "know" to "known". Change-Id: Ib4c1d1f183e7debbc769693f303caa141f2138b6 Arun Isaac 2024-05-30gnu: torbrowser: Update to 13.0.15 [security fixes]....Fixes CVEs 2024-4367, 2024-4767, 2024-4768, 2024-4769, 2024-4770 and 2024-4777. See the Mozilla Foundation Security Advisory <https://www.mozilla.org/en-US/security/advisories/mfsa2024-22/> for details. * gnu/packages/tor-browsers.scm (%torbrowser-locales): Update changesets. (%torbrowser-build-date): Update to 20240510150000. (%torbrowser-version): Update to 13.0.15. (%torbrowser-firefox-version): Update to 115.11.0esr-13.0-1-build2. (torbrowser-translation-base): Update to a28a8b2cb9e207d12fca11181818c0a0694b56af. (torbrowser-translation-specific): Update to e03ffdea5b74ad280616dccd21744cba7b2d4565. Signed-off-by: Maxim Cournoyer <maxim.cournoyer@gmail.com> André Batista 2024-04-29gnu: make-torbrowser: Fix file picker....* gnu/packages/tor-browsers.scm (make-torbrowser): Set "widget.use-xdg-desktop-portal.file-picker" to 1 (Always) instead of 2 (Auto) to force the use of XDG portal. Change-Id: Id3c24a292a309c3a079a3843e8cb1c00f2cf9551 Clément Lassieur 2024-04-17gnu: mullvadbrowser: Update to 13.0.14 [security fixes]....Fixes CVE-2024-3852, CVE-2024-3854, CVE-2024-3857, CVE-2024-2609, CVE-2024-3859, CVE-2024-3861, CVE-2024-3863, CVE-2024-3302, CVE-2024-3864. See the Mozilla Foundation Security Advisory <https://www.mozilla.org/en-US/security/advisories/mfsa2024-19/> for details. * gnu/packages/mullvad-browsers.scm (%mullvadbrowser-build-date): Update to 20240408204645. (%mullvadbrowser-version): Update to 13.0.14. (%mullvadbrowser-firefox-version): Update to 115.10.0esr-13.0-1-build1. (mullvadbrowser-translation-base): Update to d31e6b16c372e2eb235c4f2b0eae0b573a5515ba. Change-Id: I22793fd35dd041fe5d2a47e16a26f1d48e37d2d2 Clément Lassieur 2024-04-17gnu: torbrowser: Update to 13.0.14 [security fixes]....Fixes CVE-2024-3852, CVE-2024-3854, CVE-2024-3857, CVE-2024-2609, CVE-2024-3859, CVE-2024-3861, CVE-2024-3863, CVE-2024-3302, CVE-2024-3864. See the Mozilla Foundation Security Advisory <https://www.mozilla.org/en-US/security/advisories/mfsa2024-19/> for details. * gnu/packages/tor-browsers.scm (%torbrowser-build-date): Update to 20240416150000. (%torbrowser-version): Update to 13.0.14. (%torbrowser-firefox-version): Update to 115.10.0esr-13.0-1-build1. (torbrowser-translation-base): Update to d31e6b16c372e2eb235c4f2b0eae0b573a5515ba. (torbrowser-translation-specific): Update to d37455a56f966b4f87f5f326b534a91f71fd5c88. Change-Id: I499d38f66e5528a566a6c105f621fe52b0ea1bc9 Clément Lassieur 2024-03-30Merge branch 'gnome-team'Liliana Marie Prikler 2024-03-23gnu: mullvadbrowser: Update to 13.0.13 [fixes CVE-2024-29944]....* gnu/packages/mullvad-browsers.scm (%mullvadbrowser-build-date): Update to 20240322132912. (%mullvadbrowser-version): Update to 13.0.13. (%mullvadbrowser-firefox-version): Update to 115.9.1esr-13.0-1-build1. (mullvadbrowser-translation-base): Update to 8e04ca3c5f440ed8f16b2069ae9565e4b044ec29. Change-Id: Id19ba361e9867200edd5ee9f35142d8dbe5447ab Clément Lassieur 2024-03-23gnu: torbrowser: Update to 13.0.13 [fixes CVE-2024-29944]....* gnu/packages/tor-browsers.scm (%torbrowser-build-date): Update to 20240322115718. (%torbrowser-version): Update to 13.0.13. (%torbrowser-firefox-version): Update to 115.9.1esr-13.0-1-build1. (torbrowser-translation-base): Update to 8e04ca3c5f440ed8f16b2069ae9565e4b044ec29. (torbrowser-translation-specific): Update to bf2fac60a6c41aa67b8147f22a638d498ac2dcdd. Change-Id: Ife0cb3b2d42dc5d6b39d5a11827c0a234c950126 Clément Lassieur 2024-03-21gnu: mullvadbrowser: Update to 13.0.12....* gnu/packages/mullvad-browsers.scm (%mullvadbrowser-build-date): Update to 20240313183935. (%mullvadbrowser-version): Update to 13.0.12. (%mullvadbrowser-firefox-version): Update to 115.9.0esr-13.0-1-build2. (mullvadbrowser-translation-base): Update to 595dcd5efe752cddc1b6ba47082ad9f5f4917fee. (mullvadbrowser-translation-specific): Update to c5361cb496ae7e047fd9226139537f1fcfc7938d. Change-Id: I365d5517cc145c0b66b502b5ed1738bf978a29da Clément Lassieur 2024-03-21gnu: torbrowser: Update to 13.0.12....* gnu/packages/tor-browsers.scm (%torbrowser-build-date): Update to 20240318163712. (%torbrowser-version): Update to 13.0.12. (%torbrowser-firefox-version): Update to 115.9.0esr-13.0-1-build3. (torbrowser-translation-base): Update to a4d224e82808529e135259e04fb58fb39b90da2d. (torbrowser-translation-specific): Update to e7aabc54138211e23bc60af1abe492c8bc68ce4b. Change-Id: I878f26149b22f5703e2e9bb7ee0aa1f4c4ada589 Clément Lassieur 2024-03-21gnu: make-torbrowser: Make products independent from each other....* gnu/packages/tor-browsers.scm (translation-base-browser): Rename to torbrowser-translation-base. (mullvadbrowser-translation-base): New variable. (translation-tor-browser): Rename to torbrowser-translation-specific. (translation-mullvad-browser): Rename to mullvadbrowser-translation-specific. (make-torbrowser): Add ‘translation-base’ and ‘translation-specific’ parameters and use them. (torbrowser, mullvadbrowser-base): Use the above parameters. (mullvadbrowser): Handle renaming. This allows translation-base-browser (now torbrowser-translation-base) and translation-tor-browser (now torbrowser-translation-specific) to be updated without triggering an update for Mullvad Browser. Change-Id: I2a94636eb6b0531c3a03cdb73c560d68060721ef Clément Lassieur 2024-03-16Merge remote-tracking branch 'savannah/master' into gnome-team...Change-Id: I775274c2693536e2efa36c9abca4c54c5c458e26 Christopher Baines 2024-03-12gnu: tor-browser: Build with newest rust-cbindgen....* gnu/packages/tor-browsers.scm (make-torbrowser)[inputs]: Replace rust-cbindgen-0.24 with rust-cbindgen. Change-Id: I6263a11342cb506c6c271e0360b7273c35be585d Efraim Flashner 2024-03-10Merge branch 'master' into gnome-teamLiliana Marie Prikler 2024-03-08gnu: torbrowser: Update to 13.0.11....* gnu/packages/tor-browsers.scm (%torbrowser-build-date): Update to 20240305132801. (%torbrowser-version): Update to 13.0.11. (%torbrowser-firefox-version): Update to 115.8.0esr-13.0-1-build2. (translation-base-browser): Update to 16211a4b8524d71525f0ea73c07771c634132b30. (translation-tor-browser): Update to 012f643d2d6b04ebf868bf62cdb7ad5b727734f5. Change-Id: I1d5cd4a0d7c3a01f8489db7b69b65a9451ead315 Clément Lassieur 2024-02-25Merge branch 'master' into gnome-teamLiliana Marie Prikler 2024-02-21gnu: mullvadbrowser: Update to 13.0.10....* gnu/packages/tor-browsers.scm (%mullvadbrowser-build-date): Update to 20240213150358. (%mullvadbrowser-version): Update to 13.0.10. (%mullvadbrowser-firefox-version): Update to 115.8.0esr-13.0-1-build1. Change-Id: Ia3c444e893bf7c3299d2d091c6c6578be272a782 Clément Lassieur 2024-02-21gnu: torbrowser: Update to 13.0.10....* gnu/packages/tor-browsers.scm (%torbrowser-build-date): Update to 20240213172118. (%torbrowser-version): Update to 13.0.10. (%torbrowser-firefox-version): Update to 115.8.0esr-13.0-1-build1. (translation-tor-browser): Update to a50fa943d7428ebe6e4e6b09f175e098a97eec63. Change-Id: Idbb708d8bdd5e75bed1423c0748007864f96da0f Clément Lassieur 2024-02-16gnu: icu4c-73: Move it from gnuzilla.scm to icu4c.scm....* gnu/packages/gnuzilla.scm (icu4c-73-promise): Delete variable. (icecat-minimal)[inputs]: Use ‘icu4c-73’ instead of the promise. * gnu/packages/icu4c.scm (icu4c-73): New variable. (make-torbrowser)[inputs]: Use ‘icu4c-73’ instead of the promise. Change-Id: I017e1416b70ecb94313aeb71aa4a0cafdfe0e9ab Signed-off-by: Clément Lassieur <clement@lassieur.org> Ian Eure 2024-02-13Merge branch 'master' into gnome-teamLiliana Marie Prikler 2024-02-05gnu: Add mullvadbrowser....* gnu/packages/tor-browsers.scm (%moz-build-date): Rename to %torbrowser-build-date. (make-torbrowser, torbrowser): Add a ‘build-date’ parameter and use it. (%mullvadbrowser-locales, %mullvadbrowser-build-date, %mullvadbrowser-version, %mullvadbrowser-firefox-version, translation-mullvad-browser, mullvadbrowser-assets, mullvadbrowser-base, mullvadbrowser): New variables. Change-Id: Ie6d48823b3794710f60f0ae201a0297925221f66 Clément Lassieur 2024-02-03gnu: tor-browsers: Use freedesktop module....The shared-mime-info package has been moved from gnome to freedesktop, causing the variable to be unbound where this module is not imported. * gnu/packages/tor-browsers.scm <define-package>: Add #:use-module (gnu packages freedesktop). Fixes: Unbound variable ‘shared-mime-info’. Liliana Marie Prikler 2024-02-02gnu: torbrowser: Stop inheriting Icecat....* gnu/local.mk (GNU_SYSTEM_MODULES): Add packages/tor-browsers.scm. * gnu/packages/gnupg.scm: Remove fix for dependency loop (fixed because we use a new file). * gnu/packages/tor-browsers.scm (mozilla-locale, mozilla-locales, %torbrowser-locales, %moz-build-date, %torbrowser-version, %torbrowser-firefox-version, translation-base-browser, translation-tor-browser, torbrowser-assets, torbrowser): New variables. (make-torbrowser): New procedure, which is a merge of ‘make-torbrowser’ (from tor.scm) with ‘icecat-minimal’ (from gnuzilla.scm). * gnu/packages/tor.scm (%moz-build-date, %torbrowser-version, %torbrowser-firefox-version, %torbrowser-locales, translation-base-browser, translation-tor-browser, torbrowser-assets, torbrowser): Remove variables. Change-Id: I5fcf73e53fe4481a18e13cdeb3515c3dc4430090 Clément Lassieur