[vlc-devel] [PATCH 10/13] keystore: add a unique memory keystore

Thomas Guillem thomas at gllm.fr
Wed Feb 24 14:25:19 CET 2016


This keystore is used to store credentials on memory if no others keystore is
found or if the user doesn't want to store them permanently. This keystore is
owned by libvlc and is shared with all vlc objects. It's released when the
libvlc instance is released.
---
 include/vlc_keystore.h      |  13 +++++-
 modules/access/dsm/access.c |   2 +-
 modules/access/ftp.c        |   2 +-
 modules/access/http.c       |   2 +-
 modules/access/live555.cpp  |   2 +-
 modules/access/sftp.c       |   2 +-
 modules/access/smb.c        |   2 +-
 src/libvlc.c                |   4 ++
 src/libvlc.h                |   2 +
 src/libvlccore.sym          |   2 +
 src/misc/keystore.c         | 108 ++++++++++++++++++++++++++++++++++----------
 11 files changed, 111 insertions(+), 30 deletions(-)

diff --git a/include/vlc_keystore.h b/include/vlc_keystore.h
index c743683..5dbbd48 100644
--- a/include/vlc_keystore.h
+++ b/include/vlc_keystore.h
@@ -27,6 +27,14 @@ typedef struct vlc_keystore vlc_keystore;
 typedef struct vlc_keystore_entry vlc_keystore_entry;
 typedef struct vlc_credential vlc_credential;
 
+/* Called from src/libvlc.c */
+int
+libvlc_InternalKeystoreInit(libvlc_int_t *p_libvlc);
+
+/* Called from src/libvlc.c */
+void
+libvlc_InternalKeystoreClean(libvlc_int_t *p_libvlc);
+
 /**
  * @defgroup keystore Keystore and credential API
  * @{
@@ -168,6 +176,7 @@ struct vlc_credential
     enum {
         GET_FROM_URL,
         GET_FROM_OPTION,
+        GET_FROM_MEMORY_KEYSTORE,
         GET_FROM_KEYSTORE,
         GET_FROM_DIALOG,
     } i_get_order;
@@ -242,7 +251,9 @@ vlc_credential_get(vlc_credential *p_credential, vlc_object_t *p_parent,
  * otherwise
  */
 VLC_API bool
-vlc_credential_store(vlc_credential *p_credential);
+vlc_credential_store(vlc_credential *p_credential, vlc_object_t *p_parent);
+#define vlc_credential_store(a, b) \
+    vlc_credential_store(a, VLC_OBJECT(b))
 
 /**
  * @}
diff --git a/modules/access/dsm/access.c b/modules/access/dsm/access.c
index 3fcfe46..340d2fa 100644
--- a/modules/access/dsm/access.c
+++ b/modules/access/dsm/access.c
@@ -384,7 +384,7 @@ success:
                       credential.psz_realm ) == -1 )
             p_sys->psz_domain_opt = NULL;
 
-        if( !vlc_credential_store( &credential )
+        if( !vlc_credential_store( &credential, p_access  )
          && asprintf( &p_sys->psz_pwd_opt, "smb-pwd=%s", psz_password ) == -1 )
             p_sys->psz_pwd_opt = NULL;
     }
diff --git a/modules/access/ftp.c b/modules/access/ftp.c
index 5a94733..42ea40c 100644
--- a/modules/access/ftp.c
+++ b/modules/access/ftp.c
@@ -427,7 +427,7 @@ static int Login( vlc_object_t *p_access, access_sys_t *p_sys )
         && !b_logged );
     if( b_logged )
     {
-        vlc_credential_store( &credential );
+        vlc_credential_store( &credential, p_access );
         vlc_credential_clean( &credential );
         vlc_UrlClean( &url );
         return 0;
diff --git a/modules/access/http.c b/modules/access/http.c
index 4e3beb6..075cd42 100644
--- a/modules/access/http.c
+++ b/modules/access/http.c
@@ -407,7 +407,7 @@ connect:
             goto error;
     }
     else
-        vlc_credential_store( &credential );
+        vlc_credential_store( &credential, p_access );
 
     if( ( p_sys->i_code == 301 || p_sys->i_code == 302 ||
           p_sys->i_code == 303 || p_sys->i_code == 307 ) &&
diff --git a/modules/access/live555.cpp b/modules/access/live555.cpp
index 56ecc35..8b0fdcd 100644
--- a/modules/access/live555.cpp
+++ b/modules/access/live555.cpp
@@ -680,7 +680,7 @@ describe:
         i_ret = VLC_EGENERIC;
     }
     else
-        vlc_credential_store( &credential );
+        vlc_credential_store( &credential, p_demux );
 
 bailout:
     /* malloc-ated copy */
