Minor connection API fixes
[freeradius.git] / src / modules / rlm_yubikey / validate.c
index 8e14d32..9486f96 100644 (file)
 #ifdef HAVE_YKCLIENT
 #include <freeradius-devel/connection.h>
 
+/** Frees a ykclient handle
+ *
+ * @param[in] yandle rlm_yubikey_handle_t to close and free.
+ * @return returns 0.
+ */
+static int _mod_conn_free(ykclient_handle_t **yandle)
+{
+       ykclient_handle_done(yandle);
+
+       return 0;
+}
+
 /** Creates a new connection handle for use by the FR connection API.
  *
  * Matches the fr_connection_create_t function prototype, is passed to
  * fr_connection_pool_init, and called when a new connection is required by the
  * connection pool API.
  *
- * @see mod_conn_delete
  * @see fr_connection_pool_init
  * @see fr_connection_create_t
  * @see connection.c
  *
+ * @param[in] ctx to allocate connection data from.
  * @param[in] instance configuration data.
  * @return connection handle or NULL if the connection failed or couldn't
  *     be initialised.
  */
-static void *mod_socket_create(void *instance)
+static void *mod_conn_create(TALLOC_CTX *ctx, void *instance)
 {
        rlm_yubikey_t *inst = instance;
        ykclient_rc status;
-       ykclient_handle_t *yandle;
+       ykclient_handle_t *yandle, **marker;
 
        status = ykclient_handle_init(inst->ykc, &yandle);
        if (status != YKCLIENT_OK) {
-               EDEBUG("rlm_yubikey (%s): %s", inst->name, ykclient_strerror(status));
-               
+               ERROR("rlm_yubikey (%s): %s", inst->name, ykclient_strerror(status));
+
                return NULL;
        }
-       
-       return yandle;
-}
+       marker = talloc(ctx, ykclient_handle_t *);
+       talloc_set_destructor(marker, _mod_conn_free);
+       *marker = yandle;
 
-/** Frees a ykclient handle
- *
- * @param[in] instance configuration data.
- * @param[in] handle rlm_yubikey_handle_t to close and free.
- * @return returns true.
- */
-static int mod_socket_delete(UNUSED void *instance, void *handle)
-{
-       ykclient_handle_t *yandle = handle;
-       
-       ykclient_handle_done(&yandle);
-       
-       return true;
+       return yandle;
 }
 
 int rlm_yubikey_ykclient_init(CONF_SECTION *conf, rlm_yubikey_t *inst)
 {
        ykclient_rc status;
        CONF_SECTION *servers;
-       
+
        char prefix[100];
-       
+
        int count = 0;
 
        if (!inst->client_id) {
-               EDEBUG("rlm_yubikey (%s): client_id must be set when validation is enabled", inst->name); 
-       
+               ERROR("rlm_yubikey (%s): validation.client_id must be set (to a valid id) when validation is enabled",
+                     inst->name);
+
                return -1;
        }
-       
-       if (!inst->api_key) {
-               EDEBUG("rlm_yubikey (%s): api_key must be set when validation is enabled", inst->name);
-               
+
+       if (!inst->api_key || !*inst->api_key || is_zero(inst->api_key)) {
+               ERROR("rlm_yubikey (%s): validation.api_key must be set (to a valid key) when validation is enabled",
+                     inst->name);
+
                return -1;
        }
 
        DEBUG("rlm_yubikey (%s): Initialising ykclient", inst->name);
-       
+
        status = ykclient_global_init();
        if (status != YKCLIENT_OK) {
 yk_error:
-               EDEBUG("rlm_yubikey (%s): %s", ykclient_strerror(status), inst->name);
-               
+               ERROR("rlm_yubikey (%s): %s", ykclient_strerror(status), inst->name);
+
                return -1;
        }
-       
+
        status = ykclient_init(&inst->ykc);
        if (status != YKCLIENT_OK) {
                goto yk_error;
        }
-       
+
        servers = cf_section_sub_find(conf, "servers");
        if (servers) {
                CONF_PAIR *uri, *first;
@@ -105,13 +107,13 @@ yk_error:
                if (!uri) {
                        goto init;
                }
-       
+
                while (uri) {
                        count++;
                        uri = cf_pair_find_next(servers, uri, "uri");
                }
                inst->uris = talloc_zero_array(inst, char const *, count);
-       
+
                uri = first;
                count = 0;
                while (uri) {
@@ -125,23 +127,23 @@ yk_error:
                        }
                }
        }
-       
+
 init:
        status = ykclient_set_client_b64(inst->ykc, inst->client_id, inst->api_key);
        if (status != YKCLIENT_OK) {
-               EDEBUG("rlm_yubikey (%s): Failed setting API credentials: %s", ykclient_strerror(status), inst->name);  
-               
+               ERROR("rlm_yubikey (%s): Failed setting API credentials: %s", ykclient_strerror(status), inst->name);
+
                return -1;
        }
-       
+
        snprintf(prefix, sizeof(prefix), "rlm_yubikey (%s)", inst->name);
-       inst->conn_pool = fr_connection_pool_init(conf, inst, mod_socket_create, NULL, mod_socket_delete, prefix);
+       inst->conn_pool = fr_connection_pool_init(conf, inst, mod_conn_create, NULL, prefix);
        if (!inst->conn_pool) {
                ykclient_done(&inst->ykc);
-               
+
                return -1;
        }
-       
+
        return 0;
 }
 
