| 
 | 1 | +#include "lix/libstore/store-api.hh"  | 
 | 2 | +#include "lix/libutil/config.hh"  | 
 | 3 | +#include "lix/libstore/http-binary-cache-store.hh"  | 
 | 4 | +#include <stdlib.h>  | 
 | 5 | +#include <curl/curl.h>  | 
 | 6 | + | 
 | 7 | +namespace nix {  | 
 | 8 | +struct mTLSBinaryCacheStoreConfig : HttpBinaryCacheStoreConfig  | 
 | 9 | +{  | 
 | 10 | +    using HttpBinaryCacheStoreConfig::HttpBinaryCacheStoreConfig;  | 
 | 11 | + | 
 | 12 | +    const std::string name() override  | 
 | 13 | +    {  | 
 | 14 | +        return "mTLS HTTP Binary Cache Store";  | 
 | 15 | +    }  | 
 | 16 | + | 
 | 17 | +    std::string doc() override  | 
 | 18 | +    {  | 
 | 19 | +        return  | 
 | 20 | +#include "mtls-http-binary-cache-store.md"  | 
 | 21 | +            ;  | 
 | 22 | +    }  | 
 | 23 | + | 
 | 24 | +    PathsSetting<nix::Path> tlsCertificate{  | 
 | 25 | +        this,  | 
 | 26 | +        "",  | 
 | 27 | +        "tls-certificate",  | 
 | 28 | +        "Path of an optional TLS client certificate in PEM format as expected by CURLOPT_SSLCERT"  | 
 | 29 | +    };  | 
 | 30 | + | 
 | 31 | +    PathsSetting<nix::Path> tlsKey{  | 
 | 32 | +        this,  | 
 | 33 | +        "",  | 
 | 34 | +        "tls-private-key",  | 
 | 35 | +        "Path of an TLS client certificate private key in PEM format as expected by CURLOPT_SSLKEY"  | 
 | 36 | +    };  | 
 | 37 | +};  | 
 | 38 | + | 
 | 39 | +struct mTLSBinaryCacheStoreImpl : public HttpBinaryCacheStore  | 
 | 40 | +{  | 
 | 41 | +    struct Keyring  | 
 | 42 | +    {  | 
 | 43 | +        nix::Path tlsCertificate;  | 
 | 44 | +        nix::Path tlsKey;  | 
 | 45 | +    };  | 
 | 46 | + | 
 | 47 | +    mTLSBinaryCacheStoreConfig config_;  | 
 | 48 | +    std::shared_ptr<Keyring> keyring;  | 
 | 49 | + | 
 | 50 | +    mTLSBinaryCacheStoreConfig & config() override  | 
 | 51 | +    {  | 
 | 52 | +        return config_;  | 
 | 53 | +    }  | 
 | 54 | +    const mTLSBinaryCacheStoreConfig & config() const override  | 
 | 55 | +    {  | 
 | 56 | +        return config_;  | 
 | 57 | +    }  | 
 | 58 | + | 
 | 59 | +    mTLSBinaryCacheStoreImpl(  | 
 | 60 | +        const std::string & uriScheme, const Path & _cacheUri, mTLSBinaryCacheStoreConfig config  | 
 | 61 | +    )  | 
 | 62 | +        : Store(config)  | 
 | 63 | +        , HttpBinaryCacheStore("https", _cacheUri, config)  | 
 | 64 | +        , config_(std::move(config))  | 
 | 65 | +        , keyring(std::make_shared<Keyring>(config_.tlsCertificate.get(), config_.tlsKey.get()))  | 
 | 66 | +    {  | 
 | 67 | +    }  | 
 | 68 | + | 
 | 69 | +    FileTransferOptions makeOptions(Headers && headers = {}) override  | 
 | 70 | +    {  | 
 | 71 | +        auto options = HttpBinaryCacheStore::makeOptions(std::move(headers));  | 
 | 72 | +        auto baseExtraSetup = std::move(options.extraSetup);  | 
 | 73 | +        auto keyring = this->keyring;  | 
 | 74 | + | 
 | 75 | +        options.extraSetup =  | 
 | 76 | +            [keyring, baseExtraSetup{std::move(baseExtraSetup)}](CURL * req) {  | 
 | 77 | +                if (baseExtraSetup) {  | 
 | 78 | +                    baseExtraSetup(req);  | 
 | 79 | +                }  | 
 | 80 | + | 
 | 81 | +                if (!keyring->tlsCertificate.empty()) {  | 
 | 82 | +                    curl_easy_setopt(req, CURLOPT_SSLCERT, keyring->tlsCertificate.c_str());  | 
 | 83 | +                }  | 
 | 84 | + | 
 | 85 | +                curl_easy_setopt(req, CURLOPT_SSLKEY, keyring->tlsKey.c_str());  | 
 | 86 | +            };  | 
 | 87 | + | 
 | 88 | +        return options;  | 
 | 89 | +    }  | 
 | 90 | + | 
 | 91 | +    static std::set<std::string> uriSchemes()  | 
 | 92 | +    {  | 
 | 93 | +        return {"https+mtls"};  | 
 | 94 | +    }  | 
 | 95 | +};  | 
 | 96 | +}  | 
 | 97 | + | 
 | 98 | + | 
 | 99 | +extern "C" void nix_plugin_entry()  | 
 | 100 | +{  | 
 | 101 | +    nix::StoreImplementations::add<nix::mTLSBinaryCacheStoreImpl, nix::mTLSBinaryCacheStoreConfig>();  | 
 | 102 | +}  | 
0 commit comments