keystore/plaintext: rename to memory
[vlc.git] / test / modules / keystore / test.c
1 /*****************************************************************************
2  * test.c: test keystore module
3  *****************************************************************************
4  * Copyright Ā© 2015-2016 VLC authors, VideoLAN and VideoLabs
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation; either version 2.1 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
19  *****************************************************************************/
20
21 #ifdef HAVE_CONFIG_H
22 # include "config.h"
23 #endif
24 #include <vlc/vlc.h>
25
26 #include "../../../lib/libvlc_internal.h"
27
28 #include <vlc_common.h>
29 #include <vlc_plugin.h>
30 #include <vlc_modules.h>
31 #include <vlc_interrupt.h>
32 #include <vlc_keystore.h>
33
34 #undef NDEBUG
35 #include <assert.h>
36
37 /*
38  * Build and exec all keystore tests:
39  * $ cd vlc/build-<name>/test
40  * $ make test_modules_keystore
41  * $ ./test_modules_keystore -a
42  */
43
44 static const struct
45 {
46     const char *psz_module;
47     bool b_test_default;
48 } keystore_args[] =
49 {
50     { "memory", true },
51     /* Following keystores are tested only when asked explicitly by the tester
52      * (with "-a" argv) */
53     { "secret", false },
54     { "kwallet", false },
55     { "keychain", false }
56 };
57
58 static void
59 values_reinit(const char * ppsz_values[KEY_MAX])
60 {
61     VLC_KEYSTORE_VALUES_INIT(ppsz_values);
62     ppsz_values[KEY_REALM] = "libVLC TEST";
63 }
64
65 static unsigned int
66 ks_find(vlc_keystore *p_keystore, const char *const ppsz_values[KEY_MAX],
67         const char* psz_cmp_secret)
68 {
69     vlc_keystore_entry *p_entries;
70     unsigned int i_entries = vlc_keystore_find(p_keystore, ppsz_values,
71                                                &p_entries);
72     for (unsigned int i = 0; i < i_entries; ++i)
73     {
74         vlc_keystore_entry *p_entry = &p_entries[i];
75         assert(p_entry->p_secret[p_entry->i_secret_len - 1] == '\0');
76         assert(strcmp((const char *)p_entry->p_secret, psz_cmp_secret) == 0);
77
78         for (unsigned int j = 0; j < KEY_MAX; ++j)
79         {
80             const char *psz_value1 = ppsz_values[j];
81             const char *psz_value2 = p_entry->ppsz_values[j];
82
83             if (!psz_value1)
84                 continue;
85             assert(psz_value2);
86             assert(strcmp(psz_value1, psz_value2) == 0);
87         }
88     }
89     if (i_entries > 0)
90         vlc_keystore_release_entries(p_entries, i_entries);
91     return i_entries;
92 }
93
94 static unsigned int
95 ks_remove(vlc_keystore *p_keystore, const char *const ppsz_values[KEY_MAX])
96 {
97     return vlc_keystore_remove(p_keystore, ppsz_values);
98 }
99
100 static void
101 ks_store(vlc_keystore *p_keystore, const char *const ppsz_values[KEY_MAX],
102          const uint8_t* p_secret, size_t i_secret_len)
103 {
104     assert(vlc_keystore_store(p_keystore, ppsz_values,
105                               (const uint8_t *)p_secret,
106                               i_secret_len,
107                               "libVLC TEST") == VLC_SUCCESS);
108 }
109
110 static void
111 test_module(const char *psz_module, bool b_test_all,
112             int argc, const char * const *argv)
113 {
114 #define VALUES_INSERT(i_key, psz_value) ppsz_values[i_key] = psz_value
115 #define VALUES_REINIT() values_reinit(ppsz_values)
116 #define KS_FIND() do { \
117     i_entries = ks_find(p_keystore, ppsz_values, psz_secret); \
118 } while (0)
119 #define KS_REMOVE() do { \
120     i_entries = ks_remove(p_keystore, ppsz_values); \
121 } while(0)
122 #define KS_STORE() ks_store(p_keystore, ppsz_values, (const uint8_t *)psz_secret, -1)
123
124     printf("\n== Testing %s keystore module ==\n\n", psz_module);
125
126     printf("creating libvlc\n");
127     libvlc_instance_t *p_libvlc = libvlc_new(argc, argv);
128     assert(p_libvlc != NULL);
129
130     vlc_interrupt_t *ctx = vlc_interrupt_create();
131     assert(ctx != NULL);
132
133     printf("creating %s keystore\n", psz_module);
134     vlc_keystore *p_keystore = vlc_keystore_create(p_libvlc->p_libvlc_int);
135     assert(p_keystore);
136
137     const char *psz_secret = "libvlc test secret";
138     unsigned int i_entries;
139     const char *ppsz_values[KEY_MAX];
140
141     printf("testing that there is no entry\n");
142     VALUES_REINIT();
143     VALUES_INSERT(KEY_PROTOCOL, "http");
144     VALUES_INSERT(KEY_SERVER, "www.example.com");
145     VALUES_INSERT(KEY_PATH, "/example/example.mkv");
146     VALUES_INSERT(KEY_PORT, "88");
147     VALUES_INSERT(KEY_USER, "user1");
148     KS_FIND();
149     assert(i_entries == 0);
150
151     printf("testing adding an entry\n");
152     KS_STORE();
153     KS_FIND();
154     assert(i_entries == 1);
155
156     printf("testing adding an other entry\n");
157     VALUES_INSERT(KEY_USER, "user2");
158     KS_FIND();
159     assert(i_entries == 0);
160     KS_STORE();
161     KS_FIND();
162     assert(i_entries == 1);
163
164     printf("testing finding the 2 previous entries\n");
165     VALUES_INSERT(KEY_USER, NULL);
166     KS_FIND();
167     assert(i_entries == 2);
168
169     printf("testing that we can't store 2 duplicate entries\n");
170     VALUES_INSERT(KEY_USER, "user2");
171     KS_STORE();
172     VALUES_INSERT(KEY_USER, NULL);
173     KS_FIND();
174     assert(i_entries == 2);
175
176     printf("testing that entries are still present after a module unload\n");
177     vlc_keystore_release(p_keystore);
178     p_keystore = vlc_keystore_create(p_libvlc->p_libvlc_int);
179     assert(p_keystore);
180     KS_FIND();
181     assert(i_entries == 2);
182
183     printf("testing adding a third entry from a second running instance\n");
184     VALUES_REINIT();
185     VALUES_INSERT(KEY_PROTOCOL, "smb");
186     VALUES_INSERT(KEY_SERVER, "example");
187     VALUES_INSERT(KEY_PATH, "/example.mkv");
188     VALUES_INSERT(KEY_USER, "user1");
189     KS_FIND();
190     assert(i_entries == 0);
191
192     vlc_keystore *old_keystore = p_keystore;
193     p_keystore = vlc_keystore_create(p_libvlc->p_libvlc_int);
194     assert(p_keystore);
195
196     KS_STORE();
197     KS_FIND();
198     assert(i_entries == 1);
199
200     vlc_keystore_release(p_keystore);
201     p_keystore = old_keystore;
202     KS_FIND();
203     assert(i_entries == 1);
204
205     printf("testing adding a fourth entry (without user/path)\n");
206     VALUES_REINIT();
207     VALUES_INSERT(KEY_PROTOCOL, "ftp");
208     VALUES_INSERT(KEY_SERVER, "example.com");
209     KS_FIND();
210     assert(i_entries == 0);
211     KS_STORE();
212     KS_FIND();
213     assert(i_entries == 1);
214
215     printf("testing finding an entry only by its protocol\n");
216     VALUES_REINIT();
217     VALUES_INSERT(KEY_PROTOCOL, "smb");
218     KS_FIND();
219     assert(i_entries == 1);
220     VALUES_REINIT();
221     VALUES_INSERT(KEY_PROTOCOL, "http");
222     KS_FIND();
223     assert(i_entries == 2);
224     VALUES_REINIT();
225     VALUES_INSERT(KEY_PROTOCOL, "ftp");
226     KS_FIND();
227     assert(i_entries == 1);
228
229     printf("testing finding all previous entries\n");
230     VALUES_REINIT();
231     KS_FIND();
232     assert(i_entries == 4);
233
234     if (b_test_all)
235     {
236         printf("\nPress ENTER to remove entries\n");
237         getchar();
238     }
239
240     printf("testing removing entries that match user => user1\n");
241     VALUES_REINIT();
242     VALUES_INSERT(KEY_USER, "user1");
243     KS_REMOVE();
244     assert(i_entries == 2);
245
246     printf("testing removing entries that match user => user2\n");
247     VALUES_INSERT(KEY_USER, "user2");
248     KS_REMOVE();
249     assert(i_entries == 1);
250
251     printf("testing removing entries that match protocol => ftp\n");
252     VALUES_REINIT();
253     VALUES_INSERT(KEY_PROTOCOL, "ftp");
254     KS_REMOVE();
255     assert(i_entries == 1);
256
257     printf("testing that all entries are deleted\n");
258     VALUES_REINIT();
259     KS_FIND();
260     assert(i_entries == 0);
261
262     vlc_keystore_release(p_keystore);
263
264     vlc_interrupt_destroy(ctx);
265
266     libvlc_release(p_libvlc);
267 }
268
269 int
270 main(int i_argc, char *ppsz_argv[])
271 {
272     /* If b_test_all is true, this test could pollute the developerĀ“s keystores */
273     bool b_test_all = i_argc > 1 && strcmp(ppsz_argv[1], "-a") == 0;
274
275     if (!b_test_all)
276         alarm(3);
277
278     setenv("VLC_PLUGIN_PATH", "../modules", 1);
279
280     /* Create a dummy libvlc to initialize module bank, needed by module_exists */
281     libvlc_instance_t *p_libvlc = libvlc_new(0, NULL);
282     assert(p_libvlc != NULL);
283
284     for (unsigned int i = 0; i < sizeof(keystore_args)/sizeof(*keystore_args); ++i)
285     {
286         const char *psz_module = keystore_args[i].psz_module;
287
288         if ((b_test_all || keystore_args[i].b_test_default)
289          && module_exists(psz_module))
290         {
291             int i_vlc_argc = 1;
292             char *ppsz_vlc_argv[2] = { 0 };
293             int i_tmp_fd = -1;
294             char psz_tmp_path[] = "/tmp/libvlc_XXXXXX";
295
296             assert(asprintf(&ppsz_vlc_argv[0], "--keystore=%s,none",
297                    psz_module) != -1);
298
299             if (strcmp(psz_module, "memory") == 0)
300             {
301                 assert((i_tmp_fd = mkstemp(psz_tmp_path)) != -1);
302                 printf("plaintext tmp file: '%s'\n", psz_tmp_path);
303                 assert(asprintf(&ppsz_vlc_argv[1],
304                        "--keystore-file=%s", psz_tmp_path) != -1);
305                 i_vlc_argc++;
306             }
307             else if (strcmp(psz_module, "kwallet") == 0)
308             {
309                 /* See TODO in kwallet.cpp, VLCKWallet::connect() */
310                 assert(libvlc_InternalAddIntf(p_libvlc->p_libvlc_int, "qt") == VLC_SUCCESS);
311             }
312
313             test_module(psz_module, b_test_all, i_vlc_argc,
314                         (const char * const *)ppsz_vlc_argv);
315
316             if (i_tmp_fd != -1)
317             {
318                 close(i_tmp_fd);
319                 unlink(psz_tmp_path);
320             }
321             free(ppsz_vlc_argv[0]);
322             free(ppsz_vlc_argv[1]);
323         }
324         else
325             printf("not testing %s\n", psz_module);
326     }
327     libvlc_release(p_libvlc);
328
329     return 0;
330 }