challenger

OAuth 2.0-based authentication service that validates user can receive messages at a certain address
Log | Files | Refs | Submodules | README | LICENSE

challenger-admin.c (8565B)


      1 /*
      2   This file is part of Challenger
      3   Copyright (C) 2023 Taler Systems SA
      4 
      5   Challenger is free software; you can redistribute it and/or modify it under the
      6   terms of the GNU General Public License as published by the Free Software
      7   Foundation; either version 3, or (at your option) any later version.
      8 
      9   Challenger is distributed in the hope that it will be useful, but WITHOUT ANY
     10   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
     11   A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
     12 
     13   You should have received a copy of the GNU General Public License along with
     14   Challenger; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
     15 */
     16 /**
     17  * @file challenger/challenger-admin.c
     18  * @brief Administer clients of a challenger service
     19  * @author Christian Grothoff
     20  */
     21 #include "platform.h"
     22 #include <gnunet/gnunet_util_lib.h>
     23 #include <gnunet/gnunet_db_lib.h>
     24 #include "challenger_util.h"
     25 #include "challenger_database_lib.h"
     26 #include "challenger-database/client_delete.h"
     27 #include "challenger-database/client_check.h"
     28 #include "challenger-database/client_modify.h"
     29 #include "challenger-database/client_add.h"
     30 #include "challenger-database/preflight.h"
     31 
     32 
     33 /**
     34  * Prefix required for all Bearer tokens.
     35  */
     36 #define RFC_8959_PREFIX "secret-token:"
     37 
     38 
     39 /**
     40  * Return value from main().
     41  */
     42 static int global_ret;
     43 
     44 /**
     45  * -a option: client secret
     46  */
     47 static char *client_secret;
     48 
     49 /**
     50  * -m option: client ID
     51  */
     52 static char *client_id;
     53 
     54 /**
     55  * -d option: delete client
     56  */
     57 static int del_flag;
     58 
     59 /**
     60  * -q option: be quiet
     61  */
     62 static int be_quiet;
     63 
     64 
     65 /**
     66  * Main function that will be run.
     67  *
     68  * @param cls closure
     69  * @param args remaining command-line arguments
     70  * @param cfgfile name of the configuration file used (for saving, can be NULL!)
     71  * @param cfg configuration
     72  */
     73 static void
     74 run (void *cls,
     75      char *const *args,
     76      const char *cfgfile,
     77      const struct GNUNET_CONFIGURATION_Handle *cfg)
     78 {
     79   const char *redirect_uri = args[0];
     80   struct CHALLENGERDB_PostgresContext *db;
     81 
     82   (void) cls;
     83   (void) cfgfile;
     84   if (NULL == redirect_uri)
     85   {
     86     fprintf (stderr,
     87              "challenger-admin must be invoked with the client REDIRECT URI as first argument\n");
     88     global_ret = EXIT_INVALIDARGUMENT;
     89     return;
     90   }
     91   if ( (NULL != client_secret) &&
     92        (0 != strncasecmp (client_secret,
     93                           RFC_8959_PREFIX,
     94                           strlen (RFC_8959_PREFIX))) )
     95   {
     96     fprintf (stderr,
     97              "CLIENT_SECRET must begin with `%s'\n",
     98              RFC_8959_PREFIX);
     99     global_ret = EXIT_INVALIDARGUMENT;
    100     return;
    101   }
    102   if (NULL ==
    103       (db = CHALLENGERDB_connect (cfg,
    104                                   false)))
    105   {
    106     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
    107                 "Failed to initialize database connection.\n");
    108     global_ret = EXIT_NOTINSTALLED;
    109     return;
    110   }
    111   if (del_flag)
    112   {
    113     enum GNUNET_DB_QueryStatus qs;
    114 
    115     if (NULL != client_id)
    116     {
    117       fprintf (stderr,
    118                "'-m' and '-d' options cannot be used at the same time\n");
    119       global_ret = EXIT_INVALIDARGUMENT;
    120       goto cleanup;
    121     }
    122     qs = CHALLENGERDB_client_delete (db,
    123                                      redirect_uri);
    124     switch (qs)
    125     {
    126     case GNUNET_DB_STATUS_SOFT_ERROR:
    127     case GNUNET_DB_STATUS_HARD_ERROR:
    128       GNUNET_break (0);
    129       global_ret = EXIT_FAILURE;
    130       goto cleanup;
    131     case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
    132       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
    133                   "Client with this CLIENT_REDIRECT_URI is not known.\n");
    134       global_ret = EXIT_FAILURE;
    135       goto cleanup;
    136     case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
    137       GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
    138                   "Client deleted\n");
    139       break;
    140     }
    141     goto cleanup;
    142   }
    143   if (NULL != client_id)
    144   {
    145     enum GNUNET_DB_QueryStatus qs;
    146     unsigned long long row_id;
    147     char dummy;
    148 
    149     if (1 !=
    150         sscanf (client_id,
    151                 "%llu%c",
    152                 &row_id,
    153                 &dummy))
    154     {
    155       fprintf (stderr,
    156                "CLIENT_ID must be a positive number\n");
    157       global_ret = EXIT_INVALIDARGUMENT;
    158       goto cleanup;
    159     }
    160 
    161     qs = CHALLENGERDB_client_modify (db,
    162                                      row_id,
    163                                      redirect_uri,
    164                                      client_secret);
    165     switch (qs)
    166     {
    167     case GNUNET_DB_STATUS_SOFT_ERROR:
    168     case GNUNET_DB_STATUS_HARD_ERROR:
    169       GNUNET_break (0);
    170       global_ret = EXIT_FAILURE;
    171       goto cleanup;
    172     case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
    173       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
    174                   "Client %llu not found.\n",
    175                   row_id);
    176       global_ret = EXIT_FAILURE;
    177       goto cleanup;
    178     case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
    179       if (! be_quiet)
    180         fprintf (stdout,
    181                  "Client modified.\n");
    182       break;
    183     }
    184     goto cleanup;
    185   }
    186   if (NULL != client_secret)
    187   {
    188     enum GNUNET_DB_QueryStatus qs;
    189     uint64_t row_id;
    190 
    191     qs = CHALLENGERDB_client_check2 (db,
    192                                      redirect_uri,
    193                                      client_secret,
    194                                      &row_id);
    195     switch (qs)
    196     {
    197     case GNUNET_DB_STATUS_SOFT_ERROR:
    198     case GNUNET_DB_STATUS_HARD_ERROR:
    199       GNUNET_break (0);
    200       global_ret = EXIT_FAILURE;
    201       goto cleanup;
    202     case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
    203       break;
    204     case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
    205       if (be_quiet)
    206         fprintf (stdout,
    207                  "%llu\n",
    208                  (unsigned long long) row_id);
    209       else
    210         fprintf (stdout,
    211                  "Client added. Client ID is: %llu\n",
    212                  (unsigned long long) row_id);
    213       goto cleanup;
    214     }
    215     qs = CHALLENGERDB_client_add (db,
    216                                   redirect_uri,
    217                                   client_secret,
    218                                   &row_id);
    219     switch (qs)
    220     {
    221     case GNUNET_DB_STATUS_SOFT_ERROR:
    222     case GNUNET_DB_STATUS_HARD_ERROR:
    223       GNUNET_break (0);
    224       global_ret = EXIT_FAILURE;
    225       goto cleanup;
    226     case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
    227       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
    228                   "Client with this CLIENT_REDIRECT_URI already exists.\n");
    229       global_ret = EXIT_FAILURE;
    230       goto cleanup;
    231     case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
    232       if (be_quiet)
    233         fprintf (stdout,
    234                  "%llu\n",
    235                  (unsigned long long) row_id);
    236       else
    237         fprintf (stdout,
    238                  "Client added. Client ID is: %llu\n",
    239                  (unsigned long long) row_id);
    240       break;
    241     }
    242     goto cleanup;
    243   }
    244 cleanup:
    245   CHALLENGERDB_disconnect (db);
    246 }
    247 
    248 
    249 /**
    250  * The main function of the client management tool.  Used to add or
    251  * remove clients from the Challenger' database.
    252  *
    253  * @param argc number of arguments from the command line
    254  * @param argv command line arguments
    255  * @return 0 ok, non-zero on error
    256  */
    257 int
    258 main (int argc,
    259       char *const *argv)
    260 {
    261   struct GNUNET_GETOPT_CommandLineOption options[] = {
    262     GNUNET_GETOPT_option_string ('a',
    263                                  "add",
    264                                  "CLIENT_SECRET",
    265                                  "add client",
    266                                  &client_secret),
    267     GNUNET_GETOPT_option_flag ('d',
    268                                "delete",
    269                                "delete client",
    270                                &del_flag),
    271     GNUNET_GETOPT_option_string ('m',
    272                                  "modify-client",
    273                                  "CLIENT_ID",
    274                                  "modify existing client to use the given secret and redirect URL",
    275                                  &client_id),
    276     GNUNET_GETOPT_option_flag ('q',
    277                                "quiet",
    278                                "be less verbose in the output",
    279                                &be_quiet),
    280     /* FIXME: add -s / --show option */
    281     GNUNET_GETOPT_OPTION_END
    282   };
    283   enum GNUNET_GenericReturnValue ret;
    284 
    285   ret = GNUNET_PROGRAM_run (CHALLENGER_project_data (),
    286                             argc, argv,
    287                             "challenger-admin CLIENT_REDIRECT_URI",
    288                             "Tool to add, modify or remove clients from challenger",
    289                             options,
    290                             &run, NULL);
    291   if (GNUNET_SYSERR == ret)
    292     return EXIT_INVALIDARGUMENT;
    293   if (GNUNET_NO == ret)
    294     return EXIT_SUCCESS;
    295   return global_ret;
    296 }
    297 
    298 
    299 /* end of challenger-dbinit.c */