@@ -150,21 +152,19 @@ int rlm_yubikey_ykclient_detach(rlm_yubikey_t *inst)
        fr_connection_pool_delete(inst->conn_pool);
        ykclient_done(&inst->ykc);
        ykclient_global_done();
-       
+
        return 0;
 }
 
-rlm_rcode_t rlm_yubikey_validate(rlm_yubikey_t *inst, REQUEST *request,  VALUE_PAIR *otp)
+rlm_rcode_t rlm_yubikey_validate(rlm_yubikey_t *inst, REQUEST *request,  char const *passcode)
 {
        rlm_rcode_t rcode = RLM_MODULE_OK;
        ykclient_rc status;
        ykclient_handle_t *yandle;
-       
+
        yandle = fr_connection_get(inst->conn_pool);
-       if (!yandle) {
-               return RLM_MODULE_FAIL;
-       }
-       
+       if (!yandle) return RLM_MODULE_FAIL;
+
        /*
         *      The libcurl multi-handle interface will tear down the TCP sockets for any partially completed
         *      requests when their easy handle is removed from the multistack.
@@ -180,28 +180,27 @@ rlm_rcode_t rlm_yubikey_validate(rlm_yubikey_t *inst, REQUEST *request,  VALUE_P
         *
         */
        ykclient_handle_cleanup(yandle);
-       
-       status = ykclient_request_process(inst->ykc, yandle, otp->vp_strvalue);
+
+       status = ykclient_request_process(inst->ykc, yandle, passcode);
        if (status != YKCLIENT_OK) {
                REDEBUG("%s", ykclient_strerror(status));
-               
                switch (status) {
-                       case YKCLIENT_BAD_OTP:
-                       case YKCLIENT_REPLAYED_OTP:
-                               rcode = RLM_MODULE_REJECT;
-                               break;
-                               
-                       case YKCLIENT_NO_SUCH_CLIENT:
-                               rcode = RLM_MODULE_NOTFOUND;
-                               break;
-                               
-                       default:
-                               rcode = RLM_MODULE_FAIL;
+               case YKCLIENT_BAD_OTP:
+               case YKCLIENT_REPLAYED_OTP:
+                       rcode = RLM_MODULE_REJECT;
+                       break;
+
+               case YKCLIENT_NO_SUCH_CLIENT:
+                       rcode = RLM_MODULE_NOTFOUND;
+                       break;
+
+               default:
+                       rcode = RLM_MODULE_FAIL;
                }
        }
-       
+
        fr_connection_release(inst->conn_pool, yandle);
-       
+
        return rcode;
 }
 #endif