From a820f204162f61e3e7a91e66c1aabea22f23d0cb Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
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 <assert.h>
 #include <glib.h>
 #include <malloc.h>
 #include <stdio.h>
@@ -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 <malloc.h>
 #include <string.h>
 
 
 #include <i18n.h>
 
 
+#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 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.21.0 -->
+<!-- Generated with glade 3.22.1 -->
 <interface>
   <requires lib="gtk+" version="3.12"/>
   <object class="GtkDialog" id="window">
@@ -8,8 +8,12 @@
     <property name="title" translatable="yes">Identity</property>
     <property name="modal">True</property>
     <property name="window_position">center-on-parent</property>
-    <property name="default_width">515</property>
+    <property name="default_width">520</property>
+    <property name="default_height">550</property>
     <property name="type_hint">dialog</property>
+    <child>
+      <placeholder/>
+    </child>
     <child internal-child="vbox">
       <object class="GtkBox" id="dialog-vbox1">
         <property name="can_focus">False</property>
@@ -78,7 +82,7 @@
               </object>
               <packing>
                 <property name="left_attach">0</property>
-                <property name="top_attach">1</property>
+                <property name="top_attach">2</property>
                 <property name="width">2</property>
               </packing>
             </child>
@@ -87,9 +91,7 @@
                 <property name="width_request">500</property>
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
-                <property name="label" translatable="yes">All the following information is used to create your authentication certifcate. This certificate grants you access to database servers and identifies each analysis change.
-
-&lt;b&gt;Warning: &lt;/b&gt; updating this information drives to new signing requests for remote servers!</property>
+                <property name="label" translatable="yes">All the following information is used to create your authentication certifcates. These certificates grant you access to database servers and identify each analysis change.</property>
                 <property name="use_markup">True</property>
                 <property name="wrap">True</property>
                 <property name="xalign">0</property>
@@ -109,7 +111,7 @@
               </object>
               <packing>
                 <property name="left_attach">0</property>
-                <property name="top_attach">2</property>
+                <property name="top_attach">3</property>
               </packing>
             </child>
             <child>
@@ -122,7 +124,7 @@
               </object>
               <packing>
                 <property name="left_attach">1</property>
-                <property name="top_attach">2</property>
+                <property name="top_attach">3</property>
               </packing>
             </child>
             <child>
@@ -134,7 +136,7 @@
               </object>
               <packing>
                 <property name="left_attach">0</property>
-                <property name="top_attach">3</property>
+                <property name="top_attach">4</property>
                 <property name="width">2</property>
               </packing>
             </child>
@@ -147,7 +149,7 @@
               </object>
               <packing>
                 <property name="left_attach">0</property>
-                <property name="top_attach">4</property>
+                <property name="top_attach">5</property>
               </packing>
             </child>
             <child>
@@ -157,7 +159,7 @@
               </object>
               <packing>
                 <property name="left_attach">1</property>
-                <property name="top_attach">4</property>
+                <property name="top_attach">5</property>
               </packing>
             </child>
             <child>
@@ -167,7 +169,7 @@
               </object>
               <packing>
                 <property name="left_attach">1</property>
-                <property name="top_attach">5</property>
+                <property name="top_attach">6</property>
               </packing>
             </child>
             <child>
@@ -179,7 +181,7 @@
               </object>
               <packing>
                 <property name="left_attach">0</property>
-                <property name="top_attach">5</property>
+                <property name="top_attach">6</property>
               </packing>
             </child>
             <child>
@@ -191,7 +193,7 @@
               </object>
               <packing>
                 <property name="left_attach">0</property>
-                <property name="top_attach">6</property>
+                <property name="top_attach">7</property>
                 <property name="width">2</property>
               </packing>
             </child>
@@ -204,7 +206,7 @@
               </object>
               <packing>
                 <property name="left_attach">0</property>
-                <property name="top_attach">7</property>
+                <property name="top_attach">8</property>
               </packing>
             </child>
             <child>
@@ -214,7 +216,7 @@
               </object>
               <packing>
                 <property name="left_attach">1</property>
-                <property name="top_attach">7</property>
+                <property name="top_attach">8</property>
               </packing>
             </child>
             <child>
@@ -224,7 +226,7 @@
               </object>
               <packing>
                 <property name="left_attach">1</property>
-                <property name="top_attach">8</property>
+                <property name="top_attach">9</property>
               </packing>
             </child>
             <child>
@@ -236,7 +238,7 @@
               </object>
               <packing>
                 <property name="left_attach">0</property>
-                <property name="top_attach">8</property>
+                <property name="top_attach">9</property>
               </packing>
             </child>
             <child>
@@ -248,7 +250,7 @@
               </object>
               <packing>
                 <property name="left_attach">0</property>
-                <property name="top_attach">9</property>
+                <property name="top_attach">10</property>
               </packing>
             </child>
             <child>
@@ -258,7 +260,81 @@
               </object>
               <packing>
                 <property name="left_attach">1</property>
-                <property name="top_attach">9</property>
+                <property name="top_attach">10</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkFrame">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label_xalign">0</property>
+                <property name="shadow_type">none</property>
+                <child>
+                  <object class="GtkAlignment">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="left_padding">12</property>
+                    <child>
+                      <object class="GtkLabel">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="label" translatable="yes">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.</property>
+                        <property name="wrap">True</property>
+                      </object>
+                    </child>
+                  </object>
+                </child>
+                <child type="label">
+                  <object class="GtkLabel">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label" translatable="yes">Warning</property>
+                    <attributes>
+                      <attribute name="weight" value="bold"/>
+                    </attributes>
+                  </object>
+                </child>
+              </object>
+              <packing>
+                <property name="left_attach">0</property>
+                <property name="top_attach">1</property>
+                <property name="width">2</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkSeparator" id="separator2">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+              </object>
+              <packing>
+                <property name="left_attach">0</property>
+                <property name="top_attach">11</property>
+                <property name="width">2</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkLabel">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label" translatable="yes">Certificate validity period (in seconds):</property>
+                <property name="xalign">1</property>
+              </object>
+              <packing>
+                <property name="left_attach">0</property>
+                <property name="top_attach">12</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkEntry">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="placeholder_text" translatable="yes">94608000</property>
+              </object>
+              <packing>
+                <property name="left_attach">1</property>
+                <property name="top_attach">12</property>
               </packing>
             </child>
           </object>
@@ -274,8 +350,5 @@
       <action-widget response="-6">button1</action-widget>
       <action-widget response="-10">button2</action-widget>
     </action-widgets>
-    <child>
-      <placeholder/>
-    </child>
   </object>
 </interface>
-- 
cgit v0.11.2-87-g4458