• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mendersoftware / mender / 2271300743

19 Jan 2026 11:42AM UTC coverage: 81.376% (+1.7%) from 79.701%
2271300743

push

gitlab-ci

web-flow
Merge pull request #1879 from lluiscampos/MEN-8687-ci-debian-updates

MEN-8687: Update Debian base images for CI jobs

8791 of 10803 relevant lines covered (81.38%)

20310.08 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

52.17
/src/mender-auth/cli/actions.cpp
1
// Copyright 2023 Northern.tech AS
2
//
3
//    Licensed under the Apache License, Version 2.0 (the "License");
4
//    you may not use this file except in compliance with the License.
5
//    You may obtain a copy of the License at
6
//
7
//        http://www.apache.org/licenses/LICENSE-2.0
8
//
9
//    Unless required by applicable law or agreed to in writing, software
10
//    distributed under the License is distributed on an "AS IS" BASIS,
11
//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
//    See the License for the specific language governing permissions and
13
//    limitations under the License.
14

15
#include <mender-auth/cli/actions.hpp>
16

17
#include <string>
18
#include <memory>
19

20
#include <mender-auth/api/auth.hpp>
21

22
#include <mender-auth/context.hpp>
23
#include <mender-auth/cli/keystore.hpp>
24

25
#include <client_shared/conf.hpp>
26
#include <common/events.hpp>
27
#include <common/log.hpp>
28

29
#ifdef MENDER_USE_DBUS
30
#include <mender-auth/ipc/server.hpp>
31
#endif
32

