diff --git a/src/libstore/auth-tunnel.cc b/src/libstore/auth-tunnel.cc index 42a62f70dfd..7c1c891fbea 100644 --- a/src/libstore/auth-tunnel.cc +++ b/src/libstore/auth-tunnel.cc @@ -8,25 +8,22 @@ namespace nix { -AuthTunnel::AuthTunnel( - StoreDirConfig & storeConfig, - WorkerProto::Version clientVersion) +AuthTunnel::AuthTunnel(StoreDirConfig & storeConfig, WorkerProto::Version clientVersion) : clientVersion(clientVersion) { auto sockets = socketPair(); serverFd = std::move(sockets.first); clientFd = std::move(sockets.second); - serverThread = std::thread([this, clientVersion, &storeConfig]() - { + serverThread = std::thread([this, clientVersion, &storeConfig]() { try { FdSource fromSource(serverFd.get()); - WorkerProto::ReadConn from { + WorkerProto::ReadConn from{ .from = fromSource, .version = clientVersion, }; FdSink toSource(serverFd.get()); - WorkerProto::WriteConn to { + WorkerProto::WriteConn to{ .to = toSource, .version = clientVersion, }; @@ -95,28 +92,25 @@ struct TunneledAuthSource : auth::AuthSource WorkerProto::ReadConn fromConn; WorkerProto::WriteConn toConn; - State( - WorkerProto::Version clientVersion, - AutoCloseFD && fd) + State(WorkerProto::Version clientVersion, AutoCloseFD && fd) : fd(std::move(fd)) , from(this->fd.get()) , to(this->fd.get()) - , fromConn {.from = from, .version = clientVersion} - , toConn {.to = to, .version = clientVersion} - { } + , fromConn{.from = from, .version = clientVersion} + , toConn{.to = to, .version = clientVersion} + { + } }; Sync state_; ref storeConfig; - TunneledAuthSource( - ref storeConfig, - WorkerProto::Version clientVersion, - AutoCloseFD && fd) + TunneledAuthSource(ref storeConfig, WorkerProto::Version clientVersion, AutoCloseFD && fd) : state_(clientVersion, std::move(fd)) , storeConfig(storeConfig) - { } + { + } std::optional get(const auth::AuthData & request, bool required) override { @@ -145,10 +139,8 @@ struct TunneledAuthSource : auth::AuthSource } }; -ref makeTunneledAuthSource( - ref storeConfig, - WorkerProto::Version clientVersion, - AutoCloseFD && clientFd) +ref +makeTunneledAuthSource(ref storeConfig, WorkerProto::Version clientVersion, AutoCloseFD && clientFd) { return make_ref(storeConfig, clientVersion, std::move(clientFd)); } diff --git a/src/libstore/auth-tunnel.hh b/src/libstore/auth-tunnel.hh index e53cd2475a6..50152805ae8 100644 --- a/src/libstore/auth-tunnel.hh +++ b/src/libstore/auth-tunnel.hh @@ -17,11 +17,11 @@ struct AuthTunnel ~AuthTunnel(); }; -namespace auth { struct AuthSource; } +namespace auth { +struct AuthSource; +} -ref makeTunneledAuthSource( - ref storeConfig, - WorkerProto::Version clientVersion, - AutoCloseFD && clientFd); +ref +makeTunneledAuthSource(ref storeConfig, WorkerProto::Version clientVersion, AutoCloseFD && clientFd); } diff --git a/src/libutil/auth.cc b/src/libutil/auth.cc index b7cfb77c4f1..9260929c810 100644 --- a/src/libutil/auth.cc +++ b/src/libutil/auth.cc @@ -15,32 +15,45 @@ namespace nix { using namespace auth; // FIXME: need to generalize defining enum settings. -template<> AuthForwarding BaseSetting::parse(const std::string & str) const +template<> +AuthForwarding BaseSetting::parse(const std::string & str) const { - if (str == "false") return AuthForwarding::Disabled; - else if (str == "trusted-users") return AuthForwarding::TrustedUsers; - else if (str == "all-users") return AuthForwarding::AllUsers; - else throw UsageError("option '%s' has invalid value '%s'", name, str); + if (str == "false") + return AuthForwarding::Disabled; + else if (str == "trusted-users") + return AuthForwarding::TrustedUsers; + else if (str == "all-users") + return AuthForwarding::AllUsers; + else + throw UsageError("option '%s' has invalid value '%s'", name, str); } -template<> struct BaseSetting::trait +template<> +struct BaseSetting::trait { static constexpr bool appendable = false; }; -template<> std::string BaseSetting::to_string() const +template<> +std::string BaseSetting::to_string() const { - if (value == AuthForwarding::Disabled) return "false"; - else if (value == AuthForwarding::TrustedUsers) return "trusted-users"; - else if (value == AuthForwarding::AllUsers) return "all-users"; - else abort(); + if (value == AuthForwarding::Disabled) + return "false"; + else if (value == AuthForwarding::TrustedUsers) + return "trusted-users"; + else if (value == AuthForwarding::AllUsers) + return "all-users"; + else + abort(); } -NLOHMANN_JSON_SERIALIZE_ENUM(AuthForwarding, { - {AuthForwarding::Disabled, "false"}, - {AuthForwarding::TrustedUsers, "trusted-users"}, - {AuthForwarding::AllUsers, "all-users"}, -}); +NLOHMANN_JSON_SERIALIZE_ENUM( + AuthForwarding, + { + {AuthForwarding::Disabled, "false"}, + {AuthForwarding::TrustedUsers, "trusted-users"}, + {AuthForwarding::AllUsers, "all-users"}, + }); } @@ -56,7 +69,8 @@ AuthData AuthData::parseGitAuthData(std::string_view raw) for (auto & line : tokenizeString>(raw, "\n")) { auto eq = line.find('='); - if (eq == line.npos) continue; + if (eq == line.npos) + continue; auto key = trim(line.substr(0, eq)); auto value = trim(line.substr(eq + 1)); if (key == "protocol") @@ -83,7 +97,8 @@ std::optional AuthData::match(const AuthData & request) const return std::nullopt; // `request.path` must be within `path`. - if (path && request.path && !(*path == *request.path || request.path->substr(0, path->size() + 1) == *request.path + "/")) + if (path && request.path + && !(*path == *request.path || request.path->substr(0, path->size() + 1) == *request.path + "/")) return std::nullopt; if (userName && request.userName && *userName != request.userName) @@ -103,17 +118,23 @@ std::optional AuthData::match(const AuthData & request) const std::string AuthData::toGitAuthData() const { std::string res; - if (protocol) res += fmt("protocol=%s\n", *protocol); - if (host) res += fmt("host=%s\n", *host); - if (path) res += fmt("path=%s\n", *path); - if (userName) res += fmt("username=%s\n", *userName); - if (password) res += fmt("password=%s\n", *password); + if (protocol) + res += fmt("protocol=%s\n", *protocol); + if (host) + res += fmt("host=%s\n", *host); + if (path) + res += fmt("path=%s\n", *path); + if (userName) + res += fmt("username=%s\n", *userName); + if (password) + res += fmt("password=%s\n", *password); return res; } -std::ostream & operator << (std::ostream & str, const AuthData & authData) +std::ostream & operator<<(std::ostream & str, const AuthData & authData) { - str << fmt("{protocol = %s, host=%s, path=%s, userName=%s, password=%s}", + str << fmt( + "{protocol = %s, host=%s, path=%s, userName=%s, password=%s}", authData.protocol.value_or(""), authData.host.value_or(""), authData.path.value_or(""), @@ -133,7 +154,8 @@ struct NixAuthSource : AuthSource { if (pathExists(authDir)) for (auto & file : std::filesystem::directory_iterator{authDir}) { - if (hasSuffix(file.path().filename().string(), "~")) continue; + if (hasSuffix(file.path().filename().string(), "~")) + continue; auto path = authDir / file.path().filename(); auto authData = AuthData::parseGitAuthData(readFile(path)); if (!authData.password) @@ -154,7 +176,8 @@ struct NixAuthSource : AuthSource bool set(const AuthData & authData) override { - if (get(authData, false)) return true; + if (get(authData, false)) + return true; auto authFile = authDir / fmt("auto-%s-%s", authData.host.value_or("none"), authData.userName.value_or("none")); @@ -175,7 +198,8 @@ struct NetrcAuthSource : AuthSource // FIXME: read netrc lazily. debug("reading netrc '%s'", path); - if (!pathExists(path)) return; + if (!pathExists(path)) + return; auto raw = readFile(path); @@ -183,11 +207,11 @@ struct NetrcAuthSource : AuthSource auto whitespace = "\n\r\t "; - auto nextToken = [&]() -> std::optional - { + auto nextToken = [&]() -> std::optional { // Skip whitespace. auto n = remaining.find_first_not_of(whitespace); - if (n == remaining.npos) return std::nullopt; + if (n == remaining.npos) + return std::nullopt; remaining = remaining.substr(n); if (remaining.substr(0, 1) == "\"") @@ -202,8 +226,7 @@ struct NetrcAuthSource : AuthSource std::optional curMachine; - auto flushMachine = [&]() - { + auto flushMachine = [&]() { if (curMachine) { authDatas.push_back(std::move(*curMachine)); curMachine.reset(); @@ -214,35 +237,32 @@ struct NetrcAuthSource : AuthSource if (token == "machine") { flushMachine(); auto name = nextToken(); - if (!name) throw Error("netrc 'machine' token requires a name"); - curMachine = AuthData { - .protocol = "https", - .host = std::string(*name) - }; - } - else if (token == "default") { + if (!name) + throw Error("netrc 'machine' token requires a name"); + curMachine = AuthData{.protocol = "https", .host = std::string(*name)}; + } else if (token == "default") { flushMachine(); - curMachine = AuthData { + curMachine = AuthData{ .protocol = "https", }; - } - else if (token == "login") { - if (!curMachine) throw Error("netrc 'login' token must be preceded by a 'machine'"); + } else if (token == "login") { + if (!curMachine) + throw Error("netrc 'login' token must be preceded by a 'machine'"); auto userName = nextToken(); - if (!userName) throw Error("netrc 'login' token requires a user name"); + if (!userName) + throw Error("netrc 'login' token requires a user name"); curMachine->userName = std::string(*userName); - } - else if (token == "password") { - if (!curMachine) throw Error("netrc 'password' token must be preceded by a 'machine'"); + } else if (token == "password") { + if (!curMachine) + throw Error("netrc 'password' token must be preceded by a 'machine'"); auto password = nextToken(); - if (!password) throw Error("netrc 'password' token requires a password"); + if (!password) + throw Error("netrc 'password' token requires a password"); curMachine->password = std::string(*password); - } - else if (token == "account") { + } else if (token == "account") { // Ignore this. nextToken(); - } - else + } else warn("unrecognized netrc token '%s'", *token); } @@ -277,16 +297,17 @@ struct ExternalAuthSource : AuthSource std::optional get(const AuthData & request, bool required) override { try { - if (!enabled) return std::nullopt; + if (!enabled) + return std::nullopt; - auto response = AuthData::parseGitAuthData( - runProgram(program, true, {"get"}, request.toGitAuthData())); + auto response = AuthData::parseGitAuthData(runProgram(program, true, {"get"}, request.toGitAuthData())); if (!response.password) return std::nullopt; AuthData res{request}; - if (response.userName) res.userName = response.userName; + if (response.userName) + res.userName = response.userName; res.password = response.password; return res; } catch (SysError & e) { @@ -303,7 +324,8 @@ struct ExternalAuthSource : AuthSource bool set(const AuthData & authData) override { try { - if (!enabled) return false; + if (!enabled) + return false; runProgram(program, true, {"store"}, authData.toGitAuthData()); @@ -322,7 +344,8 @@ struct ExternalAuthSource : AuthSource void erase(const AuthData & authData) override { try { - if (!enabled) return; + if (!enabled) + return; runProgram(program, true, {"erase"}, authData.toGitAuthData()); } catch (SysError & e) { @@ -369,17 +392,13 @@ std::optional Authenticator::fill(const AuthData & request, bool requi // for the expected format of the phrases. if (!request.userName) { - res.userName = chomp( - runProgram(*askPassHelper, true, - {fmt("Username for '%s': ", request.host.value_or(""))}, - std::nullopt, true)); + res.userName = chomp(runProgram( + *askPassHelper, true, {fmt("Username for '%s': ", request.host.value_or(""))}, std::nullopt, true)); } if (!request.password) { - res.password = chomp( - runProgram(*askPassHelper, true, - {fmt("Password for '%s': ", request.host.value_or(""))}, - std::nullopt, true)); + res.password = chomp(runProgram( + *askPassHelper, true, {fmt("Password for '%s': ", request.host.value_or(""))}, std::nullopt, true)); } if (res.userName && res.password) { @@ -429,8 +448,7 @@ ref getAuthenticator() else if (s == "builtin:netrc") { if (authSettings.netrcFile != "") authSources.push_back(make_ref(authSettings.netrcFile)); - } - else + } else warn("unknown authentication sources '%s'", s); } else authSources.push_back(make_ref(s)); diff --git a/src/libutil/auth.hh b/src/libutil/auth.hh index ee1354a16b9..a7dedb2db45 100644 --- a/src/libutil/auth.hh +++ b/src/libutil/auth.hh @@ -43,7 +43,9 @@ struct AuthSettings : Config )"}; Setting netrcFile{ - this, "", "netrc-file", + this, + "", + "netrc-file", R"( An absolute path to a `netrc` file. Nix will use the HTTP authentication credentials in this file when trying to download from @@ -68,14 +70,18 @@ struct AuthSettings : Config )"}; Setting storeAuth{ - this, false, "store-auth", + this, + false, + "store-auth", R"( Whether to store user names and passwords using the authentication sources configured in [`auth-sources`](#conf-auth-sources). )"}; Setting authForwarding{ - this, AuthForwarding::TrustedUsers, "auth-forwarding", + this, + AuthForwarding::TrustedUsers, + "auth-forwarding", R"( Whether to forward authentication data to the Nix daemon. This setting can have the following values: @@ -83,7 +89,9 @@ struct AuthSettings : Config * `trusted-users`: Forwarding is only supported for [trusted users](#conf-trusted-users). * `all-users`: Forwarding is supported for all users. )", - {}, true, Xp::AuthForwarding}; + {}, + true, + Xp::AuthForwarding}; }; extern AuthSettings authSettings; @@ -103,20 +111,20 @@ struct AuthData std::string toGitAuthData() const; }; -std::ostream & operator << (std::ostream & str, const AuthData & authData); +std::ostream & operator<<(std::ostream & str, const AuthData & authData); struct AuthSource { - virtual ~AuthSource() - { } + virtual ~AuthSource() {} virtual std::optional get(const AuthData & request, bool required) = 0; virtual bool set(const AuthData & authData) - { return false; } + { + return false; + } - virtual void erase(const AuthData & authData) - { } + virtual void erase(const AuthData & authData) {} }; class Authenticator @@ -129,7 +137,8 @@ public: Authenticator(std::vector> authSources = {}) : authSources(std::move(authSources)) - { } + { + } std::optional fill(const AuthData & request, bool required); diff --git a/src/nix/auth.cc b/src/nix/auth.cc index dc257babfd0..687dceb03bb 100644 --- a/src/nix/auth.cc +++ b/src/nix/auth.cc @@ -22,14 +22,14 @@ struct CmdAuthFill : Command return "obtain a user name and password from the configured authentication sources"; } - #if 0 +#if 0 std::string doc() override { return - #include "auth-fill.md" +# include "auth-fill.md" ; } - #endif +#endif void run() override { @@ -58,7 +58,10 @@ struct CmdAuth : NixMultiCommand return "authentication-related commands"; } - Category category() override { return catUtility; } + Category category() override + { + return catUtility; + } }; static auto rCmdAuth = registerCommand("auth");