aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog10
-rw-r--r--README2
-rw-r--r--README.md2
-rw-r--r--include/libssh/options.h1
-rw-r--r--include/libssh/priv.h4
-rw-r--r--src/client.c143
-rw-r--r--src/config.c54
-rw-r--r--src/kex.c76
-rw-r--r--src/misc.c23
-rw-r--r--src/pki_gcrypt.c5
-rw-r--r--tests/client/torture_algorithms.c57
-rw-r--r--tests/pkd/pkd_daemon.c33
-rw-r--r--tests/pkd/pkd_hello.c65
-rw-r--r--tests/server/CMakeLists.txt1
-rw-r--r--tests/server/torture_server_algorithms.c364
-rw-r--r--tests/torture.c20
-rw-r--r--tests/unittests/torture_config.c1238
17 files changed, 1510 insertions, 588 deletions
diff --git a/ChangeLog b/ChangeLog
index 91c3d0e5..8bc15d9a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -362,14 +362,6 @@ version 0.3.1 (released 2009-07-14)
* Fixed a possible crash bug.
* Fixed build warnings.
* Fixed cmake on BSD.
-version 0.3.1 (released 2009-07-14)
- * Added return code SSH_SERVER_FILE_NOT_FOUND.
- * Fixed compilation of SSHv1.
- * Fixed several memory leaks.
- * Fixed possible infinite loops.
- * Fixed a possible crash bug.
- * Fixed build warnings.
- * Fixed cmake on BSD.
version 0.3 (released 2009-05-21)
* Added support for ssh-agent authentication.
@@ -411,7 +403,7 @@ version 0.2 (released 2007-11-29)
version 0.11-dev
* Server implementation development.
* Small bug corrected when connecting to sun ssh servers.
- * Channel wierdness corrected (writing huge data packets)
+ * Channel weirdness corrected (writing huge data packets)
* Channel_read_nonblocking added
* Channel bug where stderr wasn't correctly read fixed.
* Added sftp_file_set_nonblocking(), which is nonblocking SFTP IO
diff --git a/README b/README
index 44100e7c..09a7e569 100644
--- a/README
+++ b/README
@@ -36,7 +36,7 @@ https://www.libssh.org
4* Contributing
-_-_-_-_-_-_-_-_-_
-Please read the file 'SubmittingPatches' next to this README file. It explains
+Please read the file 'CONTRIBUTING.md' next to this README file. It explains
our copyright policy and how you should send patches for upstream inclusion.
Have fun and happy libssh hacking!
diff --git a/README.md b/README.md
index 511ab748..cd6b9eaa 100644
--- a/README.md
+++ b/README.md
@@ -37,7 +37,7 @@ https://www.libssh.org
# Contributing
-Please read the file 'SubmittingPatches' next to this README file. It explains
+Please read the file 'CONTRIBUTING.md' next to this README file. It explains
our copyright policy and how you should send patches for upstream inclusion.
Have fun and happy libssh hacking!
diff --git a/include/libssh/options.h b/include/libssh/options.h
index 5b1cb9f0..e8dc6c69 100644
--- a/include/libssh/options.h
+++ b/include/libssh/options.h
@@ -22,6 +22,7 @@
#define _OPTIONS_H
int ssh_config_parse_file(ssh_session session, const char *filename);
+int ssh_config_parse_string(ssh_session session, const char *input);
int ssh_options_set_algo(ssh_session session,
enum ssh_kex_types_e algo,
const char *list);
diff --git a/include/libssh/priv.h b/include/libssh/priv.h
index 3cf2004e..b18ece4c 100644
--- a/include/libssh/priv.h
+++ b/include/libssh/priv.h
@@ -167,7 +167,7 @@ int gettimeofday(struct timeval *__p, void *__t);
#include "libssh/callbacks.h"
/* some constants */
-#ifndef MAX_PACKAT_LEN
+#ifndef MAX_PACKET_LEN
#define MAX_PACKET_LEN 262144
#endif
#ifndef ERROR_BUFFERLEN
@@ -341,7 +341,7 @@ void explicit_bzero(void *s, size_t n);
#define discard_const_p(type, ptr) ((type *)discard_const(ptr))
/**
- * Get the argument cound of variadic arguments
+ * Get the argument count of variadic arguments
*/
/*
* Since MSVC 2010 there is a bug in passing __VA_ARGS__ to subsequent
diff --git a/src/client.c b/src/client.c
index 4610b787..3984b3f4 100644
--- a/src/client.c
+++ b/src/client.c
@@ -689,84 +689,89 @@ int ssh_get_openssh_version(ssh_session session) {
*
* @param[in] session The SSH session to use.
*/
-void ssh_disconnect(ssh_session session) {
- struct ssh_iterator *it;
- int rc;
+void
+ssh_disconnect(ssh_session session)
+{
+ struct ssh_iterator *it;
+ int rc;
- if (session == NULL) {
- return;
- }
+ if (session == NULL) {
+ return;
+ }
- if (session->socket != NULL && ssh_socket_is_open(session->socket)) {
- rc = ssh_buffer_pack(session->out_buffer,
- "bdss",
- SSH2_MSG_DISCONNECT,
- SSH2_DISCONNECT_BY_APPLICATION,
- "Bye Bye",
- ""); /* language tag */
- if (rc != SSH_OK){
- ssh_set_error_oom(session);
- goto error;
+ if (session->socket != NULL && ssh_socket_is_open(session->socket)) {
+ rc = ssh_buffer_pack(session->out_buffer,
+ "bdss",
+ SSH2_MSG_DISCONNECT,
+ SSH2_DISCONNECT_BY_APPLICATION,
+ "Bye Bye",
+ ""); /* language tag */
+ if (rc != SSH_OK) {
+ ssh_set_error_oom(session);
+ goto error;
+ }
+
+ ssh_packet_send(session);
+ ssh_socket_close(session->socket);
}
- ssh_packet_send(session);
- ssh_socket_close(session->socket);
- }
error:
- session->recv_seq = 0;
- session->send_seq = 0;
- session->alive = 0;
- if (session->socket != NULL){
- ssh_socket_reset(session->socket);
- }
- session->opts.fd = SSH_INVALID_SOCKET;
- session->session_state=SSH_SESSION_STATE_DISCONNECTED;
+ session->recv_seq = 0;
+ session->send_seq = 0;
+ session->alive = 0;
+ if (session->socket != NULL){
+ ssh_socket_reset(session->socket);
+ }
+ session->opts.fd = SSH_INVALID_SOCKET;
+ session->session_state = SSH_SESSION_STATE_DISCONNECTED;
+ session->pending_call_state = SSH_PENDING_CALL_NONE;
- while ((it=ssh_list_get_iterator(session->channels)) != NULL) {
- ssh_channel_do_free(ssh_iterator_value(ssh_channel,it));
- ssh_list_remove(session->channels, it);
- }
- if(session->current_crypto){
- crypto_free(session->current_crypto);
- session->current_crypto=NULL;
- }
- if (session->next_crypto) {
- crypto_free(session->next_crypto);
- session->next_crypto = crypto_new();
- if (session->next_crypto == NULL) {
- ssh_set_error_oom(session);
+ while ((it = ssh_list_get_iterator(session->channels)) != NULL) {
+ ssh_channel_do_free(ssh_iterator_value(ssh_channel, it));
+ ssh_list_remove(session->channels, it);
}
- }
- if (session->in_buffer) {
- ssh_buffer_reinit(session->in_buffer);
- }
- if (session->out_buffer) {
- ssh_buffer_reinit(session->out_buffer);
- }
- if (session->in_hashbuf) {
- ssh_buffer_reinit(session->in_hashbuf);
- }
- if (session->out_hashbuf) {
- ssh_buffer_reinit(session->out_hashbuf);
- }
- session->auth.supported_methods = 0;
- SAFE_FREE(session->serverbanner);
- SAFE_FREE(session->clientbanner);
-
- if(session->ssh_message_list){
- ssh_message msg;
- while((msg=ssh_list_pop_head(ssh_message ,session->ssh_message_list))
- != NULL){
- ssh_message_free(msg);
+ if (session->current_crypto) {
+ crypto_free(session->current_crypto);
+ session->current_crypto = NULL;
}
- ssh_list_free(session->ssh_message_list);
- session->ssh_message_list=NULL;
- }
+ if (session->next_crypto) {
+ crypto_free(session->next_crypto);
+ session->next_crypto = crypto_new();
+ if (session->next_crypto == NULL) {
+ ssh_set_error_oom(session);
+ }
+ }
+ if (session->in_buffer) {
+ ssh_buffer_reinit(session->in_buffer);
+ }
+ if (session->out_buffer) {
+ ssh_buffer_reinit(session->out_buffer);
+ }
+ if (session->in_hashbuf) {
+ ssh_buffer_reinit(session->in_hashbuf);
+ }
+ if (session->out_hashbuf) {
+ ssh_buffer_reinit(session->out_hashbuf);
+ }
+ session->auth.supported_methods = 0;
+ SAFE_FREE(session->serverbanner);
+ SAFE_FREE(session->clientbanner);
- if (session->packet_callbacks){
- ssh_list_free(session->packet_callbacks);
- session->packet_callbacks=NULL;
- }
+ if (session->ssh_message_list) {
+ ssh_message msg = NULL;
+
+ while ((msg = ssh_list_pop_head(ssh_message,
+ session->ssh_message_list)) != NULL) {
+ ssh_message_free(msg);
+ }
+ ssh_list_free(session->ssh_message_list);
+ session->ssh_message_list = NULL;
+ }
+
+ if (session->packet_callbacks) {
+ ssh_list_free(session->packet_callbacks);
+ session->packet_callbacks = NULL;
+ }
}
const char *ssh_copyright(void) {
diff --git a/src/config.c b/src/config.c
index 79a64339..198a4726 100644
--- a/src/config.c
+++ b/src/config.c
@@ -1170,3 +1170,57 @@ int ssh_config_parse_file(ssh_session session, const char *filename)
fclose(f);
return 0;
}
+
+/* @brief Parse configuration string and set the options to the given session
+ *
+ * @params[in] session The ssh session
+ * @params[in] input Null terminated string containing the configuration
+ *
+ * @returns SSH_OK on successful parsing the configuration string,
+ * SSH_ERROR on error
+ */
+int ssh_config_parse_string(ssh_session session, const char *input)
+{
+ char line[MAX_LINE_SIZE] = {0};
+ const char *c = input, *line_start = input;
+ unsigned int line_num = 0, line_len;
+ int parsing, rv;
+
+ SSH_LOG(SSH_LOG_DEBUG, "Reading configuration data from string:");
+ SSH_LOG(SSH_LOG_DEBUG, "START\n%s\nEND", input);
+
+ parsing = 1;
+ while (1) {
+ line_num++;
+ line_start = c;
+ c = strchr(line_start, '\n');
+ if (c == NULL) {
+ /* if there is no newline in the end of the string */
+ c = strchr(line_start, '\0');
+ }
+ if (c == NULL) {
+ /* should not happen, would mean a string without trailing '\0' */
+ SSH_LOG(SSH_LOG_WARN, "No trailing '\\0' in config string");
+ return SSH_ERROR;
+ }
+ line_len = c - line_start;
+ if (line_len > MAX_LINE_SIZE - 1) {
+ SSH_LOG(SSH_LOG_WARN, "Line %u too long: %u characters",
+ line_num, line_len);
+ return SSH_ERROR;
+ }
+ memcpy(line, line_start, line_len);
+ line[line_len] = '\0';
+ SSH_LOG(SSH_LOG_DEBUG, "Line %u: %s", line_num, line);
+ rv = ssh_config_parse_line(session, line, line_num, &parsing);
+ if (rv < 0) {
+ return SSH_ERROR;
+ }
+ if (*c == '\0') {
+ break;
+ }
+ c++;
+ }
+
+ return SSH_OK;
+}
diff --git a/src/kex.c b/src/kex.c
index c2c59de2..95948136 100644
--- a/src/kex.c
+++ b/src/kex.c
@@ -168,16 +168,17 @@
#define CHACHA20 "chacha20-poly1305@openssh.com,"
-#define KEY_EXCHANGE \
+#define DEFAULT_KEY_EXCHANGE \
CURVE25519 \
ECDH \
"diffie-hellman-group18-sha512,diffie-hellman-group16-sha512," \
GEX_SHA256 \
- "diffie-hellman-group14-sha256," \
- "diffie-hellman-group14-sha1,diffie-hellman-group1-sha1"
+ "diffie-hellman-group14-sha256" \
+
#define KEY_EXCHANGE_SUPPORTED \
GEX_SHA1 \
- KEY_EXCHANGE
+ DEFAULT_KEY_EXCHANGE \
+ ",diffie-hellman-group14-sha1,diffie-hellman-group1-sha1"
/* RFC 8308 */
#define KEX_EXTENSION_CLIENT "ext-info-c"
@@ -231,12 +232,12 @@ static const char *fips_methods[] = {
/* NOTE: This is a fixed API and the index is defined by ssh_kex_types_e */
static const char *default_methods[] = {
- KEY_EXCHANGE,
+ DEFAULT_KEY_EXCHANGE,
DEFAULT_PUBLIC_KEY_ALGORITHMS,
- CHACHA20 AES DES,
- CHACHA20 AES DES,
- "hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1",
- "hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1",
+ CHACHA20 AES,
+ CHACHA20 AES,
+ "hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha2-256,hmac-sha2-512",
+ "hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha2-256,hmac-sha2-512",
"none",
"none",
"",
@@ -754,13 +755,29 @@ int ssh_set_client_kex(ssh_session session)
return SSH_OK;
}
+static const char *ssh_find_aead_hmac(const char *cipher)
+{
+ if (cipher == NULL) {
+ return NULL;
+ } else if (strcmp(cipher, "chacha20-poly1305@openssh.com") == 0) {
+ return "aead-poly1305";
+ } else if (strcmp(cipher, "aes256-gcm@openssh.com") == 0) {
+ return "aead-gcm";
+ } else if (strcmp(cipher, "aes128-gcm@openssh.com") == 0) {
+ return "aead-gcm";
+ }
+ return NULL;
+}
+
/** @brief Select the different methods on basis of client's and
* server's kex messages, and watches out if a match is possible.
*/
-int ssh_kex_select_methods (ssh_session session){
+int ssh_kex_select_methods (ssh_session session)
+{
struct ssh_kex_struct *server = &session->next_crypto->server_kex;
struct ssh_kex_struct *client = &session->next_crypto->client_kex;
char *ext_start = NULL;
+ const char *aead_hmac = NULL;
int i;
/* Here we should drop the ext-info-c from the list so we avoid matching.
@@ -772,7 +789,15 @@ int ssh_kex_select_methods (ssh_session session){
for (i = 0; i < SSH_KEX_METHODS; i++) {
session->next_crypto->kex_methods[i]=ssh_find_matching(server->methods[i],client->methods[i]);
- if(session->next_crypto->kex_methods[i] == NULL && i < SSH_LANG_C_S){
+
+ if (i == SSH_MAC_C_S || i == SSH_MAC_S_C) {
+ aead_hmac = ssh_find_aead_hmac(session->next_crypto->kex_methods[i-2]);
+ if (aead_hmac) {
+ free(session->next_crypto->kex_methods[i]);
+ session->next_crypto->kex_methods[i] = strdup(aead_hmac);
+ }
+ }
+ if (session->next_crypto->kex_methods[i] == NULL && i < SSH_LANG_C_S){
ssh_set_error(session,SSH_FATAL,"kex error : no match for method %s: server [%s], client [%s]",
ssh_kex_descriptions[i],server->methods[i],client->methods[i]);
return SSH_ERROR;
@@ -781,31 +806,31 @@ int ssh_kex_select_methods (ssh_session session){
session->next_crypto->kex_methods[i] = strdup("");
}
}
- if(strcmp(session->next_crypto->kex_methods[SSH_KEX], "diffie-hellman-group1-sha1") == 0){
+ if (strcmp(session->next_crypto->kex_methods[SSH_KEX], "diffie-hellman-group1-sha1") == 0){
session->next_crypto->kex_type=SSH_KEX_DH_GROUP1_SHA1;
- } else if(strcmp(session->next_crypto->kex_methods[SSH_KEX], "diffie-hellman-group14-sha1") == 0){
+ } else if (strcmp(session->next_crypto->kex_methods[SSH_KEX], "diffie-hellman-group14-sha1") == 0){
session->next_crypto->kex_type=SSH_KEX_DH_GROUP14_SHA1;
- } else if(strcmp(session->next_crypto->kex_methods[SSH_KEX], "diffie-hellman-group14-sha256") == 0){
+ } else if (strcmp(session->next_crypto->kex_methods[SSH_KEX], "diffie-hellman-group14-sha256") == 0){
session->next_crypto->kex_type=SSH_KEX_DH_GROUP14_SHA256;
- } else if(strcmp(session->next_crypto->kex_methods[SSH_KEX], "diffie-hellman-group16-sha512") == 0){
+ } else if (strcmp(session->next_crypto->kex_methods[SSH_KEX], "diffie-hellman-group16-sha512") == 0){
session->next_crypto->kex_type=SSH_KEX_DH_GROUP16_SHA512;
- } else if(strcmp(session->next_crypto->kex_methods[SSH_KEX], "diffie-hellman-group18-sha512") == 0){
+ } else if (strcmp(session->next_crypto->kex_methods[SSH_KEX], "diffie-hellman-group18-sha512") == 0){
session->next_crypto->kex_type=SSH_KEX_DH_GROUP18_SHA512;
#ifdef WITH_GEX
- } else if(strcmp(session->next_crypto->kex_methods[SSH_KEX], "diffie-hellman-group-exchange-sha1") == 0){
+ } else if (strcmp(session->next_crypto->kex_methods[SSH_KEX], "diffie-hellman-group-exchange-sha1") == 0){
session->next_crypto->kex_type=SSH_KEX_DH_GEX_SHA1;
- } else if(strcmp(session->next_crypto->kex_methods[SSH_KEX], "diffie-hellman-group-exchange-sha256") == 0){
+ } else if (strcmp(session->next_crypto->kex_methods[SSH_KEX], "diffie-hellman-group-exchange-sha256") == 0){
session->next_crypto->kex_type=SSH_KEX_DH_GEX_SHA256;
#endif /* WITH_GEX */
- } else if(strcmp(session->next_crypto->kex_methods[SSH_KEX], "ecdh-sha2-nistp256") == 0){
+ } else if (strcmp(session->next_crypto->kex_methods[SSH_KEX], "ecdh-sha2-nistp256") == 0){
session->next_crypto->kex_type=SSH_KEX_ECDH_SHA2_NISTP256;
- } else if(strcmp(session->next_crypto->kex_methods[SSH_KEX], "ecdh-sha2-nistp384") == 0){
+ } else if (strcmp(session->next_crypto->kex_methods[SSH_KEX], "ecdh-sha2-nistp384") == 0){
session->next_crypto->kex_type=SSH_KEX_ECDH_SHA2_NISTP384;
- } else if(strcmp(session->next_crypto->kex_methods[SSH_KEX], "ecdh-sha2-nistp521") == 0){
+ } else if (strcmp(session->next_crypto->kex_methods[SSH_KEX], "ecdh-sha2-nistp521") == 0){
session->next_crypto->kex_type=SSH_KEX_ECDH_SHA2_NISTP521;
- } else if(strcmp(session->next_crypto->kex_methods[SSH_KEX], "curve25519-sha256@libssh.org") == 0){
+ } else if (strcmp(session->next_crypto->kex_methods[SSH_KEX], "curve25519-sha256@libssh.org") == 0){
session->next_crypto->kex_type=SSH_KEX_CURVE25519_SHA256_LIBSSH_ORG;
- } else if(strcmp(session->next_crypto->kex_methods[SSH_KEX], "curve25519-sha256") == 0){
+ } else if (strcmp(session->next_crypto->kex_methods[SSH_KEX], "curve25519-sha256") == 0){
session->next_crypto->kex_type=SSH_KEX_CURVE25519_SHA256;
}
SSH_LOG(SSH_LOG_INFO, "Negotiated %s,%s,%s,%s,%s,%s,%s,%s,%s,%s",
@@ -825,7 +850,8 @@ int ssh_kex_select_methods (ssh_session session){
/* this function only sends the predefined set of kex methods */
-int ssh_send_kex(ssh_session session, int server_kex) {
+int ssh_send_kex(ssh_session session, int server_kex)
+{
struct ssh_kex_struct *kex = (server_kex ? &session->next_crypto->server_kex :
&session->next_crypto->client_kex);
ssh_string str = NULL;
@@ -1042,7 +1068,7 @@ int ssh_make_sessionid(ssh_session session)
ssh_buffer_get(server_hash),
server_pubkey_blob);
SSH_STRING_FREE(server_pubkey_blob);
- if(rc != SSH_OK){
+ if (rc != SSH_OK){
goto error;
}
diff --git a/src/misc.c b/src/misc.c
index 955ceed6..167beaf1 100644
--- a/src/misc.c
+++ b/src/misc.c
@@ -1749,6 +1749,8 @@ int ssh_tmpname(char *template)
{
char *tmp = NULL;
size_t i = 0;
+ int rc = 0;
+ uint8_t random[6];
if (template == NULL) {
goto err;
@@ -1767,17 +1769,18 @@ int ssh_tmpname(char *template)
}
}
- srand(time(NULL));
+ rc = ssh_get_random(random, 6, 0);
+ if (!rc) {
+ SSH_LOG(SSH_LOG_WARNING,
+ "Could not generate random data\n");
+ goto err;
+ }
- for (i = 0; i < 6; ++i) {
-#ifdef _WIN32
- /* in win32 MAX_RAND is 32767, thus we can not shift that far,
- * otherwise the last three chars are 0 */
- int hexdigit = (rand() >> (i * 2)) & 0x1f;
-#else
- int hexdigit = (rand() >> (i * 5)) & 0x1f;
-#endif
- tmp[i] = hexdigit > 9 ? hexdigit + 'a' - 10 : hexdigit + '0';
+ for (i = 0; i < 6; i++) {
+ /* Limit the random[i] < 32 */
+ random[i] &= 0x1f;
+ /* For values from 0 to 9 use numbers, otherwise use letters */
+ tmp[i] = random[i] > 9 ? random[i] + 'a' - 10 : random[i] + '0';
}
return 0;
diff --git a/src/pki_gcrypt.c b/src/pki_gcrypt.c
index 62ec8ea7..0373cdae 100644
--- a/src/pki_gcrypt.c
+++ b/src/pki_gcrypt.c
@@ -1983,8 +1983,9 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey,
if (len > rsalen) {
SSH_LOG(SSH_LOG_WARN,
- "Signature is to big size: %lu",
- (unsigned long)len);
+ "Signature is too big: %lu > %lu",
+ (unsigned long)len,
+ (unsigned long)rsalen);
ssh_signature_free(sig);
return NULL;
}
diff --git a/tests/client/torture_algorithms.c b/tests/client/torture_algorithms.c
index 729505ef..ea3b647b 100644
--- a/tests/client/torture_algorithms.c
+++ b/tests/client/torture_algorithms.c
@@ -45,6 +45,16 @@ static int sshd_teardown(void **state) {
return 0;
}
+static int sshd_setup_hmac(void **state)
+{
+ torture_setup_sshd_server(state, false);
+ /* Set MAC to be something other than what the client will offer */
+ torture_update_sshd_config(state, "MACs hmac-sha2-512");
+
+ return 0;
+}
+
+
static int session_setup(void **state) {
struct torture_state *s = *state;
int verbosity = torture_libssh_verbosity();
@@ -412,6 +422,20 @@ static void torture_algorithms_aes256_gcm(void **state)
test_algorithm(s->ssh.session, NULL/*kex*/, "aes256-gcm@openssh.com", NULL);
}
+static void torture_algorithms_aes128_gcm_mac(void **state)
+{
+ struct torture_state *s = *state;
+
+ test_algorithm(s->ssh.session, NULL/*kex*/, "aes128-gcm@openssh.com", "hmac-sha1");
+}
+
+static void torture_algorithms_aes256_gcm_mac(void **state)
+{
+ struct torture_state *s = *state;
+
+ test_algorithm(s->ssh.session, NULL/*kex*/, "aes256-gcm@openssh.com", "hmac-sha1");
+}
+
static void torture_algorithms_3des_cbc_hmac_sha1(void **state) {
struct torture_state *s = *state;
@@ -548,6 +572,19 @@ static void torture_algorithms_chacha20_poly1305(void **state)
"chacha20-poly1305@openssh.com",
NULL);
}
+static void torture_algorithms_chacha20_poly1305_mac(void **state)
+{
+ struct torture_state *s = *state;
+
+ if (ssh_fips_mode()) {
+ skip();
+ }
+
+ test_algorithm(s->ssh.session,
+ NULL, /*kex*/
+ "chacha20-poly1305@openssh.com",
+ "hmac-sha1"); /* different from the server */
+}
#endif /* OPENSSH_CHACHA20_POLY1305_OPENSSH_COM */
static void torture_algorithms_zlib(void **state) {
@@ -951,10 +988,30 @@ int torture_run_tests(void) {
#endif
};
+ struct CMUnitTest tests_hmac[] = {
+ cmocka_unit_test_setup_teardown(torture_algorithms_aes128_gcm_mac,
+ session_setup,
+ session_teardown),
+ cmocka_unit_test_setup_teardown(torture_algorithms_aes256_gcm_mac,
+ session_setup,
+ session_teardown),
+#ifdef OPENSSH_CHACHA20_POLY1305_OPENSSH_COM
+ cmocka_unit_test_setup_teardown(torture_algorithms_chacha20_poly1305_mac,
+ session_setup,
+ session_teardown),
+#endif /* OPENSSH_CHACHA20_POLY1305_OPENSSH_COM */
+ };
+
ssh_init();
torture_filter_tests(tests);
rc = cmocka_run_group_tests(tests, sshd_setup, sshd_teardown);
+ if (rc != 0) {
+ return rc;
+ }
+
+ torture_filter_tests(tests);
+ rc = cmocka_run_group_tests(tests_hmac, sshd_setup_hmac, sshd_teardown);
ssh_finalize();
diff --git a/tests/pkd/pkd_daemon.c b/tests/pkd/pkd_daemon.c
index 239bdd36..5325a5de 100644
--- a/tests/pkd/pkd_daemon.c
+++ b/tests/pkd/pkd_daemon.c
@@ -247,10 +247,9 @@ static int pkd_exec_hello(int fd, struct pkd_daemon_args *args)
int level = args->opts.libssh_log_level;
enum pkd_hostkey_type_e type = args->type;
const char *hostkeypath = args->hostkeypath;
- const char *default_kex = NULL;
- char *all_kex = NULL;
- size_t kex_len = 0;
+ const char *all_kex = NULL;
const char *all_ciphers = NULL;
+ const char *all_macs = NULL;
const uint64_t rekey_data_limit = args->rekey_data_limit;
bool process_config = false;
@@ -302,17 +301,10 @@ static int pkd_exec_hello(int fd, struct pkd_daemon_args *args)
if (!ssh_fips_mode()) {
const char *all_hostkeys = NULL;
/* Add methods not enabled by default */
-#define GEX_SHA1 "diffie-hellman-group-exchange-sha1"
- default_kex = ssh_kex_get_default_methods(SSH_KEX);
- kex_len = strlen(default_kex) + strlen(GEX_SHA1) + 2;
- all_kex = malloc(kex_len);
- if (all_kex == NULL) {
- pkderr("Failed to alloc more memory.\n");
- goto outclose;
- }
- snprintf(all_kex, kex_len, "%s," GEX_SHA1, default_kex);
+
+ /* Enable all supported key exchange methods */
+ all_kex = ssh_kex_get_supported_method(SSH_KEX);
rc = ssh_bind_options_set(b, SSH_BIND_OPTIONS_KEY_EXCHANGE, all_kex);
- free(all_kex);
if (rc != 0) {
pkderr("ssh_bind_options_set kex methods: %s\n", ssh_get_error(b));
goto outclose;
@@ -341,6 +333,21 @@ static int pkd_exec_hello(int fd, struct pkd_daemon_args *args)
goto outclose;
}
+ /* Enable all message authentication codes */
+ all_macs = ssh_kex_get_supported_method(SSH_MAC_C_S);
+ rc = ssh_bind_options_set(b, SSH_BIND_OPTIONS_HMAC_C_S, all_macs);
+ if (rc != 0) {
+ pkderr("ssh_bind_options_set MACs C-S: %s\n", ssh_get_error(b));
+ goto outclose;
+ }
+
+ all_macs = ssh_kex_get_supported_method(SSH_MAC_S_C);
+ rc = ssh_bind_options_set(b, SSH_BIND_OPTIONS_HMAC_S_C, all_macs);
+ if (rc != 0) {
+ pkderr("ssh_bind_options_set MACs S-C: %s\n", ssh_get_error(b));
+ goto outclose;
+ }
+
}
s = ssh_new();
diff --git a/tests/pkd/pkd_hello.c b/tests/pkd/pkd_hello.c
index 3a5768d7..01b1b10d 100644
--- a/tests/pkd/pkd_hello.c
+++ b/tests/pkd/pkd_hello.c
@@ -392,45 +392,37 @@ static int torture_pkd_setup_ecdsa_521(void **state) {
#endif
-#define PKDTESTS_CIPHER_FIPS(f, client, ciphercmd) \
- f(client, rsa_aes128_cbc, ciphercmd("aes128-cbc"), setup_rsa, teardown) \
+#define PKDTESTS_CIPHER_COMMON(f, client, ciphercmd) \
f(client, rsa_aes128_ctr, ciphercmd("aes128-ctr"), setup_rsa, teardown) \
- f(client, rsa_aes256_cbc, ciphercmd("aes256-cbc"), setup_rsa, teardown) \
f(client, rsa_aes256_ctr, ciphercmd("aes256-ctr"), setup_rsa, teardown) \
- f(client, ecdsa_256_aes128_cbc, ciphercmd("aes128-cbc"), setup_ecdsa_256, teardown) \
f(client, ecdsa_256_aes128_ctr, ciphercmd("aes128-ctr"), setup_ecdsa_256, teardown) \
- f(client, ecdsa_256_aes256_cbc, ciphercmd("aes256-cbc"), setup_ecdsa_256, teardown) \
f(client, ecdsa_256_aes256_ctr, ciphercmd("aes256-ctr"), setup_ecdsa_256, teardown) \
- f(client, ecdsa_384_aes128_cbc, ciphercmd("aes128-cbc"), setup_ecdsa_384, teardown) \
f(client, ecdsa_384_aes128_ctr, ciphercmd("aes128-ctr"), setup_ecdsa_384, teardown) \
- f(client, ecdsa_384_aes256_cbc, ciphercmd("aes256-cbc"), setup_ecdsa_384, teardown) \
f(client, ecdsa_384_aes256_ctr, ciphercmd("aes256-ctr"), setup_ecdsa_384, teardown) \
- f(client, ecdsa_521_aes128_cbc, ciphercmd("aes128-cbc"), setup_ecdsa_521, teardown) \
f(client, ecdsa_521_aes128_ctr, ciphercmd("aes128-ctr"), setup_ecdsa_521, teardown) \
- f(client, ecdsa_521_aes256_cbc, ciphercmd("aes256-cbc"), setup_ecdsa_521, teardown) \
f(client, ecdsa_521_aes256_ctr, ciphercmd("aes256-ctr"), setup_ecdsa_521, teardown)
+#define PKDTESTS_CIPHER_FIPS(f, client, ciphercmd) \
+ PKDTESTS_CIPHER_COMMON(f, client, ciphercmd) \
+ f(client, rsa_aes128_cbc, ciphercmd("aes128-cbc"), setup_rsa, teardown) \
+ f(client, rsa_aes256_cbc, ciphercmd("aes256-cbc"), setup_rsa, teardown) \
+ f(client, ecdsa_256_aes128_cbc, ciphercmd("aes128-cbc"), setup_ecdsa_256, teardown) \
+ f(client, ecdsa_256_aes256_cbc, ciphercmd("aes256-cbc"), setup_ecdsa_256, teardown) \
+ f(client, ecdsa_384_aes128_cbc, ciphercmd("aes128-cbc"), setup_ecdsa_384, teardown) \
+ f(client, ecdsa_384_aes256_cbc, ciphercmd("aes256-cbc"), setup_ecdsa_384, teardown) \
+ f(client, ecdsa_521_aes128_cbc, ciphercmd("aes128-cbc"), setup_ecdsa_521, teardown) \
+ f(client, ecdsa_521_aes256_cbc, ciphercmd("aes256-cbc"), setup_ecdsa_521, teardown)
+
#ifdef HAVE_DSA
#define PKDTESTS_CIPHER(f, client, ciphercmd) \
/* Ciphers. */ \
- PKDTESTS_CIPHER_FIPS(f, client, ciphercmd) \
- f(client, rsa_3des_cbc, ciphercmd("3des-cbc"), setup_rsa, teardown) \
- f(client, dsa_3des_cbc, ciphercmd("3des-cbc"), setup_dsa, teardown) \
- f(client, dsa_aes128_cbc, ciphercmd("aes128-cbc"), setup_dsa, teardown) \
+ PKDTESTS_CIPHER_COMMON(f, client, ciphercmd) \
f(client, dsa_aes128_ctr, ciphercmd("aes128-ctr"), setup_dsa, teardown) \
- f(client, dsa_aes256_cbc, ciphercmd("aes256-cbc"), setup_dsa, teardown) \
- f(client, dsa_aes256_ctr, ciphercmd("aes256-ctr"), setup_dsa, teardown) \
- f(client, ecdsa_256_3des_cbc, ciphercmd("3des-cbc"), setup_ecdsa_256, teardown) \
- f(client, ecdsa_384_3des_cbc, ciphercmd("3des-cbc"), setup_ecdsa_384, teardown) \
- f(client, ecdsa_521_3des_cbc, ciphercmd("3des-cbc"), setup_ecdsa_521, teardown)
+ f(client, dsa_aes256_ctr, ciphercmd("aes256-ctr"), setup_dsa, teardown)
#else
#define PKDTESTS_CIPHER(f, client, ciphercmd) \
/* Ciphers. */ \
- PKDTESTS_CIPHER_FIPS(f, client, ciphercmd) \
- f(client, rsa_3des_cbc, ciphercmd("3des-cbc"), setup_rsa, teardown) \
- f(client, ecdsa_256_3des_cbc, ciphercmd("3des-cbc"), setup_ecdsa_256, teardown) \
- f(client, ecdsa_384_3des_cbc, ciphercmd("3des-cbc"), setup_ecdsa_384, teardown) \
- f(client, ecdsa_521_3des_cbc, ciphercmd("3des-cbc"), setup_ecdsa_521, teardown)
+ PKDTESTS_CIPHER_COMMON(f, client, ciphercmd)
#endif
#define CHACHA20 "chacha20-poly1305@openssh.com"
@@ -451,10 +443,16 @@ static int torture_pkd_setup_ecdsa_521(void **state) {
#define PKDTESTS_CIPHER_OPENSSHONLY(f, client, ciphercmd) \
/* Ciphers. */ \
PKDTESTS_CIPHER_OPENSSHONLY_FIPS(f, client, ciphercmd) \
+ f(client, rsa_3des_cbc, ciphercmd("3des-cbc"), setup_rsa, teardown) \
+ f(client, rsa_aes128_cbc, ciphercmd("aes128-cbc"), setup_rsa, teardown) \
f(client, rsa_aes192_cbc, ciphercmd("aes192-cbc"), setup_rsa, teardown) \
+ f(client, rsa_aes256_cbc, ciphercmd("aes256-cbc"), setup_rsa, teardown) \
f(client, rsa_aes192_ctr, ciphercmd("aes192-ctr"), setup_rsa, teardown) \
f(client, rsa_chacha20, ciphercmd(CHACHA20), setup_rsa, teardown) \
+ f(client, dsa_3des_cbc, ciphercmd("3des-cbc"), setup_dsa, teardown) \
+ f(client, dsa_aes128_cbc, ciphercmd("aes128-cbc"), setup_dsa, teardown) \
f(client, dsa_aes192_cbc, ciphercmd("aes192-cbc"), setup_dsa, teardown) \
+ f(client, dsa_aes256_cbc, ciphercmd("aes256-cbc"), setup_dsa, teardown) \
f(client, dsa_aes192_ctr, ciphercmd("aes192-ctr"), setup_dsa, teardown) \
f(client, dsa_chacha20, ciphercmd(CHACHA20), setup_dsa, teardown) \
f(client, dsa_aes128_gcm, ciphercmd(AES128_GCM), setup_dsa, teardown) \
@@ -469,20 +467,32 @@ static int torture_pkd_setup_ecdsa_521(void **state) {
f(client, ed25519_chacha20, ciphercmd(CHACHA20), setup_ed25519, teardown) \
f(client, ed25519_aes128_gcm, ciphercmd(AES128_GCM), setup_ed25519, teardown) \
f(client, ed25519_aes256_gcm, ciphercmd(AES256_GCM), setup_ed25519, teardown) \
+ f(client, ecdsa_256_3des_cbc, ciphercmd("3des-cbc"), setup_ecdsa_256, teardown) \
+ f(client, ecdsa_256_aes128_cbc, ciphercmd("aes128-cbc"), setup_ecdsa_256, teardown) \
f(client, ecdsa_256_aes192_cbc, ciphercmd("aes192-cbc"), setup_ecdsa_256, teardown) \
+ f(client, ecdsa_256_aes256_cbc, ciphercmd("aes256-cbc"), setup_ecdsa_256, teardown) \
f(client, ecdsa_256_aes192_ctr, ciphercmd("aes192-ctr"), setup_ecdsa_256, teardown) \
f(client, ecdsa_256_chacha20, ciphercmd(CHACHA20), setup_ecdsa_256, teardown) \
+ f(client, ecdsa_384_3des_cbc, ciphercmd("3des-cbc"), setup_ecdsa_384, teardown) \
+ f(client, ecdsa_384_aes128_cbc, ciphercmd("aes128-cbc"), setup_ecdsa_384, teardown) \
f(client, ecdsa_384_aes192_cbc, ciphercmd("aes192-cbc"), setup_ecdsa_384, teardown) \
+ f(client, ecdsa_384_aes256_cbc, ciphercmd("aes256-cbc"), setup_ecdsa_384, teardown) \
f(client, ecdsa_384_aes192_ctr, ciphercmd("aes192-ctr"), setup_ecdsa_384, teardown) \
f(client, ecdsa_384_chacha20, ciphercmd(CHACHA20), setup_ecdsa_384, teardown) \
+ f(client, ecdsa_521_3des_cbc, ciphercmd("3des-cbc"), setup_ecdsa_521, teardown) \
+ f(client, ecdsa_521_aes128_cbc, ciphercmd("aes128-cbc"), setup_ecdsa_521, teardown) \
f(client, ecdsa_521_aes192_cbc, ciphercmd("aes192-cbc"), setup_ecdsa_521, teardown) \
+ f(client, ecdsa_521_aes256_cbc, ciphercmd("aes256-cbc"), setup_ecdsa_521, teardown) \
f(client, ecdsa_521_aes192_ctr, ciphercmd("aes192-ctr"), setup_ecdsa_521, teardown) \
f(client, ecdsa_521_chacha20, ciphercmd(CHACHA20), setup_ecdsa_521, teardown)
#else
#define PKDTESTS_CIPHER_OPENSSHONLY(f, client, ciphercmd) \
/* Ciphers. */ \
PKDTESTS_CIPHER_OPENSSHONLY_FIPS(f, client, ciphercmd) \
+ f(client, rsa_3des_cbc, ciphercmd("3des-cbc"), setup_rsa, teardown) \
+ f(client, rsa_aes128_cbc, ciphercmd("aes128-cbc"), setup_rsa, teardown) \
f(client, rsa_aes192_cbc, ciphercmd("aes192-cbc"), setup_rsa, teardown) \
+ f(client, rsa_aes256_cbc, ciphercmd("aes256-cbc"), setup_rsa, teardown) \
f(client, rsa_aes192_ctr, ciphercmd("aes192-ctr"), setup_rsa, teardown) \
f(client, rsa_chacha20, ciphercmd(CHACHA20), setup_rsa, teardown) \
f(client, ed25519_3des_cbc, ciphercmd("3des-cbc"), setup_ed25519, teardown) \
@@ -493,13 +503,22 @@ static int torture_pkd_setup_ecdsa_521(void **state) {
f(client, ed25519_aes192_cbc, ciphercmd("aes192-cbc"), setup_ed25519, teardown) \
f(client, ed25519_aes192_ctr, ciphercmd("aes192-ctr"), setup_ed25519, teardown) \
f(client, ed25519_chacha20, ciphercmd(CHACHA20), setup_ed25519, teardown) \
+ f(client, ecdsa_256_3des_cbc, ciphercmd("3des-cbc"), setup_ecdsa_256, teardown) \
+ f(client, ecdsa_256_aes128_cbc, ciphercmd("aes128-cbc"), setup_ecdsa_256, teardown) \
f(client, ecdsa_256_aes192_cbc, ciphercmd("aes192-cbc"), setup_ecdsa_256, teardown) \
+ f(client, ecdsa_256_aes256_cbc, ciphercmd("aes256-cbc"), setup_ecdsa_256, teardown) \
f(client, ecdsa_256_aes192_ctr, ciphercmd("aes192-ctr"), setup_ecdsa_256, teardown) \
f(client, ecdsa_256_chacha20, ciphercmd(CHACHA20), setup_ecdsa_256, teardown) \
+ f(client, ecdsa_384_3des_cbc, ciphercmd("3des-cbc"), setup_ecdsa_384, teardown) \
+ f(client, ecdsa_384_aes128_cbc, ciphercmd("aes128-cbc"), setup_ecdsa_384, teardown) \
f(client, ecdsa_384_aes192_cbc, ciphercmd("aes192-cbc"), setup_ecdsa_384, teardown) \
+ f(client, ecdsa_384_aes256_cbc, ciphercmd("aes256-cbc"), setup_ecdsa_384, teardown) \
f(client, ecdsa_384_aes192_ctr, ciphercmd("aes192-ctr"), setup_ecdsa_384, teardown) \
f(client, ecdsa_384_chacha20, ciphercmd(CHACHA20), setup_ecdsa_384, teardown) \
+ f(client, ecdsa_521_3des_cbc, ciphercmd("3des-cbc"), setup_ecdsa_521, teardown) \
+ f(client, ecdsa_521_aes128_cbc, ciphercmd("aes128-cbc"), setup_ecdsa_521, teardown) \
f(client, ecdsa_521_aes192_cbc, ciphercmd("aes192-cbc"), setup_ecdsa_521, teardown) \
+ f(client, ecdsa_521_aes256_cbc, ciphercmd("aes256-cbc"), setup_ecdsa_521, teardown) \
f(client, ecdsa_521_aes192_ctr, ciphercmd("aes192-ctr"), setup_ecdsa_521, teardown) \
f(client, ecdsa_521_chacha20, ciphercmd(CHACHA20), setup_ecdsa_521, teardown)
#endif
diff --git a/tests/server/CMakeLists.txt b/tests/server/CMakeLists.txt
index ebe2d169..96457cd2 100644
--- a/tests/server/CMakeLists.txt
+++ b/tests/server/CMakeLists.txt
@@ -10,6 +10,7 @@ set(LIBSSH_SERVER_TESTS
torture_server
torture_server_auth_kbdint
torture_server_config
+ torture_server_algorithms
)
include_directories(${libssh_SOURCE_DIR}/include
diff --git a/tests/server/torture_server_algorithms.c b/tests/server/torture_server_algorithms.c
new file mode 100644
index 00000000..3963e368
--- /dev/null
+++ b/tests/server/torture_server_algorithms.c
@@ -0,0 +1,364 @@
+/*
+ * This file is part of the SSH Library
+ *
+ * Copyright (c) 2019 by Red Hat, Inc.
+ *
+ * Author: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
+ *
+ * The SSH Library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at your
+ * option) any later version.
+ *
+ * The SSH Library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with the SSH Library; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#define LIBSSH_STATIC
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <pwd.h>
+
+#include "torture.h"
+#include "torture_key.h"
+#include "libssh/libssh.h"
+#include "libssh/priv.h"
+#include "libssh/session.h"
+#include "libssh/token.h"
+
+#include "test_server.h"
+#include "default_cb.h"
+
+const char template[] = "temp_dir_XXXXXX";
+
+struct test_server_st {
+ struct torture_state *state;
+ char *cwd;
+ char *temp_dir;
+ char rsa_hostkey[1024];
+};
+
+static int setup_files(void **state)
+{
+ struct test_server_st *tss;
+ struct torture_state *s;
+ char sshd_path[1024];
+
+ int rc;
+
+ tss = (struct test_server_st*)calloc(1, sizeof(struct test_server_st));
+ assert_non_null(tss);
+
+ torture_setup_socket_dir((void **)&s);
+ assert_non_null(s->socket_dir);
+
+ /* Set the default interface for the server */
+ setenv("SOCKET_WRAPPER_DEFAULT_IFACE", "10", 1);
+
+ snprintf(sshd_path,
+ sizeof(sshd_path),
+ "%s/sshd",
+ s->socket_dir);
+
+ rc = mkdir(sshd_path, 0755);
+ assert_return_code(rc, errno);
+
+ snprintf(tss->rsa_hostkey,
+ sizeof(tss->rsa_hostkey),
+ "%s/sshd/ssh_host_rsa_key",
+ s->socket_dir);
+ torture_write_file(tss->rsa_hostkey, torture_get_testkey(SSH_KEYTYPE_RSA, 0));
+
+ tss->state = s;
+ *state = tss;
+
+ return 0;
+}
+
+static int teardown_files(void **state)
+{
+ struct torture_state *s;
+ struct test_server_st *tss;
+
+ tss = *state;
+ assert_non_null(tss);
+
+ s = tss->state;
+ assert_non_null(s);
+
+ torture_teardown_socket_dir((void **)&s);
+ SAFE_FREE(tss);
+
+ return 0;
+}
+
+static int setup_temp_dir(void **state)
+{
+ struct test_server_st *tss = *state;
+ struct torture_state *s;
+
+ char *cwd = NULL;
+ char *tmp_dir = NULL;
+
+ assert_non_null(tss);
+
+ s = tss->state;
+ assert_non_null(s);
+
+ cwd = torture_get_current_working_dir();
+ assert_non_null(cwd);
+
+ tmp_dir = torture_make_temp_dir(template);
+ assert_non_null(tmp_dir);
+
+ tss->cwd = cwd;
+ tss->temp_dir = tmp_dir;
+
+ return 0;
+}
+
+static int teardown_temp_dir(void **state)
+{
+ struct test_server_st *tss = *state;
+ int rc;
+
+ assert_non_null(tss);
+
+ rc = torture_change_dir(tss->cwd);
+ assert_int_equal(rc, 0);
+
+ rc = torture_rmdirs(tss->temp_dir);
+ assert_int_equal(rc, 0);
+
+ SAFE_FREE(tss->temp_dir);
+ SAFE_FREE(tss->cwd);
+
+ return 0;
+}
+
+static int start_server(void **state)
+{
+ struct test_server_st *tss = *state;
+ struct torture_state *s;
+
+ assert_non_null(tss);
+
+ s = tss->state;
+ assert_non_null(s);
+
+ /* Start the server using the default values */
+ torture_setup_libssh_server((void **)&s, "./test_server/test_server");
+ assert_non_null(s);
+
+ return 0;
+}
+
+static int stop_server(void **state)
+{
+ struct torture_state *s;
+ struct test_server_st *tss;
+
+ int rc;
+
+ tss = *state;
+ assert_non_null(tss);
+
+ s = tss->state;
+ assert_non_null(s);
+
+ rc = torture_terminate_process(s->srv_pidfile);
+ assert_return_code(rc, errno);
+
+ unlink(s->srv_pidfile);
+
+ return 0;
+}
+
+static int session_setup(void **state)
+{
+ struct test_server_st *tss = *state;
+ struct torture_state *s;
+ int verbosity = torture_libssh_verbosity();
+ struct passwd *pwd;
+ bool b = false;
+ int rc;
+
+ assert_non_null(tss);
+
+ /* Make sure we do not test the agent */
+ unsetenv("SSH_AUTH_SOCK");
+
+ s = tss->state;
+ assert_non_null(s);
+
+ pwd = getpwnam("bob");
+ assert_non_null(pwd);
+
+ rc = setuid(pwd->pw_uid);
+ assert_return_code(rc, errno);
+
+ s->ssh.session = ssh_new();
+ assert_non_null(s->ssh.session);
+
+ rc = ssh_options_set(s->ssh.session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity);
+ assert_ssh_return_code(s->ssh.session, rc);
+ rc = ssh_options_set(s->ssh.session, SSH_OPTIONS_HOST, TORTURE_SSH_SERVER);
+ assert_ssh_return_code(s->ssh.session, rc);
+ /* Make sure no other configuration options from system will get used */
+ rc = ssh_options_set(s->ssh.session, SSH_OPTIONS_PROCESS_CONFIG, &b);
+ assert_ssh_return_code(s->ssh.session, rc);
+
+ return 0;
+}
+
+static int session_teardown(void **state)
+{
+ struct test_server_st *tss = *state;
+ struct torture_state *s;
+
+ assert_non_null(tss);
+
+ s = tss->state;
+ assert_non_null(s);
+
+ ssh_disconnect(s->ssh.session);
+ ssh_free(s->ssh.session);
+
+ return 0;
+}
+
+/*
+ * Check that the handshake works with an AEAD cipher configured
+ * but with no overlap for HMACs. AEAD ciphers have an implied HMAC
+ * so no HMAC overlap in the handshake should not fail the connection.
+ */
+static void test_algorithm_no_hmac_overlap(void **state, const char *algorithm)
+{
+ struct test_server_st *tss = *state;
+ struct torture_state *s = NULL;
+ char config_content[4096];
+
+ ssh_session session = NULL;
+
+ int rc;
+
+ assert_non_null(tss);
+ s = tss->state;
+ assert_non_null(s);
+
+ /* Prepare key files */
+ snprintf(config_content,
+ sizeof(config_content),
+ "HostKey %s\nCiphers %s\nMACs %s\n",
+ tss->rsa_hostkey,
+ algorithm,
+ "hmac-sha2-512-etm@openssh.com");
+
+ assert_non_null(s->srv_config);
+ torture_write_file(s->srv_config, config_content);
+
+ fprintf(stderr, "Config file %s content: \n\n%s\n", s->srv_config,
+ config_content);
+ fflush(stderr);
+
+ /* Start server */
+ rc = start_server(state);
+ assert_int_equal(rc, 0);
+
+ /* Setup session */
+ rc = session_setup(state);
+ assert_int_equal(rc, 0);
+
+ session = s->ssh.session;
+ assert_non_null(session);
+
+ rc = ssh_options_set(session, SSH_OPTIONS_USER, TORTURE_SSH_USER_ALICE);
+ assert_int_equal(rc, SSH_OK);
+
+ rc = ssh_options_set(session, SSH_OPTIONS_CIPHERS_C_S, algorithm);
+ assert_int_equal(rc, SSH_OK);
+
+ rc = ssh_options_set(session, SSH_OPTIONS_CIPHERS_S_C, algorithm);
+ assert_int_equal(rc, SSH_OK);
+
+ rc = ssh_options_set(session, SSH_OPTIONS_HMAC_C_S, "hmac-sha2-512");
+ assert_int_equal(rc, SSH_OK);
+
+ rc = ssh_options_set(session, SSH_OPTIONS_HMAC_S_C, "hmac-sha2-512");
+ assert_int_equal(rc, SSH_OK);
+
+ rc = ssh_connect(session);
+ assert_int_equal(rc, SSH_OK);
+
+ rc = ssh_userauth_none(session, NULL);
+ /* This request should return a SSH_REQUEST_DENIED error */
+ if (rc == SSH_ERROR) {
+ assert_int_equal(ssh_get_error_code(session), SSH_REQUEST_DENIED);
+ }
+ rc = ssh_userauth_list(session, NULL);
+ assert_true(rc & SSH_AUTH_METHOD_PUBLICKEY);
+
+ rc = ssh_userauth_publickey_auto(session, NULL, NULL);
+ assert_ssh_return_code(session, rc);
+
+ rc = session_teardown(state);
+ assert_int_equal(rc, 0);
+
+ rc = stop_server(state);
+ assert_int_equal(rc, 0);
+
+ SAFE_FREE(s->srv_additional_config);
+}
+
+static void torture_algorithm_chacha20_with_no_hmac_overlap(void **state)
+{
+ if (ssh_fips_mode()) {
+ skip();
+ }
+ test_algorithm_no_hmac_overlap(state, "chacha20-poly1305@openssh.com");
+}
+
+static void torture_algorithm_aes256gcm_with_no_hmac_overlap(void **state)
+{
+ test_algorithm_no_hmac_overlap(state, "aes256-gcm@openssh.com");
+}
+
+static void torture_algorithm_aes128gcm_with_no_hmac_overlap(void **state)
+{
+ test_algorithm_no_hmac_overlap(state, "aes128-gcm@openssh.com");
+}
+
+int torture_run_tests(void)
+{
+ int rc;
+ struct CMUnitTest tests[] = {
+ cmocka_unit_test_setup_teardown(torture_algorithm_chacha20_with_no_hmac_overlap,
+ setup_temp_dir, teardown_temp_dir),
+ cmocka_unit_test_setup_teardown(torture_algorithm_aes256gcm_with_no_hmac_overlap,
+ setup_temp_dir, teardown_temp_dir),
+ cmocka_unit_test_setup_teardown(torture_algorithm_aes128gcm_with_no_hmac_overlap,
+ setup_temp_dir, teardown_temp_dir),
+ };
+
+ ssh_init();
+
+ torture_filter_tests(tests);
+ rc = cmocka_run_group_tests(tests,
+ setup_files,
+ teardown_files);
+
+ ssh_finalize();
+
+ return rc;
+}
diff --git a/tests/torture.c b/tests/torture.c
index cf5e4293..7d26b013 100644
--- a/tests/torture.c
+++ b/tests/torture.c
@@ -744,7 +744,8 @@ static void torture_setup_create_sshd_config(void **state, bool pam)
"\n"
"StrictModes no\n"
"\n"
- "%s" /* Here comes UsePam */
+ "%s\n" /* Here comes UsePam */
+ "%s" /* The space for test-specific options */
"\n"
/* add all supported algorithms */
"HostKeyAlgorithms " OPENSSH_KEYS "\n"
@@ -759,8 +760,7 @@ static void torture_setup_create_sshd_config(void **state, bool pam)
"AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT\n"
"AcceptEnv LC_IDENTIFICATION LC_ALL LC_LIBSSH\n"
"\n"
- "PidFile %s\n"
- "%s\n"; /* The space for test-specific options */
+ "PidFile %s\n";
/* FIPS config */
const char fips_config_string[]=
"Port 22\n"
@@ -778,7 +778,8 @@ static void torture_setup_create_sshd_config(void **state, bool pam)
"\n"
"StrictModes no\n"
"\n"
- "%s" /* UsePam */
+ "%s\n" /* Here comes UsePam */
+ "%s" /* The space for test-specific options */
"\n"
"Ciphers "
"aes256-gcm@openssh.com,aes256-ctr,aes256-cbc,"
@@ -807,8 +808,7 @@ static void torture_setup_create_sshd_config(void **state, bool pam)
"AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT\n"
"AcceptEnv LC_IDENTIFICATION LC_ALL LC_LIBSSH\n"
"\n"
- "PidFile %s\n" /* PID file */
- "%s\n"; /* The space for test-specific options */
+ "PidFile %s\n"; /* PID file */
const char usepam_yes[] =
"UsePAM yes\n"
"KbdInteractiveAuthentication yes\n";
@@ -909,8 +909,8 @@ static void torture_setup_create_sshd_config(void **state, bool pam)
trusted_ca_pubkey,
sftp_server,
usepam,
- s->srv_pidfile,
- additional_config);
+ additional_config,
+ s->srv_pidfile);
} else {
snprintf(sshd_config, sizeof(sshd_config),
config_string,
@@ -923,8 +923,8 @@ static void torture_setup_create_sshd_config(void **state, bool pam)
trusted_ca_pubkey,
sftp_server,
usepam,
- s->srv_pidfile,
- additional_config);
+ additional_config,
+ s->srv_pidfile);
}
torture_write_file(s->srv_config, sshd_config);
diff --git a/tests/unittests/torture_config.c b/tests/unittests/torture_config.c
index 671e88c2..7ae846a4 100644
--- a/tests/unittests/torture_config.c
+++ b/tests/unittests/torture_config.c
@@ -10,6 +10,18 @@
extern LIBSSH_THREAD int ssh_log_level;
+#define USERNAME "testuser"
+#define PROXYCMD "ssh -q -W %h:%p gateway.example.com"
+#define ID_FILE "/etc/xxx"
+#define KEXALGORITHMS "ecdh-sha2-nistp521,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group14-sha1"
+#define HOSTKEYALGORITHMS "ssh-ed25519,ecdsa-sha2-nistp521,ssh-rsa"
+#define PUBKEYACCEPTEDTYPES "rsa-sha2-512,ssh-rsa,ecdsa-sha2-nistp521"
+#define MACS "hmac-sha1,hmac-sha2-256,hmac-sha2-512,hmac-sha1-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com"
+#define USER_KNOWN_HOSTS "%d/my_known_hosts"
+#define GLOBAL_KNOWN_HOSTS "/etc/ssh/my_ssh_known_hosts"
+#define BIND_ADDRESS "::1"
+
+
#define LIBSSH_TESTCONFIG1 "libssh_testconfig1.tmp"
#define LIBSSH_TESTCONFIG2 "libssh_testconfig2.tmp"
#define LIBSSH_TESTCONFIG3 "libssh_testconfig3.tmp"
@@ -23,25 +35,177 @@ extern LIBSSH_THREAD int ssh_log_level;
#define LIBSSH_TESTCONFIG11 "libssh_testconfig11.tmp"
#define LIBSSH_TESTCONFIG12 "libssh_testconfig12.tmp"
#define LIBSSH_TESTCONFIGGLOB "libssh_testc*[36].tmp"
-#define LIBSSH_TEST_PUBKEYACCEPTEDKEYTYPES "libssh_test_PubkeyAcceptedKeyTypes.tmp"
+#define LIBSSH_TEST_PUBKEYTYPES "libssh_test_PubkeyAcceptedKeyTypes.tmp"
+#define LIBSSH_TEST_NONEWLINEEND "libssh_test_NoNewLineEnd.tmp"
+#define LIBSSH_TEST_NONEWLINEONELINE "libssh_test_NoNewLineOneline.tmp"
+
+#define LIBSSH_TESTCONFIG_STRING1 \
+ "User "USERNAME"\nInclude "LIBSSH_TESTCONFIG2"\n\n"
+
+#define LIBSSH_TESTCONFIG_STRING2 \
+ "Include "LIBSSH_TESTCONFIG3"\n" \
+ "ProxyCommand "PROXYCMD"\n\n"
+
+#define LIBSSH_TESTCONFIG_STRING3 \
+ "\n\nIdentityFile "ID_FILE"\n" \
+ "\n\nKexAlgorithms "KEXALGORITHMS"\n" \
+ "\n\nHostKeyAlgorithms "HOSTKEYALGORITHMS"\n" \
+ "\n\nPubkeyAcceptedTypes "PUBKEYACCEPTEDTYPES"\n" \
+ "\n\nMACs "MACS"\n"
+
+/* Multiple Port settings -> parsing returns early. */
+#define LIBSSH_TESTCONFIG_STRING4 \
+ "Port 123\nPort 456\n"
+
+/* Testing glob include */
+#define LIBSSH_TESTCONFIG_STRING5 \
+ "User "USERNAME"\nInclude "LIBSSH_TESTCONFIGGLOB"\n\n" \
+
+#define LIBSSH_TESTCONFIG_STRING6 \
+ "ProxyCommand "PROXYCMD"\n\n"
+
+/* new options */
+#define LIBSSH_TESTCONFIG_STRING7 \
+ "\tBindAddress "BIND_ADDRESS"\n" \
+ "\tConnectTimeout 30\n" \
+ "\tLogLevel DEBUG3\n" \
+ "\tGlobalKnownHostsFile "GLOBAL_KNOWN_HOSTS"\n" \
+ "\tCompression yes\n" \
+ "\tStrictHostkeyChecking no\n" \
+ "\tGSSAPIDelegateCredentials yes\n" \
+ "\tGSSAPIServerIdentity example.com\n" \
+ "\tGSSAPIClientIdentity home.sweet\n" \
+ "\tUserKnownHostsFile "USER_KNOWN_HOSTS"\n"
+
+/* authentication methods */
+#define LIBSSH_TESTCONFIG_STRING8 \
+ "Host gss\n" \
+ "\tGSSAPIAuthentication yes\n" \
+ "Host kbd\n" \
+ "\tKbdInteractiveAuthentication yes\n" \
+ "Host pass\n" \
+ "\tPasswordAuthentication yes\n" \
+ "Host pubkey\n" \
+ "\tPubkeyAuthentication yes\n" \
+ "Host nogss\n" \
+ "\tGSSAPIAuthentication no\n" \
+ "Host nokbd\n" \
+ "\tKbdInteractiveAuthentication no\n" \
+ "Host nopass\n" \
+ "\tPasswordAuthentication no\n" \
+ "Host nopubkey\n" \
+ "\tPubkeyAuthentication no\n"
+
+/* unsupported options and corner cases */
+#define LIBSSH_TESTCONFIG_STRING9 \
+ "\n" /* empty line */ \
+ "# comment line\n" \
+ " # comment line not starting with hash\n" \
+ "UnknownConfigurationOption yes\n" \
+ "GSSAPIKexAlgorithms yes\n" \
+ "ControlMaster auto\n" /* SOC_NA */ \
+ "VisualHostkey yes\n" /* SOC_UNSUPPORTED */ \
+ "HostName =equal.sign\n" /* valid */ \
+ "ProxyJump = many-spaces.com\n" /* valid */
+
+/* Match keyword */
+#define LIBSSH_TESTCONFIG_STRING10 \
+ "Match host example\n" \
+ "\tHostName example.com\n" \
+ "Match host example1,example2\n" \
+ "\tHostName exampleN\n" \
+ "Match user guest\n" \
+ "\tHostName guest.com\n" \
+ "Match user tester host testhost\n" \
+ "\tHostName testhost.com\n" \
+ "Match !user tester host testhost\n" \
+ "\tHostName nonuser-testhost.com\n" \
+ "Match all\n" \
+ "\tHostName all-matched.com\n" \
+ /* Unsupported options */ \
+ "Match originalhost example\n" \
+ "\tHostName original-example.com\n" \
+ "Match localuser guest\n" \
+ "\tHostName local-guest.com\n"
+
+/* ProxyJump */
+#define LIBSSH_TESTCONFIG_STRING11 \
+ "Host simple\n" \
+ "\tProxyJump jumpbox\n" \
+ "Host user\n" \
+ "\tProxyJump user@jumpbox\n" \
+ "Host port\n" \
+ "\tProxyJump jumpbox:2222\n" \
+ "Host two-step\n" \
+ "\tProxyJump u1@first:222,u2@second:33\n" \
+ "Host none\n" \
+ "\tProxyJump none\n" \
+ "Host only-command\n" \
+ "\tProxyCommand "PROXYCMD"\n" \
+ "\tProxyJump jumpbox\n" \
+ "Host only-jump\n" \
+ "\tProxyJump jumpbox\n" \
+ "\tProxyCommand "PROXYCMD"\n" \
+ "Host ipv6\n" \
+ "\tProxyJump [2620:52:0::fed]\n"
+
+/* RekeyLimit combinations */
+#define LIBSSH_TESTCONFIG_STRING12 \
+ "Host default\n" \
+ "\tRekeyLimit default none\n" \
+ "Host data1\n" \
+ "\tRekeyLimit 42G\n" \
+ "Host data2\n" \
+ "\tRekeyLimit 31M\n" \
+ "Host data3\n" \
+ "\tRekeyLimit 521K\n" \
+ "Host time1\n" \
+ "\tRekeyLimit default 3D\n" \
+ "Host time2\n" \
+ "\tRekeyLimit default 2h\n" \
+ "Host time3\n" \
+ "\tRekeyLimit default 160m\n" \
+ "Host time4\n" \
+ "\tRekeyLimit default 9600\n"
+
+#define LIBSSH_TEST_PUBKEYTYPES_STRING \
+ "PubkeyAcceptedKeyTypes "PUBKEYACCEPTEDTYPES"\n"
+
+#define LIBSSH_TEST_NONEWLINEEND_STRING \
+ "ConnectTimeout 30\n" \
+ "LogLevel DEBUG3"
+
+#define LIBSSH_TEST_NONEWLINEONELINE_STRING \
+ "ConnectTimeout 30"
-#define USERNAME "testuser"
-#define PROXYCMD "ssh -q -W %h:%p gateway.example.com"
-#define ID_FILE "/etc/xxx"
-#define KEXALGORITHMS "ecdh-sha2-nistp521,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group14-sha1"
-#define HOSTKEYALGORITHMS "ssh-ed25519,ecdsa-sha2-nistp521,ssh-rsa"
-#define PUBKEYACCEPTEDTYPES "rsa-sha2-512,ssh-rsa,ecdsa-sha2-nistp521"
-#define MACS "hmac-sha1,hmac-sha2-256,hmac-sha2-512,hmac-sha1-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com"
-#define USER_KNOWN_HOSTS "%d/my_known_hosts"
-#define GLOBAL_KNOWN_HOSTS "/etc/ssh/my_ssh_known_hosts"
-#define BIND_ADDRESS "::1"
+/**
+ * @brief helper function loading configuration from either file or string
+ */
+static void _parse_config(ssh_session session,
+ const char *file, const char *string, int expected)
+{
+ int ret = -1;
+ /* make sure either config file or config string is given,
+ * not both */
+ assert_int_not_equal(file == NULL, string == NULL);
+ if (file != NULL) {
+ ret = ssh_config_parse_file(session, file);
+ } else if (string != NULL) {
+ ret = ssh_config_parse_string(session, string);
+ } else {
+ /* should not happen */
+ fail();
+ }
+
+ /* make sure parsing went as expected */
+ assert_ssh_return_code_equal(session, ret, expected);
+}
static int setup_config_files(void **state)
{
- ssh_session session;
- int verbosity;
+ (void) state; /* unused */
unlink(LIBSSH_TESTCONFIG1);
unlink(LIBSSH_TESTCONFIG2);
@@ -55,154 +219,68 @@ static int setup_config_files(void **state)
unlink(LIBSSH_TESTCONFIG10);
unlink(LIBSSH_TESTCONFIG11);
unlink(LIBSSH_TESTCONFIG12);
- unlink(LIBSSH_TEST_PUBKEYACCEPTEDKEYTYPES);
+ unlink(LIBSSH_TEST_PUBKEYTYPES);
+ unlink(LIBSSH_TEST_NONEWLINEEND);
+ unlink(LIBSSH_TEST_NONEWLINEONELINE);
torture_write_file(LIBSSH_TESTCONFIG1,
- "User "USERNAME"\nInclude "LIBSSH_TESTCONFIG2"\n\n");
+ LIBSSH_TESTCONFIG_STRING1);
torture_write_file(LIBSSH_TESTCONFIG2,
- "Include "LIBSSH_TESTCONFIG3"\n"
- "ProxyCommand "PROXYCMD"\n\n");
+ LIBSSH_TESTCONFIG_STRING2);
torture_write_file(LIBSSH_TESTCONFIG3,
- "\n\nIdentityFile "ID_FILE"\n"
- "\n\nKexAlgorithms "KEXALGORITHMS"\n"
- "\n\nHostKeyAlgorithms "HOSTKEYALGORITHMS"\n"
- "\n\nPubkeyAcceptedTypes "PUBKEYACCEPTEDTYPES"\n"
- "\n\nMACs "MACS"\n");
+ LIBSSH_TESTCONFIG_STRING3);
/* Multiple Port settings -> parsing returns early. */
torture_write_file(LIBSSH_TESTCONFIG4,
- "Port 123\nPort 456\n");
+ LIBSSH_TESTCONFIG_STRING4);
/* Testing glob include */
torture_write_file(LIBSSH_TESTCONFIG5,
- "User "USERNAME"\nInclude "LIBSSH_TESTCONFIGGLOB"\n\n");
+ LIBSSH_TESTCONFIG_STRING5);
torture_write_file(LIBSSH_TESTCONFIG6,
- "ProxyCommand "PROXYCMD"\n\n");
+ LIBSSH_TESTCONFIG_STRING6);
/* new options */
torture_write_file(LIBSSH_TESTCONFIG7,
- "\tBindAddress "BIND_ADDRESS"\n"
- "\tConnectTimeout 30\n"
- "\tLogLevel DEBUG3\n"
- "\tGlobalKnownHostsFile "GLOBAL_KNOWN_HOSTS"\n"
- "\tCompression yes\n"
- "\tStrictHostkeyChecking no\n"
- "\tGSSAPIDelegateCredentials yes\n"
- "\tGSSAPIServerIdentity example.com\n"
- "\tGSSAPIClientIdentity home.sweet\n"
- "\tUserKnownHostsFile "USER_KNOWN_HOSTS"\n");
+ LIBSSH_TESTCONFIG_STRING7);
/* authentication methods */
torture_write_file(LIBSSH_TESTCONFIG8,
- "Host gss\n"
- "\tGSSAPIAuthentication yes\n"
- "Host kbd\n"
- "\tKbdInteractiveAuthentication yes\n"
- "Host pass\n"
- "\tPasswordAuthentication yes\n"
- "Host pubkey\n"
- "\tPubkeyAuthentication yes\n"
- "Host nogss\n"
- "\tGSSAPIAuthentication no\n"
- "Host nokbd\n"
- "\tKbdInteractiveAuthentication no\n"
- "Host nopass\n"
- "\tPasswordAuthentication no\n"
- "Host nopubkey\n"
- "\tPubkeyAuthentication no\n");
+ LIBSSH_TESTCONFIG_STRING8);
/* unsupported options and corner cases */
torture_write_file(LIBSSH_TESTCONFIG9,
- "\n" /* empty line */
- "# comment line\n"
- " # comment line not starting with hash\n"
- "UnknownConfigurationOption yes\n"
- "GSSAPIKexAlgorithms yes\n"
- "ControlMaster auto\n" /* SOC_NA */
- "VisualHostkey yes\n" /* SOC_UNSUPPORTED */
- "HostName =equal.sign\n" /* valid */
- "ProxyJump = many-spaces.com\n" /* valid */
- "");
+ LIBSSH_TESTCONFIG_STRING9);
/* Match keyword */
torture_write_file(LIBSSH_TESTCONFIG10,
- "Match host example\n"
- "\tHostName example.com\n"
- "Match host example1,example2\n"
- "\tHostName exampleN\n"
- "Match user guest\n"
- "\tHostName guest.com\n"
- "Match user tester host testhost\n"
- "\tHostName testhost.com\n"
- "Match !user tester host testhost\n"
- "\tHostName nonuser-testhost.com\n"
- "Match all\n"
- "\tHostName all-matched.com\n"
- /* Unsupported options */
- "Match originalhost example\n"
- "\tHostName original-example.com\n"
- "Match localuser guest\n"
- "\tHostName local-guest.com\n"
- "");
+ LIBSSH_TESTCONFIG_STRING10);
/* ProxyJump */
torture_write_file(LIBSSH_TESTCONFIG11,
- "Host simple\n"
- "\tProxyJump jumpbox\n"
- "Host user\n"
- "\tProxyJump user@jumpbox\n"
- "Host port\n"
- "\tProxyJump jumpbox:2222\n"
- "Host two-step\n"
- "\tProxyJump u1@first:222,u2@second:33\n"
- "Host none\n"
- "\tProxyJump none\n"
- "Host only-command\n"
- "\tProxyCommand "PROXYCMD"\n"
- "\tProxyJump jumpbox\n"
- "Host only-jump\n"
- "\tProxyJump jumpbox\n"
- "\tProxyCommand "PROXYCMD"\n"
- "Host ipv6\n"
- "\tProxyJump [2620:52:0::fed]\n"
- "");
+ LIBSSH_TESTCONFIG_STRING11);
/* RekeyLimit combinations */
torture_write_file(LIBSSH_TESTCONFIG12,
- "Host default\n"
- "\tRekeyLimit default none\n"
- "Host data1\n"
- "\tRekeyLimit 42G\n"
- "Host data2\n"
- "\tRekeyLimit 31M\n"
- "Host data3\n"
- "\tRekeyLimit 521K\n"
- "Host time1\n"
- "\tRekeyLimit default 3D\n"
- "Host time2\n"
- "\tRekeyLimit default 2h\n"
- "Host time3\n"
- "\tRekeyLimit default 160m\n"
- "Host time4\n"
- "\tRekeyLimit default 9600\n"
- "");
-
- torture_write_file(LIBSSH_TEST_PUBKEYACCEPTEDKEYTYPES,
- "PubkeyAcceptedKeyTypes "PUBKEYACCEPTEDTYPES"\n");
+ LIBSSH_TESTCONFIG_STRING12);
- session = ssh_new();
+ torture_write_file(LIBSSH_TEST_PUBKEYTYPES,
+ LIBSSH_TEST_PUBKEYTYPES_STRING);
- verbosity = torture_libssh_verbosity();
- ssh_options_set(session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity);
+ torture_write_file(LIBSSH_TEST_NONEWLINEEND,
+ LIBSSH_TEST_NONEWLINEEND_STRING);
- *state = session;
+ torture_write_file(LIBSSH_TEST_NONEWLINEONELINE,
+ LIBSSH_TEST_NONEWLINEONELINE_STRING);
return 0;
}
-static int teardown(void **state)
+static int teardown_config_files(void **state)
{
+ (void) state; /* unused */
+
unlink(LIBSSH_TESTCONFIG1);
unlink(LIBSSH_TESTCONFIG2);
unlink(LIBSSH_TESTCONFIG3);
@@ -215,27 +293,47 @@ static int teardown(void **state)
unlink(LIBSSH_TESTCONFIG10);
unlink(LIBSSH_TESTCONFIG11);
unlink(LIBSSH_TESTCONFIG12);
- unlink(LIBSSH_TEST_PUBKEYACCEPTEDKEYTYPES);
+ unlink(LIBSSH_TEST_PUBKEYTYPES);
+ return 0;
+}
+
+static int setup(void **state)
+{
+ ssh_session session = NULL;
+ int verbosity;
+
+ session = ssh_new();
+
+ verbosity = torture_libssh_verbosity();
+ ssh_options_set(session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity);
+
+ *state = session;
+
+ return 0;
+}
+
+static int teardown(void **state)
+{
ssh_free(*state);
return 0;
}
/**
- * @brief tests ssh_config_parse_file with Include directives
+ * @brief tests ssh config parsing with Include directives
*/
-static void torture_config_from_file(void **state) {
- ssh_session session = *state;
+static void torture_config_include(void **state,
+ const char *file, const char *string)
+{
int ret;
char *v = NULL;
char *fips_algos = NULL;
+ ssh_session session = *state;
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG1);
- assert_true(ret == 0);
+ _parse_config(session, file, string, SSH_OK);
/* Test the variable presence */
-
ret = ssh_options_get(session, SSH_OPTIONS_PROXYCOMMAND, &v);
assert_true(ret == 0);
assert_non_null(v);
@@ -264,7 +362,8 @@ static void torture_config_from_file(void **state) {
SAFE_FREE(fips_algos);
fips_algos = ssh_keep_fips_algos(SSH_HOSTKEYS, HOSTKEYALGORITHMS);
assert_non_null(fips_algos);
- assert_string_equal(session->opts.wanted_methods[SSH_HOSTKEYS], fips_algos);
+ assert_string_equal(session->opts.wanted_methods[SSH_HOSTKEYS],
+ fips_algos);
SAFE_FREE(fips_algos);
fips_algos = ssh_keep_fips_algos(SSH_HOSTKEYS, PUBKEYACCEPTEDTYPES);
assert_non_null(fips_algos);
@@ -272,19 +371,24 @@ static void torture_config_from_file(void **state) {
SAFE_FREE(fips_algos);
fips_algos = ssh_keep_fips_algos(SSH_MAC_C_S, MACS);
assert_non_null(fips_algos);
- assert_string_equal(session->opts.wanted_methods[SSH_MAC_C_S], fips_algos);
+ assert_string_equal(session->opts.wanted_methods[SSH_MAC_C_S],
+ fips_algos);
SAFE_FREE(fips_algos);
fips_algos = ssh_keep_fips_algos(SSH_MAC_S_C, MACS);
assert_non_null(fips_algos);
- assert_string_equal(session->opts.wanted_methods[SSH_MAC_S_C], fips_algos);
+ assert_string_equal(session->opts.wanted_methods[SSH_MAC_S_C],
+ fips_algos);
SAFE_FREE(fips_algos);
} else {
assert_non_null(session->opts.wanted_methods[SSH_KEX]);
- assert_string_equal(session->opts.wanted_methods[SSH_KEX], KEXALGORITHMS);
+ assert_string_equal(session->opts.wanted_methods[SSH_KEX],
+ KEXALGORITHMS);
assert_non_null(session->opts.wanted_methods[SSH_HOSTKEYS]);
- assert_string_equal(session->opts.wanted_methods[SSH_HOSTKEYS], HOSTKEYALGORITHMS);
+ assert_string_equal(session->opts.wanted_methods[SSH_HOSTKEYS],
+ HOSTKEYALGORITHMS);
assert_non_null(session->opts.pubkey_accepted_types);
- assert_string_equal(session->opts.pubkey_accepted_types, PUBKEYACCEPTEDTYPES);
+ assert_string_equal(session->opts.pubkey_accepted_types,
+ PUBKEYACCEPTEDTYPES);
assert_non_null(session->opts.wanted_methods[SSH_MAC_S_C]);
assert_string_equal(session->opts.wanted_methods[SSH_MAC_C_S], MACS);
assert_non_null(session->opts.wanted_methods[SSH_MAC_S_C]);
@@ -293,27 +397,49 @@ static void torture_config_from_file(void **state) {
}
/**
+ * @brief tests ssh_config_parse_file with Include directives from file
+ */
+static void torture_config_include_file(void **state)
+{
+ torture_config_include(state, LIBSSH_TESTCONFIG1, NULL);
+}
+
+/**
+ * @brief tests ssh_config_parse_string with Include directives from string
+ */
+static void torture_config_include_string(void **state)
+{
+ torture_config_include(state, NULL, LIBSSH_TESTCONFIG_STRING1);
+}
+
+/**
* @brief tests ssh_config_parse_file with multiple Port settings.
*/
-static void torture_config_double_ports(void **state) {
- ssh_session session = *state;
- int ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG4);
- assert_true(ret == 0);
+static void torture_config_double_ports_file(void **state)
+{
+ _parse_config(*state, LIBSSH_TESTCONFIG4, NULL, SSH_OK);
}
-static void torture_config_glob(void **state) {
- ssh_session session = *state;
- int ret;
+/**
+ * @brief tests ssh_config_parse_string with multiple Port settings.
+ */
+static void torture_config_double_ports_string(void **state)
+{
+ _parse_config(*state, NULL, LIBSSH_TESTCONFIG_STRING4, SSH_OK);
+}
+
+static void torture_config_glob(void **state,
+ const char *file, const char *string)
+{
#if defined(HAVE_GLOB) && defined(HAVE_GLOB_GL_FLAGS_MEMBER)
+ int ret;
char *v;
-#endif /* HAVE_GLOB && HAVE_GLOB_GL_FLAGS_MEMBER */
+ ssh_session session = *state;
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG5);
- assert_true(ret == 0); /* non-existing files should not error */
+ _parse_config(session, file, string, SSH_OK);
/* Test the variable presence */
-#if defined(HAVE_GLOB) && defined(HAVE_GLOB_GL_FLAGS_MEMBER)
ret = ssh_options_get(session, SSH_OPTIONS_PROXYCOMMAND, &v);
assert_true(ret == 0);
assert_non_null(v);
@@ -330,16 +456,25 @@ static void torture_config_glob(void **state) {
#endif /* HAVE_GLOB && HAVE_GLOB_GL_FLAGS_MEMBER */
}
+static void torture_config_glob_file(void **state)
+{
+ torture_config_glob(state, LIBSSH_TESTCONFIG5, NULL);
+}
+
+static void torture_config_glob_string(void **state)
+{
+ torture_config_glob(state, NULL, LIBSSH_TESTCONFIG_STRING5);
+}
+
/**
* @brief Verify the new options are passed from configuration
*/
-static void torture_config_new(void **state)
+static void torture_config_new(void ** state,
+ const char *file, const char *string)
{
ssh_session session = *state;
- int ret = 0;
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG7);
- assert_true(ret == 0);
+ _parse_config(session, file, string, SSH_OK);
assert_string_equal(session->opts.knownhosts, USER_KNOWN_HOSTS);
assert_string_equal(session->opts.global_knownhosts, GLOBAL_KNOWN_HOSTS);
@@ -363,33 +498,40 @@ static void torture_config_new(void **state)
assert_int_equal(session->common.log_verbosity, SSH_LOG_TRACE);
}
+static void torture_config_new_file(void **state)
+{
+ torture_config_new(state, LIBSSH_TESTCONFIG7, NULL);
+}
+
+static void torture_config_new_string(void **state)
+{
+ torture_config_new(state, NULL, LIBSSH_TESTCONFIG_STRING7);
+}
+
/**
* @brief Verify the authentication methods from configuration are effective
*/
-static void torture_config_auth_methods(void **state) {
+static void torture_config_auth_methods(void **state,
+ const char *file, const char *string)
+{
ssh_session session = *state;
- int ret = 0;
/* gradually disable all the methods based on different hosts */
ssh_options_set(session, SSH_OPTIONS_HOST, "nogss");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG8);
- assert_true(ret == 0);
+ _parse_config(session, file, string, SSH_OK);
assert_false(session->opts.flags & SSH_OPT_FLAG_GSSAPI_AUTH);
assert_true(session->opts.flags & SSH_OPT_FLAG_KBDINT_AUTH);
ssh_options_set(session, SSH_OPTIONS_HOST, "nokbd");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG8);
- assert_true(ret == 0);
+ _parse_config(session, file, string, SSH_OK);
assert_false(session->opts.flags & SSH_OPT_FLAG_KBDINT_AUTH);
ssh_options_set(session, SSH_OPTIONS_HOST, "nopass");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG8);
- assert_true(ret == 0);
+ _parse_config(session, file, string, SSH_OK);
assert_false(session->opts.flags & SSH_OPT_FLAG_PASSWORD_AUTH);
ssh_options_set(session, SSH_OPTIONS_HOST, "nopubkey");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG8);
- assert_true(ret == 0);
+ _parse_config(session, file, string, SSH_OK);
assert_false(session->opts.flags & SSH_OPT_FLAG_PUBKEY_AUTH);
/* no method should be left enabled */
@@ -398,39 +540,55 @@ static void torture_config_auth_methods(void **state) {
/* gradually enable them again */
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "gss");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG8);
- assert_true(ret == 0);
+ _parse_config(session, file, string, SSH_OK);
assert_true(session->opts.flags & SSH_OPT_FLAG_GSSAPI_AUTH);
assert_false(session->opts.flags & SSH_OPT_FLAG_KBDINT_AUTH);
ssh_options_set(session, SSH_OPTIONS_HOST, "kbd");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG8);
- assert_true(ret == 0);
+ _parse_config(session, file, string, SSH_OK);
assert_true(session->opts.flags & SSH_OPT_FLAG_KBDINT_AUTH);
ssh_options_set(session, SSH_OPTIONS_HOST, "pass");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG8);
- assert_true(ret == 0);
+ _parse_config(session, file, string, SSH_OK);
assert_true(session->opts.flags & SSH_OPT_FLAG_PASSWORD_AUTH);
ssh_options_set(session, SSH_OPTIONS_HOST, "pubkey");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG8);
- assert_true(ret == 0);
+ _parse_config(session, file, string, SSH_OK);
assert_true(session->opts.flags & SSH_OPT_FLAG_PUBKEY_AUTH);
}
/**
+ * @brief Verify the authentication methods from configuration file
+ * are effective
+ */
+static void torture_config_auth_methods_file(void **state)
+{
+ torture_config_auth_methods(state, LIBSSH_TESTCONFIG8, NULL);
+}
+
+/**
+ * @brief Verify the authentication methods from configuration string
+ * are effective
+ */
+static void torture_config_auth_methods_string(void **state)
+{
+ torture_config_auth_methods(state, NULL, LIBSSH_TESTCONFIG_STRING8);
+}
+
+/**
* @brief Verify the configuration parser does not choke on unknown
* or unsupported configuration options
*/
-static void torture_config_unknown(void **state) {
+static void torture_config_unknown(void **state,
+ const char *file, const char *string)
+{
ssh_session session = *state;
int ret = 0;
/* test corner cases */
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG9);
- assert_true(ret == 0);
- assert_string_equal(session->opts.ProxyCommand, "ssh -W [%h]:%p many-spaces.com");
+ _parse_config(session, file, string, SSH_OK);
+ assert_string_equal(session->opts.ProxyCommand,
+ "ssh -W [%h]:%p many-spaces.com");
assert_string_equal(session->opts.host, "equal.sign");
ret = ssh_config_parse_file(session, "/etc/ssh/ssh_config");
@@ -439,128 +597,155 @@ static void torture_config_unknown(void **state) {
assert_true(ret == 0);
}
+/**
+ * @brief Verify the configuration parser does not choke on unknown
+ * or unsupported configuration options in configuration file
+ */
+static void torture_config_unknown_file(void **state)
+{
+ torture_config_unknown(state, LIBSSH_TESTCONFIG9, NULL);
+}
+
+/**
+ * @brief Verify the configuration parser does not choke on unknown
+ * or unsupported configuration options in configuration string
+ */
+static void torture_config_unknown_string(void **state)
+{
+ torture_config_unknown(state, NULL, LIBSSH_TESTCONFIG_STRING9);
+}
/**
* @brief Verify the configuration parser accepts Match keyword with
* full OpenSSH syntax.
*/
-static void torture_config_match(void **state)
+static void torture_config_match(void **state,
+ const char *file, const char *string)
{
ssh_session session = *state;
char *localuser = NULL;
- char config[1024];
- int ret = 0;
+ const char *config;
+ char config_string[1024];
/* Without any settings we should get all-matched.com hostname */
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "unmatched");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG10);
- assert_ssh_return_code(session, ret);
+ _parse_config(session, file, string, SSH_OK);
assert_string_equal(session->opts.host, "all-matched.com");
/* Hostname example does simple hostname matching */
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "example");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG10);
- assert_ssh_return_code(session, ret);
+ _parse_config(session, file, string, SSH_OK);
assert_string_equal(session->opts.host, "example.com");
/* We can match also both hosts from a comma separated list */
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "example1");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG10);
- assert_ssh_return_code(session, ret);
+ _parse_config(session, file, string, SSH_OK);
assert_string_equal(session->opts.host, "exampleN");
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "example2");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG10);
- assert_ssh_return_code(session, ret);
+ _parse_config(session, file, string, SSH_OK);
assert_string_equal(session->opts.host, "exampleN");
/* We can match by user */
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_USER, "guest");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG10);
- assert_ssh_return_code(session, ret);
+ _parse_config(session, file, string, SSH_OK);
assert_string_equal(session->opts.host, "guest.com");
/* We can combine two options on a single line to match both of them */
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_USER, "tester");
ssh_options_set(session, SSH_OPTIONS_HOST, "testhost");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG10);
- assert_ssh_return_code(session, ret);
+ _parse_config(session, file, string, SSH_OK);
assert_string_equal(session->opts.host, "testhost.com");
/* We can also negate conditions */
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_USER, "not-tester");
ssh_options_set(session, SSH_OPTIONS_HOST, "testhost");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG10);
- assert_ssh_return_code(session, ret);
+ _parse_config(session, file, string, SSH_OK);
assert_string_equal(session->opts.host, "nonuser-testhost.com");
+ /* In this part, we try various other config files and strings. */
+
/* Match final is not completely supported, but should do quite much the
* same as "match all". The trailing "all" is not mandatory. */
- torture_write_file(LIBSSH_TESTCONFIG10,
- "Match final all\n"
- "\tHostName final-all.com\n"
- "");
+ config = "Match final all\n"
+ "\tHostName final-all.com\n";
+ if (file != NULL) {
+ torture_write_file(file, config);
+ } else {
+ string = config;
+ }
torture_reset_config(session);
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG10);
- assert_ssh_return_code(session, ret);
+ _parse_config(session, file, string, SSH_OK);
assert_string_equal(session->opts.host, "final-all.com");
- torture_write_file(LIBSSH_TESTCONFIG10,
- "Match final\n"
- "\tHostName final.com\n"
- "");
+ config = "Match final\n"
+ "\tHostName final.com\n";
+ if (file != NULL) {
+ torture_write_file(file, config);
+ } else {
+ string = config;
+ }
torture_reset_config(session);
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG10);
- assert_ssh_return_code(session, ret);
+ _parse_config(session, file, string, SSH_OK);
assert_string_equal(session->opts.host, "final.com");
- /* Match canonical is not completely supported, but should do quite much the
- * same as "match all". The trailing "all" is not mandatory. */
- torture_write_file(LIBSSH_TESTCONFIG10,
- "Match canonical all\n"
- "\tHostName canonical-all.com\n"
- "");
+ /* Match canonical is not completely supported, but should do quite
+ * much the same as "match all". The trailing "all" is not mandatory. */
+ config = "Match canonical all\n"
+ "\tHostName canonical-all.com\n";
+ if (file != NULL) {
+ torture_write_file(file, config);
+ } else {
+ string = config;
+ }
torture_reset_config(session);
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG10);
- assert_ssh_return_code(session, ret);
+ _parse_config(session, file, string, SSH_OK);
assert_string_equal(session->opts.host, "canonical-all.com");
- torture_write_file(LIBSSH_TESTCONFIG10,
- "Match canonical all\n"
- "\tHostName canonical.com\n"
- "");
+ config = "Match canonical all\n"
+ "\tHostName canonical.com\n";
+ if (file != NULL) {
+ torture_write_file(file, config);
+ } else {
+ string = config;
+ }
torture_reset_config(session);
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG10);
- assert_ssh_return_code(session, ret);
+ _parse_config(session, file, string, SSH_OK);
assert_string_equal(session->opts.host, "canonical.com");
localuser = ssh_get_local_username();
assert_non_null(localuser);
- snprintf(config, sizeof(config),
+ snprintf(config_string, sizeof(config_string),
"Match localuser %s\n"
- "\tHostName otherhost\n"
- "", localuser);
+ "\tHostName otherhost\n",
+ localuser);
+ config = config_string;
free(localuser);
- torture_write_file(LIBSSH_TESTCONFIG10, config);
+ if (file != NULL) {
+ torture_write_file(file, config);
+ } else {
+ string = config;
+ }
torture_reset_config(session);
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG10);
- assert_ssh_return_code(session, ret);
+ _parse_config(session, file, string, SSH_OK);
assert_string_equal(session->opts.host, "otherhost");
- torture_write_file(LIBSSH_TESTCONFIG10,
- "Match exec true\n"
- "\tHostName execed-true.com\n"
- "");
+ config = "Match exec true\n"
+ "\tHostName execed-true.com\n";
+ if (file != NULL) {
+ torture_write_file(file, config);
+ } else {
+ string = config;
+ }
torture_reset_config(session);
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG10);
- assert_ssh_return_code(session, ret);
+ _parse_config(session, file, string, SSH_OK);
#ifdef _WIN32
/* The match exec is not supported on windows at this moment */
assert_string_equal(session->opts.host, "otherhost");
@@ -568,13 +753,15 @@ static void torture_config_match(void **state)
assert_string_equal(session->opts.host, "execed-true.com");
#endif
- torture_write_file(LIBSSH_TESTCONFIG10,
- "Match !exec false\n"
- "\tHostName execed-false.com\n"
- "");
+ config = "Match !exec false\n"
+ "\tHostName execed-false.com\n";
+ if (file != NULL) {
+ torture_write_file(file, config);
+ } else {
+ string = config;
+ }
torture_reset_config(session);
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG10);
- assert_ssh_return_code(session, ret);
+ _parse_config(session, file, string, SSH_OK);
#ifdef _WIN32
/* The match exec is not supported on windows at this moment */
assert_string_equal(session->opts.host, "otherhost");
@@ -582,13 +769,15 @@ static void torture_config_match(void **state)
assert_string_equal(session->opts.host, "execed-false.com");
#endif
- torture_write_file(LIBSSH_TESTCONFIG10,
- "Match exec \"test 1 -eq 1\"\n"
- "\tHostName execed-arguments.com\n"
- "");
+ config = "Match exec \"test 1 -eq 1\"\n"
+ "\tHostName execed-arguments.com\n";
+ if (file != NULL) {
+ torture_write_file(file, config);
+ } else {
+ string = config;
+ }
torture_reset_config(session);
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG10);
- assert_ssh_return_code(session, ret);
+ _parse_config(session, file, string, SSH_OK);
#ifdef _WIN32
/* The match exec is not supported on windows at this moment */
assert_string_equal(session->opts.host, "otherhost");
@@ -598,355 +787,435 @@ static void torture_config_match(void **state)
/* Try to create some invalid configurations */
/* Missing argument to Match*/
- torture_write_file(LIBSSH_TESTCONFIG10,
- "Match\n"
- "\tHost missing.com\n"
- "");
+ config = "Match\n"
+ "\tHost missing.com\n";
+ if (file != NULL) {
+ torture_write_file(file, config);
+ } else {
+ string = config;
+ }
torture_reset_config(session);
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG10);
- assert_ssh_return_code_equal(session, ret, SSH_ERROR);
+ _parse_config(session, file, string, SSH_ERROR);
/* Missing argument to unsupported option originalhost */
- torture_write_file(LIBSSH_TESTCONFIG10,
- "Match originalhost\n"
- "\tHost originalhost.com\n"
- "");
+ config = "Match originalhost\n"
+ "\tHost originalhost.com\n";
+ if (file != NULL) {
+ torture_write_file(file, config);
+ } else {
+ string = config;
+ }
torture_reset_config(session);
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG10);
- assert_ssh_return_code_equal(session, ret, SSH_ERROR);
+ _parse_config(session, file, string, SSH_ERROR);
/* Missing argument to option localuser */
- torture_write_file(LIBSSH_TESTCONFIG10,
- "Match localuser\n"
- "\tUser localuser2\n"
- "");
+ config = "Match localuser\n"
+ "\tUser localuser2\n";
+ if (file != NULL) {
+ torture_write_file(file, config);
+ } else {
+ string = config;
+ }
torture_reset_config(session);
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG10);
- assert_ssh_return_code_equal(session, ret, SSH_ERROR);
+ _parse_config(session, file, string, SSH_ERROR);
/* Missing argument to option user */
- torture_write_file(LIBSSH_TESTCONFIG10,
- "Match user\n"
- "\tUser user2\n"
- "");
+ config = "Match user\n"
+ "\tUser user2\n";
+ if (file != NULL) {
+ torture_write_file(file, config);
+ } else {
+ string = config;
+ }
torture_reset_config(session);
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG10);
- assert_ssh_return_code_equal(session, ret, SSH_ERROR);
+ _parse_config(session, file, string, SSH_ERROR);
/* Missing argument to option host */
- torture_write_file(LIBSSH_TESTCONFIG10,
- "Match host\n"
- "\tUser host2\n"
- "");
+ config = "Match host\n"
+ "\tUser host2\n";
+ if (file != NULL) {
+ torture_write_file(file, config);
+ } else {
+ string = config;
+ }
torture_reset_config(session);
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG10);
- assert_ssh_return_code_equal(session, ret, SSH_ERROR);
+ _parse_config(session, file, string, SSH_ERROR);
/* Missing argument to option exec */
- torture_write_file(LIBSSH_TESTCONFIG10,
- "Match exec\n"
- "\tUser exec\n"
- "");
+ config = "Match exec\n"
+ "\tUser exec\n";
+ if (file != NULL) {
+ torture_write_file(file, config);
+ } else {
+ string = config;
+ }
torture_reset_config(session);
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG10);
- assert_ssh_return_code_equal(session, ret, SSH_ERROR);
+ _parse_config(session, file, string, SSH_ERROR);
+}
+
+/**
+ * @brief Verify the configuration parser accepts Match keyword with
+ * full OpenSSH syntax through configuration file.
+ */
+static void torture_config_match_file(void **state)
+{
+ torture_config_match(state, LIBSSH_TESTCONFIG10, NULL);
+}
+
+/**
+ * @brief Verify the configuration parser accepts Match keyword with
+ * full OpenSSH syntax through configuration string.
+ */
+static void torture_config_match_string(void **state)
+{
+ torture_config_match(state, NULL, LIBSSH_TESTCONFIG_STRING10);
}
/**
* @brief Verify we can parse ProxyJump configuration option
*/
-static void torture_config_proxyjump(void **state) {
+static void torture_config_proxyjump(void **state,
+ const char *file, const char *string)
+{
ssh_session session = *state;
- int ret = 0;
+ const char *config;
/* Simplest version with just a hostname */
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "simple");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG11);
- assert_ssh_return_code(session, ret);
+ _parse_config(session, file, string, SSH_OK);
assert_string_equal(session->opts.ProxyCommand, "ssh -W [%h]:%p jumpbox");
/* With username */
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "user");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG11);
- assert_ssh_return_code(session, ret);
+ _parse_config(session, file, string, SSH_OK);
assert_string_equal(session->opts.ProxyCommand,
"ssh -l user -W [%h]:%p jumpbox");
/* With port */
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "port");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG11);
- assert_ssh_return_code(session, ret);
+ _parse_config(session, file, string, SSH_OK);
assert_string_equal(session->opts.ProxyCommand,
"ssh -p 2222 -W [%h]:%p jumpbox");
/* Two step jump */
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "two-step");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG11);
- assert_ssh_return_code(session, ret);
+ _parse_config(session, file, string, SSH_OK);
assert_string_equal(session->opts.ProxyCommand,
"ssh -l u1 -p 222 -J u2@second:33 -W [%h]:%p first");
/* none */
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "none");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG11);
- assert_ssh_return_code(session, ret);
+ _parse_config(session, file, string, SSH_OK);
assert_true(session->opts.ProxyCommand == NULL);
/* If also ProxyCommand is specifed, the first is applied */
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "only-command");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG11);
- assert_ssh_return_code(session, ret);
+ _parse_config(session, file, string, SSH_OK);
assert_string_equal(session->opts.ProxyCommand, PROXYCMD);
/* If also ProxyCommand is specifed, the first is applied */
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "only-jump");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG11);
- assert_ssh_return_code(session, ret);
+ _parse_config(session, file, string, SSH_OK);
assert_string_equal(session->opts.ProxyCommand,
"ssh -W [%h]:%p jumpbox");
/* IPv6 address */
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "ipv6");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG11);
- assert_ssh_return_code(session, ret);
+ _parse_config(session, file, string, SSH_OK);
assert_string_equal(session->opts.ProxyCommand,
"ssh -W [%h]:%p 2620:52:0::fed");
+ /* In this part, we try various other config files and strings. */
+
/* Try to create some invalid configurations */
/* Non-numeric port */
- torture_write_file(LIBSSH_TESTCONFIG11,
- "Host bad-port\n"
- "\tProxyJump jumpbox:22bad22\n"
- "");
+ config = "Host bad-port\n"
+ "\tProxyJump jumpbox:22bad22\n";
+ if (file != NULL) {
+ torture_write_file(file, config);
+ } else {
+ string = config;
+ }
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "bad-port");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG11);
- assert_ssh_return_code_equal(session, ret, SSH_ERROR);
+ _parse_config(session, file, string, SSH_ERROR);
/* Too many @ */
- torture_write_file(LIBSSH_TESTCONFIG11,
- "Host bad-hostname\n"
- "\tProxyJump user@principal.com@jumpbox:22\n"
- "");
+ config = "Host bad-hostname\n"
+ "\tProxyJump user@principal.com@jumpbox:22\n";
+ if (file != NULL) {
+ torture_write_file(file, config);
+ } else {
+ string = config;
+ }
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "bad-hostname");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG11);
- assert_ssh_return_code_equal(session, ret, SSH_ERROR);
+ _parse_config(session, file, string, SSH_ERROR);
/* Braces mismatch in hostname */
- torture_write_file(LIBSSH_TESTCONFIG11,
- "Host mismatch\n"
- "\tProxyJump [::1\n"
- "");
+ config = "Host mismatch\n"
+ "\tProxyJump [::1\n";
+ if (file != NULL) {
+ torture_write_file(file, config);
+ } else {
+ string = config;
+ }
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "mismatch");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG11);
- assert_ssh_return_code_equal(session, ret, SSH_ERROR);
+ _parse_config(session, file, string, SSH_ERROR);
/* Bad host-port separator */
- torture_write_file(LIBSSH_TESTCONFIG11,
- "Host beef\n"
- "\tProxyJump [dead::beef]::22\n"
- "");
+ config = "Host beef\n"
+ "\tProxyJump [dead::beef]::22\n";
+ if (file != NULL) {
+ torture_write_file(file, config);
+ } else {
+ string = config;
+ }
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "beef");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG11);
- assert_ssh_return_code_equal(session, ret, SSH_ERROR);
+ _parse_config(session, file, string, SSH_ERROR);
/* Missing hostname */
- torture_write_file(LIBSSH_TESTCONFIG11,
- "Host no-host\n"
- "\tProxyJump user@:22\n"
- "");
+ config = "Host no-host\n"
+ "\tProxyJump user@:22\n";
+ if (file != NULL) {
+ torture_write_file(file, config);
+ } else {
+ string = config;
+ }
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "no-host");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG11);
- assert_ssh_return_code_equal(session, ret, SSH_ERROR);
+ _parse_config(session, file, string, SSH_ERROR);
/* Missing user */
- torture_write_file(LIBSSH_TESTCONFIG11,
- "Host no-user\n"
- "\tProxyJump @host:22\n"
- "");
+ config = "Host no-user\n"
+ "\tProxyJump @host:22\n";
+ if (file != NULL) {
+ torture_write_file(file, config);
+ } else {
+ string = config;
+ }
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "no-user");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG11);
- assert_ssh_return_code_equal(session, ret, SSH_ERROR);
+ _parse_config(session, file, string, SSH_ERROR);
/* Missing port */
- torture_write_file(LIBSSH_TESTCONFIG11,
- "Host no-port\n"
- "\tProxyJump host:\n"
- "");
+ config = "Host no-port\n"
+ "\tProxyJump host:\n";
+ if (file != NULL) {
+ torture_write_file(file, config);
+ } else {
+ string = config;
+ }
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "no-port");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG11);
- assert_ssh_return_code_equal(session, ret, SSH_ERROR);
+ _parse_config(session, file, string, SSH_ERROR);
/* Non-numeric port in second jump */
- torture_write_file(LIBSSH_TESTCONFIG11,
- "Host bad-port-2\n"
- "\tProxyJump localhost,jumpbox:22bad22\n"
- "");
+ config = "Host bad-port-2\n"
+ "\tProxyJump localhost,jumpbox:22bad22\n";
+ if (file != NULL) {
+ torture_write_file(file, config);
+ } else {
+ string = config;
+ }
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "bad-port-2");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG11);
- assert_ssh_return_code_equal(session, ret, SSH_ERROR);
+ _parse_config(session, file, string, SSH_ERROR);
/* Too many @ in second jump */
- torture_write_file(LIBSSH_TESTCONFIG11,
- "Host bad-hostname\n"
- "\tProxyJump localhost,user@principal.com@jumpbox:22\n"
- "");
+ config = "Host bad-hostname\n"
+ "\tProxyJump localhost,user@principal.com@jumpbox:22\n";
+ if (file != NULL) {
+ torture_write_file(file, config);
+ } else {
+ string = config;
+ }
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "bad-hostname");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG11);
- assert_ssh_return_code_equal(session, ret, SSH_ERROR);
+ _parse_config(session, file, string, SSH_ERROR);
/* Braces mismatch in second jump */
- torture_write_file(LIBSSH_TESTCONFIG11,
- "Host mismatch\n"
- "\tProxyJump localhost,[::1:20\n"
- "");
+ config = "Host mismatch\n"
+ "\tProxyJump localhost,[::1:20\n";
+ if (file != NULL) {
+ torture_write_file(file, config);
+ } else {
+ string = config;
+ }
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "mismatch");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG11);
- assert_ssh_return_code_equal(session, ret, SSH_ERROR);
+ _parse_config(session, file, string, SSH_ERROR);
/* Bad host-port separator in second jump */
- torture_write_file(LIBSSH_TESTCONFIG11,
- "Host beef\n"
- "\tProxyJump localhost,[dead::beef]::22\n"
- "");
+ config = "Host beef\n"
+ "\tProxyJump localhost,[dead::beef]::22\n";
+ if (file != NULL) {
+ torture_write_file(file, config);
+ } else {
+ string = config;
+ }
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "beef");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG11);
- assert_ssh_return_code_equal(session, ret, SSH_ERROR);
+ _parse_config(session, file, string, SSH_ERROR);
/* Missing hostname in second jump */
- torture_write_file(LIBSSH_TESTCONFIG11,
- "Host no-host\n"
- "\tProxyJump localhost,user@:22\n"
- "");
+ config = "Host no-host\n"
+ "\tProxyJump localhost,user@:22\n";
+ if (file != NULL) {
+ torture_write_file(file, config);
+ } else {
+ string = config;
+ }
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "no-host");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG11);
- assert_ssh_return_code_equal(session, ret, SSH_ERROR);
+ _parse_config(session, file, string, SSH_ERROR);
/* Missing user in second jump */
- torture_write_file(LIBSSH_TESTCONFIG11,
- "Host no-user\n"
- "\tProxyJump localhost,@host:22\n"
- "");
+ config = "Host no-user\n"
+ "\tProxyJump localhost,@host:22\n";
+ if (file != NULL) {
+ torture_write_file(file, config);
+ } else {
+ string = config;
+ }
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "no-user");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG11);
- assert_ssh_return_code_equal(session, ret, SSH_ERROR);
+ _parse_config(session, file, string, SSH_ERROR);
/* Missing port in second jump */
- torture_write_file(LIBSSH_TESTCONFIG11,
- "Host no-port\n"
- "\tProxyJump localhost,host:\n"
- "");
+ config = "Host no-port\n"
+ "\tProxyJump localhost,host:\n";
+ if (file != NULL) {
+ torture_write_file(file, config);
+ } else {
+ string = config;
+ }
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "no-port");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG11);
- assert_ssh_return_code_equal(session, ret, SSH_ERROR);
+ _parse_config(session, file, string, SSH_ERROR);
+}
+
+/**
+ * @brief Verify we can parse ProxyJump configuration option from file
+ */
+static void torture_config_proxyjump_file(void **state)
+{
+ torture_config_proxyjump(state, LIBSSH_TESTCONFIG11, NULL);
+}
+
+/**
+ * @brief Verify we can parse ProxyJump configuration option from string
+ */
+static void torture_config_proxyjump_string(void **state)
+{
+ torture_config_proxyjump(state, NULL, LIBSSH_TESTCONFIG_STRING11);
}
/**
* @brief Verify the configuration parser handles all the possible
* versions of RekeyLimit configuration option.
*/
-static void torture_config_rekey(void **state)
+static void torture_config_rekey(void **state,
+ const char *file, const char *string)
{
ssh_session session = *state;
- int ret = 0;
/* Default values */
ssh_options_set(session, SSH_OPTIONS_HOST, "default");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG12);
- assert_ssh_return_code(session, ret);
+ _parse_config(session, file, string, SSH_OK);
assert_int_equal(session->opts.rekey_data, 0);
assert_int_equal(session->opts.rekey_time, 0);
/* 42 GB */
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "data1");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG12);
- assert_ssh_return_code(session, ret);
- assert_int_equal(session->opts.rekey_data, (uint64_t) 42 * 1024 * 1024 * 1024);
+ _parse_config(session, file, string, SSH_OK);
+ assert_int_equal(session->opts.rekey_data,
+ (uint64_t) 42 * 1024 * 1024 * 1024);
assert_int_equal(session->opts.rekey_time, 0);
/* 41 MB */
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "data2");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG12);
- assert_ssh_return_code(session, ret);
+ _parse_config(session, file, string, SSH_OK);
assert_int_equal(session->opts.rekey_data, 31 * 1024 * 1024);
assert_int_equal(session->opts.rekey_time, 0);
/* 521 KB */
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "data3");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG12);
- assert_ssh_return_code(session, ret);
+ _parse_config(session, file, string, SSH_OK);
assert_int_equal(session->opts.rekey_data, 521 * 1024);
assert_int_equal(session->opts.rekey_time, 0);
/* default 3D */
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "time1");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG12);
- assert_ssh_return_code(session, ret);
+ _parse_config(session, file, string, SSH_OK);
assert_int_equal(session->opts.rekey_data, 0);
assert_int_equal(session->opts.rekey_time, 3 * 24 * 60 * 60 * 1000);
/* default 2h */
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "time2");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG12);
- assert_ssh_return_code(session, ret);
+ _parse_config(session, file, string, SSH_OK);
assert_int_equal(session->opts.rekey_data, 0);
assert_int_equal(session->opts.rekey_time, 2 * 60 * 60 * 1000);
/* default 160m */
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "time3");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG12);
- assert_ssh_return_code(session, ret);
+ _parse_config(session, file, string, SSH_OK);
assert_int_equal(session->opts.rekey_data, 0);
assert_int_equal(session->opts.rekey_time, 160 * 60 * 1000);
/* default 9600 [s] */
torture_reset_config(session);
ssh_options_set(session, SSH_OPTIONS_HOST, "time4");
- ret = ssh_config_parse_file(session, LIBSSH_TESTCONFIG12);
- assert_ssh_return_code(session, ret);
+ _parse_config(session, file, string, SSH_OK);
assert_int_equal(session->opts.rekey_data, 0);
assert_int_equal(session->opts.rekey_time, 9600 * 1000);
}
/**
- * @brief test ssh_config_parse_file with PubkeyAcceptedKeyTypes
+ * @brief Verify the configuration parser handles all the possible
+ * versions of RekeyLimit configuration option in file
+ */
+static void torture_config_rekey_file(void **state)
+{
+ torture_config_rekey(state, LIBSSH_TESTCONFIG12, NULL);
+}
+
+/**
+ * @brief Verify the configuration parser handles all the possible
+ * versions of RekeyLimit configuration option in string
+ */
+static void torture_config_rekey_string(void **state)
+{
+ torture_config_rekey(state, NULL, LIBSSH_TESTCONFIG_STRING12);
+}
+
+/**
+ * @brief test PubkeyAcceptedKeyTypes helper function
*/
-static void torture_config_pubkeyacceptedkeytypes(void **state)
+static void torture_config_pubkeytypes(void **state,
+ const char *file, const char *string)
{
ssh_session session = *state;
- int rc;
char *fips_algos;
- rc = ssh_config_parse_file(session, LIBSSH_TEST_PUBKEYACCEPTEDKEYTYPES);
- assert_int_equal(rc, SSH_OK);
+ _parse_config(session, file, string, SSH_OK);
if (ssh_fips_mode()) {
fips_algos = ssh_keep_fips_algos(SSH_HOSTKEYS, PUBKEYACCEPTEDTYPES);
@@ -954,10 +1223,85 @@ static void torture_config_pubkeyacceptedkeytypes(void **state)
assert_string_equal(session->opts.pubkey_accepted_types, fips_algos);
SAFE_FREE(fips_algos);
} else {
- assert_string_equal(session->opts.pubkey_accepted_types, PUBKEYACCEPTEDTYPES);
+ assert_string_equal(session->opts.pubkey_accepted_types,
+ PUBKEYACCEPTEDTYPES);
}
}
+/**
+ * @brief test parsing PubkeyAcceptedKeyTypes from file
+ */
+static void torture_config_pubkeytypes_file(void **state)
+{
+ torture_config_pubkeytypes(state, LIBSSH_TEST_PUBKEYTYPES, NULL);
+}
+
+/**
+ * @brief test parsing PubkeyAcceptedKeyTypes from string
+ */
+static void torture_config_pubkeytypes_string(void **state)
+{
+ torture_config_pubkeytypes(state, NULL, LIBSSH_TEST_PUBKEYTYPES_STRING);
+}
+
+/**
+ * @brief Verify the configuration parser handles
+ * missing newline in the end
+ */
+static void torture_config_nonewlineend(void **state,
+ const char *file, const char *string)
+{
+ _parse_config(*state, file, string, SSH_OK);
+}
+
+/**
+ * @brief Verify the configuration parser handles
+ * missing newline in the end of file
+ */
+static void torture_config_nonewlineend_file(void **state)
+{
+ torture_config_nonewlineend(state, LIBSSH_TEST_NONEWLINEEND, NULL);
+}
+
+/**
+ * @brief Verify the configuration parser handles
+ * missing newline in the end of string
+ */
+static void torture_config_nonewlineend_string(void **state)
+{
+ torture_config_nonewlineend(state, NULL, LIBSSH_TEST_NONEWLINEEND_STRING);
+}
+
+/**
+ * @brief Verify the configuration parser handles
+ * missing newline in the end
+ */
+static void torture_config_nonewlineoneline(void **state,
+ const char *file,
+ const char *string)
+{
+ _parse_config(*state, file, string, SSH_OK);
+}
+
+/**
+ * @brief Verify the configuration parser handles
+ * missing newline in the end of file
+ */
+static void torture_config_nonewlineoneline_file(void **state)
+{
+ torture_config_nonewlineend(state, LIBSSH_TEST_NONEWLINEONELINE, NULL);
+}
+
+/**
+ * @brief Verify the configuration parser handles
+ * missing newline in the end of string
+ */
+static void torture_config_nonewlineoneline_string(void **state)
+{
+ torture_config_nonewlineoneline(state,
+ NULL, LIBSSH_TEST_NONEWLINEONELINE_STRING);
+}
+
/* ssh_config_get_cmd() does three things:
* * Strips leading whitespace
* * Terminate the characted on the end of next quotes-enclosed string
@@ -994,7 +1338,8 @@ static void torture_config_parser_get_cmd(void **state)
assert_string_equal(tok, "something");
assert_int_equal(*p, '\0');
- /* But it does not split tokens by whitespace if they are not quoted, which is weird */
+ /* But it does not split tokens by whitespace
+ * if they are not quoted, which is weird */
strncpy(data, "multi string something\n", sizeof(data));
p = data;
tok = ssh_config_get_cmd(&p);
@@ -1004,7 +1349,8 @@ static void torture_config_parser_get_cmd(void **state)
/* ssh_config_get_token() should behave as expected
* * Strip leading whitespace
- * * Return first token separated by whitespace or equal sign, respecting quotes!
+ * * Return first token separated by whitespace or equal sign,
+ * respecting quotes!
*/
static void torture_config_parser_get_token(void **state)
{
@@ -1206,7 +1552,8 @@ static void torture_config_match_pattern(void **state)
assert_int_equal(rv, 1);
rv = match_pattern("aa", "?", MAX_MATCH_RECURSION);
assert_int_equal(rv, 0);
- rv = match_pattern("?", "a", MAX_MATCH_RECURSION); /* Wildcard in search string */
+ /* Wildcard in search string */
+ rv = match_pattern("?", "a", MAX_MATCH_RECURSION);
assert_int_equal(rv, 0);
rv = match_pattern("?", "?", MAX_MATCH_RECURSION);
assert_int_equal(rv, 1);
@@ -1216,7 +1563,8 @@ static void torture_config_match_pattern(void **state)
assert_int_equal(rv, 1);
rv = match_pattern("aa", "*", MAX_MATCH_RECURSION);
assert_int_equal(rv, 1);
- rv = match_pattern("*", "a", MAX_MATCH_RECURSION); /* Wildcard in search string */
+ /* Wildcard in search string */
+ rv = match_pattern("*", "a", MAX_MATCH_RECURSION);
assert_int_equal(rv, 0);
rv = match_pattern("*", "*", MAX_MATCH_RECURSION);
assert_int_equal(rv, 1);
@@ -1256,34 +1604,78 @@ static void torture_config_match_pattern(void **state)
/* Limit the maximum recursion */
rv = match_pattern("hostname", "*p*a*t*t*e*r*n*", 5);
assert_int_equal(rv, 0);
- rv = match_pattern("pattern", "*p*a*t*t*e*r*n*", 5); /* Too much recursion */
+ /* Too much recursion */
+ rv = match_pattern("pattern", "*p*a*t*t*e*r*n*", 5);
assert_int_equal(rv, 0);
}
-int torture_run_tests(void) {
+int torture_run_tests(void)
+{
int rc;
struct CMUnitTest tests[] = {
- cmocka_unit_test(torture_config_from_file),
- cmocka_unit_test(torture_config_double_ports),
- cmocka_unit_test(torture_config_glob),
- cmocka_unit_test(torture_config_new),
- cmocka_unit_test(torture_config_auth_methods),
- cmocka_unit_test(torture_config_unknown),
- cmocka_unit_test(torture_config_match),
- cmocka_unit_test(torture_config_proxyjump),
- cmocka_unit_test(torture_config_rekey),
- cmocka_unit_test(torture_config_pubkeyacceptedkeytypes),
- cmocka_unit_test(torture_config_parser_get_cmd),
- cmocka_unit_test(torture_config_parser_get_token),
- cmocka_unit_test(torture_config_match_pattern),
+ cmocka_unit_test_setup_teardown(torture_config_include_file,
+ setup, teardown),
+ cmocka_unit_test_setup_teardown(torture_config_include_string,
+ setup, teardown),
+ cmocka_unit_test_setup_teardown(torture_config_double_ports_file,
+ setup, teardown),
+ cmocka_unit_test_setup_teardown(torture_config_double_ports_string,
+ setup, teardown),
+ cmocka_unit_test_setup_teardown(torture_config_glob_file,
+ setup, teardown),
+ cmocka_unit_test_setup_teardown(torture_config_glob_string,
+ setup, teardown),
+ cmocka_unit_test_setup_teardown(torture_config_new_file,
+ setup, teardown),
+ cmocka_unit_test_setup_teardown(torture_config_new_string,
+ setup, teardown),
+ cmocka_unit_test_setup_teardown(torture_config_auth_methods_file,
+ setup, teardown),
+ cmocka_unit_test_setup_teardown(torture_config_auth_methods_string,
+ setup, teardown),
+ cmocka_unit_test_setup_teardown(torture_config_unknown_file,
+ setup, teardown),
+ cmocka_unit_test_setup_teardown(torture_config_unknown_string,
+ setup, teardown),
+ cmocka_unit_test_setup_teardown(torture_config_match_file,
+ setup, teardown),
+ cmocka_unit_test_setup_teardown(torture_config_match_string,
+ setup, teardown),
+ cmocka_unit_test_setup_teardown(torture_config_proxyjump_file,
+ setup, teardown),
+ cmocka_unit_test_setup_teardown(torture_config_proxyjump_string,
+ setup, teardown),
+ cmocka_unit_test_setup_teardown(torture_config_rekey_file,
+ setup, teardown),
+ cmocka_unit_test_setup_teardown(torture_config_rekey_string,
+ setup, teardown),
+ cmocka_unit_test_setup_teardown(torture_config_pubkeytypes_file,
+ setup, teardown),
+ cmocka_unit_test_setup_teardown(torture_config_pubkeytypes_string,
+ setup, teardown),
+ cmocka_unit_test_setup_teardown(torture_config_nonewlineend_file,
+ setup, teardown),
+ cmocka_unit_test_setup_teardown(torture_config_nonewlineend_string,
+ setup, teardown),
+ cmocka_unit_test_setup_teardown(torture_config_nonewlineoneline_file,
+ setup, teardown),
+ cmocka_unit_test_setup_teardown(torture_config_nonewlineoneline_string,
+ setup, teardown),
+ cmocka_unit_test_setup_teardown(torture_config_parser_get_cmd,
+ setup, teardown),
+ cmocka_unit_test_setup_teardown(torture_config_parser_get_token,
+ setup, teardown),
+ cmocka_unit_test_setup_teardown(torture_config_match_pattern,
+ setup, teardown),
};
ssh_init();
torture_filter_tests(tests);
- rc = cmocka_run_group_tests(tests, setup_config_files, teardown);
+ rc = cmocka_run_group_tests(tests,
+ setup_config_files, teardown_config_files);
ssh_finalize();
return rc;
}