33
namespace mender {
34
namespace auth {
35
namespace cli {
36

37
using namespace std;
38

39
namespace auth_client = mender::auth::api::auth;
40
namespace events = mender::common::events;
41
namespace http = mender::common::http;
42
namespace log = mender::common::log;
43

44
#ifdef MENDER_USE_DBUS
45
namespace ipc = mender::auth::ipc;
46
#endif
47

48
shared_ptr<MenderKeyStore> KeystoreFromConfig(
4✔
49
        const conf::MenderConfig &config, const string &passphrase) {
50
        cli::StaticKey static_key = cli::StaticKey::No;
4✔
51
        string pem_file;
52
        string ssl_engine;
53

54
        if (config.security.auth_private_key != "") {
4✔
55
                pem_file = config.security.auth_private_key;
56
                ssl_engine = config.security.ssl_engine;
×
57
                static_key = cli::StaticKey::Yes;
×
58
        } else {
59
                pem_file = config.paths.GetKeyFile();
8✔
60
                static_key = cli::StaticKey::No;
61
        }
62

63
        return make_shared<MenderKeyStore>(pem_file, ssl_engine, static_key, passphrase);
8✔
64
}
65

66
error::Error DoBootstrap(shared_ptr<MenderKeyStore> keystore, const bool force) {
4✔
67
        auto err = keystore->Load();
4✔
68
        if (err != error::NoError && err.code != MakeError(NoKeysError, "").code) {
8✔
69
                return err;
70
        }
71
        if (err != error::NoError) {
4✔
72
                log::Error("Got error loading the private key from the keystore: " + err.String());
4✔
73
        }
74
        if (err.code == MakeError(NoKeysError, "").code || force) {
8✔
75
                log::Info("Generating new ED25519 key");
6✔
76
                err = keystore->Generate();
3✔
77
                if (err != error::NoError) {
3✔
78
                        return err;
79
                }
80
                err = keystore->Save();
6✔
81
                if (err != error::NoError) {
82
                        return err;
83
                }
84
        }
85
        return err;
86
}
87

88
error::Error DoAuthenticate(
4✔
89
        context::MenderContext &main_context, shared_ptr<MenderKeyStore> keystore) {
90
        events::EventLoop loop;
91
        auto &config = main_context.GetConfig();
92
        if (config.servers.size() == 0) {
4✔
93
                log::Info("No server set in the configuration, skipping authentication");
3✔
94
                return error::NoError;
3✔
95
        }
96
        mender::common::events::Timer timer {loop};
1✔
97
        http::Client client {config.GetHttpClientConfig(), loop};
1✔
98
        auto err = auth_client::FetchJWTToken(
1✔
99
                client,
100
                config.servers,
1✔
101
                {keystore->KeyName(), keystore->PassPhrase(), keystore->SSLEngine()},
102
                config.paths.GetIdentityScript(),
1✔
103
                [&loop, &timer](auth_client::APIResponse resp) {
1✔
104
                        log::Info("Got Auth response");
2✔
105
                        if (resp) {
1✔
106
                                log::Info(
1✔
107
                                        "Successfully authorized with the server '" + resp.value().server_url + "'");
2✔
108
                        } else {
109
                                log::Error(resp.error().String());
×
110
                        }
111
                        timer.Cancel();
1✔
112
                        loop.Stop();
1✔
113
                },
1✔
114
                config.tenant_token,
1✔
115
                config.device_tier);
2✔
116
        if (err != error::NoError) {
1✔
117
                return err;
×
118
        }
119
        timer.AsyncWait(chrono::seconds {30}, [&loop](error::Error err) { loop.Stop(); });
1✔
120
        loop.Run();
1✔
121
        return error::NoError;
1✔
122
}
1✔
123

124
#ifdef MENDER_USE_DBUS
125
DaemonAction::DaemonAction(shared_ptr<MenderKeyStore> keystore, const bool force_bootstrap) :
×
126
        keystore_(keystore),
127
        force_bootstrap_(force_bootstrap) {
×
128
}
×
129

130
ExpectedActionPtr DaemonAction::Create(
×
131
        const conf::MenderConfig &config, const string &passphrase, const bool force_bootstrap) {
132
        auto key_store = KeystoreFromConfig(config, passphrase);
×
133

134
        return make_shared<DaemonAction>(key_store, force_bootstrap);
×
135
}
136

137
error::Error DaemonAction::Execute(context::MenderContext &main_context) {
×
138
        log::Info("Running mender-auth " + conf::kMenderVersion);
×
139

140
        auto &config = main_context.GetConfig();
141
        if (none_of(config.servers.cbegin(), config.servers.cend(), [](const string &it) {
×
142
                        return it != "";
×
143
                })) {
144
                log::Error("Cannot run in daemon mode with no server URL specified");
×
145
                return error::MakeError(error::ExitWithFailureError, "");
×
146
        }
147

148
        auto err = DoBootstrap(keystore_, force_bootstrap_);
×
149
        if (err != error::NoError) {
×
150
                log::Error("Failed to bootstrap: " + err.String());
×
151
                return error::MakeError(error::ExitWithFailureError, "");
×
152
        }
153

154
        events::EventLoop loop {};
×
155

156
        events::SignalHandler signal_handler {loop};
×
157

158
        err = signal_handler.RegisterHandler(
×
159
                {SIGTERM, SIGINT, SIGQUIT}, [&loop](events::SignalNumber signum) {
×
160
                        log::Info("Termination signal received, shutting down gracefully");
×
161
                        loop.Stop();
×
162
                });
×
163
        if (err != error::NoError) {
×
164
                return err;
×
165
        }
166

167
        ipc::Server ipc_server {loop, config};
×
168

169
        err = ipc_server.Listen(
×
170
                {keystore_->KeyName(), keystore_->PassPhrase(), keystore_->SSLEngine()},
171
                config.paths.GetIdentityScript());
×
172
        if (err != error::NoError) {
×
173
                log::Error("Failed to start the listen loop");
×
174
                log::Error(err.String());
×
175
                return error::MakeError(error::ExitWithFailureError, "");
×
176
        }
177

178
        loop.Post([]() {
×
179
                log::Info(
×
180
                        "The authentication daemon is now ready to accept incoming authentication request");
181
        });
×
182

183
        loop.Run();
×
184

185
        return error::NoError;
×
186
}
×
187
#endif // MENDER_USE_DBUS
188

189
BootstrapAction::BootstrapAction(shared_ptr<MenderKeyStore> keystore, bool force_bootstrap) :
4✔
190
        keystore_(keystore),
191
        force_bootstrap_(force_bootstrap) {
4✔
192
}
×
193

194
ExpectedActionPtr BootstrapAction::Create(
4✔
195
        const conf::MenderConfig &config, const string &passphrase, bool force_bootstrap) {
196
        auto key_store = KeystoreFromConfig(config, passphrase);
4✔
197

198
        return make_shared<BootstrapAction>(key_store, force_bootstrap);
8✔
199
}
200

201
error::Error BootstrapAction::Execute(context::MenderContext &main_context) {
4✔
202
        auto err = DoBootstrap(keystore_, force_bootstrap_);
4✔
203
        if (err != error::NoError) {
4✔
204
                return err;
×
205
        }
206
        return DoAuthenticate(main_context, keystore_);
8✔
207
}
208

209
} // namespace cli
210
} // namespace auth
211
} // namespace mender
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc