"Fossies" - the Fresh Open Source Software Archive

Member "gvm-libs-11.0.1/util/radiusutils.c" (12 May 2020, 8099 Bytes) of package /linux/misc/openvas/gvm-libs-11.0.1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "radiusutils.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 1.0-beta2_vs_1.0.0.

    1 /* Copyright (C) 2015-2019 Greenbone Networks GmbH
    2  *
    3  * SPDX-License-Identifier: GPL-2.0-or-later
    4  *
    5  * This program is free software; you can redistribute it and/or
    6  * modify it under the terms of the GNU General Public License
    7  * as published by the Free Software Foundation; either version 2
    8  * of the License, or (at your option) any later version.
    9  *
   10  * This program is distributed in the hope that it will be useful,
   11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   13  * GNU General Public License for more details.
   14  *
   15  * You should have received a copy of the GNU General Public License
   16  * along with this program; if not, write to the Free Software
   17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   18  */
   19 
   20 /**
   21  * @file
   22  * @brief Implementation of an API for Radius authentication.
   23  */
   24 
   25 #ifdef ENABLE_RADIUS_AUTH
   26 
   27 #include <arpa/inet.h> /* for inet_pton */
   28 
   29 #if defined(RADIUS_AUTH_FREERADIUS)
   30 #include <freeradius-client.h>
   31 #ifndef RC_CONFIG_FILE
   32 #define RC_DICTIONARY_FILE "/etc/radiusclient/dictionary"
   33 #endif
   34 #elif defined(RADIUS_AUTH_RADCLI)
   35 #include <errno.h>
   36 #include <radcli/radcli.h>
   37 #include <stdlib.h> /* for mkstemp */
   38 #include <string.h> /* for strerror */
   39 #include <unistd.h>
   40 #ifndef RC_CONFIG_FILE
   41 #define RC_DICTIONARY_FILE "/etc/radcli/dictionary"
   42 #endif
   43 #endif
   44 
   45 #include "../base/networking.h" /* for gvm_resolve */
   46 
   47 #include <glib.h> /* for g_warning */
   48 
   49 #ifndef PW_MAX_MSG_SIZE
   50 #define PW_MAX_MSG_SIZE 4096
   51 #endif
   52 
   53 /**
   54  * Initialize the Radius client configuration.
   55  *
   56  * @param[in]   hostname    Server hostname.
   57  * @param[in]   secret      Radius secret key.
   58  *
   59  * @return Radius Client handle if success, NULL otherwise.
   60  */
   61 static rc_handle *
   62 radius_init (const char *hostname, const char *secret)
   63 {
   64   rc_handle *rh;
   65   char authserver[4096];
   66   struct sockaddr_in6 ip6;
   67 
   68   rh = NULL;
   69 
   70   if (inet_pton (AF_INET6, hostname, &(ip6.sin6_addr)) == 1)
   71     snprintf (authserver, sizeof (authserver), "[%s]::%s", hostname, secret);
   72   else
   73     snprintf (authserver, sizeof (authserver), "%s::%s", hostname, secret);
   74 
   75 #if defined(RADIUS_AUTH_RADCLI)
   76   // Create config from file for older radcli versions
   77   FILE *config_file = NULL;
   78   char config_filename[35] = "/tmp/gvm_radius_conf_XXXXXX";
   79   int config_fd = mkstemp (config_filename);
   80 
   81   if (config_fd == -1)
   82     {
   83       g_warning ("%s: Couldn't create temp radius config file: %s\n",
   84                  __FUNCTION__, strerror (errno));
   85       goto radius_init_fail;
   86     }
   87 
   88   config_file = fdopen (config_fd, "w");
   89   if (config_file == NULL)
   90     {
   91       close (config_fd);
   92       g_warning ("%s: Couldn't open temp radius config file %s: %s\n",
   93                  __FUNCTION__, config_filename, strerror (errno));
   94       goto radius_init_fail;
   95     }
   96 
   97   if (fprintf (config_file,
   98                "auth_order  radius\n"
   99                "login_tries  4\n"
  100                "dictionary  %s\n"
  101                "seqfile  /var/run/radius.seq\n"
  102                "radius_retries  3\n"
  103                "radius_timeout  5\n"
  104                "radius_deadtime  0\n"
  105                "authserver  %s\n"
  106                "acctserver  %s\n",
  107                RC_DICTIONARY_FILE, authserver, authserver)
  108       < 0)
  109     {
  110       fclose (config_file);
  111       g_warning ("%s: Couldn't write to temp radius config file %s:%s\n",
  112                  __FUNCTION__, config_filename, strerror (errno));
  113       unlink (config_filename);
  114       goto radius_init_fail;
  115     }
  116   fclose (config_file);
  117 
  118   rh = rc_read_config (config_filename);
  119   if (rh == NULL)
  120     {
  121       g_warning ("%s: Couldn't read temp radius config file %s\n", __FUNCTION__,
  122                  config_filename);
  123       unlink (config_filename);
  124       goto radius_init_fail;
  125     }
  126   unlink (config_filename);
  127 #else  // defined(RADIUS_AUTH_RADCLI)
  128   if ((rh = rc_new ()) == NULL)
  129     {
  130       g_warning ("radius_init: Couldn't allocate memory");
  131       return NULL;
  132     }
  133   if (!rc_config_init (rh))
  134     {
  135       g_warning ("radius_init: Couldn't initialize the config");
  136       return NULL;
  137     }
  138 
  139   /* Set the basic configuration options. */
  140   if (rc_add_config (rh, "auth_order", "radius", "config", 0))
  141     {
  142       g_warning ("radius_init: Couldn't set auth_order");
  143       goto radius_init_fail;
  144     }
  145   if (rc_add_config (rh, "login_tries", "4", "config", 0))
  146     {
  147       g_warning ("radius_init: Couldn't set login_tries");
  148       goto radius_init_fail;
  149     }
  150   if (rc_add_config (rh, "dictionary", RC_DICTIONARY_FILE, "config", 0))
  151     {
  152       g_warning ("radius_init: Couldn't set dictionary");
  153       goto radius_init_fail;
  154     }
  155   if (rc_add_config (rh, "seqfile", "/var/run/radius.seq", "config", 0))
  156     {
  157       g_warning ("radius_init: Couldn't set seqfile");
  158       goto radius_init_fail;
  159     }
  160   if (rc_add_config (rh, "radius_retries", "3", "config", 0))
  161     {
  162       g_warning ("radius_init: Couldn't set radius_retries");
  163       goto radius_init_fail;
  164     }
  165   if (rc_add_config (rh, "radius_timeout", "5", "config", 0))
  166     {
  167       g_warning ("radius_init: Couldn't set radius_timeout");
  168       goto radius_init_fail;
  169     }
  170   if (rc_add_config (rh, "radius_deadtime", "0", "config", 0))
  171     {
  172       g_warning ("radius_init: Couldn't set radius_deadtime");
  173       goto radius_init_fail;
  174     }
  175   if (rc_add_config (rh, "authserver", authserver, "config", 0) != 0)
  176     {
  177       g_warning ("radius_init: Couldn't set authserver %s", authserver);
  178       goto radius_init_fail;
  179     }
  180   if (rc_read_dictionary (rh, RC_DICTIONARY_FILE) != 0)
  181     {
  182       g_warning ("radius_init: Couldn't read the dictionary file %s",
  183                  RC_DICTIONARY_FILE);
  184       goto radius_init_fail;
  185     }
  186 #endif // defined(RADIUS_AUTH_RADCLI)
  187 
  188   return rh;
  189 
  190 radius_init_fail:
  191   rc_destroy (rh);
  192   return NULL;
  193 }
  194 
  195 /**
  196  * @brief Authenticate against a Radius server.
  197  *
  198  * @param[in]   hostname    Server hostname.
  199  * @param[in]   secret      Radius secret key.
  200  * @param[in]   username    Username to authenticate.
  201  * @param[in]   password    Password to use with username.
  202  *
  203  * @return 0 authentication success, 1 authentication failure, -1 error.
  204  */
  205 int
  206 radius_authenticate (const char *hostname, const char *secret,
  207                      const char *username, const char *password)
  208 {
  209   uint32_t service = PW_AUTHENTICATE_ONLY;
  210   char msg[PW_MAX_MSG_SIZE];
  211   VALUE_PAIR *send = NULL, *received = NULL;
  212   rc_handle *rh;
  213   int rc = -1;
  214   struct sockaddr_in ip4;
  215   struct sockaddr_in6 ip6;
  216 
  217   rh = radius_init (hostname, secret);
  218   if (!rh)
  219     return -1;
  220   if (rc_avpair_add (rh, &send, PW_USER_NAME, (char *) username, -1, 0) == NULL)
  221     {
  222       g_warning ("radius_authenticate: Couldn't set the username");
  223       goto authenticate_leave;
  224     }
  225   if (rc_avpair_add (rh, &send, PW_USER_PASSWORD, (char *) password, -1, 0)
  226       == NULL)
  227     {
  228       g_warning ("radius_authenticate: Couldn't set the password");
  229       goto authenticate_leave;
  230     }
  231   if (rc_avpair_add (rh, &send, PW_SERVICE_TYPE, &service, -1, 0) == NULL)
  232     {
  233       g_warning ("radius_authenticate: Couldn't set the service type");
  234       goto authenticate_leave;
  235     }
  236   if (gvm_resolve (hostname, &ip4, AF_INET)
  237       && gvm_resolve (hostname, &ip6, AF_INET6))
  238     {
  239       g_warning ("radius_authenticate: Couldn't resolve %s", hostname);
  240       goto authenticate_leave;
  241     }
  242 
  243   rc = 1;
  244   if (rc_auth (rh, 0, send, &received, msg) == OK_RC)
  245     rc = 0;
  246 
  247 authenticate_leave:
  248   rc_destroy (rh);
  249   if (send)
  250     rc_avpair_free (send);
  251   if (received)
  252     rc_avpair_free (received);
  253   return rc;
  254 }
  255 
  256 #else /* ENABLE_RADIUS_AUTH */
  257 
  258 /**
  259  * @brief Dummy function for manager.
  260  *
  261  * @param[in]   hostname    Server hostname.
  262  * @param[in]   secret      Radius secret key.
  263  * @param[in]   username    Username to authenticate.
  264  * @param[in]   password    Password to use with username.
  265  *
  266  * @return -1.
  267  */
  268 int
  269 radius_authenticate (const char *hostname, const char *secret,
  270                      const char *username, const char *password)
  271 {
  272   (void) hostname;
  273   (void) secret;
  274   (void) username;
  275   (void) password;
  276 
  277   return -1;
  278 }
  279 
  280 #endif /* ENABLE_RADIUS_AUTH */