From a820f204162f61e3e7a91e66c1aabea22f23d0cb Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Sun, 1 Sep 2019 23:37:51 +0200 Subject: Prepared the update of the user identity from the GUI. --- src/analysis/db/auth.c | 49 +++++++++++++----- src/analysis/db/auth.h | 3 ++ src/analysis/db/certs.c | 109 +++++++++++++++++++++++++++++++++++----- src/analysis/db/certs.h | 3 ++ src/gui/dialogs/identity.c | 111 +++++++++++++++++++++++++---------------- src/gui/dialogs/identity.ui | 119 +++++++++++++++++++++++++++++++++++--------- 6 files changed, 301 insertions(+), 93 deletions(-) diff --git a/src/analysis/db/auth.c b/src/analysis/db/auth.c index af51af6..5e62f58 100644 --- a/src/analysis/db/auth.c +++ b/src/analysis/db/auth.c @@ -209,6 +209,38 @@ static char *get_cert_storage_directory(const char *outdir, const char *host, co /****************************************************************************** * * +* Paramètres : - * +* * +* Description : Détermine la désignation par défaut de l'usager. * +* * +* Retour : Nom déterminé à libérer de la mémoire. * +* * +* Remarques : - * +* * +******************************************************************************/ + +char *get_default_username(void) +{ + char *result; /* Désignation à retourner */ + uid_t uid; /* Identifiant d'utilisateur */ + struct passwd *pw; /* Indications sur l'usager */ + + uid = geteuid(); + pw = getpwuid(uid); + + if (pw != NULL) + result = strdup(pw->pw_name); + + else + result = strdup("anonymous"); + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : valid = durée de validité des certificats. * * entries = éléments d'identité à utiliser pour l'opération. * * * @@ -224,8 +256,6 @@ bool setup_client_identity(unsigned long valid, x509_entries *entries) { bool result; /* Bilan de l'opération */ char *working; /* Répertoire pour le client */ - uid_t uid; /* Identifiant d'utilisateur */ - struct passwd *pw; /* Indications sur l'usager */ working = get_db_working_directory("clients", NULL, NULL, NULL); @@ -235,18 +265,11 @@ bool setup_client_identity(unsigned long valid, x509_entries *entries) { if (entries->common_name == NULL) { - uid = geteuid(); - pw = getpwuid(uid); - - if (pw != NULL) - { - log_variadic_message(LMT_WARNING, - _("Replaced the empty identity common name with '%s'"), - pw->pw_name); - - entries->common_name = strdup(pw->pw_name); + entries->common_name = get_default_username(); - } + log_variadic_message(LMT_WARNING, + _("Replaced the empty identity common name with '%s'"), + entries->common_name); } diff --git a/src/analysis/db/auth.h b/src/analysis/db/auth.h index 4db7af7..4464244 100644 --- a/src/analysis/db/auth.h +++ b/src/analysis/db/auth.h @@ -39,6 +39,9 @@ bool build_internal_server_socket(struct sockaddr_un *); /* Fournit le répertoire de travail pour les données d'analyse. */ char *get_db_working_directory(const char *, const char *, const char *, const char *); +/* Détermine la désignation par défaut de l'usager. */ +char *get_default_username(void); + /* Etablit une base pour l'identité de l'utilisateur. */ bool setup_client_identity(unsigned long, x509_entries *); diff --git a/src/analysis/db/certs.c b/src/analysis/db/certs.c index a333d9a..107b7b9 100644 --- a/src/analysis/db/certs.c +++ b/src/analysis/db/certs.c @@ -24,6 +24,7 @@ #include "certs.h" +#include #include #include #include @@ -258,7 +259,7 @@ bool build_keys_and_ca(const char *dir, const char *label, unsigned long valid, EVP_PKEY *pk; /* Enveloppe pour clef publique*/ int ret; /* Bilan d'un appel */ X509 *x509; /* Certificat X509 à définir */ - X509_NAME *name; /* Désignation du certificat */ + X509_NAME *subject; /* SUjet du certificat */ char *filename; /* Chemin d'accès à un fichier */ FILE *stream; /* Flux ouvert en écriture */ @@ -288,14 +289,14 @@ bool build_keys_and_ca(const char *dir, const char *label, unsigned long valid, /* Etablissement d'une identité */ - name = X509_get_subject_name(x509); + subject = X509_get_subject_name(x509); #define SET_NAME_ENTRY(key, value) \ do \ { \ if (entries->value != NULL) \ { \ - ret = X509_NAME_add_entry_by_txt(name, key, MBSTRING_UTF8, \ + ret = X509_NAME_add_entry_by_txt(subject, key, MBSTRING_UTF8, \ (unsigned char *)entries->value, -1, -1, 0); \ if (ret != 1) goto ca_failed; \ } \ @@ -316,7 +317,7 @@ bool build_keys_and_ca(const char *dir, const char *label, unsigned long valid, #undef SET_NAME_ENTRY - ret = X509_set_issuer_name(x509, name); + ret = X509_set_issuer_name(x509, subject); if (ret != 1) goto ca_failed; /* Extensions */ @@ -461,7 +462,7 @@ bool build_keys_and_request(const char *dir, const char *label, const x509_entri EVP_PKEY *pk; /* Enveloppe pour clef publique*/ int ret; /* Bilan d'un appel */ X509_REQ *x509; /* Certificat X509 à définir */ - X509_NAME *name; /* Désignation du certificat */ + X509_NAME *subject; /* Sujet du certificat */ STACK_OF(X509_EXTENSION) *exts; /* Extensions du certificat */ char *filename; /* Chemin d'accès à un fichier */ FILE *stream; /* Flux ouvert en écriture */ @@ -483,14 +484,14 @@ bool build_keys_and_request(const char *dir, const char *label, const x509_entri /* Etablissement d'une identité */ - name = X509_REQ_get_subject_name(x509); + subject = X509_REQ_get_subject_name(x509); #define SET_NAME_ENTRY(key, value) \ do \ { \ if (entries->value != NULL) \ { \ - ret = X509_NAME_add_entry_by_txt(name, key, MBSTRING_UTF8, \ + ret = X509_NAME_add_entry_by_txt(subject, key, MBSTRING_UTF8, \ (unsigned char *)entries->value, -1, -1, 0); \ if (ret != 1) goto req_failed; \ } \ @@ -603,6 +604,88 @@ bool build_keys_and_request(const char *dir, const char *label, const x509_entri /****************************************************************************** * * +* Paramètres : csr = fichier contenant le certificat à signer. * +* entries = éléments de l'identité constituée. [OUT] * +* * +* Description : Recharge l'identité inscrite dans une requête de signature. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool load_identity_from_request(const char *csr, x509_entries *entries) +{ + bool result; /* Bilan à retourner */ + FILE *stream; /* Flux ouvert en lecture */ + X509_REQ *req; /* Certificat X509 à signer */ + X509_NAME *subject; /* Sujet du certificat */ + int length; /* Taille du champ visé */ + + result = false; + + memset(entries, 0, sizeof(*entries)); + + /* Chargement de la requête */ + + stream = fopen(csr, "rb"); + if (stream == NULL) goto csr_read_failed; + + req = PEM_read_X509_REQ(stream, NULL, NULL, NULL); + + fclose(stream); + + if (req == NULL) + { + log_variadic_message(LMT_ERROR, _("Unable to read the certificate signing request from '%s'"), csr); + goto csr_read_failed; + } + + /* Recherche des éléments */ + + subject = X509_REQ_get_subject_name(req); + +#define GET_NAME_ENTRY(key, value) \ + do \ + { \ + length = X509_NAME_get_text_by_NID(subject, key, NULL, -1); \ + if (length != -1) \ + { \ + entries->value = malloc((length + 1) * sizeof(char)); \ + length = X509_NAME_get_text_by_NID(subject, key, entries->value, length + 1); \ + assert(length != -1); \ + } \ + } \ + while (0) + + GET_NAME_ENTRY(NID_countryName, country); + + GET_NAME_ENTRY(NID_stateOrProvinceName, state); + + GET_NAME_ENTRY(NID_localityName, locality); + + GET_NAME_ENTRY(NID_organizationName, organisation); + + GET_NAME_ENTRY(NID_organizationalUnitName, organisational_unit); + + GET_NAME_ENTRY(NID_commonName, common_name); + +#undef GET_NAME_ENTRY + + X509_REQ_free(req); + + result = true; + + csr_read_failed: + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : csr = fichier contenant le certificat à signer. * * cacert = fichier contenant le certificat de l'autorité. * * cakey = fichier contenant la clef privée du CA. * @@ -619,14 +702,14 @@ bool build_keys_and_request(const char *dir, const char *label, const x509_entri bool sign_cert(const char *csr, const char *cacert, const char *cakey, const char *cert, unsigned long valid) { - FILE *stream; /* Flux ouvert en écriture */ + FILE *stream; /* Flux ouvert en lecture */ X509_REQ *req; /* Certificat X509 à signer */ EVP_PKEY *pk; /* Enveloppe pour clef publique*/ X509 *ca_cert; /* Certificat de l'autorité */ EVP_PKEY *ca_pk; /* Enveloppe pour clef privée */ X509 *x509; /* Certificat X509 à définir */ int ret; /* Bilan d'un appel */ - X509_NAME *name; /* Désignation du certificat */ + X509_NAME *subject; /* Sujet de certificat */ /* Chargement de la requête */ @@ -696,14 +779,14 @@ bool sign_cert(const char *csr, const char *cacert, const char *cakey, const cha ret = X509_set_pubkey(x509, pk); if (ret != 1) goto signing_failed; - name = X509_REQ_get_subject_name(req); + subject = X509_REQ_get_subject_name(req); - ret = X509_set_subject_name(x509, name); + ret = X509_set_subject_name(x509, subject); if (ret != 1) goto signing_failed; - name = X509_get_subject_name(ca_cert); + subject = X509_get_subject_name(ca_cert); - ret = X509_set_issuer_name(x509, name); + ret = X509_set_issuer_name(x509, subject); if (ret != 1) goto signing_failed; /* Extensions */ diff --git a/src/analysis/db/certs.h b/src/analysis/db/certs.h index 132cd7f..50c96c0 100644 --- a/src/analysis/db/certs.h +++ b/src/analysis/db/certs.h @@ -54,6 +54,9 @@ bool build_keys_and_ca(const char *, const char *, unsigned long, const x509_ent /* Crée un certificat pour application. */ bool build_keys_and_request(const char *, const char *, const x509_entries *); +/* Recharge l'identité inscrite dans une requête de signature. */ +bool load_identity_from_request(const char *, x509_entries *); + /* Signe un certificat pour application. */ bool sign_cert(const char *, const char *, const char *, const char *, unsigned long); diff --git a/src/gui/dialogs/identity.c b/src/gui/dialogs/identity.c index 625c556..eae1069 100644 --- a/src/gui/dialogs/identity.c +++ b/src/gui/dialogs/identity.c @@ -24,19 +24,22 @@ #include "identity.h" +#include #include #include +#include "../../analysis/db/auth.h" #include "../../analysis/db/certs.h" +#include "../../common/extstr.h" #include "../../core/logs.h" /* Applique la nouvelle définition d'identité. */ -static void update_identity(GtkButton *button, GtkBuilder *); +static void update_identity(GtkButton *, GtkBuilder *); @@ -57,8 +60,11 @@ GtkWidget *create_identity_dialog(GtkWindow *parent, GtkBuilder **outb) { GtkWidget *result; /* Fenêtre à renvoyer */ GtkBuilder *builder; /* Constructeur utilisé */ - x509_entries entries; /* Eléments identitaires */ + char *username; /* Nom par défaut */ GtkEntry *entry; /* Zone de saisie à initialiser*/ + char *filename; /* Fichier devant être présent */ + x509_entries identity; /* Eléments identitaires */ + bool status; /* Bilan d'un chargement */ builder = gtk_builder_new_from_resource("/org/chrysalide/gui/dialogs/identity.ui"); *outb = builder; @@ -67,47 +73,64 @@ GtkWidget *create_identity_dialog(GtkWindow *parent, GtkBuilder **outb) gtk_window_set_transient_for(GTK_WINDOW(result), parent); - /* Mise à jour de l'interface */ + username = get_default_username(); - memset(&entries, 0, sizeof(entries)); - //load_identity(true, &entries); + entry = GTK_ENTRY(gtk_builder_get_object(builder, "cn")); + gtk_entry_set_placeholder_text(entry, username); - if (entries.country != NULL) - { - entry = GTK_ENTRY(gtk_builder_get_object(builder, "c")); - gtk_entry_set_text(entry, entries.country); - } + free(username); - if (entries.state != NULL) - { - entry = GTK_ENTRY(gtk_builder_get_object(builder, "st")); - gtk_entry_set_text(entry, entries.state); - } + /* Mise à jour de l'interface */ - if (entries.locality != NULL) - { - entry = GTK_ENTRY(gtk_builder_get_object(builder, "l")); - gtk_entry_set_text(entry, entries.locality); - } + filename = get_db_working_directory("clients", NULL, NULL, NULL); + filename = stradd(filename, "client-csr.pem"); - if (entries.organisation != NULL) - { - entry = GTK_ENTRY(gtk_builder_get_object(builder, "o")); - gtk_entry_set_text(entry, entries.organisation); - } + status = load_identity_from_request(filename, &identity); - if (entries.organisational_unit != NULL) - { - entry = GTK_ENTRY(gtk_builder_get_object(builder, "ou")); - gtk_entry_set_text(entry, entries.organisational_unit); - } + free(filename); - if (entries.country != NULL) + if (status) { - entry = GTK_ENTRY(gtk_builder_get_object(builder, "cn")); - gtk_entry_set_text(entry, entries.common_name); - - gtk_editable_select_region(GTK_EDITABLE(entry), 0, -1); + if (identity.country != NULL) + { + entry = GTK_ENTRY(gtk_builder_get_object(builder, "c")); + gtk_entry_set_text(entry, identity.country); + } + + if (identity.state != NULL) + { + entry = GTK_ENTRY(gtk_builder_get_object(builder, "st")); + gtk_entry_set_text(entry, identity.state); + } + + if (identity.locality != NULL) + { + entry = GTK_ENTRY(gtk_builder_get_object(builder, "l")); + gtk_entry_set_text(entry, identity.locality); + } + + if (identity.organisation != NULL) + { + entry = GTK_ENTRY(gtk_builder_get_object(builder, "o")); + gtk_entry_set_text(entry, identity.organisation); + } + + if (identity.organisational_unit != NULL) + { + entry = GTK_ENTRY(gtk_builder_get_object(builder, "ou")); + gtk_entry_set_text(entry, identity.organisational_unit); + } + + if (identity.common_name != NULL) + { + entry = GTK_ENTRY(gtk_builder_get_object(builder, "cn")); + gtk_entry_set_text(entry, identity.common_name); + + gtk_editable_select_region(GTK_EDITABLE(entry), 0, -1); + + } + + free_x509_entries(&identity); } @@ -141,7 +164,7 @@ static void update_identity(GtkButton *button, GtkBuilder *builder) { GtkEntry *entry; /* Zone de saisie à consulter */ const gchar *data; /* Données internes à GTK */ - x509_entries entries; /* Nouvelle identité à pousser */ + x509_entries identity; /* Nouvelle identité à pousser */ bool status; /* Bilan de la mise à jour */ /* Récupération des éléments */ @@ -149,42 +172,42 @@ static void update_identity(GtkButton *button, GtkBuilder *builder) entry = GTK_ENTRY(gtk_builder_get_object(builder, "c")); data = gtk_entry_get_text(entry); - entries.country = (strlen(data) > 0 ? strdup(data) : NULL); + identity.country = (strlen(data) > 0 ? strdup(data) : NULL); entry = GTK_ENTRY(gtk_builder_get_object(builder, "st")); data = gtk_entry_get_text(entry); - entries.state = (strlen(data) > 0 ? strdup(data) : NULL); + identity.state = (strlen(data) > 0 ? strdup(data) : NULL); entry = GTK_ENTRY(gtk_builder_get_object(builder, "l")); data = gtk_entry_get_text(entry); - entries.locality = (strlen(data) > 0 ? strdup(data) : NULL); + identity.locality = (strlen(data) > 0 ? strdup(data) : NULL); entry = GTK_ENTRY(gtk_builder_get_object(builder, "o")); data = gtk_entry_get_text(entry); - entries.organisation = (strlen(data) > 0 ? strdup(data) : NULL); + identity.organisation = (strlen(data) > 0 ? strdup(data) : NULL); entry = GTK_ENTRY(gtk_builder_get_object(builder, "ou")); data = gtk_entry_get_text(entry); - entries.organisational_unit = (strlen(data) > 0 ? strdup(data) : NULL); + identity.organisational_unit = (strlen(data) > 0 ? strdup(data) : NULL); entry = GTK_ENTRY(gtk_builder_get_object(builder, "cn")); data = gtk_entry_get_text(entry); - entries.common_name = (strlen(data) > 0 ? strdup(data) : NULL); + identity.common_name = (strlen(data) > 0 ? strdup(data) : NULL); /* Application de la nouvelle définition */ status = false;//register_standalone_certs(&entries); - free_x509_entries(&entries); + free_x509_entries(&identity); if (status) log_simple_message(LMT_INFO, _("New identity has been loaded with success!")); else - log_simple_message(LMT_ERROR, _("Failure while loading the new identity...")); + log_simple_message(LMT_ERROR, _("Failure while reloading the new identity...")); } diff --git a/src/gui/dialogs/identity.ui b/src/gui/dialogs/identity.ui index 25d398f..413d7f6 100644 --- a/src/gui/dialogs/identity.ui +++ b/src/gui/dialogs/identity.ui @@ -1,5 +1,5 @@ - + @@ -8,8 +8,12 @@ Identity True center-on-parent - 515 + 520 + 550 dialog + + + False @@ -78,7 +82,7 @@ 0 - 1 + 2 2 @@ -87,9 +91,7 @@ 500 True False - All the following information is used to create your authentication certifcate. This certificate grants you access to database servers and identifies each analysis change. - -<b>Warning: </b> updating this information drives to new signing requests for remote servers! + All the following information is used to create your authentication certifcates. These certificates grant you access to database servers and identify each analysis change. True True 0 @@ -109,7 +111,7 @@ 0 - 2 + 3 @@ -122,7 +124,7 @@ 1 - 2 + 3 @@ -134,7 +136,7 @@ 0 - 3 + 4 2 @@ -147,7 +149,7 @@ 0 - 4 + 5 @@ -157,7 +159,7 @@ 1 - 4 + 5 @@ -167,7 +169,7 @@ 1 - 5 + 6 @@ -179,7 +181,7 @@ 0 - 5 + 6 @@ -191,7 +193,7 @@ 0 - 6 + 7 2 @@ -204,7 +206,7 @@ 0 - 7 + 8 @@ -214,7 +216,7 @@ 1 - 7 + 8 @@ -224,7 +226,7 @@ 1 - 8 + 9 @@ -236,7 +238,7 @@ 0 - 8 + 9 @@ -248,7 +250,7 @@ 0 - 9 + 10 @@ -258,7 +260,81 @@ 1 - 9 + 10 + + + + + True + False + 0 + none + + + True + False + 12 + + + True + False + Updating this information drives to new signing requests! Please contact the administrators of all the remote servers to update your accesses. + +The authorization for the internal server is updated automatically. + True + + + + + + + True + False + Warning + + + + + + + + 0 + 1 + 2 + + + + + True + False + + + 0 + 11 + 2 + + + + + True + False + Certificate validity period (in seconds): + 1 + + + 0 + 12 + + + + + True + True + 94608000 + + + 1 + 12 @@ -274,8 +350,5 @@ button1 button2 - - - -- cgit v0.11.2-87-g4458