bool vlc_credential_get(vlc_credential *p_credential, vlc_object_t *p_parent, const char *psz_option_username, const char *psz_option_password, const char *psz_dialog_title, const char *psz_dialog_fmt, ...) { assert(p_credential && p_parent); const vlc_url_t *p_url = p_credential->p_url; if (!is_url_valid(p_url)) { msg_Err(p_parent, "vlc_credential_get: invalid url"); return false; } p_credential->b_from_keystore = false; /* Don't set username to NULL, we may want to use the last one set */ p_credential->psz_password = NULL; while (!is_credential_valid(p_credential)) { /* First, fetch credential from URL (if any). * Secondly, fetch credential from VLC Options (if any). * Thirdly, fetch credential from keystore (if any) using user and realm * previously set by the caller, the URL or by VLC Options. * Finally, fetch credential from the dialog (if any). This last will be * repeated until user cancel the dialog. */ switch (p_credential->i_get_order) { case GET_FROM_URL: p_credential->psz_username = p_url->psz_username; p_credential->psz_password = p_url->psz_password; if (p_credential->psz_password) msg_Warn(p_parent, "Password in a URI is DEPRECATED"); if (p_url->psz_username && protocol_is_smb(p_url)) smb_split_domain(p_credential); p_credential->i_get_order++; break; case GET_FROM_OPTION: free(p_credential->psz_var_username); free(p_credential->psz_var_password); p_credential->psz_var_username = p_credential->psz_var_password = NULL; if (psz_option_username) p_credential->psz_var_username = var_InheritString(p_parent, psz_option_username); if (psz_option_password) p_credential->psz_var_password = var_InheritString(p_parent, psz_option_password); if (p_credential->psz_var_username) p_credential->psz_username = p_credential->psz_var_username; if (p_credential->psz_var_password) p_credential->psz_password = p_credential->psz_var_password; 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; 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, p_credential->p_keystore); p_credential->i_get_order++; break; default: case GET_FROM_DIALOG: if (!psz_dialog_title || !psz_dialog_fmt) return false; char *psz_dialog_username = NULL; char *psz_dialog_password = NULL; va_list ap; va_start(ap, psz_dialog_fmt); bool *p_store = p_credential->p_keystore != NULL ? &p_credential->b_store : NULL; int i_ret = vlc_dialog_wait_login_va(p_parent, &psz_dialog_username, &psz_dialog_password, p_store, p_credential->psz_username, psz_dialog_title, psz_dialog_fmt, ap); va_end(ap); /* Free previous dialog strings after vlc_dialog_wait_login_va call * since p_credential->psz_username (default username) can be a * pointer to p_credential->psz_dialog_username */ free(p_credential->psz_dialog_username); free(p_credential->psz_dialog_password); p_credential->psz_dialog_username = psz_dialog_username; p_credential->psz_dialog_password = psz_dialog_password; if (i_ret != 1) { p_credential->psz_username = p_credential->psz_password = NULL; return false; } p_credential->psz_username = p_credential->psz_dialog_username; p_credential->psz_password = p_credential->psz_dialog_password; if (protocol_is_smb(p_url)) smb_split_domain(p_credential); break; } } return is_credential_valid(p_credential); }
static void test_module(const char *psz_module, bool b_test_all, bool b_persistent, int argc, const char * const *argv) { #define VALUES_INSERT(i_key, psz_value) ppsz_values[i_key] = psz_value #define VALUES_REINIT() values_reinit(ppsz_values) #define KS_FIND() do { \ i_entries = ks_find(p_keystore, ppsz_values, psz_secret); \ } while (0) #define KS_REMOVE() do { \ i_entries = ks_remove(p_keystore, ppsz_values); \ } while(0) #define KS_STORE() ks_store(p_keystore, ppsz_values, (const uint8_t *)psz_secret, -1) printf("\n== Testing %s keystore module ==\n\n", psz_module); printf("creating libvlc\n"); libvlc_instance_t *p_libvlc = libvlc_new(argc, argv); assert(p_libvlc != NULL); vlc_interrupt_t *ctx = vlc_interrupt_create(); assert(ctx != NULL); printf("creating %s keystore\n", psz_module); vlc_keystore *p_keystore = vlc_keystore_create(p_libvlc->p_libvlc_int); assert(p_keystore); const char *psz_secret = "libvlc test secret"; unsigned int i_entries; const char *ppsz_values[KEY_MAX]; printf("testing that there is no entry\n"); VALUES_REINIT(); VALUES_INSERT(KEY_PROTOCOL, "http"); VALUES_INSERT(KEY_SERVER, "www.example.com"); VALUES_INSERT(KEY_PATH, "/example/example.mkv"); VALUES_INSERT(KEY_PORT, "88"); VALUES_INSERT(KEY_USER, "user1"); KS_FIND(); assert(i_entries == 0); printf("testing adding an entry\n"); KS_STORE(); KS_FIND(); assert(i_entries == 1); printf("testing adding an other entry\n"); VALUES_INSERT(KEY_USER, "user2"); KS_FIND(); assert(i_entries == 0); KS_STORE(); KS_FIND(); assert(i_entries == 1); printf("testing finding the 2 previous entries\n"); VALUES_INSERT(KEY_USER, NULL); KS_FIND(); assert(i_entries == 2); printf("testing that we can't store 2 duplicate entries\n"); VALUES_INSERT(KEY_USER, "user2"); KS_STORE(); VALUES_INSERT(KEY_USER, NULL); KS_FIND(); assert(i_entries == 2); if (b_persistent) { printf("testing that entries are still present after a module unload\n"); vlc_keystore_release(p_keystore); p_keystore = vlc_keystore_create(p_libvlc->p_libvlc_int); assert(p_keystore); KS_FIND(); assert(i_entries == 2); } VALUES_REINIT(); VALUES_INSERT(KEY_PROTOCOL, "smb"); VALUES_INSERT(KEY_SERVER, "example"); VALUES_INSERT(KEY_PATH, "/example.mkv"); VALUES_INSERT(KEY_USER, "user1"); if (b_persistent) { printf("testing adding a third entry from a second running instance\n"); KS_FIND(); assert(i_entries == 0); vlc_keystore *old_keystore = p_keystore; p_keystore = vlc_keystore_create(p_libvlc->p_libvlc_int); assert(p_keystore); KS_STORE(); KS_FIND(); assert(i_entries == 1); vlc_keystore_release(p_keystore); p_keystore = old_keystore; KS_FIND(); assert(i_entries == 1); } else { printf("testing adding a third entry\n"); KS_FIND(); assert(i_entries == 0); KS_STORE(); KS_FIND(); assert(i_entries == 1); } printf("testing adding a fourth entry (without user/path)\n"); VALUES_REINIT(); VALUES_INSERT(KEY_PROTOCOL, "ftp"); VALUES_INSERT(KEY_SERVER, "example.com"); KS_FIND(); assert(i_entries == 0); KS_STORE(); KS_FIND(); assert(i_entries == 1); printf("testing finding an entry only by its protocol\n"); VALUES_REINIT(); VALUES_INSERT(KEY_PROTOCOL, "smb"); KS_FIND(); assert(i_entries == 1); VALUES_REINIT(); VALUES_INSERT(KEY_PROTOCOL, "http"); KS_FIND(); assert(i_entries == 2); VALUES_REINIT(); VALUES_INSERT(KEY_PROTOCOL, "ftp"); KS_FIND(); assert(i_entries == 1); printf("testing finding all previous entries\n"); VALUES_REINIT(); KS_FIND(); assert(i_entries == 4); if (b_test_all && b_persistent) { printf("\nPress ENTER to remove entries\n"); getchar(); } printf("testing removing entries that match user => user1\n"); VALUES_REINIT(); VALUES_INSERT(KEY_USER, "user1"); KS_REMOVE(); assert(i_entries == 2); printf("testing removing entries that match user => user2\n"); VALUES_INSERT(KEY_USER, "user2"); KS_REMOVE(); assert(i_entries == 1); printf("testing removing entries that match protocol => ftp\n"); VALUES_REINIT(); VALUES_INSERT(KEY_PROTOCOL, "ftp"); KS_REMOVE(); assert(i_entries == 1); printf("testing that all entries are deleted\n"); VALUES_REINIT(); KS_FIND(); assert(i_entries == 0); vlc_keystore_release(p_keystore); vlc_interrupt_destroy(ctx); libvlc_release(p_libvlc); }