Skip to content

Commit a9e25dc

Browse files
romanmichalvasko
authored andcommitted
session ssh UPDATE add ssh banner support
1 parent 40862fb commit a9e25dc

File tree

6 files changed

+118
-1
lines changed

6 files changed

+118
-1
lines changed

modules/[email protected]

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,23 @@ module libnetconf2-netconf-server {
269269
}
270270
}
271271

272+
grouping ssh-server-banner-grouping {
273+
description
274+
"Grouping for the SSH server banner.";
275+
276+
leaf banner {
277+
type string {
278+
length "1..247";
279+
}
280+
description
281+
"The banner that will be sent to the client when connecting to the server.
282+
If not set, the libnetconf2 default with its version will be used.";
283+
284+
reference
285+
"RFC 4253: The Secure Shell (SSH) Transport Layer Protocol, section 4.2.";
286+
}
287+
}
288+
272289
grouping system-auth-public-keys-grouping {
273290
description
274291
"Grouping for using the system configured keys in the SSH public key authentication method.";
@@ -350,6 +367,16 @@ module libnetconf2-netconf-server {
350367
uses ssh-authentication-params-grouping;
351368
}
352369

370+
augment "/ncs:netconf-server/ncs:listen/ncs:endpoints/ncs:endpoint/ncs:transport/ncs:ssh" +
371+
"/ncs:ssh/ncs:ssh-server-parameters/ncs:server-identity" {
372+
uses ssh-server-banner-grouping;
373+
}
374+
375+
augment "/ncs:netconf-server/ncs:call-home/ncs:netconf-client/ncs:endpoints" +
376+
"/ncs:endpoint/ncs:transport/ncs:ssh/ncs:ssh/ncs:ssh-server-parameters/ncs:server-identity" {
377+
uses ssh-authentication-params-grouping;
378+
}
379+
353380
augment "/ncs:netconf-server/ncs:listen/ncs:endpoints/ncs:endpoint/ncs:transport/ncs:ssh/ncs:ssh/ncs:ssh-server-parameters" +
354381
"/ncs:client-authentication/ncs:users/ncs:user/ncs:public-keys/ncs:inline-or-truststore" {
355382
case system-auth-public-keys {

src/server_config.c

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -663,6 +663,8 @@ nc_server_config_del_ssh_opts(struct nc_bind *bind, struct nc_server_ssh_opts *o
663663
free(opts->encryption_algs);
664664
free(opts->mac_algs);
665665

666+
free(opts->banner);
667+
666668
free(opts);
667669
}
668670

@@ -2970,6 +2972,43 @@ nc_server_config_asymmetric_key(const struct lyd_node *node, enum nc_operation o
29702972
return ret;
29712973
}
29722974

2975+
static int
2976+
nc_server_config_banner(const struct lyd_node *node, enum nc_operation op)
2977+
{
2978+
int ret = 0;
2979+
struct nc_server_ssh_opts *opts;
2980+
struct nc_ch_client *ch_client = NULL;
2981+
2982+
assert(!strcmp(LYD_NAME(node), "banner"));
2983+
2984+
if (is_ch(node) && nc_server_config_get_ch_client_with_lock(node, &ch_client)) {
2985+
/* to avoid unlock on fail */
2986+
return 1;
2987+
}
2988+
2989+
if (nc_server_config_get_ssh_opts(node, ch_client, &opts)) {
2990+
ret = 1;
2991+
goto cleanup;
2992+
}
2993+
2994+
if ((op == NC_OP_CREATE) || (op == NC_OP_REPLACE)) {
2995+
free(opts->banner);
2996+
opts->banner = strdup(lyd_get_value(node));
2997+
NC_CHECK_ERRMEM_GOTO(!opts->banner, ret = 1, cleanup);
2998+
} else {
2999+
free(opts->banner);
3000+
opts->banner = NULL;
3001+
}
3002+
3003+
cleanup:
3004+
if (is_ch(node)) {
3005+
/* UNLOCK */
3006+
nc_ch_client_unlock(ch_client);
3007+
}
3008+
3009+
return ret;
3010+
}
3011+
29733012
static int
29743013
nc_server_config_client_authentication(const struct lyd_node *node, enum nc_operation op)
29753014
{
@@ -3881,6 +3920,8 @@ nc_server_config_parse_netconf_server(const struct lyd_node *node, enum nc_opera
38813920
ret = nc_server_config_auth_timeout(node, op);
38823921
} else if (!strcmp(name, "asymmetric-key")) {
38833922
ret = nc_server_config_asymmetric_key(node, op);
3923+
} else if (!strcmp(name, "banner")) {
3924+
ret = nc_server_config_banner(node, op);
38843925
} else if (!strcmp(name, "ca-certs")) {
38853926
ret = nc_server_config_ca_certs(node, op);
38863927
} else if (!strcmp(name, "central-keystore-reference")) {

src/session.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -615,6 +615,29 @@ nc_session_get_port(const struct nc_session *session)
615615
return session->port;
616616
}
617617

618+
#ifdef NC_ENABLED_SSH_TLS
619+
620+
API const char *
621+
nc_session_ssh_get_banner(const struct nc_session *session)
622+
{
623+
NC_CHECK_ARG_RET(NULL, session, NULL);
624+
625+
if (session->ti_type != NC_TI_SSH) {
626+
ERR(NULL, "Cannot get the SSH banner of a non-SSH session.");
627+
return NULL;
628+
}
629+
630+
if (session->side == NC_SERVER) {
631+
/* get the banner sent by the client */
632+
return ssh_get_clientbanner(session->ti.libssh.session);
633+
} else {
634+
/* get the banner received from the server */
635+
return ssh_get_serverbanner(session->ti.libssh.session);
636+
}
637+
}
638+
639+
#endif
640+
618641
API const struct ly_ctx *
619642
nc_session_get_ctx(const struct nc_session *session)
620643
{

src/session.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,18 @@ const char *nc_session_get_host(const struct nc_session *session);
191191
*/
192192
uint16_t nc_session_get_port(const struct nc_session *session);
193193

194+
#ifdef NC_ENABLED_SSH_TLS
195+
196+
/**
197+
* @brief Get the SSH banner sent by the peer.
198+
*
199+
* @param[in] session Session to get the banner from.
200+
* @return SSH banner on success, NULL on error.
201+
*/
202+
const char *nc_session_ssh_get_banner(const struct nc_session *session);
203+
204+
#endif
205+
194206
/**
195207
* @brief Get session path (unix socket only).
196208
*

src/session_p.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,8 @@ struct nc_server_ssh_opts {
214214
char *kex_algs; /**< Key exchange algorithms supported by the server. */
215215
char *mac_algs; /**< MAC algorithms supported by the server. */
216216

217+
char *banner; /**< SSH banner message. */
218+
217219
uint16_t auth_timeout; /**< Authentication timeout. */
218220
};
219221

src/session_server_ssh.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242

4343
#include "compat.h"
4444
#include "log_p.h"
45+
#include "nc_version.h"
4546
#include "session.h"
4647
#include "session_p.h"
4748
#include "session_wrapper.h"
@@ -1918,7 +1919,7 @@ nc_accept_ssh_session(struct nc_session *session, struct nc_server_ssh_opts *opt
19181919
ssh_bind sbind = NULL;
19191920
int rc = 1, r;
19201921
struct timespec ts_timeout;
1921-
const char *err_msg;
1922+
const char *err_msg, *banner;
19221923

19231924
/* other transport-specific data */
19241925
session->ti_type = NC_TI_SSH;
@@ -1960,6 +1961,17 @@ nc_accept_ssh_session(struct nc_session *session, struct nc_server_ssh_opts *opt
19601961
goto cleanup;
19611962
}
19621963

1964+
/* configure the ssh banner */
1965+
if (opts->banner) {
1966+
banner = opts->banner;
1967+
} else {
1968+
banner = "libnetconf2-" NC_VERSION;
1969+
}
1970+
if (ssh_bind_options_set(sbind, SSH_BIND_OPTIONS_BANNER, banner)) {
1971+
rc = -1;
1972+
goto cleanup;
1973+
}
1974+
19631975
/* accept new connection on the bind */
19641976
if (ssh_bind_accept_fd(sbind, session->ti.libssh.session, sock) == SSH_ERROR) {
19651977
ERR(session, "SSH failed to accept a new connection (%s).", ssh_get_error(sbind));

0 commit comments

Comments
 (0)