krb5 commit: Use krb5int_open_plugin for PKCS#11 module

Greg Hudson <[email protected]>
Newsgroups gmane.comp.encryption.kerberos.cvs
Message-ID <[email protected]>
https://github.com/krb5/krb5/commit/c5c11839e02c7993eb78f2c94c75c10cf93f2195
commit c5c11839e02c7993eb78f2c94c75c10cf93f2195
Author: Ken Hornstein <[email protected]>
Date:   Sun Mar 14 22:18:53 2021 -0400

    Use krb5int_open_plugin for PKCS#11 module
    
    Instead of calling dlopen() directly, use the krb5 cross-platform
    interfaces (krb5int_open_plugin()).
    
    The goal here is to eventually support pkinit on Windows; this is just
    the first small step in that direction.
    
    [[email protected]: fixed memory leak; changed type of p11_module field;
    added intermediate sym variable for strict aliasing conformance;
    simplified out pkinit_C_UnloadModule() wrapper]

 src/plugins/preauth/pkinit/pkinit_clnt.c           |    1 -
 src/plugins/preauth/pkinit/pkinit_crypto_openssl.c |   37 ++++++++++---------
 src/plugins/preauth/pkinit/pkinit_crypto_openssl.h |    2 +-
 src/plugins/preauth/pkinit/pkinit_identity.c       |    1 -
 4 files changed, 20 insertions(+), 21 deletions(-)

diff --git a/src/plugins/preauth/pkinit/pkinit_clnt.c b/src/plugins/preauth/pkinit/pkinit_clnt.c
index d29b03d..b6266b4 100644
--- a/src/plugins/preauth/pkinit/pkinit_clnt.c
+++ b/src/plugins/preauth/pkinit/pkinit_clnt.c
@@ -34,7 +34,6 @@
 #include "k5-json.h"
 
 #include <unistd.h>
-#include <dlfcn.h>
 #include <sys/stat.h>
 
 /**
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
index e5940a5..fbbdab5 100644
--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
+++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
@@ -33,7 +33,6 @@
 #include "pkinit_crypto_openssl.h"
 #include "k5-buf.h"
 #include "k5-hex.h"
-#include <dlfcn.h>
 #include <unistd.h>
 #include <dirent.h>
 #include <arpa/inet.h>
@@ -102,8 +101,8 @@ static krb5_error_code pkinit_login
  CK_TOKEN_INFO *tip, const char *password);
 static krb5_error_code pkinit_open_session
 (krb5_context context, pkinit_identity_crypto_context id_cryptoctx);
-static void * pkinit_C_LoadModule(const char *modname, CK_FUNCTION_LIST_PTR_PTR p11p);
-static CK_RV pkinit_C_UnloadModule(void *handle);
+static struct plugin_file_handle *pkinit_C_LoadModule
+(const char *modname, CK_FUNCTION_LIST_PTR_PTR p11p);
 #ifdef SILLYDECRYPT
 CK_RV pkinit_C_Decrypt
 (pkinit_identity_crypto_context id_cryptoctx,
@@ -1006,7 +1005,7 @@ pkinit_fini_pkcs11(pkinit_identity_crypto_context ctx)
         ctx->p11 = NULL;
     }
     if (ctx->p11_module != NULL) {
-        pkinit_C_UnloadModule(ctx->p11_module);
+        krb5int_close_plugin(ctx->p11_module);
         ctx->p11_module = NULL;
     }
     free(ctx->p11_module_name);
@@ -3548,21 +3547,30 @@ prepare_enc_data(const uint8_t *indata, int indata_len, uint8_t **outdata,
 }
 
 #ifndef WITHOUT_PKCS11
-static void *
+static struct plugin_file_handle *
 pkinit_C_LoadModule(const char *modname, CK_FUNCTION_LIST_PTR_PTR p11p)
 {
-    void *handle;
+    struct plugin_file_handle *handle;
     CK_RV (*getflist)(CK_FUNCTION_LIST_PTR_PTR);
+    struct errinfo einfo = EMPTY_ERRINFO;
+    void (*sym)();
+    long err;
+    CK_RV rv;
 
     pkiDebug("loading module \"%s\"... ", modname);
-    handle = dlopen(modname, RTLD_NOW);
-    if (handle == NULL) {
+    if (krb5int_open_plugin(modname, &handle, &einfo) != 0) {
         pkiDebug("not found\n");
         return NULL;
     }
-    getflist = (CK_RV (*)(CK_FUNCTION_LIST_PTR_PTR)) dlsym(handle, "C_GetFunctionList");
-    if (getflist == NULL || (*getflist)(p11p) != CKR_OK) {
-        dlclose(handle);
+
+    err = krb5int_get_plugin_func(handle, "C_GetFunctionList", &sym, &einfo);
+    k5_clear_error(&einfo);
+    if (!err) {
+        getflist = (CK_RV (*)())sym;
+        rv = (*getflist)(p11p);
+    }
+    if (err || rv != CKR_OK) {
+        krb5int_close_plugin(handle);
         pkiDebug("failed\n");
         return NULL;
     }
@@ -3570,13 +3578,6 @@ pkinit_C_LoadModule(const char *modname, CK_FUNCTION_LIST_PTR_PTR p11p)
     return handle;
 }
 
-static CK_RV
-pkinit_C_UnloadModule(void *handle)
-{
-    dlclose(handle);
-    return CKR_OK;
-}
-
 static krb5_error_code
 pkinit_login(krb5_context context,
              pkinit_identity_crypto_context id_cryptoctx,
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.h b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.h
index 957c3de..ea28b8e 100644
--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.h
+++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.h
@@ -84,7 +84,7 @@ struct _pkinit_identity_crypto_context {
     char *token_label;
     char *cert_label;
     /* These are crypto-specific */
-    void *p11_module;
+    struct plugin_file_handle *p11_module;
     CK_SESSION_HANDLE session;
     CK_FUNCTION_LIST_PTR p11;
     uint8_t *cert_id;
diff --git a/src/plugins/preauth/pkinit/pkinit_identity.c b/src/plugins/preauth/pkinit/pkinit_identity.c
index cee448d..4c8e843 100644
--- a/src/plugins/preauth/pkinit/pkinit_identity.c
+++ b/src/plugins/preauth/pkinit/pkinit_identity.c
@@ -30,7 +30,6 @@
  */
 
 #include "pkinit.h"
-#include <dlfcn.h>
 #include <dirent.h>
 
 static void
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.