blob: 06f935bb7b522a1557335672a2d31798a2c75681 [file] [log] [blame]
Michal Vaskob83a3fa2021-05-26 09:53:42 +02001#include <errno.h>
2#include <setjmp.h>
David Sedlákddde4492018-09-30 21:34:38 +02003#include <stdio.h>
4#include <stdlib.h>
David Sedlákddde4492018-09-30 21:34:38 +02005#include <sys/socket.h>
Michal Vaskob83a3fa2021-05-26 09:53:42 +02006#include <sys/types.h>
David Sedlákddde4492018-09-30 21:34:38 +02007
8#include <cmocka.h>
Michal Vaskob83a3fa2021-05-26 09:53:42 +02009#include <config.h>
David Sedlákddde4492018-09-30 21:34:38 +020010#include <libyang/libyang.h>
Michal Vaskob83a3fa2021-05-26 09:53:42 +020011#include <log.h>
David Sedlákddde4492018-09-30 21:34:38 +020012#include <session_client.h>
Fred Gan3a736e02021-01-04 17:59:38 +080013#include <session_client_ch.h>
14#include <session_p.h>
David Sedlákddde4492018-09-30 21:34:38 +020015#include "tests/config.h"
16
David Sedlákddde4492018-09-30 21:34:38 +020017#include <libssh/callbacks.h>
Michal Vaskob83a3fa2021-05-26 09:53:42 +020018#include <libssh/libssh.h>
David Sedlákddde4492018-09-30 21:34:38 +020019#include <libssh/server.h>
20
21static int
22ssh_hostkey_check_clb(const char *hostname, ssh_session session, void *priv)
23{
24 (void)hostname;
25 (void)session;
26 (void)priv;
27
28 return 0;
29}
30
31static int
32setup_f(void **state)
33{
34 (void)state;
35 int ret;
36
37 nc_verbosity(NC_VERB_VERBOSE);
38
39 ret = nc_client_ssh_set_username("username");
40 assert_int_equal(ret, 0);
Fred Gan3a736e02021-01-04 17:59:38 +080041 ret = nc_client_ssh_ch_set_username("ch_username");
42 assert_int_equal(ret, 0);
David Sedlákddde4492018-09-30 21:34:38 +020043 nc_client_ssh_set_auth_hostkey_check_clb(ssh_hostkey_check_clb, NULL);
44
45 return 0;
46}
47
48static int
49teardown_f(void **state)
50{
51 (void)state;
52 return 0;
53}
54
55MOCK int
56__wrap_connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
57{
58 (void)sockfd;
59 (void)addr;
60 (void)addrlen;
61
62 return (int)mock();
63}
64
65MOCK int
66__wrap_ssh_connect(ssh_session session)
67{
68 (void)session;
69
70 /* set support of all authentication methods by fake server */
71 ssh_set_auth_methods(session, SSH_AUTH_METHOD_PUBLICKEY | SSH_AUTH_METHOD_PASSWORD | SSH_AUTH_METHOD_INTERACTIVE);
72 return (int)mock();
73}
74
75MOCK int
76__wrap_ssh_userauth_none(ssh_session session, const char *username)
77{
78 (void)session;
79 (void)username;
80
81 return (int)mock();
82}
83
84MOCK int
85__wrap_ssh_userauth_kbdint(ssh_session session, const char *user, const char *submethods)
86{
87 (void)session;
88 (void)user;
89 (void)submethods;
90
91 return (int)mock();
92}
93
94MOCK int
95__wrap_ssh_is_connected(ssh_session session)
96{
97 (void)session;
98
99 return (int)mock();
100}
101
102MOCK int
103__wrap_ssh_channel_open_session(ssh_channel channel)
104{
105 (void)channel;
106
107 return (int)mock();
108}
109
110MOCK int
111__wrap_ssh_channel_request_subsystem(ssh_channel channel, const char *subsystem)
112{
113 (void)channel;
114 (void)subsystem;
115
116 return (int)mock();
117}
118
119MOCK int
120__wrap_ssh_channel_is_closed(ssh_channel channel)
121{
122 (void)channel;
123
124 return 0;
125}
126
127MOCK int
128__wrap_ssh_channel_write(ssh_channel channel, const void *data, uint32_t len)
129{
130 (void)channel;
131 (void)data;
132
133 return len;
134}
135
136MOCK int
137__wrap_ssh_channel_poll_timeout(ssh_channel channel, int timeout, int is_stderr)
138{
139 (void)channel;
140 (void)timeout;
141 (void)is_stderr;
142
143 return (int)mock();
144}
145
146MOCK int
147__wrap_ssh_userauth_password(ssh_session session, const char *username, const char *password)
148{
149 (void)session;
150 check_expected(password);
151 check_expected(username);
152
David Sedlákddde4492018-09-30 21:34:38 +0200153 return (int)mock();
154}
155
156MOCK int
157__wrap_nc_handshake_io(struct nc_session *session)
158{
159 (void)session;
160
161 return (int)mock();
162}
163
164MOCK int
165__wrap_nc_ctx_check_and_fill(struct nc_session *session)
166{
167 (void)session;
168
169 return (int)mock();
170}
171
David Sedlák77acc202018-10-08 21:44:14 +0200172MOCK int
173__wrap_ssh_userauth_try_publickey(ssh_session session, const char *username, const ssh_key pubkey)
174{
175 (void)session;
176 (void)username;
177 (void)pubkey;
178
179 return (int)mock();
180}
181
182MOCK int
183__wrap_ssh_userauth_publickey(ssh_session session, const char *username, const ssh_key privkey)
184{
185 (void)session;
186 (void)username;
187 (void)privkey;
188
189 return (int)mock();
190}
191
Fred Gan3a736e02021-01-04 17:59:38 +0800192MOCK int
193__wrap_nc_sock_listen_inet(const char *address, uint16_t port, struct nc_keepalives *ka)
194{
195 (void)address;
196 (void)port;
197 (void)ka;
198
199 return (int)mock();
200}
201
202MOCK int
203__wrap_nc_sock_accept_binds(struct nc_bind *binds, uint16_t bind_count, int timeout, char **host, uint16_t *port, uint16_t *idx)
204{
205 (void)binds;
206 (void)bind_count;
207 (void)timeout;
208 (void)host;
209 (void)port;
210
211 *idx = 0;
212 return (int)mock();
213}
214
215MOCK struct nc_session *
216__wrap_nc_accept_callhome_ssh_sock(int sock, const char *host, uint16_t port, struct ly_ctx *ctx, int timeout)
217{
218 (void)sock;
219 (void)host;
220 (void)port;
221 (void)ctx;
222 (void)timeout;
223
224 return mock_ptr_type(struct nc_session *);
225}
226
David Sedlákddde4492018-09-30 21:34:38 +0200227static int
228test_hostkey_clb(const char *hostname, ssh_session session, void *priv)
229{
230 (void)hostname;
231 (void)session;
232 (void)priv;
233
234 return 0;
235}
236
237static void
238test_nc_client_ssh_setting_auth_hostkey_check_clb(void **state)
239{
240 (void)state;
241 int (*ret_f)(const char *hostname, ssh_session session, void *priv);
242 char *priv_data_ret;
243
244 /* ssh_hostkey_check_clb is set in setup_f */
245 nc_client_ssh_get_auth_hostkey_check_clb(&ret_f, (void **)&priv_data_ret);
246 assert_ptr_equal(ret_f, ssh_hostkey_check_clb);
247 assert_null(priv_data_ret);
248
249 /* set different callback and private data */
250 nc_client_ssh_set_auth_hostkey_check_clb(test_hostkey_clb, "DATA");
251 nc_client_ssh_get_auth_hostkey_check_clb(&ret_f, (void **)&priv_data_ret);
252 assert_ptr_equal(ret_f, test_hostkey_clb);
253 assert_string_equal(priv_data_ret, "DATA");
254}
255
256char *
257test_pwd_clb1(const char *username, const char *hostname, void *priv)
258{
259 char *pass, *pass_to_return;
260
261 check_expected(username);
262 check_expected(hostname);
263 check_expected(priv);
264
265 pass = (char *)mock();
266 pass_to_return = malloc(sizeof *pass * (strlen(pass) + 1));
267 strcpy(pass_to_return, pass);
268
269 return pass_to_return;
270}
271
272char *
273test_pwd_clb2(const char *username, const char *hostname, void *priv)
274{
275 (void)username;
276 (void)hostname;
277 (void)priv;
278
279 return 0;
280}
281
282static void
283test_nc_client_ssh_setting_auth_password_clb(void **state)
284{
285 (void)state;
286 char *(*ret_f)(const char *username, const char *hostname, void *priv);
287 char *priv_data_ret;
288
289 /* set callback */
290 nc_client_ssh_set_auth_password_clb(test_pwd_clb1, "DATA");
291 nc_client_ssh_get_auth_password_clb(&ret_f, (void **)&priv_data_ret);
292 assert_ptr_equal(test_pwd_clb1, ret_f);
293 assert_string_equal("DATA", priv_data_ret);
294
295 /* set different callback */
296 nc_client_ssh_set_auth_password_clb(test_pwd_clb2, "NEW DATA");
297 nc_client_ssh_get_auth_password_clb(&ret_f, (void **)&priv_data_ret);
298 assert_ptr_equal(test_pwd_clb2, ret_f);
299 assert_string_equal("NEW DATA", priv_data_ret);
300}
301
302char *
303test_inter_clb1(const char *auth_name, const char *instruction, const char *prompt, int echo, void *priv)
304{
305 (void)auth_name;
306 (void)instruction;
307 (void)prompt;
308 (void)echo;
309 (void)priv;
310
311 return 0;
312}
313
314char *
315test_inter_clb2(const char *auth_name, const char *instruction, const char *prompt, int echo, void *priv)
316{
317 (void)auth_name;
318 (void)instruction;
319 (void)prompt;
320 (void)echo;
321 (void)priv;
322
323 return 0;
324}
325
326static void
327test_nc_client_ssh_setting_auth_interactive_clb(void **state)
328{
329 (void)state;
330 char *(*ret_f)(const char *auth_name, const char *instruction, const char *prompt, int echo, void *priv);
331 char *priv_data_ret;
332
333 /* set callback */
334 nc_client_ssh_set_auth_interactive_clb(test_inter_clb1, "DATA");
335 nc_client_ssh_get_auth_interactive_clb(&ret_f, (void **)&priv_data_ret);
336 assert_ptr_equal(test_inter_clb1, ret_f);
337 assert_string_equal("DATA", priv_data_ret);
338
339 /* set diferent callback */
340 nc_client_ssh_set_auth_interactive_clb(test_inter_clb2, "NEW DATA");
341 nc_client_ssh_get_auth_interactive_clb(&ret_f, (void **)&priv_data_ret);
342 assert_ptr_equal(test_inter_clb2, ret_f);
343 assert_string_equal("NEW DATA", priv_data_ret);
344}
345
346char *
347test_passphrase_clb1(const char *privkey_path, void *priv)
348{
349 (void)privkey_path;
350 (void)priv;
351
352 return 0;
353}
354
355char *
356test_passphrase_clb2(const char *privkey_path, void *priv)
357{
358 (void)privkey_path;
359 (void)priv;
360
361 return 0;
362}
363
364static void
365test_nc_client_ssh_setting_auth_privkey_passphrase_clb(void **state)
366{
367 (void)state;
368 char *(*ret_f)(const char *privkey_path, void *priv);
369 char *priv_data_ret;
Michal Vaskob83a3fa2021-05-26 09:53:42 +0200370
David Sedlákddde4492018-09-30 21:34:38 +0200371 /* set first callback */
372 nc_client_ssh_set_auth_privkey_passphrase_clb(test_passphrase_clb1, "DATA");
373 nc_client_ssh_get_auth_privkey_passphrase_clb(&ret_f, (void **)&priv_data_ret);
374 assert_ptr_equal(ret_f, test_passphrase_clb1);
375 assert_string_equal("DATA", priv_data_ret);
376
377 /* set different callback */
378 nc_client_ssh_set_auth_privkey_passphrase_clb(test_passphrase_clb2, "NEW DATA");
379 nc_client_ssh_get_auth_privkey_passphrase_clb(&ret_f, (void **)&priv_data_ret);
380 assert_ptr_equal(ret_f, test_passphrase_clb2);
381 assert_string_equal("NEW DATA", priv_data_ret);
382}
383
384static void
385test_nc_client_ssh_adding_keypair(void **state)
386{
387 (void)state;
388 int ret;
389 const char *pubkey1, *pubkey2;
Michal Vaskob83a3fa2021-05-26 09:53:42 +0200390
David Sedlákddde4492018-09-30 21:34:38 +0200391 /* at the beginning keypair count should be 0 */
392 ret = nc_client_ssh_get_keypair_count();
393 assert_int_equal(ret, 0);
394
395 /* add first key pair */
Michal Vaskob83a3fa2021-05-26 09:53:42 +0200396 ret = nc_client_ssh_add_keypair(TESTS_DIR "/data/key_dsa.pub", TESTS_DIR "/data/key_dsa");
David Sedlákddde4492018-09-30 21:34:38 +0200397 assert_int_equal(ret, 0);
398 ret = nc_client_ssh_get_keypair_count();
399 assert_int_equal(ret, 1);
400
401 /* add second keypair */
402 ret = nc_client_ssh_add_keypair("key_pub", "key_priv");
403 assert_int_equal(ret, 0);
404 ret = nc_client_ssh_get_keypair_count();
405 assert_int_equal(ret, 2);
406 ret = nc_client_ssh_get_keypair(1, &pubkey1, &pubkey2);
407 assert_int_equal(ret, 0);
408 assert_string_equal(pubkey1, "key_pub");
409 assert_string_equal(pubkey2, "key_priv");
410
411 /* delete first keypair */
412 ret = nc_client_ssh_del_keypair(0);
413 assert_int_equal(ret, 0);
414 ret = nc_client_ssh_get_keypair_count();
415 assert_int_equal(ret, 1);
416 /* try to get deleted keypair */
417 ret = nc_client_ssh_get_keypair(5, &pubkey1, &pubkey2);
418 assert_int_equal(ret, -1);
419
420 /* try to add keypair that is already set */
421 ret = nc_client_ssh_add_keypair("key_pub", "key_priv");
422 assert_int_equal(ret, -1);
423 ret = nc_client_ssh_get_keypair_count();
424 assert_int_equal(ret, 1);
425
426 /* try to delete keypair with id that is not used */
427 ret = nc_client_ssh_del_keypair(42);
428 assert_int_equal(ret, -1);
429 ret = nc_client_ssh_get_keypair_count();
430 assert_int_equal(ret, 1);
431
432 /* remove remaining keypairs */
433 ret = nc_client_ssh_del_keypair(0);
434 assert_int_equal(ret, 0);
435 ret = nc_client_ssh_get_keypair_count();
436 assert_int_equal(ret, 0);
437}
438
439static void
440test_nc_client_ssh_setting_auth_pref(void **state)
441{
442 (void)state;
443 int ret;
444
David Sedlákaae4df32018-10-08 22:27:22 +0200445 /* initiate client, must be called in first test */
David Sedlákddde4492018-09-30 21:34:38 +0200446 nc_client_init();
447
448 /* check default prefference settings according to documentation */
449 ret = nc_client_ssh_get_auth_pref(NC_SSH_AUTH_INTERACTIVE);
450 assert_int_equal(ret, 3);
451 ret = nc_client_ssh_get_auth_pref(NC_SSH_AUTH_PASSWORD);
452 assert_int_equal(ret, 2);
453 ret = nc_client_ssh_get_auth_pref(NC_SSH_AUTH_PUBLICKEY);
454 assert_int_equal(ret, 1);
455
456 /* try to set prefetence of non existing method */
457 nc_client_ssh_set_auth_pref(42, 22);
458
459 /* try to get preference of non existing method */
460 ret = nc_client_ssh_get_auth_pref(42);
461 assert_int_equal(ret, 0);
462
463 /* change values of all methods and check if they actually changed */
464 nc_client_ssh_set_auth_pref(NC_SSH_AUTH_INTERACTIVE, 9);
465 ret = nc_client_ssh_get_auth_pref(NC_SSH_AUTH_INTERACTIVE);
466 assert_int_equal(ret, 9);
467
468 /* negative value should be set as -1 */
469 nc_client_ssh_set_auth_pref(NC_SSH_AUTH_PASSWORD, -5);
470 ret = nc_client_ssh_get_auth_pref(NC_SSH_AUTH_PASSWORD);
471 assert_int_equal(ret, -1);
472
473 nc_client_ssh_set_auth_pref(NC_SSH_AUTH_PUBLICKEY, 11);
474 ret = nc_client_ssh_get_auth_pref(NC_SSH_AUTH_PUBLICKEY);
475 assert_int_equal(ret, 11);
476}
477
478static void
479test_nc_client_ssh_setting_username(void **state)
480{
481 (void)state;
482 int ret;
483 const char *username_ret;
Michal Vaskob83a3fa2021-05-26 09:53:42 +0200484
David Sedlákddde4492018-09-30 21:34:38 +0200485 username_ret = nc_client_ssh_get_username();
486 /* username is set to "username" in setup_f */
487 assert_string_equal(username_ret, "username");
488
489 /* set new username and check if it changes */
490 ret = nc_client_ssh_set_username("new_username");
491 assert_int_equal(ret, 0);
492 username_ret = nc_client_ssh_get_username();
493 assert_string_equal(username_ret, "new_username");
494}
495
496static void
497test_nc_connect_ssh_interactive_succesfull(void **state)
498{
499 (void)state;
500 struct nc_session *session;
501
502 /* set authentication method to use interactive authentication */
503 nc_client_ssh_set_auth_pref(NC_SSH_AUTH_INTERACTIVE, 1);
504 nc_client_ssh_set_auth_pref(NC_SSH_AUTH_PASSWORD, -1);
505 nc_client_ssh_set_auth_pref(NC_SSH_AUTH_PUBLICKEY, -1);
506
507 nc_client_ssh_set_auth_pref(NC_SSH_AUTH_INTERACTIVE, 20);
508
509 /* prepare return values for functions used by nc_connect_ssh */
510 will_return(__wrap_connect, 0);
511 will_return(__wrap_ssh_connect, 0);
512 will_return(__wrap_ssh_userauth_none, 1);
513
514 will_return(__wrap_ssh_userauth_kbdint, 0);
515 will_return(__wrap_ssh_is_connected, 1);
516 will_return(__wrap_ssh_is_connected, 1);
517
518 will_return(__wrap_ssh_channel_open_session, 0);
519 will_return(__wrap_ssh_channel_request_subsystem, 0);
520
521 will_return(__wrap_nc_handshake_io, 3);
522 will_return(__wrap_nc_ctx_check_and_fill, 0);
523
524 session = nc_connect_ssh("127.0.0.1", 8080, NULL);
525 assert_non_null(session);
526
527 nc_session_free(session, NULL);
528}
529
530static void
531test_nc_connect_ssh_password_succesfull(void **state)
532{
533 (void)state;
534 struct nc_session *session;
535
536 /* set authentication method to use password authentication */
537 nc_client_ssh_set_auth_pref(NC_SSH_AUTH_PASSWORD, 1);
538 nc_client_ssh_set_auth_pref(NC_SSH_AUTH_PUBLICKEY, -1);
539 nc_client_ssh_set_auth_pref(NC_SSH_AUTH_INTERACTIVE, -1);
540
541 /* set authentication callback */
542 nc_client_ssh_set_auth_password_clb(test_pwd_clb1, "private_data");
543 will_return(test_pwd_clb1, "secret password");
544 /* set values that are expected as parameters for authentication callback */
545 expect_string(test_pwd_clb1, username, "username");
546 expect_string(test_pwd_clb1, hostname, "127.0.0.1");
547 expect_string(test_pwd_clb1, priv, "private_data");
548
549 /* fake succesfull connection */
550 will_return(__wrap_connect, 0);
551 will_return(__wrap_ssh_connect, 0);
552 /* do not authenticate using no authentication method */
553 will_return(__wrap_ssh_userauth_none, 1);
554
555 /* succesfully authenticate via password authentication */
556 expect_string(__wrap_ssh_userauth_password, password, "secret password");
557 expect_string(__wrap_ssh_userauth_password, username, "username");
558 will_return(__wrap_ssh_userauth_password, 0);
559
560 /* fake ssh functions that are used to open netconf channel */
561 will_return(__wrap_ssh_channel_open_session, 0);
562 will_return(__wrap_ssh_channel_request_subsystem, 0);
563
564 /* fake that connection is still alive*/
565 will_return(__wrap_ssh_is_connected, 1);
566
567 /* fake ssh function for recieving hello message */
568 will_return(__wrap_ssh_is_connected, 1);
569
570 will_return(__wrap_nc_handshake_io, 3);
571 will_return(__wrap_nc_ctx_check_and_fill, 0);
572
573 session = nc_connect_ssh("127.0.0.1", 8080, NULL);
574 assert_non_null(session);
575
576 /* disconnect */
577 nc_session_free(session, NULL);
578}
579
580static void
David Sedlák77acc202018-10-08 21:44:14 +0200581test_nc_connect_ssh_pubkey_succesfull(void **state)
582{
583 (void)state;
584 struct nc_session *session;
585 int ret = 0;
586
587 /* set authentication method to use password authentication */
588 nc_client_ssh_set_auth_pref(NC_SSH_AUTH_PASSWORD, -1);
589 nc_client_ssh_set_auth_pref(NC_SSH_AUTH_PUBLICKEY, 1);
590 nc_client_ssh_set_auth_pref(NC_SSH_AUTH_INTERACTIVE, -1);
591
592 /* add keypair for authentication */
Michal Vaskob83a3fa2021-05-26 09:53:42 +0200593 ret = nc_client_ssh_add_keypair(TESTS_DIR "/data/key_dsa.pub", TESTS_DIR "/data/key_dsa");
David Sedlák77acc202018-10-08 21:44:14 +0200594 assert_int_equal(ret, 0);
595
596 /* fake succesfull connection */
597 will_return(__wrap_connect, 0);
598 will_return(__wrap_ssh_connect, 0);
599 /* do not authenticate using no authentication method */
600 will_return(__wrap_ssh_userauth_none, 1);
601 will_return(__wrap_ssh_userauth_try_publickey, 0);
602 will_return(__wrap_ssh_userauth_publickey, 0);
603 will_return(__wrap_ssh_is_connected, 1);
604 will_return(__wrap_ssh_channel_open_session, 0);
605 will_return(__wrap_ssh_channel_request_subsystem, 0);
606
607 /* fake ssh function for recieving hello message */
608 will_return(__wrap_ssh_is_connected, 1);
609
610 will_return(__wrap_nc_handshake_io, 3);
611 will_return(__wrap_nc_ctx_check_and_fill, 0);
612 session = nc_connect_ssh("127.0.0.1", 8080, NULL);
613 assert_non_null(session);
614
615 /* disconnect */
616 nc_session_free(session, NULL);
617}
618
619static void
David Sedlákddde4492018-09-30 21:34:38 +0200620test_nc_connect_connection_failed(void **state)
621{
622 (void)state;
623 struct nc_session *session;
624
625 errno = ECONNREFUSED;
626 will_return(__wrap_connect, -1);
627 will_return(__wrap_ssh_is_connected, 0);
628
629 session = nc_connect_ssh("127.0.0.1", 8080, NULL);
630 assert_null(session);
631}
632
633static void
634test_nc_connect_ssh_bad_hello(void **state)
635{
636 (void)state;
637 struct nc_session *session;
638
639 /* set authentication method to use interactive authentication */
640 nc_client_ssh_set_auth_pref(NC_SSH_AUTH_INTERACTIVE, 1);
641 nc_client_ssh_set_auth_pref(NC_SSH_AUTH_PASSWORD, -1);
642 nc_client_ssh_set_auth_pref(NC_SSH_AUTH_PUBLICKEY, 1);
643
644 nc_client_ssh_set_auth_password_clb(test_pwd_clb2, NULL);
645
646 will_return(__wrap_connect, 0);
647 will_return(__wrap_ssh_connect, 0);
648 will_return(__wrap_ssh_userauth_none, 1);
649
650 will_return(__wrap_ssh_userauth_kbdint, 0);
651 will_return(__wrap_ssh_is_connected, 1);
652 will_return(__wrap_ssh_is_connected, 1);
653
654 will_return(__wrap_ssh_channel_open_session, 0);
655 will_return(__wrap_ssh_channel_request_subsystem, 0);
656 will_return(__wrap_nc_handshake_io, 4);
657
658 session = nc_connect_ssh("127.0.0.1", 8080, NULL);
659 assert_null(session);
660
David Sedlákaae4df32018-10-08 22:27:22 +0200661 /* destroy client, must be called in last test */
David Sedlákddde4492018-09-30 21:34:38 +0200662 nc_client_destroy();
663}
664
Fred Gan3a736e02021-01-04 17:59:38 +0800665static void
666test_nc_client_ssh_ch_setting_username(void **state)
667{
668 (void)state;
669 const char *username_ret;
670 int ret;
671
672 /* username is set to "ch_username" in setup_f */
673 username_ret = nc_client_ssh_ch_get_username();
674 assert_string_equal(username_ret, "ch_username");
675 /* set new username and check if it changes */
676 ret = nc_client_ssh_ch_set_username("new_ch_username");
677 assert_int_equal(ret, 0);
678 username_ret = nc_client_ssh_ch_get_username();
679 assert_string_equal(username_ret, "new_ch_username");
680}
681
682static void
683test_nc_client_ssh_ch_add_bind_listen(void **state)
684{
685 (void)state;
686 int ret;
687
688 /* invalid parameters, address NULL or port 0 */
689 ret = nc_client_ssh_ch_add_bind_listen(NULL, 4334);
690 assert_int_equal(ret, -1);
691 ret = nc_client_ssh_ch_add_bind_listen("127.0.0.1", 0);
692 assert_int_equal(ret, -1);
693
694 /* failed to create an ssh listening socket */
695 will_return(__wrap_nc_sock_listen_inet, -1);
696 ret = nc_client_ssh_ch_add_bind_listen("127.0.0.1", 4334);
697 assert_int_equal(ret, -1);
698
699 /* fake a successful CH ssh listening socket */
700 will_return(__wrap_nc_sock_listen_inet, 1);
701 ret = nc_client_ssh_ch_add_bind_listen("127.0.0.1", 4334);
702 assert_int_equal(ret, 0);
703
704 /* remove ssh listening client binds */
705 ret = nc_client_ssh_ch_del_bind("127.0.0.1", 4334);
706 assert_int_equal(ret, 0);
707}
708
709static void
710test_nc_accept_callhome(void **state)
711{
712 (void)state;
713 struct nc_session *session = NULL;
714 int timeout = 10;
715 int ret;
716
717 /* invalid parameter session */
718 ret = nc_accept_callhome(timeout, NULL, NULL);
719 assert_int_equal(ret, -1);
720
721 /* no client bind */
722 ret = nc_accept_callhome(timeout, NULL, &session);
723 assert_int_equal(ret, -1);
724
725 /* successfully add a client Call Home bind */
726 will_return(__wrap_nc_sock_listen_inet, 1);
727 ret = nc_client_ssh_ch_add_bind_listen("127.0.0.1", 4334);
728 assert_int_equal(ret, 0);
729
730 /* failed to accept a client bind */
731 will_return(__wrap_nc_sock_accept_binds, -1);
732 ret = nc_accept_callhome(timeout, NULL, &session);
733 assert_int_equal(ret, -1);
734
735 /* failed to accept a server Call Home connection */
736 will_return(__wrap_nc_accept_callhome_ssh_sock, NULL);
737 will_return(__wrap_nc_sock_accept_binds, 2);
738 ret = nc_accept_callhome(timeout, NULL, &session);
739 assert_int_equal(ret, -1);
740
741 /* create session structure to fake a successful server call home connection */
742 session = nc_new_session(NC_CLIENT, 0);
743 assert_non_null(session);
744 will_return(__wrap_nc_sock_accept_binds, 2);
745 will_return(__wrap_nc_accept_callhome_ssh_sock, session);
746 ret = nc_accept_callhome(timeout, NULL, &session);
747 assert_int_equal(ret, 1);
748
749 /* remove ssh listening client binds */
750 ret = nc_client_ssh_ch_del_bind("127.0.0.1", 4334);
751 assert_int_equal(ret, 0);
752
753 /* free session */
754 nc_session_free(session, NULL);
755}
756
757static void
758test_nc_client_ssh_callhome_successful(void **state)
759{
760 (void)state;
761 struct nc_session *session = NULL;
762 int timeout = 10;
763 int ret;
764
765 /* create session structure */
766 session = nc_new_session(NC_CLIENT, 0);
767 assert_non_null(session);
768
769 /* prepare to fake return values for functions used by nc_accept_callhome */
770 will_return(__wrap_nc_sock_listen_inet, 1);
771 will_return(__wrap_nc_sock_accept_binds, 2);
772 will_return(__wrap_nc_accept_callhome_ssh_sock, session);
773
774 ret = nc_client_ssh_ch_add_bind_listen("127.0.0.1", 4334);
775 assert_int_equal(ret, 0);
776 ret = nc_accept_callhome(timeout, NULL, &session);
777 assert_int_equal(ret, 1);
778
779 /* remove ssh listening client binds */
780 ret = nc_client_ssh_ch_del_bind("127.0.0.1", 4334);
781 assert_int_equal(ret, 0);
782
783 /* free session */
784 nc_session_free(session, NULL);
785}
786
David Sedlákddde4492018-09-30 21:34:38 +0200787int
788main(void)
789{
790 const struct CMUnitTest tests[] = {
791 cmocka_unit_test_setup_teardown(test_nc_client_ssh_setting_auth_pref, setup_f, teardown_f),
792 cmocka_unit_test_setup_teardown(test_nc_client_ssh_setting_auth_hostkey_check_clb, setup_f, teardown_f),
793 cmocka_unit_test_setup_teardown(test_nc_client_ssh_setting_auth_password_clb, setup_f, teardown_f),
794 cmocka_unit_test_setup_teardown(test_nc_client_ssh_setting_auth_interactive_clb, setup_f, teardown_f),
795 cmocka_unit_test_setup_teardown(test_nc_client_ssh_setting_auth_privkey_passphrase_clb, setup_f, teardown_f),
796 cmocka_unit_test_setup_teardown(test_nc_client_ssh_adding_keypair, setup_f, teardown_f),
797 cmocka_unit_test_setup_teardown(test_nc_client_ssh_setting_username, setup_f, teardown_f),
798 cmocka_unit_test_setup_teardown(test_nc_connect_ssh_interactive_succesfull, setup_f, teardown_f),
799 cmocka_unit_test_setup_teardown(test_nc_connect_ssh_password_succesfull, setup_f, teardown_f),
David Sedlák77acc202018-10-08 21:44:14 +0200800 cmocka_unit_test_setup_teardown(test_nc_connect_ssh_pubkey_succesfull, setup_f, teardown_f),
David Sedlákddde4492018-09-30 21:34:38 +0200801 cmocka_unit_test_setup_teardown(test_nc_connect_connection_failed, setup_f, teardown_f),
802 cmocka_unit_test_setup_teardown(test_nc_connect_ssh_bad_hello, setup_f, teardown_f),
Fred Gan3a736e02021-01-04 17:59:38 +0800803 cmocka_unit_test_setup_teardown(test_nc_client_ssh_ch_setting_username, setup_f, teardown_f),
804 cmocka_unit_test_setup_teardown(test_nc_client_ssh_ch_add_bind_listen, setup_f, teardown_f),
805 cmocka_unit_test_setup_teardown(test_nc_accept_callhome, setup_f, teardown_f),
806 cmocka_unit_test_setup_teardown(test_nc_client_ssh_callhome_successful, setup_f, teardown_f),
David Sedlákddde4492018-09-30 21:34:38 +0200807 };
808
809 return cmocka_run_group_tests(tests, NULL, NULL);
810}