anastasis-gtk

Demonstrator GUI for Anastasis
Log | Files | Refs | README | LICENSE

anastasis-gtk_handle-method-email.c (6857B)


      1 /*
      2      This file is part of anastasis-gtk.
      3      Copyright (C) 2020 Anastasis SARL
      4 
      5      Anastasis is free software; you can redistribute it and/or modify
      6      it under the terms of the GNU General Public License as published
      7      by the Free Software Foundation; either version 3, or (at your
      8      option) any later version.
      9 
     10      Anastasis is distributed in the hope that it will be useful, but
     11      WITHOUT ANY WARRANTY; without even the implied warranty of
     12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     13      General Public License for more details.
     14 
     15      You should have received a copy of the GNU General Public License
     16      along with Anastasis; see the file COPYING.  If not, write to the
     17      Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     18      Boston, MA 02110-1301, USA.
     19 */
     20 
     21 /**
     22  * @file src/anastasis/anastasis-gtk_handle-method-email.c
     23  * @brief Handle dialogs for security email
     24  * @author Christian Grothoff
     25  */
     26 #include <gnunet/gnunet_util_lib.h>
     27 #include "anastasis_gtk_util.h"
     28 #include "anastasis-gtk_action.h"
     29 #include "anastasis-gtk_helper.h"
     30 #include "anastasis-gtk_handle-identity-changed.h"
     31 #include <jansson.h>
     32 
     33 
     34 /**
     35  * Return obfuscated variant of an e-mail address.
     36  *
     37  * @param email input address
     38  * @return obfuscated version, NULL on errors
     39  */
     40 static char *
     41 mask_email (const char *email)
     42 {
     43   char *at;
     44   char *tld;
     45   size_t nlen;
     46   char *result;
     47 
     48   result = GNUNET_strdup (email);
     49   at = strchr (result, '@');
     50   if (NULL == at)
     51   {
     52     GNUNET_break (0);
     53     GNUNET_free (result);
     54     return NULL;
     55   }
     56   tld = strrchr (result, '.');
     57   if (NULL == tld)
     58   {
     59     GNUNET_break (0);
     60     GNUNET_free (result);
     61     return NULL;
     62   }
     63   if ( (ssize_t) (at - tld) > 0)
     64   {
     65     GNUNET_break (0);
     66     GNUNET_free (result);
     67     return NULL;
     68   }
     69   nlen = at - result;
     70   switch (nlen)
     71   {
     72   case 0:
     73     GNUNET_break (0);
     74     GNUNET_free (result);
     75     return NULL;
     76   case 1:
     77     result[0] = '?';
     78     break;
     79   case 2:
     80   case 3:
     81     result[0] = '?';
     82     result[1] = '?';
     83     break;
     84   default:
     85     for (unsigned int i = 1; i<nlen - 2; i++)
     86       result[i] = '?';
     87     break;
     88   }
     89   nlen = tld - at;
     90   switch (nlen)
     91   {
     92   case 1:
     93     GNUNET_break (0);
     94     GNUNET_free (result);
     95     return NULL;
     96   case 2:
     97     at[1] = '?';
     98     break;
     99   case 3:
    100     at[1] = '?';
    101     at[2] = '?';
    102     break;
    103   case 4:
    104     at[2] = '?';
    105     at[3] = '?';
    106     break;
    107   default:
    108     for (unsigned int i = 2; i<nlen - 2; i++)
    109       at[i] = '?';
    110     break;
    111   }
    112 
    113   /* shorten multiple consecutive "?" to "*" */
    114   {
    115     bool star = false;
    116     bool qmark = false;
    117     size_t woff = 0;
    118 
    119     for (unsigned int i = 0; i<strlen (result); i++)
    120     {
    121       result[woff++] = result[i];
    122       if ('?' == result[i])
    123       {
    124         if (star)
    125         {
    126           /* more than two "??" in a row */
    127           woff--;
    128           continue;
    129         }
    130         if (qmark)
    131         {
    132           /* two "??", combine to "*" */
    133           result[--woff - 1] = '*';
    134           star = true;
    135           continue;
    136         }
    137         /* first qmark */
    138         qmark = true;
    139       }
    140       else
    141       {
    142         star = false;
    143         qmark = false;
    144       }
    145     }
    146     result[woff] = '\0';
    147   }
    148   return result;
    149 }
    150 
    151 
    152 /**
    153  * Function called from the security-email dialog upon completion.
    154  *
    155  * @param dialog the pseudonym selection dialog
    156  * @param response_id response code from the dialog
    157  * @param user_data the builder of the dialog
    158  */
    159 void
    160 anastasis_gtk_b_email_dialog_response_cb (GtkDialog *dialog,
    161                                           gint response_id,
    162                                           gpointer user_data)
    163 {
    164   GtkBuilder *builder = GTK_BUILDER (user_data);
    165   GtkEntry *q;
    166   const char *qs;
    167   json_t *args;
    168   char *ins;
    169   char *pe;
    170 
    171   if (GTK_RESPONSE_OK != response_id)
    172   {
    173     gtk_widget_destroy (GTK_WIDGET (dialog));
    174     g_object_unref (G_OBJECT (builder));
    175     return;
    176   }
    177   q = GTK_ENTRY (gtk_builder_get_object (builder,
    178                                          "anastasis_gtk_b_email_dialog_mailaddress_entry"));
    179   qs = gtk_entry_get_text (q);
    180   pe = mask_email (qs);
    181   GNUNET_asprintf (&ins,
    182                    _ ("e-mail address %s"),
    183                    pe);
    184   GNUNET_free (pe);
    185   args = json_pack ("{ s:{s:s, s:o, s:s}}",
    186                     "authentication_method",
    187                     "type",
    188                     "email",
    189                     "challenge",
    190                     GNUNET_JSON_from_data (qs,
    191                                            strlen (qs)),
    192                     "instructions",
    193                     ins);
    194   GNUNET_free (ins);
    195   gtk_widget_destroy (GTK_WIDGET (dialog));
    196   g_object_unref (G_OBJECT (builder));
    197   AG_freeze ();
    198   AG_ra = ANASTASIS_redux_action (AG_redux_state,
    199                                   "add_authentication",
    200                                   args,
    201                                   &AG_action_cb,
    202                                   NULL);
    203   json_decref (args);
    204 }
    205 
    206 
    207 void
    208 anastasis_gtk_b_email_dialog_mailaddress_entry_changed_cb (GtkEntry *entry,
    209                                                            gpointer user_data)
    210 {
    211   GtkBuilder *builder = GTK_BUILDER (user_data);
    212   GtkEntry *q;
    213   const char *qs;
    214   regex_t regex;
    215   int regex_result;
    216   const char *regexp = "[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}";
    217 
    218   regex_result = regcomp (&regex,
    219                           regexp,
    220                           REG_EXTENDED);
    221   if (0 < regex_result)
    222   {
    223     GNUNET_break (0);
    224     return;
    225   }
    226   q = GTK_ENTRY (gtk_builder_get_object (builder,
    227                                          "anastasis_gtk_b_email_dialog_mailaddress_entry"));
    228   qs = gtk_entry_get_text (q);
    229   regex_result = regexec (&regex,
    230                           qs,
    231                           0,
    232                           NULL,
    233                           0);
    234   regfree (&regex);
    235   gtk_widget_set_sensitive (
    236     GTK_WIDGET (gtk_builder_get_object (builder,
    237                                         "anastasis_gtk_b_email_dialog_btn_ok")),
    238     0 == regex_result);
    239 }
    240 
    241 
    242 /**
    243  * Callback invoked if the the "secure email"-button is clicked.
    244  *
    245  * @param object
    246  * @param user_data unused
    247  */
    248 void
    249 anastasis_gtk_btn_add_auth_email_clicked_cb (GObject *object,
    250                                              gpointer user_data)
    251 {
    252   GtkWidget *ad;
    253   GtkBuilder *builder;
    254 
    255   builder = ANASTASIS_GTK_get_new_builder (
    256     ANASTASIS_GTK_project_data (),
    257     "anastasis_gtk_auth_add_email.glade",
    258     NULL);
    259   if (NULL == builder)
    260   {
    261     GNUNET_break (0);
    262     return;
    263   }
    264   ad = GTK_WIDGET (gtk_builder_get_object (builder,
    265                                            "anastasis_gtk_b_email_dialog"));
    266   {
    267     GtkWidget *toplevel;
    268 
    269     toplevel = gtk_widget_get_toplevel (GTK_WIDGET (object));
    270     gtk_window_set_transient_for (GTK_WINDOW (ad),
    271                                   GTK_WINDOW (toplevel));
    272     gtk_window_present (GTK_WINDOW (ad));
    273   }
    274 }