-
Notifications
You must be signed in to change notification settings - Fork 43
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
Support for authentication with client certificates #656
base: develop
Are you sure you want to change the base?
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 | ||||
---|---|---|---|---|---|---|
|
@@ -20,6 +20,7 @@ | |||||
#include <stdbool.h> | ||||||
#include <stdlib.h> | ||||||
#include <string.h> | ||||||
#include <errno.h> | ||||||
|
||||||
static pthread_mutex_t s_config_mutex = PTHREAD_MUTEX_INITIALIZER; | ||||||
|
||||||
|
@@ -57,13 +58,87 @@ static const char* CONFIG_RUN_AS = "runas"; | |||||
static const char* CONFIG_CONNECTION_SOURCE = "connectionSource"; | ||||||
static const char* CONFIG_CONNECTION_TYPE = "connectionType"; | ||||||
static const char* CONFIG_CONNECTION_DATA = "connectionData"; | ||||||
static const char* CONFIG_CONNECTION_X509_CERT_FILE_PATH = "connectionX509CertFilePath"; | ||||||
static const char* CONFIG_CONNECTION_X509_PRIVATE_KEY_FILE_PATH = "connectionX509PrivateKeyFilePath"; | ||||||
static const char* CONFIG_CONNECTION_X509_CA_CERT_FILE_PATH = "connectionX509CaCertFilePath"; | ||||||
static const char* CONFIG_ADDITIONAL_DEVICE_PROPERTIES = "additionalDeviceProperties"; | ||||||
static const char* CONFIG_AGENTS = "agents"; | ||||||
|
||||||
static const char* INVALID_OR_MISSING_FIELD_ERROR_FMT = "Invalid json - '%s' missing or incorrect"; | ||||||
|
||||||
static void ADUC_AgentInfo_Free(ADUC_AgentInfo* agent); | ||||||
|
||||||
|
||||||
static char* ADUC_AgentInfo_Read_X509_File(const char* const x509_file_path) { | ||||||
char* buffer = NULL; | ||||||
long ftellResult = 0; | ||||||
size_t bufferLength = 0; | ||||||
size_t bytesRead = 0; | ||||||
FILE* x509File = NULL; | ||||||
|
||||||
x509File = fopen(x509_file_path, "rb"); | ||||||
if (x509File) | ||||||
{ | ||||||
if (fseek(x509File, 0, SEEK_END) == 0) { | ||||||
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. Style consistency issue: Opening brace should be on next line Touch every file in the current set of commits,
Longer-term, we need to add clang-format.sh (and some other things) to the git pre-commit hook. Currently, the existing git pre-commit hook only runs sh-format.sh (
|
||||||
ftellResult = ftell(x509File); | ||||||
if (ftellResult != -1) | ||||||
{ | ||||||
bufferLength = (size_t)ftellResult; | ||||||
if (fseek(x509File, 0, SEEK_SET) == 0) | ||||||
{ | ||||||
buffer = malloc(bufferLength); | ||||||
if (buffer) | ||||||
{ | ||||||
bytesRead = fread(buffer, 1, bufferLength, x509File); | ||||||
if (bytesRead < bufferLength) | ||||||
{ | ||||||
if (feof(x509File)) | ||||||
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. Line 95 here has an if-statement that is 7 levels deep.
bool success = false;
...
if (x509File == NULL)
{
Log_Error("Failed to open '%s'!", x509_file_path);
goto done;
}
if (fseek(x509File, 0, SEEK_END) != 0)
{
Log_Error("Failed to seek end of '%s'!", x509_file_path);
goto done;
}
...
...
success = true;
done:
if (!success)
{
free(buffer);
buffer = NULL;
}
if (x509File != NULL)
{
fclose(x509File);
}
return buffer;
} |
||||||
{ | ||||||
Log_Error("Unexpected end of file while reading '%s' (bytesRead: %zu)!", x509_file_path, bytesRead); | ||||||
} | ||||||
else if (ferror(x509File)) { | ||||||
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. paren on next line |
||||||
Log_Error("Error occurred while reading '%s' (bytesRead: %zu)!", x509_file_path, bytesRead); | ||||||
} | ||||||
else | ||||||
{ | ||||||
Log_Error("Failed to read '%s' (bytesRead: %zu)!", x509_file_path, bytesRead); | ||||||
} | ||||||
free(buffer); | ||||||
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. for future maintainability, this should be done unconditionally at the end, if in "not succeeded" state. |
||||||
buffer = NULL; | ||||||
} | ||||||
} | ||||||
else | ||||||
{ | ||||||
Log_Error("Failed to get memory for buffer!"); | ||||||
} | ||||||
} | ||||||
else | ||||||
{ | ||||||
Log_Error("Failed to seek begin of '%s'!", x509_file_path); | ||||||
} | ||||||
} | ||||||
else | ||||||
{ | ||||||
Log_Error("Failed to get file position ('%d')!", errno); | ||||||
} | ||||||
} | ||||||
else | ||||||
{ | ||||||
Log_Error("Failed to seek end of '%s'!", x509_file_path); | ||||||
} | ||||||
|
||||||
if(fclose (x509File) != 0) { | ||||||
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. style: no space between function name and arg list (should be caught by clang-format) 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. would prefer this to be in centralized cleanup area, such as after 'done:' label (along with free(buffer) if in error condition). |
||||||
Log_Warn("Failed to close '%s'!", x509_file_path); | ||||||
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. omit. no need to log when fclose fails as it's not really actionable and the log trace might not even be able to flush to disk in that case (things are in a pretty bad state) |
||||||
} | ||||||
} | ||||||
else | ||||||
{ | ||||||
Log_Error("Failed to open '%s'!", x509_file_path); | ||||||
} | ||||||
|
||||||
return(buffer); | ||||||
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. style: no parens for return |
||||||
} | ||||||
|
||||||
/** | ||||||
* @brief Initializes an ADUC_AgentInfo object | ||||||
* @param agent the agent to be initialized | ||||||
|
@@ -94,6 +169,9 @@ static bool ADUC_AgentInfo_Init(ADUC_AgentInfo* agent, const JSON_Object* agent_ | |||||
JSON_Object* connection_source = json_object_get_object(agent_obj, CONFIG_CONNECTION_SOURCE); | ||||||
const char* connection_type = NULL; | ||||||
const char* connection_data = NULL; | ||||||
const char* connection_x509_cert_file_path = NULL; | ||||||
const char* connection_x509_private_key_file_path = NULL; | ||||||
const char* connection_x509_ca_cert_file_path = NULL; | ||||||
|
||||||
if (connection_source == NULL) | ||||||
{ | ||||||
|
@@ -102,6 +180,9 @@ static bool ADUC_AgentInfo_Init(ADUC_AgentInfo* agent, const JSON_Object* agent_ | |||||
|
||||||
connection_type = json_object_get_string(connection_source, CONFIG_CONNECTION_TYPE); | ||||||
connection_data = json_object_get_string(connection_source, CONFIG_CONNECTION_DATA); | ||||||
connection_x509_cert_file_path = json_object_get_string(connection_source, CONFIG_CONNECTION_X509_CERT_FILE_PATH); | ||||||
connection_x509_private_key_file_path = json_object_get_string(connection_source, CONFIG_CONNECTION_X509_PRIVATE_KEY_FILE_PATH); | ||||||
connection_x509_ca_cert_file_path = json_object_get_string(connection_source, CONFIG_CONNECTION_X509_CA_CERT_FILE_PATH); | ||||||
|
||||||
// As these fields are mandatory, if any of the fields doesn't exist, the agent will fail to be constructed. | ||||||
if (name == NULL || runas == NULL || connection_type == NULL || connection_data == NULL || manufacturer == NULL | ||||||
|
@@ -130,6 +211,28 @@ static bool ADUC_AgentInfo_Init(ADUC_AgentInfo* agent, const JSON_Object* agent_ | |||||
goto done; | ||||||
} | ||||||
|
||||||
if (connection_x509_cert_file_path || connection_x509_private_key_file_path || connection_x509_ca_cert_file_path) { | ||||||
if(connection_x509_cert_file_path && connection_x509_private_key_file_path && connection_x509_ca_cert_file_path) { | ||||||
agent->x509Cert = ADUC_AgentInfo_Read_X509_File(connection_x509_cert_file_path); | ||||||
if (!agent->x509Cert) | ||||||
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. the code base uses explicit conditions regarding check for NULL values, so please change to: if (agent->x509Cert == NULL) The same for lines 221 and 226. |
||||||
{ | ||||||
goto done; | ||||||
} | ||||||
agent->x509PrivateKey = ADUC_AgentInfo_Read_X509_File(connection_x509_private_key_file_path); | ||||||
if (!agent->x509PrivateKey) | ||||||
{ | ||||||
goto done; | ||||||
} | ||||||
agent->x509CaCert = ADUC_AgentInfo_Read_X509_File(connection_x509_ca_cert_file_path); | ||||||
if (!agent->x509CaCert) | ||||||
{ | ||||||
goto done; | ||||||
} | ||||||
} else { | ||||||
Log_Error("Incomplete X509 client certificate configuration! Cert file path or private key file path is missing."); | ||||||
} | ||||||
} | ||||||
|
||||||
if (mallocAndStrcpy_s(&(agent->manufacturer), manufacturer) != 0) | ||||||
{ | ||||||
goto done; | ||||||
|
@@ -173,6 +276,15 @@ static void ADUC_AgentInfo_Free(ADUC_AgentInfo* agent) | |||||
free(agent->connectionData); | ||||||
agent->connectionData = NULL; | ||||||
|
||||||
free(agent->x509Cert); | ||||||
agent->x509Cert = NULL; | ||||||
|
||||||
free(agent->x509PrivateKey); | ||||||
agent->x509PrivateKey = NULL; | ||||||
|
||||||
free(agent->x509CaCert); | ||||||
agent->x509CaCert = NULL; | ||||||
|
||||||
free(agent->manufacturer); | ||||||
agent->manufacturer = NULL; | ||||||
|
||||||
|
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.
use explicit checks for NULL / non-NULL: