1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2024-09-19 10:50:24 -04:00

libstore: Add the ability to use different auth methods with Http Binary Caches

This commit is contained in:
George Shammas 2024-04-21 14:51:19 -04:00
parent 622c402659
commit 049d091442
6 changed files with 64 additions and 4 deletions

View file

@ -164,6 +164,7 @@
''^src/libstore/globals\.cc$''
''^src/libstore/globals\.hh$''
''^src/libstore/http-binary-cache-store\.cc$''
''^src/libstore/http-binary-cache-store\.hh$''
''^src/libstore/legacy-ssh-store\.cc$''
''^src/libstore/legacy-ssh-store\.hh$''
''^src/libstore/length-prefixed-protocol-helper\.hh$''

View file

@ -320,7 +320,9 @@ struct curlFileTransfer : public FileTransfer
curl_easy_setopt(req, CURLOPT_PIPEWAIT, 1);
#endif
#if LIBCURL_VERSION_NUM >= 0x072f00
if (fileTransferSettings.enableHttp2)
// Our writeCallbackWrapper does not support rewinding which breaks
// negotiate/kerberos auth over http/2.
if (fileTransferSettings.enableHttp2 && request.authmethod != HttpAuthMethod::NEGOTIATE)
curl_easy_setopt(req, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2TLS);
else
curl_easy_setopt(req, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
@ -357,6 +359,14 @@ struct curlFileTransfer : public FileTransfer
curl_easy_setopt(req, CURLOPT_SSL_VERIFYHOST, 0);
}
curl_easy_setopt(req, CURLOPT_HTTPAUTH, request.authmethod);
if (request.authmethod != HttpAuthMethod::NEGOTIATE) {
curl_easy_setopt(req, CURLOPT_USERNAME, "");
curl_easy_setopt(req, CURLOPT_PASSWORD, "");
} else if (request.authmethod != HttpAuthMethod::BEARER) {
curl_easy_setopt(req, CURLOPT_XOAUTH2_BEARER, request.bearer_token.c_str());
}
curl_easy_setopt(req, CURLOPT_CONNECTTIMEOUT, fileTransferSettings.connectTimeout.get());
curl_easy_setopt(req, CURLOPT_LOW_SPEED_LIMIT, 1L);

View file

@ -1,6 +1,8 @@
#pragma once
///@file
#include "http-binary-cache-store.hh"
#include <string>
#include <future>
@ -64,6 +66,8 @@ struct FileTransferRequest
std::string expectedETag;
bool verifyTLS = true;
bool head = false;
HttpAuthMethod authmethod = HttpAuthMethod::BASIC;
std::string bearer_token;
size_t tries = fileTransferSettings.tries;
unsigned int baseRetryTimeMs = 250;
ActivityId parentAct;

View file

@ -8,6 +8,23 @@ namespace nix {
MakeError(UploadToHTTP, Error);
HttpAuthMethod parseHttpAuthMethod(const std::string &str) {
static const std::map<std::string, HttpAuthMethod> map = {
{"none", HttpAuthMethod::NONE},
{"basic", HttpAuthMethod::BASIC},
{"digest", HttpAuthMethod::DIGEST},
{"negotiate", HttpAuthMethod::NEGOTIATE},
{"ntlm", HttpAuthMethod::NTLM},
{"bearer", HttpAuthMethod::BEARER},
{"any", HttpAuthMethod::ANY},
{"anysafe", HttpAuthMethod::ANYSAFE}};
auto it = map.find(str);
if (it == map.end()) {
throw UsageError("option authmethod has invalid value '%s'", str);
}
return it->second;
}
HttpBinaryCacheStoreConfig::HttpBinaryCacheStoreConfig(
std::string_view scheme,
@ -34,7 +51,6 @@ std::string HttpBinaryCacheStoreConfig::doc()
;
}
class HttpBinaryCacheStore : public virtual HttpBinaryCacheStoreConfig, public virtual BinaryCacheStore
{
private:
@ -143,11 +159,13 @@ protected:
FileTransferRequest makeRequest(const std::string & path)
{
return FileTransferRequest(
auto request = FileTransferRequest(
hasPrefix(path, "https://") || hasPrefix(path, "http://") || hasPrefix(path, "file://")
? path
: cacheUri + "/" + path);
request.authmethod = parseHttpAuthMethod(authmethod);
request.bearer_token = bearer_token;
return request;
}
void getFile(const std::string & path, Sink & sink) override

View file

@ -1,7 +1,24 @@
#pragma once
///@file
#include "types.hh"
#include <curl/curl.h>
#include "binary-cache-store.hh"
namespace nix {
enum struct HttpAuthMethod : unsigned long {
NONE = CURLAUTH_NONE,
BASIC = CURLAUTH_BASIC,
DIGEST = CURLAUTH_DIGEST,
NEGOTIATE = CURLAUTH_NEGOTIATE,
NTLM = CURLAUTH_NTLM,
BEARER = CURLAUTH_BEARER,
ANY = CURLAUTH_ANY,
ANYSAFE = CURLAUTH_ANYSAFE
};
struct HttpBinaryCacheStoreConfig : virtual BinaryCacheStoreConfig
{
using BinaryCacheStoreConfig::BinaryCacheStoreConfig;
@ -24,6 +41,15 @@ struct HttpBinaryCacheStoreConfig : virtual BinaryCacheStoreConfig
return ret;
}
const Setting<std::string> authmethod{this, "basic", "authmethod",
R"(
libcurl auth method to use (`none`, `basic`, `digest`, `bearer`, `negotiate`, `ntlm`, `any`, or `anysafe`).
See https://curl.se/libcurl/c/CURLOPT_HTTPAUTH.html for more info.
)"};
const Setting<std::string> bearer_token{this, "", "bearer-token",
"Bearer token to use for authentication. Requires `authmethod` to be set to `bearer`."};
std::string doc() override;
};

View file

@ -72,6 +72,7 @@ mkMesonDerivation (finalAttrs: {
propagatedBuildInputs = [
nix-util
nlohmann_json
curl
];
preConfigure =