-
Notifications
You must be signed in to change notification settings - Fork 36
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add option to authenticate via client certificates #38
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,8 @@ | ||
Using the RAUC hawkbit Updater | ||
============================== | ||
|
||
Authentication | ||
-------------- | ||
Authentication via tokens | ||
------------------------- | ||
|
||
As described on the `hawkBit Authentication page <https://www.eclipse.org/hawkbit/concepts/authentication/>`_ | ||
in the "DDI API Authentication Modes" section, a device can be authenticated | ||
|
@@ -22,6 +22,68 @@ Although gateway token is very handy during development or testing, it's | |
recommended to use this token with care because it can be used to | ||
authenticate any device. | ||
|
||
Authentication via Certificates | ||
------------------------------- | ||
|
||
As can be seen in the system configuration settings of hawkBit, there is a | ||
third option to authenticate the targets. An "Allow targets to authenticate via | ||
a certificate authenticated by a reverse proxy" option. To use this | ||
authentication method a TLS reverse proxy server needs to be set up. | ||
The client and reverse proxy server perform a "SSL-handshake" that means the | ||
client validates the server certificate of the reverse proxy server with its | ||
list of trusted certificates. | ||
|
||
The clients request has: | ||
|
||
- to have a TLS connection to the reverse proxy server | ||
- to contain the client certificate | ||
- to have the common name of the server certificate match the server | ||
name set in the configuration file as "hawkbit_server" | ||
|
||
The purpose of the reverse proxy is to: | ||
|
||
- disband the TLS connection | ||
- check if sent client certificate is valid | ||
- extract the common name and fingerprint of the client certificate | ||
- forward the common name and fingerprint as HTTP headers to the | ||
hawkBit server | ||
|
||
When the hawkBit server receives the request it checks if: | ||
|
||
- sent common name matches with the controller ID of the target | ||
- sent fingerprint(s) matches the expected fingerprint(s) which is set | ||
in the system configuration settings of hawkBit | ||
Comment on lines
+38
to
+55
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No need for indentation here. |
||
|
||
The client certificate will only be used if no tokens are set and a valid path | ||
to a certificate and its key is given in the configuration file. | ||
|
||
Here an example of how the configuration file might look like: | ||
|
||
[client] | ||
hawkbit_server = CN_server_certificate:443 | ||
ssl = true | ||
ssl_verify = true | ||
Comment on lines
+64
to
+65
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What happens if these options are false? |
||
tenant_id = DEFAULT | ||
target_name = test-target | ||
auth_token = | ||
#gateway_token = bhVahL1Il1shie2aj2poojeChee6ahShu | ||
#client_cert = /path/to/client_certificate.pem | ||
#client_key = /path/to/client_certificate.key | ||
Comment on lines
+70
to
+71
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why are these options commented? |
||
bundle_download_location = /tmp/bundle.raucb | ||
retry_wait = 60 | ||
connect_timeout = 20 | ||
timeout = 60 | ||
log_level = debug | ||
post_update_reboot = false | ||
|
||
[device] | ||
product = Terminator | ||
model = T-1000 | ||
serialnumber = 8922673153 | ||
hw_revision = 2 | ||
key1 = value | ||
key2 = value | ||
|
||
Plain Bundle Support | ||
-------------------- | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -240,6 +240,8 @@ Config* load_config_file(const gchar *config_file, GError **error) | |
g_autoptr(GKeyFile) ini_file = NULL; | ||
gboolean key_auth_token_exists = FALSE; | ||
gboolean key_gateway_token_exists = FALSE; | ||
gboolean key_client_cert_exists = FALSE; | ||
gboolean key_client_key_exists = FALSE; | ||
|
||
g_return_val_if_fail(config_file, NULL); | ||
g_return_val_if_fail(error == NULL || *error == NULL, NULL); | ||
|
@@ -259,11 +261,14 @@ Config* load_config_file(const gchar *config_file, GError **error) | |
key_gateway_token_exists = get_key_string(ini_file, "client", "gateway_token", | ||
&config->gateway_token, NULL, NULL); | ||
if (!key_auth_token_exists && !key_gateway_token_exists) { | ||
g_set_error(error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE, | ||
"Neither auth_token nor gateway_token is set in the config."); | ||
return NULL; | ||
} | ||
if (key_auth_token_exists && key_gateway_token_exists) { | ||
g_info("Neither auth_token nor gateway_token is set, using client certificates"); | ||
key_client_cert_exists = get_key_string(ini_file, "client", "client_cert", &config->client_cert, NULL, NULL); | ||
key_client_key_exists = get_key_string(ini_file, "client", "client_key", &config->client_key, NULL, NULL); | ||
if (!key_client_cert_exists || !key_client_key_exists) { | ||
g_set_error(error, 1, 4, "Neither a token nor client certificate are set!"); | ||
return NULL; | ||
} | ||
} else if (key_auth_token_exists && key_gateway_token_exists) { | ||
Comment on lines
-262
to
+271
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you please read these config options outside of these |
||
g_set_error(error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE, | ||
"Both auth_token and gateway_token are set in the config."); | ||
return NULL; | ||
|
@@ -321,6 +326,8 @@ void config_file_free(Config *config) | |
g_free(config->tenant_id); | ||
g_free(config->auth_token); | ||
g_free(config->gateway_token); | ||
g_free(config->client_cert); | ||
g_free(config->client_key); | ||
g_free(config->bundle_download_location); | ||
if (config->device) | ||
g_hash_table_destroy(config->device); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -262,6 +262,13 @@ static gboolean get_binary(const gchar *download_url, const gchar *file, gint64 | |
curl_easy_setopt(curl, CURLOPT_URL, download_url); | ||
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); | ||
curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 8L); | ||
|
||
if (hawkbit_config->client_cert && hawkbit_config->client_key) { | ||
curl_easy_setopt(curl, CURLOPT_SSLKEYTYPE, "PEM"); | ||
curl_easy_setopt(curl, CURLOPT_SSLCERT, hawkbit_config->client_cert); | ||
curl_easy_setopt(curl, CURLOPT_SSLKEY, hawkbit_config->client_key); | ||
} | ||
|
||
Comment on lines
+265
to
+271
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This belongs in |
||
curl_easy_setopt(curl, CURLOPT_BUFFERSIZE, DEFAULT_CURL_DOWNLOAD_BUFFER_SIZE); | ||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_write_to_file_cb); | ||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, payload); | ||
|
@@ -368,6 +375,13 @@ static gboolean rest_request(enum HTTPMethod method, const gchar *url, | |
// set up CURL options | ||
set_default_curl_opts(curl); | ||
curl_easy_setopt(curl, CURLOPT_URL, url); | ||
|
||
if (hawkbit_config->client_cert && hawkbit_config->client_key) { | ||
curl_easy_setopt(curl, CURLOPT_SSLKEYTYPE, "PEM"); | ||
curl_easy_setopt(curl, CURLOPT_SSLCERT, hawkbit_config->client_cert); | ||
curl_easy_setopt(curl, CURLOPT_SSLKEY, hawkbit_config->client_key); | ||
} | ||
|
||
Comment on lines
+378
to
+384
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See above. |
||
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, HTTPMethod_STRING[method]); | ||
curl_easy_setopt(curl, CURLOPT_TIMEOUT, hawkbit_config->timeout); | ||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_write_cb); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.