anastasis-gtk

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

anastasis-gtk_handle-method-sms.c (6417B)


      1 /*
      2      This file is part of anastasis-gtk.
      3      Copyright (C) 2020-2021 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-sms.c
     23  * @brief Handle dialogs for security sms
     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 a phone number.
     36  *
     37  * @param number input address
     38  * @return obfuscated version, NULL on errors
     39  */
     40 static char *
     41 mask_number (const char *number)
     42 {
     43   char *at;
     44   size_t nlen;
     45   char *result;
     46 
     47   result = GNUNET_strdup (number);
     48   at = strchr (result, '+');
     49   if ( (NULL != at) &&
     50        (result != at) )
     51   {
     52     GNUNET_break (0);
     53     GNUNET_free (result);
     54     return NULL;
     55   }
     56   nlen = strlen (number);
     57   if (NULL != at)
     58   {
     59     if (strlen (at) < 3)
     60     {
     61       GNUNET_break (0);
     62       GNUNET_free (result);
     63       return NULL;
     64     }
     65     at += 3;
     66     nlen -= 3;
     67   }
     68   else
     69   {
     70     at = result;
     71   }
     72   switch (nlen)
     73   {
     74   case 0:
     75     GNUNET_break (0);
     76     GNUNET_free (result);
     77     return NULL;
     78   case 1:
     79     at[0] = '?';
     80     break;
     81   case 2:
     82   case 3:
     83   case 4:
     84     at[0] = '?';
     85     at[1] = '?';
     86     break;
     87   default:
     88     for (unsigned int i = 1; i<nlen - 3; i++)
     89       at[i] = '?';
     90     break;
     91   }
     92 
     93   /* shorten multiple consecutive "?" to "*" */
     94   {
     95     bool star = false;
     96     bool qmark = false;
     97     size_t woff = 0;
     98 
     99     for (unsigned int i = 0; i<strlen (result); i++)
    100     {
    101       result[woff++] = result[i];
    102       if ('?' == result[i])
    103       {
    104         if (star)
    105         {
    106           /* more than two "??" in a row */
    107           woff--;
    108           continue;
    109         }
    110         if (qmark)
    111         {
    112           /* two "??", combine to "*" */
    113           result[--woff - 1] = '*';
    114           star = true;
    115           continue;
    116         }
    117         /* first qmark */
    118         qmark = true;
    119       }
    120       else
    121       {
    122         star = false;
    123         qmark = false;
    124       }
    125     }
    126     result[woff] = '\0';
    127   }
    128   return result;
    129 }
    130 
    131 
    132 /**
    133  * Function called from the security-sms dialog upon completion.
    134  *
    135  * @param dialog the pseudonym selection dialog
    136  * @param response_id response code from the dialog
    137  * @param user_data the builder of the dialog
    138  */
    139 void
    140 anastasis_gtk_b_sms_dialog_response_cb (GtkDialog *dialog,
    141                                         gint response_id,
    142                                         gpointer user_data)
    143 {
    144   GtkBuilder *builder = GTK_BUILDER (user_data);
    145   GtkEntry *q;
    146   const char *qs;
    147   json_t *args;
    148   char *mn;
    149   char *ins;
    150 
    151   if (GTK_RESPONSE_OK != response_id)
    152   {
    153     gtk_widget_destroy (GTK_WIDGET (dialog));
    154     g_object_unref (G_OBJECT (builder));
    155     return;
    156   }
    157   q = GTK_ENTRY (gtk_builder_get_object (builder,
    158                                          "anastasis_gtk_b_sms_dialog_phonenumber_entry"));
    159   qs = gtk_entry_get_text (q);
    160   mn = mask_number (qs);
    161   GNUNET_asprintf (&ins,
    162                    _ ("phone number %s"),
    163                    mn);
    164   GNUNET_free (mn);
    165   args = json_pack ("{ s:{s:s, s:o, s:s}}",
    166                     "authentication_method",
    167                     "type",
    168                     "sms",
    169                     "challenge",
    170                     GNUNET_JSON_from_data (qs,
    171                                            strlen (qs)),
    172                     "instructions",
    173                     ins);
    174   GNUNET_free (ins);
    175   gtk_widget_destroy (GTK_WIDGET (dialog));
    176   g_object_unref (G_OBJECT (builder));
    177   AG_freeze ();
    178   AG_ra = ANASTASIS_redux_action (AG_redux_state,
    179                                   "add_authentication",
    180                                   args,
    181                                   &AG_action_cb,
    182                                   NULL);
    183   json_decref (args);
    184 }
    185 
    186 
    187 void
    188 anastasis_gtk_b_sms_dialog_phonenumber_entry_changed_cb (GtkEntry *entry,
    189                                                          gpointer user_data)
    190 {
    191   GtkBuilder *builder = GTK_BUILDER (user_data);
    192   GtkEntry *q;
    193   const char *qs;
    194   regex_t regex;
    195   int regex_result;
    196   const char *regexp = "^\\+[0-9]+$";
    197 
    198   regex_result = regcomp (&regex,
    199                           regexp,
    200                           REG_EXTENDED);
    201   if (0 < regex_result)
    202   {
    203     GNUNET_break (0);
    204     return;
    205   }
    206   q = GTK_ENTRY (gtk_builder_get_object (builder,
    207                                          "anastasis_gtk_b_sms_dialog_phonenumber_entry"));
    208   qs = gtk_entry_get_text (q);
    209   regex_result = regexec (&regex,
    210                           qs,
    211                           0,
    212                           NULL,
    213                           0);
    214   regfree (&regex);
    215   gtk_widget_set_sensitive (
    216     GTK_WIDGET (gtk_builder_get_object (builder,
    217                                         "anastasis_gtk_b_sms_dialog_btn_ok")),
    218     0 == regex_result);
    219 }
    220 
    221 
    222 /**
    223  * Callback invoked if the the "secure sms"-button is clicked.
    224  *
    225  * @param object
    226  * @param user_data unused
    227  */
    228 void
    229 anastasis_gtk_btn_add_auth_sms_clicked_cb (GObject *object,
    230                                            gpointer user_data)
    231 {
    232   GtkWidget *ad;
    233   GtkBuilder *builder;
    234 
    235   builder = ANASTASIS_GTK_get_new_builder (
    236     ANASTASIS_GTK_project_data (),
    237     "anastasis_gtk_auth_add_sms.glade",
    238     NULL);
    239   if (NULL == builder)
    240   {
    241     GNUNET_break (0);
    242     return;
    243   }
    244   ad = GTK_WIDGET (gtk_builder_get_object (builder,
    245                                            "anastasis_gtk_b_sms_dialog"));
    246   {
    247     GtkWidget *toplevel;
    248 
    249     toplevel = gtk_widget_get_toplevel (GTK_WIDGET (object));
    250     gtk_window_set_transient_for (GTK_WINDOW (ad),
    251                                   GTK_WINDOW (toplevel));
    252     gtk_window_present (GTK_WINDOW (ad));
    253   }
    254 }