diff --git a/modules/access/sftp.c b/modules/access/sftp.c
index ece9e95..7a95461 100644
--- a/modules/access/sftp.c
+++ b/modules/access/sftp.c
@@ -223,7 +223,7 @@ static int Open( vlc_object_t* p_this )
                                        credential.psz_username,
                                        credential.psz_password ) == 0 )
         {
-            b_stored = vlc_credential_store( &credential );
+            b_stored = vlc_credential_store( &credential, p_access );
             break;
         }
         else
diff --git a/modules/access/smb.c b/modules/access/smb.c
index d3e2c21..33e9bb8 100644
--- a/modules/access/smb.c
+++ b/modules/access/smb.c
@@ -211,7 +211,7 @@ static int Open( vlc_object_t *p_this )
         break;
     }
 
-    vlc_credential_store( &credential );
+    vlc_credential_store( &credential, p_access );
     vlc_credential_clean( &credential );
     free(psz_var_domain);
     vlc_UrlClean( &url );
diff --git a/src/libvlc.c b/src/libvlc.c
index 301b987..3468e0e 100644
--- a/src/libvlc.c
+++ b/src/libvlc.c
@@ -62,6 +62,7 @@
 
 #include <vlc_charset.h>
 #include <vlc_dialog.h>
+#include <vlc_keystore.h>
 #include <vlc_fs.h>
 #include <vlc_cpu.h>
 #include <vlc_url.h>
@@ -241,6 +242,8 @@ int libvlc_InternalInit( libvlc_int_t *p_libvlc, int i_argc,
         module_EndBank (true);
         return VLC_ENOMEM;
     }
+    if( libvlc_InternalKeystoreInit( p_libvlc ) != VLC_SUCCESS )
+        msg_Warn( p_libvlc, "memory keystore init failed" );
 
 /* FIXME: could be replaced by using Unix sockets */
 #ifdef HAVE_DBUS
@@ -511,6 +514,7 @@ void libvlc_InternalCleanup( libvlc_int_t *p_libvlc )
     intf_DestroyAll( p_libvlc );
 
     libvlc_InternalDialogClean( p_libvlc );
+    libvlc_InternalKeystoreClean( p_libvlc );
 
 #ifdef ENABLE_VLM
     /* Destroy VLM if created in libvlc_InternalInit */
diff --git a/src/libvlc.h b/src/libvlc.h
index fc57c2a..21bdfdc 100644
--- a/src/libvlc.h
+++ b/src/libvlc.h
@@ -134,6 +134,7 @@ void vlc_object_set_destructor (vlc_object_t *, vlc_destructor_t);
  * Private LibVLC instance data.
  */
 typedef struct vlc_dialog_provider vlc_dialog_provider;
