master
cpp 105 lines 2.75 KB
Raw
1 /*++
2
3 Copyright (c) Microsoft. All rights reserved.
4
5 Module Name:
6
7 RegistryService.cpp
8
9 Abstract:
10
11 This file contains the RegistryService implementation
12
13 --*/
14
15 #include "RegistryService.h"
16 #include <wslutil.h>
17
18 using namespace wsl::windows::common::wslutil;
19
20 namespace {
21
22 std::string ResolveCredentialKey(const std::string& serverAddress)
23 {
24 auto input = serverAddress;
25
26 // Strip scheme
27 if (auto pos = input.find("://"); pos != std::string::npos)
28 {
29 input = input.substr(pos + 3);
30 }
31
32 // Strip path
33 if (auto pos = input.find('/'); pos != std::string::npos)
34 {
35 input = input.substr(0, pos);
36 }
37
38 // Map Docker Hub aliases to canonical key.
39 if (input == "docker.io" || input == "index.docker.io")
40 {
41 return wsl::windows::wslc::services::RegistryService::DefaultServer;
42 }
43
44 return input;
45 }
46 } // namespace
47
48 namespace wsl::windows::wslc::services {
49
50 // Sentinel username matching Docker's convention for identity-token credentials.
51 static constexpr auto TokenUsername = "<token>";
52
53 void RegistryService::Store(const std::string& serverAddress, const std::string& username, const std::string& secret)
54 {
55 THROW_HR_IF(E_INVALIDARG, serverAddress.empty());
56 THROW_HR_IF(E_INVALIDARG, secret.empty());
57
58 auto storage = OpenCredentialStorage();
59 storage->Store(ResolveCredentialKey(serverAddress), username, secret);
60 }
61
62 std::string RegistryService::Get(const std::string& serverAddress)
63 {
64 auto storage = OpenCredentialStorage();
65 auto key = ResolveCredentialKey(serverAddress);
66 auto [username, secret] = storage->Get(key);
67
68 if (username == TokenUsername)
69 {
70 return BuildRegistryAuthHeader(secret);
71 }
72
73 return BuildRegistryAuthHeader(username, secret);
74 }
75
76 void RegistryService::Erase(const std::string& serverAddress)
77 {
78 THROW_HR_IF(E_INVALIDARG, serverAddress.empty());
79
80 auto storage = OpenCredentialStorage();
81 storage->Erase(ResolveCredentialKey(serverAddress));
82 }
83
84 std::vector<std::wstring> RegistryService::List()
85 {
86 auto storage = OpenCredentialStorage();
87 return storage->List();
88 }
89
90 std::pair<std::string, std::string> RegistryService::Authenticate(
91 wsl::windows::wslc::models::Session& session, const std::string& serverAddress, const std::string& username, const std::string& password)
92 {
93 wil::unique_cotaskmem_ansistring identityToken;
94 THROW_IF_FAILED(session.Get()->Authenticate(serverAddress.c_str(), username.c_str(), password.c_str(), &identityToken));
95
96 // If the registry returned an identity token, use it. Otherwise fall back to username/password.
97 if (identityToken && strlen(identityToken.get()) > 0)
98 {
99 return {TokenUsername, identityToken.get()};
100 }
101
102 return {username, password};
103 }
104
105 } // namespace wsl::windows::wslc::services