blob: 0a66e597b78ab9f388f21e0eaed2193d219a3947 [file] [log] [blame]
Michal Vaskoba9f3582023-02-22 10:26:32 +01001/**
2 * @file test_client_ssh.c
3 * @author David Sedlák <xsedla1d@stud.fit.vutbr.cz>
4 * @brief client SSH test
5 *
6 * Copyright (c) 2018 CESNET, z.s.p.o.
7 *
8 * This source code is licensed under BSD 3-Clause License (the "License").
9 * You may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * https://opensource.org/licenses/BSD-3-Clause
13 */
14
15#define _GNU_SOURCE
16
Michal Vaskob83a3fa2021-05-26 09:53:42 +020017#include <errno.h>
18#include <setjmp.h>
David Sedlákddde4492018-09-30 21:34:38 +020019#include <stdio.h>
20#include <stdlib.h>
David Sedlákddde4492018-09-30 21:34:38 +020021#include <sys/socket.h>
Michal Vaskob83a3fa2021-05-26 09:53:42 +020022#include <sys/types.h>
David Sedlákddde4492018-09-30 21:34:38 +020023
24#include <cmocka.h>
Michal Vaskob83a3fa2021-05-26 09:53:42 +020025#include <config.h>
David Sedlákddde4492018-09-30 21:34:38 +020026#include <libyang/libyang.h>
Michal Vaskob83a3fa2021-05-26 09:53:42 +020027#include <log.h>
romane028ef92023-02-24 16:33:08 +010028#include <server_config.h>
David Sedlákddde4492018-09-30 21:34:38 +020029#include <session_client.h>
Fred Gan3a736e02021-01-04 17:59:38 +080030#include <session_client_ch.h>
31#include <session_p.h>
roman33ef8712023-02-17 10:25:12 +010032#include <session_server.h>
David Sedlákddde4492018-09-30 21:34:38 +020033#include "tests/config.h"
34
David Sedlákddde4492018-09-30 21:34:38 +020035#include <libssh/callbacks.h>
Michal Vaskob83a3fa2021-05-26 09:53:42 +020036#include <libssh/libssh.h>
David Sedlákddde4492018-09-30 21:34:38 +020037#include <libssh/server.h>
38
romanc1d2b092023-02-02 08:58:27 +010039const char *data =
40 "<netconf-server xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-server\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:operation=\"none\">\n"
41 " <listen yang:operation=\"create\">\n"
42 " <idle-timeout>10</idle-timeout>\n"
43 " <endpoint>\n"
44 " <name>default-ssh</name>\n"
45 " <ssh>\n"
46 " <tcp-server-parameters>\n"
47 " <local-address>127.0.0.1</local-address>\n"
48 " <local-port>10005</local-port>\n"
49 " </tcp-server-parameters>\n"
50 " <ssh-server-parameters>\n"
51 " <server-identity>\n"
52 " <host-key>\n"
53 " <name>key</name>\n"
54 " <public-key>\n"
55 " <local-definition>\n"
56 " <public-key-format xmlns:ct=\"urn:ietf:params:xml:ns:yang:ietf-crypto-types\">ct:ssh-public-key-format</public-key-format>\n"
57 " <public-key>MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA6ojtjfDmvyQP1ZkIwBpr97eKDuebvpoglRHRdvVuTpf/gU1VArAQmwGh05i6lm8TkVl1noMlIxLJDcWslaeVn6KyvsX0HhsQtXwqPqwka5UCv6alwf/ivAvcNpcX1j0t/uIGCI4dSiKnzQCyf0FTirzQkjrDZUd3meDhNQTruCalGV4gfNWIq3e1oGuwAn1tLlu9oTrE4HzMpgbNEU6wNmsSqpwGxUhYLoSaM7b0dLmqP+ZczSS0Uac0PFNkehGQ2CYIT80f580o4XGtoLCUUGkp6YCTL4Z2CeBEaJABWjDIDH+dKYIUBqUpz4Th12gXAP+h+3qI6+9eppeHrfrzARDsfLjwUNxQJse1QSArjAytf0FKtGHrORc7W0TiCFvR0zaoUNLTKk7enTiRQ9rfWZOAu44fUvPCaXDE6zXXeaVgoKCo4VHlho36erUcjlEBM+jk28IykbZGtBb6igKvYa1tPSgeYm/zJoFVjQcnr14uci/ft1+Na+hOIEoEEiKxcAPk2b2vBKNlRIW7WLJ3u7ZiuQEJTNm6+3cE4+lfwaBCBqBToE+dpzvoUXoMyFFReUFd1O5axu4fXgt00jMaOQxmE0v9OmR/pL/PWIflVF4Zz5yVONYaDVc7l+veY0oEZruEPJ0hlEgxuCzLrcMhjufl2qE2Q7fQIaav/1NqBVkCAwEAAQ==</public-key>\n"
58 " <private-key-format xmlns:ct=\"urn:ietf:params:xml:ns:yang:ietf-crypto-types\">ct:rsa-private-key-format</private-key-format>\n"
59 " <cleartext-private-key>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</cleartext-private-key>\n"
60 " </local-definition>\n"
61 " </public-key>\n"
62 " </host-key>\n"
63 " </server-identity>\n"
64 " <client-authentication>\n"
65 " <users>\n"
66 " <user>\n"
67 " <name>test</name>\n"
68 " <public-keys>\n"
69 " <local-definition>\n"
70 " <public-key>\n"
71 " <name>client</name>\n"
72 " <public-key-format xmlns:ct=\"urn:ietf:params:xml:ns:yang:ietf-crypto-types\">ct:ssh-public-key-format</public-key-format>\n"
73 " <public-key>AAAAB3NzaC1yc2EAAAADAQABAAABAQDPavVALiM7QwTIUAndO8E9GOkSDQWjuEwkzbJ3kOBPa7kkq71UOZFeecDjFb9eipkljfFys/JYHGQaYVF8/svT0KV5h7HlutRdF6yvqSEbjpbTORb27pdHX3iFEyDCwCIoq9vMeX+wyXnteyn01GpIL0ig0WAnvkqX/SPjuplX5ZItUSr0MhXM7fNSX50BD6G8IO0/djUcdMUcjTjGv73SxB9ZzLvxnhXuUJbzEJJJLj6qajyEIVaJSa73vA33JCD8qzarrsuITojVLPDFmeHwSAoB5dP86yop6e6ypuXzKxxef6yNXcE8oTj8UFYBIXsgIP2nBvWk41EaK0Vk3YFl</public-key>\n"
74 " </public-key>\n"
75 " </local-definition>\n"
76 " </public-keys>\n"
77 " </user>\n"
78 " </users>\n"
79 " </client-authentication>\n"
80 " <transport-params>\n"
81 " <host-key>\n"
82 " <host-key-alg xmlns:sshpka=\"urn:ietf:params:xml:ns:yang:iana-ssh-public-key-algs\">sshpka:rsa-sha2-512</host-key-alg>\n"
83 " </host-key>\n"
84 " <key-exchange>\n"
85 " <key-exchange-alg xmlns:sshkea=\"urn:ietf:params:xml:ns:yang:iana-ssh-key-exchange-algs\">sshkea:curve25519-sha256</key-exchange-alg>\n"
86 " </key-exchange>\n"
87 " <encryption>\n"
88 " <encryption-alg xmlns:sshea=\"urn:ietf:params:xml:ns:yang:iana-ssh-encryption-algs\">sshea:aes256-ctr</encryption-alg>\n"
89 " </encryption>\n"
90 " <mac>\n"
91 " <mac-alg xmlns:sshma=\"urn:ietf:params:xml:ns:yang:iana-ssh-mac-algs\">sshma:hmac-sha2-512</mac-alg>\n"
92 " </mac>\n"
93 " </transport-params>\n"
94 " </ssh-server-parameters>\n"
95 " </ssh>\n"
96 " </endpoint>\n"
97 " </listen>\n"
98 "</netconf-server>\n";
99
David Sedlákddde4492018-09-30 21:34:38 +0200100static int
David Sedlákddde4492018-09-30 21:34:38 +0200101setup_f(void **state)
102{
103 (void)state;
104 int ret;
105
106 nc_verbosity(NC_VERB_VERBOSE);
107
108 ret = nc_client_ssh_set_username("username");
109 assert_int_equal(ret, 0);
Fred Gan3a736e02021-01-04 17:59:38 +0800110 ret = nc_client_ssh_ch_set_username("ch_username");
111 assert_int_equal(ret, 0);
David Sedlákddde4492018-09-30 21:34:38 +0200112
113 return 0;
114}
115
116static int
117teardown_f(void **state)
118{
119 (void)state;
roman33ef8712023-02-17 10:25:12 +0100120 nc_client_destroy();
David Sedlákddde4492018-09-30 21:34:38 +0200121 return 0;
122}
123
124MOCK int
125__wrap_connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
126{
127 (void)sockfd;
128 (void)addr;
129 (void)addrlen;
130
131 return (int)mock();
132}
133
134MOCK int
135__wrap_ssh_connect(ssh_session session)
136{
137 (void)session;
138
139 /* set support of all authentication methods by fake server */
140 ssh_set_auth_methods(session, SSH_AUTH_METHOD_PUBLICKEY | SSH_AUTH_METHOD_PASSWORD | SSH_AUTH_METHOD_INTERACTIVE);
141 return (int)mock();
142}
143
144MOCK int
145__wrap_ssh_userauth_none(ssh_session session, const char *username)
146{
147 (void)session;
148 (void)username;
149
150 return (int)mock();
151}
152
153MOCK int
154__wrap_ssh_userauth_kbdint(ssh_session session, const char *user, const char *submethods)
155{
156 (void)session;
157 (void)user;
158 (void)submethods;
159
160 return (int)mock();
161}
162
163MOCK int
164__wrap_ssh_is_connected(ssh_session session)
165{
166 (void)session;
167
168 return (int)mock();
169}
170
171MOCK int
172__wrap_ssh_channel_open_session(ssh_channel channel)
173{
174 (void)channel;
175
176 return (int)mock();
177}
178
179MOCK int
180__wrap_ssh_channel_request_subsystem(ssh_channel channel, const char *subsystem)
181{
182 (void)channel;
183 (void)subsystem;
184
185 return (int)mock();
186}
187
188MOCK int
189__wrap_ssh_channel_is_closed(ssh_channel channel)
190{
191 (void)channel;
192
193 return 0;
194}
195
196MOCK int
197__wrap_ssh_channel_write(ssh_channel channel, const void *data, uint32_t len)
198{
199 (void)channel;
200 (void)data;
201
202 return len;
203}
204
205MOCK int
206__wrap_ssh_channel_poll_timeout(ssh_channel channel, int timeout, int is_stderr)
207{
208 (void)channel;
209 (void)timeout;
210 (void)is_stderr;
211
212 return (int)mock();
213}
214
215MOCK int
216__wrap_ssh_userauth_password(ssh_session session, const char *username, const char *password)
217{
218 (void)session;
219 check_expected(password);
220 check_expected(username);
221
David Sedlákddde4492018-09-30 21:34:38 +0200222 return (int)mock();
223}
224
225MOCK int
226__wrap_nc_handshake_io(struct nc_session *session)
227{
228 (void)session;
229
230 return (int)mock();
231}
232
233MOCK int
234__wrap_nc_ctx_check_and_fill(struct nc_session *session)
235{
236 (void)session;
237
238 return (int)mock();
239}
240
David Sedlák77acc202018-10-08 21:44:14 +0200241MOCK int
242__wrap_ssh_userauth_try_publickey(ssh_session session, const char *username, const ssh_key pubkey)
243{
244 (void)session;
245 (void)username;
246 (void)pubkey;
247
248 return (int)mock();
249}
250
251MOCK int
252__wrap_ssh_userauth_publickey(ssh_session session, const char *username, const ssh_key privkey)
253{
254 (void)session;
255 (void)username;
256 (void)privkey;
257
258 return (int)mock();
259}
260
Fred Gan3a736e02021-01-04 17:59:38 +0800261MOCK int
262__wrap_nc_sock_listen_inet(const char *address, uint16_t port, struct nc_keepalives *ka)
263{
264 (void)address;
265 (void)port;
266 (void)ka;
267
268 return (int)mock();
269}
270
271MOCK int
272__wrap_nc_sock_accept_binds(struct nc_bind *binds, uint16_t bind_count, int timeout, char **host, uint16_t *port, uint16_t *idx)
273{
274 (void)binds;
275 (void)bind_count;
276 (void)timeout;
277 (void)host;
278 (void)port;
279
280 *idx = 0;
281 return (int)mock();
282}
283
284MOCK struct nc_session *
285__wrap_nc_accept_callhome_ssh_sock(int sock, const char *host, uint16_t port, struct ly_ctx *ctx, int timeout)
286{
287 (void)sock;
288 (void)host;
289 (void)port;
290 (void)ctx;
291 (void)timeout;
292
293 return mock_ptr_type(struct nc_session *);
294}
295
David Sedlákddde4492018-09-30 21:34:38 +0200296static void
297test_nc_client_ssh_setting_auth_hostkey_check_clb(void **state)
298{
299 (void)state;
roman472420c2023-04-24 16:28:09 +0200300 // int (*ret_f)(const char *hostname, ssh_session session, void *priv);
301 // char *priv_data_ret;
David Sedlákddde4492018-09-30 21:34:38 +0200302
roman472420c2023-04-24 16:28:09 +0200303 /// * ssh_hostkey_check_clb is set in setup_f */
304 // nc_client_ssh_get_auth_hostkey_check_clb(&ret_f, (void **)&priv_data_ret);
305 // assert_ptr_equal(ret_f, ssh_hostkey_check_clb);
306 // assert_null(priv_data_ret);
David Sedlákddde4492018-09-30 21:34:38 +0200307
roman472420c2023-04-24 16:28:09 +0200308 /// * set different callback and private data */
309 // nc_client_ssh_set_auth_hostkey_check_clb(test_hostkey_clb, "DATA");
310 // nc_client_ssh_get_auth_hostkey_check_clb(&ret_f, (void **)&priv_data_ret);
311 // assert_ptr_equal(ret_f, test_hostkey_clb);
312 // assert_string_equal(priv_data_ret, "DATA");
David Sedlákddde4492018-09-30 21:34:38 +0200313}
314
315char *
316test_pwd_clb1(const char *username, const char *hostname, void *priv)
317{
318 char *pass, *pass_to_return;
319
320 check_expected(username);
321 check_expected(hostname);
322 check_expected(priv);
323
324 pass = (char *)mock();
325 pass_to_return = malloc(sizeof *pass * (strlen(pass) + 1));
326 strcpy(pass_to_return, pass);
327
328 return pass_to_return;
329}
330
331char *
332test_pwd_clb2(const char *username, const char *hostname, void *priv)
333{
334 (void)username;
335 (void)hostname;
336 (void)priv;
337
338 return 0;
339}
340
341static void
342test_nc_client_ssh_setting_auth_password_clb(void **state)
343{
344 (void)state;
345 char *(*ret_f)(const char *username, const char *hostname, void *priv);
346 char *priv_data_ret;
347
348 /* set callback */
349 nc_client_ssh_set_auth_password_clb(test_pwd_clb1, "DATA");
350 nc_client_ssh_get_auth_password_clb(&ret_f, (void **)&priv_data_ret);
351 assert_ptr_equal(test_pwd_clb1, ret_f);
352 assert_string_equal("DATA", priv_data_ret);
353
354 /* set different callback */
355 nc_client_ssh_set_auth_password_clb(test_pwd_clb2, "NEW DATA");
356 nc_client_ssh_get_auth_password_clb(&ret_f, (void **)&priv_data_ret);
357 assert_ptr_equal(test_pwd_clb2, ret_f);
358 assert_string_equal("NEW DATA", priv_data_ret);
359}
360
361char *
362test_inter_clb1(const char *auth_name, const char *instruction, const char *prompt, int echo, void *priv)
363{
364 (void)auth_name;
365 (void)instruction;
366 (void)prompt;
367 (void)echo;
368 (void)priv;
369
370 return 0;
371}
372
373char *
374test_inter_clb2(const char *auth_name, const char *instruction, const char *prompt, int echo, void *priv)
375{
376 (void)auth_name;
377 (void)instruction;
378 (void)prompt;
379 (void)echo;
380 (void)priv;
381
382 return 0;
383}
384
385static void
386test_nc_client_ssh_setting_auth_interactive_clb(void **state)
387{
388 (void)state;
389 char *(*ret_f)(const char *auth_name, const char *instruction, const char *prompt, int echo, void *priv);
390 char *priv_data_ret;
391
392 /* set callback */
393 nc_client_ssh_set_auth_interactive_clb(test_inter_clb1, "DATA");
394 nc_client_ssh_get_auth_interactive_clb(&ret_f, (void **)&priv_data_ret);
395 assert_ptr_equal(test_inter_clb1, ret_f);
396 assert_string_equal("DATA", priv_data_ret);
397
398 /* set diferent callback */
399 nc_client_ssh_set_auth_interactive_clb(test_inter_clb2, "NEW DATA");
400 nc_client_ssh_get_auth_interactive_clb(&ret_f, (void **)&priv_data_ret);
401 assert_ptr_equal(test_inter_clb2, ret_f);
402 assert_string_equal("NEW DATA", priv_data_ret);
403}
404
405char *
406test_passphrase_clb1(const char *privkey_path, void *priv)
407{
408 (void)privkey_path;
409 (void)priv;
410
411 return 0;
412}
413
414char *
415test_passphrase_clb2(const char *privkey_path, void *priv)
416{
417 (void)privkey_path;
418 (void)priv;
419
420 return 0;
421}
422
423static void
424test_nc_client_ssh_setting_auth_privkey_passphrase_clb(void **state)
425{
426 (void)state;
427 char *(*ret_f)(const char *privkey_path, void *priv);
428 char *priv_data_ret;
Michal Vaskob83a3fa2021-05-26 09:53:42 +0200429
David Sedlákddde4492018-09-30 21:34:38 +0200430 /* set first callback */
431 nc_client_ssh_set_auth_privkey_passphrase_clb(test_passphrase_clb1, "DATA");
432 nc_client_ssh_get_auth_privkey_passphrase_clb(&ret_f, (void **)&priv_data_ret);
433 assert_ptr_equal(ret_f, test_passphrase_clb1);
434 assert_string_equal("DATA", priv_data_ret);
435
436 /* set different callback */
437 nc_client_ssh_set_auth_privkey_passphrase_clb(test_passphrase_clb2, "NEW DATA");
438 nc_client_ssh_get_auth_privkey_passphrase_clb(&ret_f, (void **)&priv_data_ret);
439 assert_ptr_equal(ret_f, test_passphrase_clb2);
440 assert_string_equal("NEW DATA", priv_data_ret);
441}
442
443static void
444test_nc_client_ssh_adding_keypair(void **state)
445{
446 (void)state;
447 int ret;
448 const char *pubkey1, *pubkey2;
Michal Vaskob83a3fa2021-05-26 09:53:42 +0200449
David Sedlákddde4492018-09-30 21:34:38 +0200450 /* at the beginning keypair count should be 0 */
451 ret = nc_client_ssh_get_keypair_count();
452 assert_int_equal(ret, 0);
453
454 /* add first key pair */
Michal Vasko7a4213f2022-09-08 11:02:34 +0200455 ret = nc_client_ssh_add_keypair(TESTS_DIR "/data/key_ecdsa.pub", TESTS_DIR "/data/key_ecdsa");
David Sedlákddde4492018-09-30 21:34:38 +0200456 assert_int_equal(ret, 0);
457 ret = nc_client_ssh_get_keypair_count();
458 assert_int_equal(ret, 1);
459
460 /* add second keypair */
461 ret = nc_client_ssh_add_keypair("key_pub", "key_priv");
462 assert_int_equal(ret, 0);
463 ret = nc_client_ssh_get_keypair_count();
464 assert_int_equal(ret, 2);
465 ret = nc_client_ssh_get_keypair(1, &pubkey1, &pubkey2);
466 assert_int_equal(ret, 0);
467 assert_string_equal(pubkey1, "key_pub");
468 assert_string_equal(pubkey2, "key_priv");
469
470 /* delete first keypair */
471 ret = nc_client_ssh_del_keypair(0);
472 assert_int_equal(ret, 0);
473 ret = nc_client_ssh_get_keypair_count();
474 assert_int_equal(ret, 1);
475 /* try to get deleted keypair */
476 ret = nc_client_ssh_get_keypair(5, &pubkey1, &pubkey2);
477 assert_int_equal(ret, -1);
478
479 /* try to add keypair that is already set */
480 ret = nc_client_ssh_add_keypair("key_pub", "key_priv");
481 assert_int_equal(ret, -1);
482 ret = nc_client_ssh_get_keypair_count();
483 assert_int_equal(ret, 1);
484
485 /* try to delete keypair with id that is not used */
486 ret = nc_client_ssh_del_keypair(42);
487 assert_int_equal(ret, -1);
488 ret = nc_client_ssh_get_keypair_count();
489 assert_int_equal(ret, 1);
490
491 /* remove remaining keypairs */
492 ret = nc_client_ssh_del_keypair(0);
493 assert_int_equal(ret, 0);
494 ret = nc_client_ssh_get_keypair_count();
495 assert_int_equal(ret, 0);
496}
497
498static void
499test_nc_client_ssh_setting_auth_pref(void **state)
500{
501 (void)state;
502 int ret;
503
David Sedlákaae4df32018-10-08 22:27:22 +0200504 /* initiate client, must be called in first test */
David Sedlákddde4492018-09-30 21:34:38 +0200505 nc_client_init();
506
507 /* check default prefference settings according to documentation */
508 ret = nc_client_ssh_get_auth_pref(NC_SSH_AUTH_INTERACTIVE);
roman41a11e42022-06-22 09:27:08 +0200509 assert_int_equal(ret, 1);
David Sedlákddde4492018-09-30 21:34:38 +0200510 ret = nc_client_ssh_get_auth_pref(NC_SSH_AUTH_PASSWORD);
511 assert_int_equal(ret, 2);
512 ret = nc_client_ssh_get_auth_pref(NC_SSH_AUTH_PUBLICKEY);
roman41a11e42022-06-22 09:27:08 +0200513 assert_int_equal(ret, 3);
David Sedlákddde4492018-09-30 21:34:38 +0200514
515 /* try to set prefetence of non existing method */
516 nc_client_ssh_set_auth_pref(42, 22);
517
518 /* try to get preference of non existing method */
519 ret = nc_client_ssh_get_auth_pref(42);
520 assert_int_equal(ret, 0);
521
522 /* change values of all methods and check if they actually changed */
523 nc_client_ssh_set_auth_pref(NC_SSH_AUTH_INTERACTIVE, 9);
524 ret = nc_client_ssh_get_auth_pref(NC_SSH_AUTH_INTERACTIVE);
525 assert_int_equal(ret, 9);
526
527 /* negative value should be set as -1 */
528 nc_client_ssh_set_auth_pref(NC_SSH_AUTH_PASSWORD, -5);
529 ret = nc_client_ssh_get_auth_pref(NC_SSH_AUTH_PASSWORD);
530 assert_int_equal(ret, -1);
531
532 nc_client_ssh_set_auth_pref(NC_SSH_AUTH_PUBLICKEY, 11);
533 ret = nc_client_ssh_get_auth_pref(NC_SSH_AUTH_PUBLICKEY);
534 assert_int_equal(ret, 11);
535}
536
537static void
538test_nc_client_ssh_setting_username(void **state)
539{
540 (void)state;
541 int ret;
542 const char *username_ret;
Michal Vaskob83a3fa2021-05-26 09:53:42 +0200543
David Sedlákddde4492018-09-30 21:34:38 +0200544 username_ret = nc_client_ssh_get_username();
545 /* username is set to "username" in setup_f */
546 assert_string_equal(username_ret, "username");
547
548 /* set new username and check if it changes */
549 ret = nc_client_ssh_set_username("new_username");
550 assert_int_equal(ret, 0);
551 username_ret = nc_client_ssh_get_username();
552 assert_string_equal(username_ret, "new_username");
553}
554
555static void
556test_nc_connect_ssh_interactive_succesfull(void **state)
557{
558 (void)state;
559 struct nc_session *session;
560
561 /* set authentication method to use interactive authentication */
562 nc_client_ssh_set_auth_pref(NC_SSH_AUTH_INTERACTIVE, 1);
563 nc_client_ssh_set_auth_pref(NC_SSH_AUTH_PASSWORD, -1);
564 nc_client_ssh_set_auth_pref(NC_SSH_AUTH_PUBLICKEY, -1);
565
566 nc_client_ssh_set_auth_pref(NC_SSH_AUTH_INTERACTIVE, 20);
567
568 /* prepare return values for functions used by nc_connect_ssh */
569 will_return(__wrap_connect, 0);
570 will_return(__wrap_ssh_connect, 0);
571 will_return(__wrap_ssh_userauth_none, 1);
572
573 will_return(__wrap_ssh_userauth_kbdint, 0);
574 will_return(__wrap_ssh_is_connected, 1);
575 will_return(__wrap_ssh_is_connected, 1);
576
577 will_return(__wrap_ssh_channel_open_session, 0);
578 will_return(__wrap_ssh_channel_request_subsystem, 0);
579
580 will_return(__wrap_nc_handshake_io, 3);
581 will_return(__wrap_nc_ctx_check_and_fill, 0);
582
583 session = nc_connect_ssh("127.0.0.1", 8080, NULL);
584 assert_non_null(session);
585
Michal Vasko0ab3a662021-07-26 12:17:41 +0200586 will_return(__wrap_ssh_channel_poll_timeout, 0);
David Sedlákddde4492018-09-30 21:34:38 +0200587 nc_session_free(session, NULL);
588}
589
590static void
591test_nc_connect_ssh_password_succesfull(void **state)
592{
593 (void)state;
594 struct nc_session *session;
595
596 /* set authentication method to use password authentication */
597 nc_client_ssh_set_auth_pref(NC_SSH_AUTH_PASSWORD, 1);
598 nc_client_ssh_set_auth_pref(NC_SSH_AUTH_PUBLICKEY, -1);
599 nc_client_ssh_set_auth_pref(NC_SSH_AUTH_INTERACTIVE, -1);
600
601 /* set authentication callback */
602 nc_client_ssh_set_auth_password_clb(test_pwd_clb1, "private_data");
603 will_return(test_pwd_clb1, "secret password");
604 /* set values that are expected as parameters for authentication callback */
605 expect_string(test_pwd_clb1, username, "username");
606 expect_string(test_pwd_clb1, hostname, "127.0.0.1");
607 expect_string(test_pwd_clb1, priv, "private_data");
608
609 /* fake succesfull connection */
610 will_return(__wrap_connect, 0);
611 will_return(__wrap_ssh_connect, 0);
612 /* do not authenticate using no authentication method */
613 will_return(__wrap_ssh_userauth_none, 1);
614
615 /* succesfully authenticate via password authentication */
616 expect_string(__wrap_ssh_userauth_password, password, "secret password");
617 expect_string(__wrap_ssh_userauth_password, username, "username");
618 will_return(__wrap_ssh_userauth_password, 0);
619
620 /* fake ssh functions that are used to open netconf channel */
621 will_return(__wrap_ssh_channel_open_session, 0);
622 will_return(__wrap_ssh_channel_request_subsystem, 0);
623
624 /* fake that connection is still alive*/
625 will_return(__wrap_ssh_is_connected, 1);
626
627 /* fake ssh function for recieving hello message */
628 will_return(__wrap_ssh_is_connected, 1);
629
630 will_return(__wrap_nc_handshake_io, 3);
631 will_return(__wrap_nc_ctx_check_and_fill, 0);
632
633 session = nc_connect_ssh("127.0.0.1", 8080, NULL);
634 assert_non_null(session);
635
636 /* disconnect */
Michal Vasko0ab3a662021-07-26 12:17:41 +0200637 will_return(__wrap_ssh_channel_poll_timeout, 0);
David Sedlákddde4492018-09-30 21:34:38 +0200638 nc_session_free(session, NULL);
639}
640
641static void
romanc1d2b092023-02-02 08:58:27 +0100642test_nc_connect_ssh_pubkey_ecdsa_succesfull(void **state)
David Sedlák77acc202018-10-08 21:44:14 +0200643{
644 (void)state;
645 struct nc_session *session;
646 int ret = 0;
647
648 /* set authentication method to use password authentication */
649 nc_client_ssh_set_auth_pref(NC_SSH_AUTH_PASSWORD, -1);
650 nc_client_ssh_set_auth_pref(NC_SSH_AUTH_PUBLICKEY, 1);
651 nc_client_ssh_set_auth_pref(NC_SSH_AUTH_INTERACTIVE, -1);
652
653 /* add keypair for authentication */
Michal Vasko7a4213f2022-09-08 11:02:34 +0200654 ret = nc_client_ssh_add_keypair(TESTS_DIR "/data/key_ecdsa.pub", TESTS_DIR "/data/key_ecdsa");
David Sedlák77acc202018-10-08 21:44:14 +0200655 assert_int_equal(ret, 0);
656
657 /* fake succesfull connection */
658 will_return(__wrap_connect, 0);
659 will_return(__wrap_ssh_connect, 0);
660 /* do not authenticate using no authentication method */
661 will_return(__wrap_ssh_userauth_none, 1);
662 will_return(__wrap_ssh_userauth_try_publickey, 0);
663 will_return(__wrap_ssh_userauth_publickey, 0);
664 will_return(__wrap_ssh_is_connected, 1);
665 will_return(__wrap_ssh_channel_open_session, 0);
666 will_return(__wrap_ssh_channel_request_subsystem, 0);
667
668 /* fake ssh function for recieving hello message */
669 will_return(__wrap_ssh_is_connected, 1);
670
671 will_return(__wrap_nc_handshake_io, 3);
672 will_return(__wrap_nc_ctx_check_and_fill, 0);
673 session = nc_connect_ssh("127.0.0.1", 8080, NULL);
674 assert_non_null(session);
675
676 /* disconnect */
Michal Vasko0ab3a662021-07-26 12:17:41 +0200677 will_return(__wrap_ssh_channel_poll_timeout, 0);
David Sedlák77acc202018-10-08 21:44:14 +0200678 nc_session_free(session, NULL);
romanc1d2b092023-02-02 08:58:27 +0100679
680 /* delete the keypair */
681 ret = nc_client_ssh_del_keypair(0);
682 assert_int_equal(ret, 0);
683}
684
685static void
686test_nc_connect_ssh_pubkey_succesfull(void **state)
687{
688 (void)state;
689 struct nc_session *session;
690 struct ly_ctx *ctx;
691 struct lyd_node *tree;
692 int ret = 0;
693
694 /* set authentication method to use password authentication */
695 nc_client_ssh_set_auth_pref(NC_SSH_AUTH_PASSWORD, -1);
696 nc_client_ssh_set_auth_pref(NC_SSH_AUTH_PUBLICKEY, 1);
697 nc_client_ssh_set_auth_pref(NC_SSH_AUTH_INTERACTIVE, -1);
698
699 /* add keypair for authentication */
700 ret = nc_client_ssh_add_keypair(TESTS_DIR "/data/key_rsa.pub", TESTS_DIR "/data/key_rsa");
701 assert_int_equal(ret, 0);
702
703 /* fake succesfull connection */
704 will_return(__wrap_connect, 0);
705 will_return(__wrap_ssh_connect, 0);
roman33ef8712023-02-17 10:25:12 +0100706 will_return(__wrap_nc_sock_listen_inet, 0);
romanc1d2b092023-02-02 08:58:27 +0100707 /* do not authenticate using no authentication method */
708 will_return(__wrap_ssh_userauth_none, 1);
709 will_return(__wrap_ssh_userauth_try_publickey, 0);
710 will_return(__wrap_ssh_userauth_publickey, 0);
711 will_return(__wrap_ssh_is_connected, 1);
712 will_return(__wrap_ssh_channel_open_session, 0);
713 will_return(__wrap_ssh_channel_request_subsystem, 0);
714
715 /* fake ssh function for recieving hello message */
716 will_return(__wrap_ssh_is_connected, 1);
717
718 will_return(__wrap_nc_handshake_io, 3);
719 will_return(__wrap_nc_ctx_check_and_fill, 0);
720
721 ret = ly_ctx_new(MODULES_DIR, 0, &ctx);
722 assert_int_equal(ret, 0);
723
724 ret = nc_server_config_load_modules(&ctx);
725 assert_int_equal(ret, 0);
726
727 ret = lyd_parse_data_mem(ctx, data, LYD_XML, LYD_PARSE_NO_STATE | LYD_PARSE_STRICT, LYD_VALIDATE_NO_STATE, &tree);
728 assert_int_equal(ret, 0);
729
730 ret = nc_server_config_setup(tree);
731 assert_int_equal(ret, 0);
732
733 session = nc_connect_ssh("127.0.0.1", 8080, NULL);
734 assert_non_null(session);
735
736 /* disconnect */
737 will_return(__wrap_ssh_channel_poll_timeout, 0);
roman33ef8712023-02-17 10:25:12 +0100738
739 /* free everything used */
romanc1d2b092023-02-02 08:58:27 +0100740 nc_session_free(session, NULL);
roman33ef8712023-02-17 10:25:12 +0100741 lyd_free_all(tree);
742 nc_server_destroy();
743 ly_ctx_destroy(ctx);
David Sedlák77acc202018-10-08 21:44:14 +0200744}
745
746static void
David Sedlákddde4492018-09-30 21:34:38 +0200747test_nc_connect_connection_failed(void **state)
748{
749 (void)state;
750 struct nc_session *session;
751
752 errno = ECONNREFUSED;
753 will_return(__wrap_connect, -1);
754 will_return(__wrap_ssh_is_connected, 0);
755
756 session = nc_connect_ssh("127.0.0.1", 8080, NULL);
757 assert_null(session);
758}
759
760static void
761test_nc_connect_ssh_bad_hello(void **state)
762{
763 (void)state;
764 struct nc_session *session;
765
766 /* set authentication method to use interactive authentication */
767 nc_client_ssh_set_auth_pref(NC_SSH_AUTH_INTERACTIVE, 1);
768 nc_client_ssh_set_auth_pref(NC_SSH_AUTH_PASSWORD, -1);
769 nc_client_ssh_set_auth_pref(NC_SSH_AUTH_PUBLICKEY, 1);
770
771 nc_client_ssh_set_auth_password_clb(test_pwd_clb2, NULL);
772
773 will_return(__wrap_connect, 0);
774 will_return(__wrap_ssh_connect, 0);
775 will_return(__wrap_ssh_userauth_none, 1);
776
777 will_return(__wrap_ssh_userauth_kbdint, 0);
778 will_return(__wrap_ssh_is_connected, 1);
779 will_return(__wrap_ssh_is_connected, 1);
780
781 will_return(__wrap_ssh_channel_open_session, 0);
782 will_return(__wrap_ssh_channel_request_subsystem, 0);
783 will_return(__wrap_nc_handshake_io, 4);
784
785 session = nc_connect_ssh("127.0.0.1", 8080, NULL);
786 assert_null(session);
787
David Sedlákaae4df32018-10-08 22:27:22 +0200788 /* destroy client, must be called in last test */
David Sedlákddde4492018-09-30 21:34:38 +0200789 nc_client_destroy();
790}
791
Fred Gan3a736e02021-01-04 17:59:38 +0800792static void
793test_nc_client_ssh_ch_setting_username(void **state)
794{
795 (void)state;
796 const char *username_ret;
797 int ret;
798
799 /* username is set to "ch_username" in setup_f */
800 username_ret = nc_client_ssh_ch_get_username();
801 assert_string_equal(username_ret, "ch_username");
802 /* set new username and check if it changes */
803 ret = nc_client_ssh_ch_set_username("new_ch_username");
804 assert_int_equal(ret, 0);
805 username_ret = nc_client_ssh_ch_get_username();
806 assert_string_equal(username_ret, "new_ch_username");
807}
808
809static void
810test_nc_client_ssh_ch_add_bind_listen(void **state)
811{
812 (void)state;
813 int ret;
814
815 /* invalid parameters, address NULL or port 0 */
816 ret = nc_client_ssh_ch_add_bind_listen(NULL, 4334);
817 assert_int_equal(ret, -1);
818 ret = nc_client_ssh_ch_add_bind_listen("127.0.0.1", 0);
819 assert_int_equal(ret, -1);
820
821 /* failed to create an ssh listening socket */
822 will_return(__wrap_nc_sock_listen_inet, -1);
823 ret = nc_client_ssh_ch_add_bind_listen("127.0.0.1", 4334);
824 assert_int_equal(ret, -1);
825
826 /* fake a successful CH ssh listening socket */
827 will_return(__wrap_nc_sock_listen_inet, 1);
828 ret = nc_client_ssh_ch_add_bind_listen("127.0.0.1", 4334);
829 assert_int_equal(ret, 0);
830
831 /* remove ssh listening client binds */
832 ret = nc_client_ssh_ch_del_bind("127.0.0.1", 4334);
833 assert_int_equal(ret, 0);
834}
835
836static void
837test_nc_accept_callhome(void **state)
838{
839 (void)state;
840 struct nc_session *session = NULL;
841 int timeout = 10;
842 int ret;
843
844 /* invalid parameter session */
845 ret = nc_accept_callhome(timeout, NULL, NULL);
846 assert_int_equal(ret, -1);
847
848 /* no client bind */
849 ret = nc_accept_callhome(timeout, NULL, &session);
850 assert_int_equal(ret, -1);
851
852 /* successfully add a client Call Home bind */
853 will_return(__wrap_nc_sock_listen_inet, 1);
854 ret = nc_client_ssh_ch_add_bind_listen("127.0.0.1", 4334);
855 assert_int_equal(ret, 0);
856
857 /* failed to accept a client bind */
858 will_return(__wrap_nc_sock_accept_binds, -1);
859 ret = nc_accept_callhome(timeout, NULL, &session);
860 assert_int_equal(ret, -1);
861
862 /* failed to accept a server Call Home connection */
863 will_return(__wrap_nc_accept_callhome_ssh_sock, NULL);
864 will_return(__wrap_nc_sock_accept_binds, 2);
865 ret = nc_accept_callhome(timeout, NULL, &session);
866 assert_int_equal(ret, -1);
867
868 /* create session structure to fake a successful server call home connection */
869 session = nc_new_session(NC_CLIENT, 0);
870 assert_non_null(session);
871 will_return(__wrap_nc_sock_accept_binds, 2);
872 will_return(__wrap_nc_accept_callhome_ssh_sock, session);
873 ret = nc_accept_callhome(timeout, NULL, &session);
874 assert_int_equal(ret, 1);
875
876 /* remove ssh listening client binds */
877 ret = nc_client_ssh_ch_del_bind("127.0.0.1", 4334);
878 assert_int_equal(ret, 0);
879
880 /* free session */
881 nc_session_free(session, NULL);
882}
883
884static void
885test_nc_client_ssh_callhome_successful(void **state)
886{
887 (void)state;
888 struct nc_session *session = NULL;
889 int timeout = 10;
890 int ret;
891
892 /* create session structure */
893 session = nc_new_session(NC_CLIENT, 0);
894 assert_non_null(session);
895
896 /* prepare to fake return values for functions used by nc_accept_callhome */
897 will_return(__wrap_nc_sock_listen_inet, 1);
898 will_return(__wrap_nc_sock_accept_binds, 2);
899 will_return(__wrap_nc_accept_callhome_ssh_sock, session);
900
901 ret = nc_client_ssh_ch_add_bind_listen("127.0.0.1", 4334);
902 assert_int_equal(ret, 0);
903 ret = nc_accept_callhome(timeout, NULL, &session);
904 assert_int_equal(ret, 1);
905
906 /* remove ssh listening client binds */
907 ret = nc_client_ssh_ch_del_bind("127.0.0.1", 4334);
908 assert_int_equal(ret, 0);
909
910 /* free session */
911 nc_session_free(session, NULL);
912}
913
David Sedlákddde4492018-09-30 21:34:38 +0200914int
915main(void)
916{
917 const struct CMUnitTest tests[] = {
918 cmocka_unit_test_setup_teardown(test_nc_client_ssh_setting_auth_pref, setup_f, teardown_f),
919 cmocka_unit_test_setup_teardown(test_nc_client_ssh_setting_auth_hostkey_check_clb, setup_f, teardown_f),
920 cmocka_unit_test_setup_teardown(test_nc_client_ssh_setting_auth_password_clb, setup_f, teardown_f),
921 cmocka_unit_test_setup_teardown(test_nc_client_ssh_setting_auth_interactive_clb, setup_f, teardown_f),
922 cmocka_unit_test_setup_teardown(test_nc_client_ssh_setting_auth_privkey_passphrase_clb, setup_f, teardown_f),
923 cmocka_unit_test_setup_teardown(test_nc_client_ssh_adding_keypair, setup_f, teardown_f),
924 cmocka_unit_test_setup_teardown(test_nc_client_ssh_setting_username, setup_f, teardown_f),
925 cmocka_unit_test_setup_teardown(test_nc_connect_ssh_interactive_succesfull, setup_f, teardown_f),
926 cmocka_unit_test_setup_teardown(test_nc_connect_ssh_password_succesfull, setup_f, teardown_f),
romanc1d2b092023-02-02 08:58:27 +0100927 cmocka_unit_test_setup_teardown(test_nc_connect_ssh_pubkey_ecdsa_succesfull, setup_f, teardown_f),
David Sedlák77acc202018-10-08 21:44:14 +0200928 cmocka_unit_test_setup_teardown(test_nc_connect_ssh_pubkey_succesfull, setup_f, teardown_f),
David Sedlákddde4492018-09-30 21:34:38 +0200929 cmocka_unit_test_setup_teardown(test_nc_connect_connection_failed, setup_f, teardown_f),
930 cmocka_unit_test_setup_teardown(test_nc_connect_ssh_bad_hello, setup_f, teardown_f),
Fred Gan3a736e02021-01-04 17:59:38 +0800931 cmocka_unit_test_setup_teardown(test_nc_client_ssh_ch_setting_username, setup_f, teardown_f),
932 cmocka_unit_test_setup_teardown(test_nc_client_ssh_ch_add_bind_listen, setup_f, teardown_f),
933 cmocka_unit_test_setup_teardown(test_nc_accept_callhome, setup_f, teardown_f),
934 cmocka_unit_test_setup_teardown(test_nc_client_ssh_callhome_successful, setup_f, teardown_f),
David Sedlákddde4492018-09-30 21:34:38 +0200935 };
936
937 return cmocka_run_group_tests(tests, NULL, NULL);
938}