+typedef struct vlc_keystore vlc_keystore;
 
 typedef struct libvlc_priv_t
 {
@@ -146,6 +147,7 @@ typedef struct libvlc_priv_t
     vlc_logger_t      *logger;
     vlm_t             *p_vlm;  ///< the VLM singleton (or NULL)
     vlc_dialog_provider *p_dialog_provider; ///< dialog provider
+    vlc_keystore      *p_memory_keystore; ///< memory keystore
     struct playlist_t *playlist; ///< Playlist for interfaces
     struct playlist_preparser_t *parser; ///< Input item meta data handler
     struct vlc_actions *actions; ///< Hotkeys handler
diff --git a/src/libvlccore.sym b/src/libvlccore.sym
index fa0aa71..0d69d14 100644
--- a/src/libvlccore.sym
+++ b/src/libvlccore.sym
@@ -224,6 +224,8 @@ intf_Create
 libvlc_InternalAddIntf
 libvlc_InternalDialogInit
 libvlc_InternalDialogClean
+libvlc_InternalKeystoreInit
+libvlc_InternalKeystoreClean
 libvlc_InternalPlay
 libvlc_InternalCleanup
 libvlc_InternalCreate
diff --git a/src/misc/keystore.c b/src/misc/keystore.c
index 3a0eafb..855e026 100644
--- a/src/misc/keystore.c
+++ b/src/misc/keystore.c
@@ -32,18 +32,15 @@
 #include <assert.h>
 #include <limits.h>
 
-#undef vlc_keystore_create
-vlc_keystore *
-vlc_keystore_create(vlc_object_t *p_parent)
+static vlc_keystore *
+keystore_create(vlc_object_t *p_parent, const char *psz_name)
 {
-    assert(p_parent);
     vlc_keystore *p_keystore = vlc_custom_create(p_parent, sizeof (*p_keystore),
                                                  "keystore");
     if (unlikely(p_keystore == NULL))
         return NULL;
 
-    p_keystore->p_module = module_need(p_keystore, "keystore", "$keystore",
-                                       true);
+    p_keystore->p_module = module_need(p_keystore, "keystore", psz_name, true);
     if (p_keystore->p_module == NULL)
     {
         vlc_object_release(p_keystore);
@@ -56,6 +53,14 @@ vlc_keystore_create(vlc_object_t *p_parent)
     return p_keystore;
 }
 
+#undef vlc_keystore_create
+vlc_keystore *
+vlc_keystore_create(vlc_object_t *p_parent)
+{
+    assert(p_parent);
+    return keystore_create(p_parent, "$keystore");
+}
+
 void
 vlc_keystore_release(vlc_keystore *p_keystore)
 {
@@ -120,6 +125,35 @@ vlc_keystore_release_entries(vlc_keystore_entry *p_entries, unsigned int i_count
     free(p_entries);
 }
 
+int
+libvlc_InternalKeystoreInit(libvlc_int_t *p_libvlc)
+{
+    assert(p_libvlc != NULL);
+    libvlc_priv_t *p_priv = libvlc_priv(p_libvlc);
+
+    p_priv->p_memory_keystore = keystore_create(VLC_OBJECT(p_libvlc), "memory");
+    return p_priv->p_memory_keystore != NULL ? VLC_SUCCESS : VLC_EGENERIC;
+}
+
+void
+libvlc_InternalKeystoreClean(libvlc_int_t *p_libvlc)
+{
+    assert(p_libvlc != NULL);
+    libvlc_priv_t *p_priv = libvlc_priv(p_libvlc);
+
+    if (p_priv->p_memory_keystore != NULL)
+    {
+        vlc_keystore_release(p_priv->p_memory_keystore);
+        p_priv->p_memory_keystore = NULL;
+    }
+}
+
+static vlc_keystore *
+get_memory_keystore(vlc_object_t *p_obj)
+{
+    return libvlc_priv(p_obj->p_libvlc)->p_memory_keystore;
+}
+
 static vlc_keystore_entry *
 find_closest_path(vlc_keystore_entry *p_entries, unsigned i_count,
                   const char *psz_path)
@@ -231,7 +265,7 @@ smb_split_domain(vlc_credential *p_credential)
 }
 
 static void
-credential_find_keystore(vlc_credential *p_credential)
+credential_find_keystore(vlc_credential *p_credential, vlc_keystore *p_keystore)
 {
     const vlc_url_t *p_url = p_credential->p_url;
 
@@ -249,16 +283,18 @@ credential_find_keystore(vlc_credential *p_credential)
         ppsz_values[KEY_PORT] = psz_port;
     }
 
+    vlc_keystore_entry *p_entries;
+    unsigned int i_entries_count;
+    i_entries_count = vlc_keystore_find(p_keystore, ppsz_values, &p_entries);
+
+    /* Remove last entries after vlc_keystore_find call since
+     * p_credential->psz_username (default username) can be a pointer to an
+     * entry */
     if (p_credential->i_entries_count > 0)
-    {
         vlc_keystore_release_entries(p_credential->p_entries,
                                      p_credential->i_entries_count);
-        p_credential->i_entries_count = 0;
-    }
-
-    p_credential->i_entries_count = vlc_keystore_find(p_credential->p_keystore,
-                                                      ppsz_values,
-                                                      &p_credential->p_entries);
+    p_credential->p_entries = p_entries;
+    p_credential->i_entries_count = i_entries_count;
 
     if (p_credential->i_entries_count > 0)
     {
@@ -298,13 +334,11 @@ vlc_credential_init(vlc_credential *p_credential, const vlc_url_t *p_url)
 void
 vlc_credential_clean(vlc_credential *p_credential)
 {
+    if (p_credential->i_entries_count > 0)
+        vlc_keystore_release_entries(p_credential->p_entries,
+                                     p_credential->i_entries_count);
     if (p_credential->p_keystore)
-    {
-        if (p_credential->i_entries_count > 0)
-            vlc_keystore_release_entries(p_credential->p_entries,
-                                         p_credential->i_entries_count);
         vlc_keystore_release(p_credential->p_keystore);
-    }
 
     free(p_credential->psz_split_realm);
     free(p_credential->psz_var_username);
@@ -378,6 +412,18 @@ vlc_credential_get(vlc_credential *p_credential, vlc_object_t *p_parent,
             p_credential->i_get_order++;
             break;
 
+        case GET_FROM_MEMORY_KEYSTORE:
+        {
+            if (!psz_dialog_title || !psz_dialog_fmt)
+                return false;
+
+            vlc_keystore *p_keystore = get_memory_keystore(p_parent);
+            if (p_keystore != NULL)
+                credential_find_keystore(p_credential, p_keystore);
+            p_credential->i_get_order++;
+            break;
+        }
+
         case GET_FROM_KEYSTORE:
             if (!psz_dialog_title || !psz_dialog_fmt)
                 return false;
@@ -385,7 +431,7 @@ vlc_credential_get(vlc_credential *p_credential, vlc_object_t *p_parent,
             if (p_credential->p_keystore == NULL)
                 p_credential->p_keystore = vlc_keystore_create(p_parent);
             if (p_credential->p_keystore != NULL)
-                credential_find_keystore(p_credential);
+                credential_find_keystore(p_credential, p_credential->p_keystore);
 
             p_credential->i_get_order++;
             break;
@@ -436,13 +482,29 @@ vlc_credential_get(vlc_credential *p_credential, vlc_object_t *p_parent,
     return is_credential_valid(p_credential);
 }
 
+#undef vlc_credential_store
 bool
-vlc_credential_store(vlc_credential *p_credential)
+vlc_credential_store(vlc_credential *p_credential, vlc_object_t *p_parent)
 {
-    if (!p_credential->p_keystore || !p_credential->b_store
-     || p_credential->b_from_keystore)
+    /* Don't need to store again */
+    if (p_credential->b_from_keystore)
         return p_credential->b_from_keystore;
 
+    vlc_keystore *p_keystore;
+    if (p_credential->b_store)
+    {
+        /* Store in permanent keystore */
+        assert(p_credential->p_keystore != NULL);
+        p_keystore = p_credential->p_keystore;
+    }
+    else
+    {
+        /* Store in memory keystore */
+        p_keystore = get_memory_keystore(p_parent);
+    }
+    if (p_keystore == NULL)
+        return false;
+
     const vlc_url_t *p_url = p_credential->p_url;
 
     char *psz_path = NULL;
-- 
2.7.0



More information about the vlc-devel mailing list