diff options
8 files changed, 1017 insertions, 0 deletions
diff --git a/meta-oe/recipes-support/libssh/libssh/0001-config-Move-common-parser-functions-to-config_parser.patch b/meta-oe/recipes-support/libssh/libssh/0001-config-Move-common-parser-functions-to-config_parser.patch new file mode 100644 index 0000000000..f26b644102 --- /dev/null +++ b/meta-oe/recipes-support/libssh/libssh/0001-config-Move-common-parser-functions-to-config_parser.patch | |||
| @@ -0,0 +1,464 @@ | |||
| 1 | From 79049981a513f9a10fac0f153e9b0b588326021f Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Anderson Toshiyuki Sasaki <ansasaki@redhat.com> | ||
| 3 | Date: Fri, 22 Feb 2019 13:06:49 +0100 | ||
| 4 | Subject: [PATCH] config: Move common parser functions to config_parser.c | ||
| 5 | |||
| 6 | This will allow the moved functions to be used in the server side | ||
| 7 | configuration parser implementation. | ||
| 8 | |||
| 9 | Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com> | ||
| 10 | Reviewed-by: Andreas Schneider <asn@cryptomilk.org> | ||
| 11 | |||
| 12 | CVE:CVE-2023-6004 | ||
| 13 | Upstream-Status: Backport [https://git.libssh.org/projects/libssh.git/commit/?id=79049981a513f9a10fac0f153e9b0b588326021f] | ||
| 14 | Signed-off-by: nikhil r <nikhil.r@kpit.com> | ||
| 15 | Comment: Removed 1 hunk from config.c as the function was intoduced in | ||
| 16 | later version | ||
| 17 | |||
| 18 | --- | ||
| 19 | include/libssh/config_parser.h | 57 ++++++++ | ||
| 20 | src/CMakeLists.txt | 1 + | ||
| 21 | src/config.c | 216 +----------------------------- | ||
| 22 | src/config_parser.c | 238 +++++++++++++++++++++++++++++++++ | ||
| 23 | 4 files changed, 297 insertions(+), 215 deletions(-) | ||
| 24 | create mode 100644 include/libssh/config_parser.h | ||
| 25 | create mode 100644 src/config_parser.c | ||
| 26 | |||
| 27 | diff --git a/include/libssh/config_parser.h b/include/libssh/config_parser.h | ||
| 28 | new file mode 100644 | ||
| 29 | index 00000000..e974917c | ||
| 30 | --- /dev/null | ||
| 31 | +++ b/include/libssh/config_parser.h | ||
| 32 | @@ -0,0 +1,57 @@ | ||
| 33 | +/* | ||
| 34 | + * config_parser.h - Common configuration file parser functions | ||
| 35 | + * | ||
| 36 | + * This file is part of the SSH Library | ||
| 37 | + * | ||
| 38 | + * Copyright (c) 2019 by Red Hat, Inc. | ||
| 39 | + * | ||
| 40 | + * Author: Anderson Toshiyuki Sasaki <ansasaki@redhat.com> | ||
| 41 | + * | ||
| 42 | + * The SSH Library is free software; you can redistribute it and/or modify | ||
| 43 | + * it under the terms of the GNU Lesser General Public License as published by | ||
| 44 | + * the Free Software Foundation; either version 2.1 of the License, or (at your | ||
| 45 | + * option) any later version. | ||
| 46 | + * | ||
| 47 | + * The SSH Library is distributed in the hope that it will be useful, but | ||
| 48 | + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | ||
| 49 | + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public | ||
| 50 | + * License for more details. | ||
| 51 | + * | ||
| 52 | + * You should have received a copy of the GNU Lesser General Public License | ||
| 53 | + * along with the SSH Library; see the file COPYING. If not, write to | ||
| 54 | + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, | ||
| 55 | + * MA 02111-1307, USA. | ||
| 56 | + */ | ||
| 57 | + | ||
| 58 | +#ifndef CONFIG_PARSER_H_ | ||
| 59 | +#define CONFIG_PARSER_H_ | ||
| 60 | + | ||
| 61 | +char *ssh_config_get_cmd(char **str); | ||
| 62 | + | ||
| 63 | +char *ssh_config_get_token(char **str); | ||
| 64 | + | ||
| 65 | +long ssh_config_get_long(char **str, long notfound); | ||
| 66 | + | ||
| 67 | +const char *ssh_config_get_str_tok(char **str, const char *def); | ||
| 68 | + | ||
| 69 | +int ssh_config_get_yesno(char **str, int notfound); | ||
| 70 | + | ||
| 71 | +/* @brief Parse SSH URI in format [user@]host[:port] from the given string | ||
| 72 | + * | ||
| 73 | + * @param[in] tok String to parse | ||
| 74 | + * @param[out] username Pointer to the location, where the new username will | ||
| 75 | + * be stored or NULL if we do not care about the result. | ||
| 76 | + * @param[out] hostname Pointer to the location, where the new hostname will | ||
| 77 | + * be stored or NULL if we do not care about the result. | ||
| 78 | + * @param[out] port Pointer to the location, where the new port will | ||
| 79 | + * be stored or NULL if we do not care about the result. | ||
| 80 | + * | ||
| 81 | + * @returns SSH_OK if the provided string is in format of SSH URI, | ||
| 82 | + * SSH_ERROR on failure | ||
| 83 | + */ | ||
| 84 | +int ssh_config_parse_uri(const char *tok, | ||
| 85 | + char **username, | ||
| 86 | + char **hostname, | ||
| 87 | + char **port); | ||
| 88 | + | ||
| 89 | +#endif /* LIBSSH_CONFIG_H_ */ | ||
| 90 | diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt | ||
| 91 | index fdb53baf..de66f056 100644 | ||
| 92 | --- a/src/CMakeLists.txt | ||
| 93 | +++ b/src/CMakeLists.txt | ||
| 94 | @@ -163,6 +163,7 @@ set(libssh_SRCS | ||
| 95 | external/poly1305.c | ||
| 96 | external/sc25519.c | ||
| 97 | chachapoly.c | ||
| 98 | + config_parser.c | ||
| 99 | ) | ||
| 100 | |||
| 101 | if (CMAKE_USE_PTHREADS_INIT) | ||
| 102 | diff --git a/src/config.c b/src/config.c | ||
| 103 | index 85ecd96a..4268545d 100644 | ||
| 104 | --- a/src/config.c | ||
| 105 | +++ b/src/config.c | ||
| 106 | @@ -22,7 +22,7 @@ | ||
| 107 | */ | ||
| 108 | |||
| 109 | #include "config.h" | ||
| 110 | - | ||
| 111 | +#include "libssh/config_parser.h" | ||
| 112 | #include <ctype.h> | ||
| 113 | #include <stdio.h> | ||
| 114 | #include <string.h> | ||
| 115 | @@ -228,102 +228,6 @@ static enum ssh_config_opcode_e ssh_config_get_opcode(char *keyword) { | ||
| 116 | return SOC_UNKNOWN; | ||
| 117 | } | ||
| 118 | |||
| 119 | -static char *ssh_config_get_cmd(char **str) { | ||
| 120 | - register char *c; | ||
| 121 | - char *r; | ||
| 122 | - | ||
| 123 | - /* Ignore leading spaces */ | ||
| 124 | - for (c = *str; *c; c++) { | ||
| 125 | - if (! isblank(*c)) { | ||
| 126 | - break; | ||
| 127 | - } | ||
| 128 | - } | ||
| 129 | - | ||
| 130 | - if (*c == '\"') { | ||
| 131 | - for (r = ++c; *c; c++) { | ||
| 132 | - if (*c == '\"') { | ||
| 133 | - *c = '\0'; | ||
| 134 | - goto out; | ||
| 135 | - } | ||
| 136 | - } | ||
| 137 | - } | ||
| 138 | - | ||
| 139 | - for (r = c; *c; c++) { | ||
| 140 | - if (*c == '\n') { | ||
| 141 | - *c = '\0'; | ||
| 142 | - goto out; | ||
| 143 | - } | ||
| 144 | - } | ||
| 145 | - | ||
| 146 | -out: | ||
| 147 | - *str = c + 1; | ||
| 148 | - | ||
| 149 | - return r; | ||
| 150 | -} | ||
| 151 | - | ||
| 152 | -static char *ssh_config_get_token(char **str) { | ||
| 153 | - register char *c; | ||
| 154 | - char *r; | ||
| 155 | - | ||
| 156 | - c = ssh_config_get_cmd(str); | ||
| 157 | - | ||
| 158 | - for (r = c; *c; c++) { | ||
| 159 | - if (isblank(*c) || *c == '=') { | ||
| 160 | - *c = '\0'; | ||
| 161 | - goto out; | ||
| 162 | - } | ||
| 163 | - } | ||
| 164 | - | ||
| 165 | -out: | ||
| 166 | - *str = c + 1; | ||
| 167 | - | ||
| 168 | - return r; | ||
| 169 | -} | ||
| 170 | - | ||
| 171 | -static long ssh_config_get_long(char **str, long notfound) { | ||
| 172 | - char *p, *endp; | ||
| 173 | - long i; | ||
| 174 | - | ||
| 175 | - p = ssh_config_get_token(str); | ||
| 176 | - if (p && *p) { | ||
| 177 | - i = strtol(p, &endp, 10); | ||
| 178 | - if (p == endp) { | ||
| 179 | - return notfound; | ||
| 180 | - } | ||
| 181 | - return i; | ||
| 182 | - } | ||
| 183 | - | ||
| 184 | - return notfound; | ||
| 185 | -} | ||
| 186 | - | ||
| 187 | -static const char *ssh_config_get_str_tok(char **str, const char *def) { | ||
| 188 | - char *p; | ||
| 189 | - | ||
| 190 | - p = ssh_config_get_token(str); | ||
| 191 | - if (p && *p) { | ||
| 192 | - return p; | ||
| 193 | - } | ||
| 194 | - | ||
| 195 | - return def; | ||
| 196 | -} | ||
| 197 | - | ||
| 198 | -static int ssh_config_get_yesno(char **str, int notfound) { | ||
| 199 | - const char *p; | ||
| 200 | - | ||
| 201 | - p = ssh_config_get_str_tok(str, NULL); | ||
| 202 | - if (p == NULL) { | ||
| 203 | - return notfound; | ||
| 204 | - } | ||
| 205 | - | ||
| 206 | - if (strncasecmp(p, "yes", 3) == 0) { | ||
| 207 | - return 1; | ||
| 208 | - } else if (strncasecmp(p, "no", 2) == 0) { | ||
| 209 | - return 0; | ||
| 210 | - } | ||
| 211 | - | ||
| 212 | - return notfound; | ||
| 213 | -} | ||
| 214 | - | ||
| 215 | static void local_parse_file(ssh_session session, const char *filename, int *parsing, int seen[]) { | ||
| 216 | FILE *f; | ||
| 217 | char line[MAX_LINE_SIZE] = {0}; | ||
| 218 | diff --git a/src/config_parser.c b/src/config_parser.c | ||
| 219 | new file mode 100644 | ||
| 220 | index 00000000..ae2aa2c8 | ||
| 221 | --- /dev/null | ||
| 222 | +++ b/src/config_parser.c | ||
| 223 | @@ -0,0 +1,238 @@ | ||
| 224 | +/* | ||
| 225 | + * config_parser.c - Common configuration file parser functions | ||
| 226 | + * | ||
| 227 | + * This file is part of the SSH Library | ||
| 228 | + * | ||
| 229 | + * Copyright (c) 2009-2013 by Andreas Schneider <asn@cryptomilk.org> | ||
| 230 | + * | ||
| 231 | + * The SSH Library is free software; you can redistribute it and/or modify | ||
| 232 | + * it under the terms of the GNU Lesser General Public License as published by | ||
| 233 | + * the Free Software Foundation; either version 2.1 of the License, or (at your | ||
| 234 | + * option) any later version. | ||
| 235 | + * | ||
| 236 | + * The SSH Library is distributed in the hope that it will be useful, but | ||
| 237 | + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | ||
| 238 | + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public | ||
| 239 | + * License for more details. | ||
| 240 | + * | ||
| 241 | + * You should have received a copy of the GNU Lesser General Public License | ||
| 242 | + * along with the SSH Library; see the file COPYING. If not, write to | ||
| 243 | + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, | ||
| 244 | + * MA 02111-1307, USA. | ||
| 245 | + */ | ||
| 246 | + | ||
| 247 | +#include "config.h" | ||
| 248 | + | ||
| 249 | +#include <ctype.h> | ||
| 250 | +#include <stdio.h> | ||
| 251 | +#include <string.h> | ||
| 252 | +#include <stdlib.h> | ||
| 253 | + | ||
| 254 | +#include "libssh/config_parser.h" | ||
| 255 | +#include "libssh/priv.h" | ||
| 256 | + | ||
| 257 | +char *ssh_config_get_cmd(char **str) | ||
| 258 | +{ | ||
| 259 | + register char *c; | ||
| 260 | + char *r; | ||
| 261 | + | ||
| 262 | + /* Ignore leading spaces */ | ||
| 263 | + for (c = *str; *c; c++) { | ||
| 264 | + if (! isblank(*c)) { | ||
| 265 | + break; | ||
| 266 | + } | ||
| 267 | + } | ||
| 268 | + | ||
| 269 | + if (*c == '\"') { | ||
| 270 | + for (r = ++c; *c; c++) { | ||
| 271 | + if (*c == '\"') { | ||
| 272 | + *c = '\0'; | ||
| 273 | + goto out; | ||
| 274 | + } | ||
| 275 | + } | ||
| 276 | + } | ||
| 277 | + | ||
| 278 | + for (r = c; *c; c++) { | ||
| 279 | + if (*c == '\n') { | ||
| 280 | + *c = '\0'; | ||
| 281 | + goto out; | ||
| 282 | + } | ||
| 283 | + } | ||
| 284 | + | ||
| 285 | +out: | ||
| 286 | + *str = c + 1; | ||
| 287 | + | ||
| 288 | + return r; | ||
| 289 | +} | ||
| 290 | + | ||
| 291 | +char *ssh_config_get_token(char **str) | ||
| 292 | +{ | ||
| 293 | + register char *c; | ||
| 294 | + char *r; | ||
| 295 | + | ||
| 296 | + c = ssh_config_get_cmd(str); | ||
| 297 | + | ||
| 298 | + for (r = c; *c; c++) { | ||
| 299 | + if (isblank(*c) || *c == '=') { | ||
| 300 | + *c = '\0'; | ||
| 301 | + goto out; | ||
| 302 | + } | ||
| 303 | + } | ||
| 304 | + | ||
| 305 | +out: | ||
| 306 | + *str = c + 1; | ||
| 307 | + | ||
| 308 | + return r; | ||
| 309 | +} | ||
| 310 | + | ||
| 311 | +long ssh_config_get_long(char **str, long notfound) | ||
| 312 | +{ | ||
| 313 | + char *p, *endp; | ||
| 314 | + long i; | ||
| 315 | + | ||
| 316 | + p = ssh_config_get_token(str); | ||
| 317 | + if (p && *p) { | ||
| 318 | + i = strtol(p, &endp, 10); | ||
| 319 | + if (p == endp) { | ||
| 320 | + return notfound; | ||
| 321 | + } | ||
| 322 | + return i; | ||
| 323 | + } | ||
| 324 | + | ||
| 325 | + return notfound; | ||
| 326 | +} | ||
| 327 | + | ||
| 328 | +const char *ssh_config_get_str_tok(char **str, const char *def) | ||
| 329 | +{ | ||
| 330 | + char *p; | ||
| 331 | + | ||
| 332 | + p = ssh_config_get_token(str); | ||
| 333 | + if (p && *p) { | ||
| 334 | + return p; | ||
| 335 | + } | ||
| 336 | + | ||
| 337 | + return def; | ||
| 338 | +} | ||
| 339 | + | ||
| 340 | +int ssh_config_get_yesno(char **str, int notfound) | ||
| 341 | +{ | ||
| 342 | + const char *p; | ||
| 343 | + | ||
| 344 | + p = ssh_config_get_str_tok(str, NULL); | ||
| 345 | + if (p == NULL) { | ||
| 346 | + return notfound; | ||
| 347 | + } | ||
| 348 | + | ||
| 349 | + if (strncasecmp(p, "yes", 3) == 0) { | ||
| 350 | + return 1; | ||
| 351 | + } else if (strncasecmp(p, "no", 2) == 0) { | ||
| 352 | + return 0; | ||
| 353 | + } | ||
| 354 | + | ||
| 355 | + return notfound; | ||
| 356 | +} | ||
| 357 | + | ||
| 358 | +int ssh_config_parse_uri(const char *tok, | ||
| 359 | + char **username, | ||
| 360 | + char **hostname, | ||
| 361 | + char **port) | ||
| 362 | +{ | ||
| 363 | + char *endp = NULL; | ||
| 364 | + long port_n; | ||
| 365 | + | ||
| 366 | + /* Sanitize inputs */ | ||
| 367 | + if (username != NULL) { | ||
| 368 | + *username = NULL; | ||
| 369 | + } | ||
| 370 | + if (hostname != NULL) { | ||
| 371 | + *hostname = NULL; | ||
| 372 | + } | ||
| 373 | + if (port != NULL) { | ||
| 374 | + *port = NULL; | ||
| 375 | + } | ||
| 376 | + | ||
| 377 | + /* Username part (optional) */ | ||
| 378 | + endp = strchr(tok, '@'); | ||
| 379 | + if (endp != NULL) { | ||
| 380 | + /* Zero-length username is not valid */ | ||
| 381 | + if (tok == endp) { | ||
| 382 | + goto error; | ||
| 383 | + } | ||
| 384 | + if (username != NULL) { | ||
| 385 | + *username = strndup(tok, endp - tok); | ||
| 386 | + if (*username == NULL) { | ||
| 387 | + goto error; | ||
| 388 | + } | ||
| 389 | + } | ||
| 390 | + tok = endp + 1; | ||
| 391 | + /* If there is second @ character, this does not look like our URI */ | ||
| 392 | + endp = strchr(tok, '@'); | ||
| 393 | + if (endp != NULL) { | ||
| 394 | + goto error; | ||
| 395 | + } | ||
| 396 | + } | ||
| 397 | + | ||
| 398 | + /* Hostname */ | ||
| 399 | + if (*tok == '[') { | ||
| 400 | + /* IPv6 address is enclosed with square brackets */ | ||
| 401 | + tok++; | ||
| 402 | + endp = strchr(tok, ']'); | ||
| 403 | + if (endp == NULL) { | ||
| 404 | + goto error; | ||
| 405 | + } | ||
| 406 | + } else { | ||
| 407 | + /* Hostnames or aliases expand to the last colon or to the end */ | ||
| 408 | + endp = strrchr(tok, ':'); | ||
| 409 | + if (endp == NULL) { | ||
| 410 | + endp = strchr(tok, '\0'); | ||
| 411 | + } | ||
| 412 | + } | ||
| 413 | + if (tok == endp) { | ||
| 414 | + /* Zero-length hostnames are not valid */ | ||
| 415 | + goto error; | ||
| 416 | + } | ||
| 417 | + if (hostname != NULL) { | ||
| 418 | + *hostname = strndup(tok, endp - tok); | ||
| 419 | + if (*hostname == NULL) { | ||
| 420 | + goto error; | ||
| 421 | + } | ||
| 422 | + } | ||
| 423 | + /* Skip also the closing bracket */ | ||
| 424 | + if (*endp == ']') { | ||
| 425 | + endp++; | ||
| 426 | + } | ||
| 427 | + | ||
| 428 | + /* Port (optional) */ | ||
| 429 | + if (*endp != '\0') { | ||
| 430 | + char *port_end = NULL; | ||
| 431 | + | ||
| 432 | + /* Verify the port is valid positive number */ | ||
| 433 | + port_n = strtol(endp + 1, &port_end, 10); | ||
| 434 | + if (port_n < 1 || *port_end != '\0') { | ||
| 435 | + SSH_LOG(SSH_LOG_WARN, "Failed to parse port number." | ||
| 436 | + " The value '%ld' is invalid or there are some" | ||
| 437 | + " trailing characters: '%s'", port_n, port_end); | ||
| 438 | + goto error; | ||
| 439 | + } | ||
| 440 | + if (port != NULL) { | ||
| 441 | + *port = strdup(endp + 1); | ||
| 442 | + if (*port == NULL) { | ||
| 443 | + goto error; | ||
| 444 | + } | ||
| 445 | + } | ||
| 446 | + } | ||
| 447 | + | ||
| 448 | + return SSH_OK; | ||
| 449 | + | ||
| 450 | +error: | ||
| 451 | + if (username != NULL) { | ||
| 452 | + SAFE_FREE(*username); | ||
| 453 | + } | ||
| 454 | + if (hostname != NULL) { | ||
| 455 | + SAFE_FREE(*hostname); | ||
| 456 | + } | ||
| 457 | + if (port != NULL) { | ||
| 458 | + SAFE_FREE(*port); | ||
| 459 | + } | ||
| 460 | + return SSH_ERROR; | ||
| 461 | +} | ||
| 462 | -- | ||
| 463 | 2.25.1 | ||
| 464 | |||
diff --git a/meta-oe/recipes-support/libssh/libssh/001_CVE-2023-6004.patch b/meta-oe/recipes-support/libssh/libssh/001_CVE-2023-6004.patch new file mode 100644 index 0000000000..e02cae182a --- /dev/null +++ b/meta-oe/recipes-support/libssh/libssh/001_CVE-2023-6004.patch | |||
| @@ -0,0 +1,30 @@ | |||
| 1 | From a66b4a6eae6614d200a3625862d77565b96a7cd3 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Norbert Pocs <norbertpocs0@gmail.com> | ||
| 3 | Date: Wed, 1 Nov 2023 11:24:43 +0100 | ||
| 4 | Subject: [PATCH] CVE-2023-6004: config_parser: Allow multiple '@' in usernames | ||
| 5 | |||
| 6 | Signed-off-by: Norbert Pocs <norbertpocs0@gmail.com> | ||
| 7 | Reviewed-by: Andreas Schneider <asn@cryptomilk.org> | ||
| 8 | Reviewed-by: Jakub Jelen <jjelen@redhat.com> | ||
| 9 | |||
| 10 | CVE: CVE-2023-6004 | ||
| 11 | Upstream-Status: Backport [https://gitlab.com/libssh/libssh-mirror/-/commit/a66b4a6eae6614d200a3625862d77565b96a7cd3] | ||
| 12 | Signed-off-by: nikhil r <nikhil.r@kpit.com> | ||
| 13 | |||
| 14 | --- | ||
| 15 | src/config_parser.c | 2 +- | ||
| 16 | 1 file changed, 1 insertion(+), 1 deletion(-) | ||
| 17 | |||
| 18 | diff --git a/src/config_parser.c b/src/config_parser.c | ||
| 19 | index 0d988fec0..cf83e2c5e 100644 | ||
| 20 | --- a/src/config_parser.c | ||
| 21 | +++ b/src/config_parser.c | ||
| 22 | @@ -180,7 +180,7 @@ int ssh_config_parse_uri(const char *tok, | ||
| 23 | } | ||
| 24 | |||
| 25 | /* Username part (optional) */ | ||
| 26 | - endp = strchr(tok, '@'); | ||
| 27 | + endp = strrchr(tok, '@'); | ||
| 28 | if (endp != NULL) { | ||
| 29 | /* Zero-length username is not valid */ | ||
| 30 | if (tok == endp) { | ||
diff --git a/meta-oe/recipes-support/libssh/libssh/002_CVE-2023-6004.patch b/meta-oe/recipes-support/libssh/libssh/002_CVE-2023-6004.patch new file mode 100644 index 0000000000..a77783453a --- /dev/null +++ b/meta-oe/recipes-support/libssh/libssh/002_CVE-2023-6004.patch | |||
| @@ -0,0 +1,83 @@ | |||
| 1 | From 8615c24647f773a5e04203c7459512715d698be1 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Norbert Pocs <norbertpocs0@gmail.com> | ||
| 3 | Date: Tue, 31 Oct 2023 09:48:52 +0100 | ||
| 4 | Subject: [PATCH] CVE-2023-6004: options: Simplify the hostname parsing in | ||
| 5 | ssh_options_set | ||
| 6 | |||
| 7 | Using ssh_config_parse_uri can simplify the parsing of the host | ||
| 8 | parsing inside the function of ssh_options_set | ||
| 9 | |||
| 10 | Signed-off-by: Norbert Pocs <norbertpocs0@gmail.com> | ||
| 11 | Reviewed-by: Andreas Schneider <asn@cryptomilk.org> | ||
| 12 | Reviewed-by: Jakub Jelen <jjelen@redhat.com> | ||
| 13 | |||
| 14 | CVE: CVE-2023-6004 | ||
| 15 | Upstream-Status: Backport [https://gitlab.com/libssh/libssh-mirror/-/commit/8615c24647f773a5e04203c7459512715d698be1] | ||
| 16 | Signed-off-by: nikhil r <nikhil.r@kpit.com> | ||
| 17 | Comment: Refreshed hunk 2 from option.c | ||
| 18 | |||
| 19 | --- | ||
| 20 | src/options.c | 40 ++++++++++++++++------------------------ | ||
| 21 | 1 file changed, 16 insertions(+), 24 deletions(-) | ||
| 22 | |||
| 23 | diff --git a/src/options.c b/src/options.c | ||
| 24 | index 6f2c9397e..385114555 100644 | ||
| 25 | --- a/src/options.c | ||
| 26 | +++ b/src/options.c | ||
| 27 | @@ -36,6 +36,7 @@ | ||
| 28 | #include "libssh/session.h" | ||
| 29 | #include "libssh/misc.h" | ||
| 30 | #include "libssh/options.h" | ||
| 31 | +#include "libssh/config_parser.h" | ||
| 32 | #ifdef WITH_SERVER | ||
| 33 | #include "libssh/server.h" | ||
| 34 | #include "libssh/bind.h" | ||
| 35 | @@ -415,33 +416,24 @@ int ssh_options_set(ssh_session session, enum ssh_options_e type, | ||
| 36 | ssh_set_error_invalid(session); | ||
| 37 | return -1; | ||
| 38 | } else { | ||
| 39 | - q = strdup(value); | ||
| 40 | - if (q == NULL) { | ||
| 41 | - ssh_set_error_oom(session); | ||
| 42 | + char *username = NULL, *hostname = NULL, *port = NULL; | ||
| 43 | + rc = ssh_config_parse_uri(value, &username, &hostname, &port); | ||
| 44 | + if (rc != SSH_OK) { | ||
| 45 | return -1; | ||
| 46 | } | ||
| 47 | - p = strchr(q, '@'); | ||
| 48 | - | ||
| 49 | - SAFE_FREE(session->opts.host); | ||
| 50 | - | ||
| 51 | - if (p) { | ||
| 52 | - *p = '\0'; | ||
| 53 | - session->opts.host = strdup(p + 1); | ||
| 54 | - if (session->opts.host == NULL) { | ||
| 55 | - SAFE_FREE(q); | ||
| 56 | - ssh_set_error_oom(session); | ||
| 57 | - return -1; | ||
| 58 | - } | ||
| 59 | - | ||
| 60 | + if (port != NULL) { | ||
| 61 | + SAFE_FREE(username); | ||
| 62 | + SAFE_FREE(hostname); | ||
| 63 | + SAFE_FREE(port); | ||
| 64 | + return -1; | ||
| 65 | + } | ||
| 66 | + if (username != NULL) { | ||
| 67 | SAFE_FREE(session->opts.username); | ||
| 68 | - session->opts.username = strdup(q); | ||
| 69 | - SAFE_FREE(q); | ||
| 70 | - if (session->opts.username == NULL) { | ||
| 71 | - ssh_set_error_oom(session); | ||
| 72 | - return -1; | ||
| 73 | - } | ||
| 74 | - } else { | ||
| 75 | - session->opts.host = q; | ||
| 76 | + session->opts.username = username; | ||
| 77 | + } | ||
| 78 | + if (hostname != NULL) { | ||
| 79 | + SAFE_FREE(session->opts.host); | ||
| 80 | + session->opts.host = hostname; | ||
| 81 | } | ||
| 82 | } | ||
| 83 | break; | ||
diff --git a/meta-oe/recipes-support/libssh/libssh/003_CVE-2023-6004.patch b/meta-oe/recipes-support/libssh/libssh/003_CVE-2023-6004.patch new file mode 100644 index 0000000000..a4e790ed0c --- /dev/null +++ b/meta-oe/recipes-support/libssh/libssh/003_CVE-2023-6004.patch | |||
| @@ -0,0 +1,117 @@ | |||
| 1 | From c6180409677c765e6b9ae2b18a3a7a9671ac1dbe Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Norbert Pocs <norbertpocs0@gmail.com> | ||
| 3 | Date: Tue, 10 Oct 2023 12:44:16 +0200 | ||
| 4 | Subject: [PATCH] CVE-2023-6004: misc: Add function to check allowed characters | ||
| 5 | of a hostname | ||
| 6 | |||
| 7 | The hostname can be a domain name or an ip address. The colon has to be | ||
| 8 | allowed because of IPv6 even it is prohibited in domain names. | ||
| 9 | |||
| 10 | Signed-off-by: Norbert Pocs <norbertpocs0@gmail.com> | ||
| 11 | Reviewed-by: Andreas Schneider <asn@cryptomilk.org> | ||
| 12 | Reviewed-by: Jakub Jelen <jjelen@redhat.com> | ||
| 13 | |||
| 14 | CVE: CVE-2023-6004 | ||
| 15 | Upstream-Status: Backport [https://gitlab.com/libssh/libssh-mirror/-/commit/c6180409677c765e6b9ae2b18a3a7a9671ac1dbe] | ||
| 16 | Signed-off-by: nikhil r <nikhil.r@kpit.com> | ||
| 17 | Comment: Refreshed hunk 1 from misc.h and hunk 2 from misc.c | ||
| 18 | --- | ||
| 19 | include/libssh/misc.h | 3 ++ | ||
| 20 | src/misc.c | 68 +++++++++++++++++++++++++++++++++++++++++++ | ||
| 21 | 2 files changed, 71 insertions(+) | ||
| 22 | |||
| 23 | diff --git a/include/libssh/misc.h b/include/libssh/misc.h | ||
| 24 | index 924da5336..0924ba7fb 100644 | ||
| 25 | --- a/include/libssh/misc.h | ||
| 26 | +++ b/include/libssh/misc.h | ||
| 27 | @@ -89,4 +89,6 @@ int ssh_match_group(const char *group, const char *object); | ||
| 28 | |||
| 29 | int ssh_quote_file_name(const char *file_name, char *buf, size_t buf_len); | ||
| 30 | |||
| 31 | +int ssh_check_hostname_syntax(const char *hostname); | ||
| 32 | + | ||
| 33 | #endif /* MISC_H_ */ | ||
| 34 | |||
| 35 | diff --git a/src/misc.c b/src/misc.c | ||
| 36 | index 7c478a773..be6ee836e 100644 | ||
| 37 | --- a/src/misc.c | ||
| 38 | +++ b/src/misc.c | ||
| 39 | @@ -94,6 +94,8 @@ | ||
| 40 | #define ZLIB_STRING "" | ||
| 41 | #endif | ||
| 42 | |||
| 43 | +#define ARPA_DOMAIN_MAX_LEN 63 | ||
| 44 | + | ||
| 45 | /** | ||
| 46 | * @defgroup libssh_misc The SSH helper functions. | ||
| 47 | * @ingroup libssh | ||
| 48 | @@ -1292,4 +1294,69 @@ error: | ||
| 49 | return SSH_ERROR; | ||
| 50 | } | ||
| 51 | |||
| 52 | +/** | ||
| 53 | + * @brief Checks syntax of a domain name | ||
| 54 | + * | ||
| 55 | + * The check is made based on the RFC1035 section 2.3.1 | ||
| 56 | + * Allowed characters are: hyphen, period, digits (0-9) and letters (a-zA-Z) | ||
| 57 | + * | ||
| 58 | + * The label should be no longer than 63 characters | ||
| 59 | + * The label should start with a letter and end with a letter or number | ||
| 60 | + * The label in this implementation can start with a number to allow virtual | ||
| 61 | + * URLs to pass. Note that this will make IPv4 addresses to pass | ||
| 62 | + * this check too. | ||
| 63 | + * | ||
| 64 | + * @param hostname The domain name to be checked, has to be null terminated | ||
| 65 | + * | ||
| 66 | + * @return SSH_OK if the hostname passes syntax check | ||
| 67 | + * SSH_ERROR otherwise or if hostname is NULL or empty string | ||
| 68 | + */ | ||
| 69 | +int ssh_check_hostname_syntax(const char *hostname) | ||
| 70 | +{ | ||
| 71 | + char *it = NULL, *s = NULL, *buf = NULL; | ||
| 72 | + size_t it_len; | ||
| 73 | + char c; | ||
| 74 | + | ||
| 75 | + if (hostname == NULL || strlen(hostname) == 0) { | ||
| 76 | + return SSH_ERROR; | ||
| 77 | + } | ||
| 78 | + | ||
| 79 | + /* strtok_r writes into the string, keep the input clean */ | ||
| 80 | + s = strdup(hostname); | ||
| 81 | + if (s == NULL) { | ||
| 82 | + return SSH_ERROR; | ||
| 83 | + } | ||
| 84 | + | ||
| 85 | + it = strtok_r(s, ".", &buf); | ||
| 86 | + /* if the token has 0 length */ | ||
| 87 | + if (it == NULL) { | ||
| 88 | + free(s); | ||
| 89 | + return SSH_ERROR; | ||
| 90 | + } | ||
| 91 | + do { | ||
| 92 | + it_len = strlen(it); | ||
| 93 | + if (it_len > ARPA_DOMAIN_MAX_LEN || | ||
| 94 | + /* the first char must be a letter, but some virtual urls start | ||
| 95 | + * with a number */ | ||
| 96 | + isalnum(it[0]) == 0 || | ||
| 97 | + isalnum(it[it_len - 1]) == 0) { | ||
| 98 | + free(s); | ||
| 99 | + return SSH_ERROR; | ||
| 100 | + } | ||
| 101 | + while (*it != '\0') { | ||
| 102 | + c = *it; | ||
| 103 | + /* the "." is allowed too, but tokenization removes it from the | ||
| 104 | + * string */ | ||
| 105 | + if (isalnum(c) == 0 && c != '-') { | ||
| 106 | + free(s); | ||
| 107 | + return SSH_ERROR; | ||
| 108 | + } | ||
| 109 | + it++; | ||
| 110 | + } | ||
| 111 | + } while ((it = strtok_r(NULL, ".", &buf)) != NULL); | ||
| 112 | + | ||
| 113 | + free(s); | ||
| 114 | + | ||
| 115 | + return SSH_OK; | ||
| 116 | +} | ||
| 117 | /** @} */ | ||
diff --git a/meta-oe/recipes-support/libssh/libssh/004_CVE-2023-6004.patch b/meta-oe/recipes-support/libssh/libssh/004_CVE-2023-6004.patch new file mode 100644 index 0000000000..39e6d94788 --- /dev/null +++ b/meta-oe/recipes-support/libssh/libssh/004_CVE-2023-6004.patch | |||
| @@ -0,0 +1,57 @@ | |||
| 1 | From 22492b69bba22b102342afc574800d354a08e405 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Norbert Pocs <norbertpocs0@gmail.com> | ||
| 3 | Date: Tue, 10 Oct 2023 18:33:56 +0200 | ||
| 4 | Subject: [PATCH] CVE-2023-6004: config_parser: Check for valid syntax of a | ||
| 5 | hostname if it is a domain name | ||
| 6 | |||
| 7 | This prevents code injection. | ||
| 8 | The domain name syntax checker is based on RFC1035. | ||
| 9 | |||
| 10 | Signed-off-by: Norbert Pocs <norbertpocs0@gmail.com> | ||
| 11 | Reviewed-by: Andreas Schneider <asn@cryptomilk.org> | ||
| 12 | Reviewed-by: Jakub Jelen <jjelen@redhat.com> | ||
| 13 | |||
| 14 | CVE: CVE-2023-6004 | ||
| 15 | Upstream-Status: Backport [https://gitlab.com/libssh/libssh-mirror/-/commit/22492b69bba22b102342afc574800d354a08e405] | ||
| 16 | Signed-off-by: nikhil r <nikhil.r@kpit.com> | ||
| 17 | Comment: Refreshed hunk 2 and 3 from config_parser.c | ||
| 18 | |||
| 19 | --- | ||
| 20 | src/config_parser.c | 12 +++++++++++- | ||
| 21 | 1 file changed, 11 insertions(+), 1 deletion(-) | ||
| 22 | |||
| 23 | diff --git a/src/config_parser.c b/src/config_parser.c | ||
| 24 | index cf83e2c5e..b8b94611a 100644 | ||
| 25 | --- a/src/config_parser.c | ||
| 26 | +++ b/src/config_parser.c | ||
| 27 | @@ -30,6 +30,7 @@ | ||
| 28 | |||
| 29 | #include "libssh/config_parser.h" | ||
| 30 | #include "libssh/priv.h" | ||
| 31 | +#include "libssh/misc.h" | ||
| 32 | |||
| 33 | char *ssh_config_get_cmd(char **str) | ||
| 34 | { | ||
| 35 | @@ -139,6 +140,7 @@ int ssh_config_parse_uri(const char *tok, | ||
| 36 | { | ||
| 37 | char *endp = NULL; | ||
| 38 | long port_n; | ||
| 39 | + int rc; | ||
| 40 | |||
| 41 | /* Sanitize inputs */ | ||
| 42 | if (username != NULL) { | ||
| 43 | @@ -196,6 +198,14 @@ int ssh_config_parse_uri(const char *tok, | ||
| 44 | if (*hostname == NULL) { | ||
| 45 | goto error; | ||
| 46 | } | ||
| 47 | + /* if not an ip, check syntax */ | ||
| 48 | + rc = ssh_is_ipaddr(*hostname); | ||
| 49 | + if (rc == 0) { | ||
| 50 | + rc = ssh_check_hostname_syntax(*hostname); | ||
| 51 | + if (rc != SSH_OK) { | ||
| 52 | + goto error; | ||
| 53 | + } | ||
| 54 | + } | ||
| 55 | } | ||
| 56 | /* Skip also the closing bracket */ | ||
| 57 | if (*endp == ']') { | ||
diff --git a/meta-oe/recipes-support/libssh/libssh/005_CVE-2023-6004.patch b/meta-oe/recipes-support/libssh/libssh/005_CVE-2023-6004.patch new file mode 100644 index 0000000000..c86aba4d88 --- /dev/null +++ b/meta-oe/recipes-support/libssh/libssh/005_CVE-2023-6004.patch | |||
| @@ -0,0 +1,142 @@ | |||
| 1 | From cea841d71c025f9c998b7d5fc9f2a2839df62921 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Norbert Pocs <norbertpocs0@gmail.com> | ||
| 3 | Date: Tue, 28 Nov 2023 15:26:45 +0100 | ||
| 4 | Subject: [PATCH] CVE-2023-6004 misc: Add ipv6 link-local check for an ip | ||
| 5 | address | ||
| 6 | |||
| 7 | Signed-off-by: Norbert Pocs <norbertpocs0@gmail.com> | ||
| 8 | Reviewed-by: Andreas Schneider <asn@cryptomilk.org> | ||
| 9 | Reviewed-by: Jakub Jelen <jjelen@redhat.com> | ||
| 10 | |||
| 11 | CVE: CVE-2023-6004 | ||
| 12 | Upstream-Status: Backport [https://gitlab.com/libssh/libssh-mirror/-/commit/cea841d71c025f9c998b7d5fc9f2a2839df62921] | ||
| 13 | Signed-off-by: nikhil r <nikhil.r@kpit.com> | ||
| 14 | Comment: Refreshed hunk 1 from CMakeLists.txt, hunk 1 from connect.c and | ||
| 15 | hunks 2,3,4 from misc.c | ||
| 16 | --- | ||
| 17 | src/CMakeLists.txt | 1 + | ||
| 18 | src/connect.c | 2 +- | ||
| 19 | src/misc.c | 44 ++++++++++++++++++++++++++++++++++++++------ | ||
| 20 | 3 files changed, 40 insertions(+), 7 deletions(-) | ||
| 21 | |||
| 22 | diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt | ||
| 23 | index d6245c0db..807313b59 100644 | ||
| 24 | --- a/src/CMakeLists.txt | ||
| 25 | +++ b/src/CMakeLists.txt | ||
| 26 | @@ -14,6 +14,7 @@ set(LIBSSH_LINK_LIBRARIES | ||
| 27 | if (WIN32) | ||
| 28 | set(LIBSSH_LINK_LIBRARIES | ||
| 29 | ${LIBSSH_LINK_LIBRARIES} | ||
| 30 | + iphlpapi | ||
| 31 | ws2_32 | ||
| 32 | ) | ||
| 33 | endif (WIN32) | ||
| 34 | diff --git a/src/connect.c b/src/connect.c | ||
| 35 | index 57e37e634..15cae6444 100644 | ||
| 36 | --- a/src/connect.c | ||
| 37 | +++ b/src/connect.c | ||
| 38 | @@ -130,7 +130,7 @@ static int getai(const char *host, int port, struct addrinfo **ai) { | ||
| 39 | #endif | ||
| 40 | } | ||
| 41 | |||
| 42 | - if (ssh_is_ipaddr(host)) { | ||
| 43 | + if (ssh_is_ipaddr(host) == 1) { | ||
| 44 | /* this is an IP address */ | ||
| 45 | SSH_LOG(SSH_LOG_PACKET,"host %s matches an IP address",host); | ||
| 46 | hints.ai_flags |= AI_NUMERICHOST; | ||
| 47 | diff --git a/src/misc.c b/src/misc.c | ||
| 48 | index be6ee836e..7081f12ae 100644 | ||
| 49 | --- a/src/misc.c | ||
| 50 | +++ b/src/misc.c | ||
| 51 | @@ -32,6 +32,7 @@ | ||
| 52 | #include <sys/socket.h> | ||
| 53 | #include <netinet/in.h> | ||
| 54 | #include <arpa/inet.h> | ||
| 55 | +#include <net/if.h> | ||
| 56 | |||
| 57 | #endif /* _WIN32 */ | ||
| 58 | |||
| 59 | @@ -59,6 +60,7 @@ | ||
| 60 | #include <ws2tcpip.h> | ||
| 61 | #include <shlobj.h> | ||
| 62 | #include <direct.h> | ||
| 63 | +#include <netioapi.h> | ||
| 64 | |||
| 65 | #ifdef HAVE_IO_H | ||
| 66 | #include <io.h> | ||
| 67 | @@ -191,22 +191,37 @@ int ssh_is_ipaddr_v4(const char *str) { | ||
| 68 | |||
| 69 | int ssh_is_ipaddr(const char *str) { | ||
| 70 | int rc = SOCKET_ERROR; | ||
| 71 | + char *s = strdup(str); | ||
| 72 | |||
| 73 | - if (strchr(str, ':')) { | ||
| 74 | + if (s == NULL) { | ||
| 75 | + return -1; | ||
| 76 | + } | ||
| 77 | + if (strchr(s, ':')) { | ||
| 78 | struct sockaddr_storage ss; | ||
| 79 | int sslen = sizeof(ss); | ||
| 80 | + char *network_interface = strchr(s, '%'); | ||
| 81 | |||
| 82 | - /* TODO link-local (IP:v6:addr%ifname). */ | ||
| 83 | - rc = WSAStringToAddressA((LPSTR) str, | ||
| 84 | + /* link-local (IP:v6:addr%ifname). */ | ||
| 85 | + if (network_interface != NULL) { | ||
| 86 | + rc = if_nametoindex(network_interface + 1); | ||
| 87 | + if (rc == 0) { | ||
| 88 | + free(s); | ||
| 89 | + return 0; | ||
| 90 | + } | ||
| 91 | + *network_interface = '\0'; | ||
| 92 | + } | ||
| 93 | + rc = WSAStringToAddressA((LPSTR) s, | ||
| 94 | AF_INET6, | ||
| 95 | NULL, | ||
| 96 | (struct sockaddr*)&ss, | ||
| 97 | &sslen); | ||
| 98 | if (rc == 0) { | ||
| 99 | + free(s); | ||
| 100 | return 1; | ||
| 101 | } | ||
| 102 | } | ||
| 103 | |||
| 104 | + free(s); | ||
| 105 | return ssh_is_ipaddr_v4(str); | ||
| 106 | } | ||
| 107 | #else /* _WIN32 */ | ||
| 108 | @@ -285,17 +300,32 @@ int ssh_is_ipaddr_v4(const char *str) { | ||
| 109 | |||
| 110 | int ssh_is_ipaddr(const char *str) { | ||
| 111 | int rc = -1; | ||
| 112 | + char *s = strdup(str); | ||
| 113 | |||
| 114 | - if (strchr(str, ':')) { | ||
| 115 | + if (s == NULL) { | ||
| 116 | + return -1; | ||
| 117 | + } | ||
| 118 | + if (strchr(s, ':')) { | ||
| 119 | struct in6_addr dest6; | ||
| 120 | + char *network_interface = strchr(s, '%'); | ||
| 121 | |||
| 122 | - /* TODO link-local (IP:v6:addr%ifname). */ | ||
| 123 | - rc = inet_pton(AF_INET6, str, &dest6); | ||
| 124 | + /* link-local (IP:v6:addr%ifname). */ | ||
| 125 | + if (network_interface != NULL) { | ||
| 126 | + rc = if_nametoindex(network_interface + 1); | ||
| 127 | + if (rc == 0) { | ||
| 128 | + free(s); | ||
| 129 | + return 0; | ||
| 130 | + } | ||
| 131 | + *network_interface = '\0'; | ||
| 132 | + } | ||
| 133 | + rc = inet_pton(AF_INET6, s, &dest6); | ||
| 134 | if (rc > 0) { | ||
| 135 | + free(s); | ||
| 136 | return 1; | ||
| 137 | } | ||
| 138 | } | ||
| 139 | |||
| 140 | + free(s); | ||
| 141 | return ssh_is_ipaddr_v4(str); | ||
| 142 | } | ||
diff --git a/meta-oe/recipes-support/libssh/libssh/006_CVE-2023-6004.patch b/meta-oe/recipes-support/libssh/libssh/006_CVE-2023-6004.patch new file mode 100644 index 0000000000..f3cb2b998e --- /dev/null +++ b/meta-oe/recipes-support/libssh/libssh/006_CVE-2023-6004.patch | |||
| @@ -0,0 +1,117 @@ | |||
| 1 | From 1a02364b5107a4125ea3cb76fcdb6beabaebf3be Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Jakub Jelen <jjelen@redhat.com> | ||
| 3 | Date: Fri, 22 Dec 2023 10:32:40 +0100 | ||
| 4 | Subject: [PATCH] Fix regression in IPv6 addresses in hostname parsing | ||
| 5 | |||
| 6 | Signed-off-by: Jakub Jelen <jjelen@redhat.com> | ||
| 7 | Reviewed-by: Andreas Schneider <asn@cryptomilk.org> | ||
| 8 | (cherry picked from commit 4f997aee7c7d7ea346b3e8ba505da0b7601ff318) | ||
| 9 | |||
| 10 | CVE: CVE-2023-6004 | ||
| 11 | Upstream-Status: Backport [https://gitlab.com/libssh/libssh-mirror/-/commit/1a02364b5107a4125ea3cb76fcdb6beabaebf3be] | ||
| 12 | Signed-off-by: nikhil r <nikhil.r@kpit.com> | ||
| 13 | Comment: Removed 1 hunk from config_parser.c as the function was intoduced in | ||
| 14 | later version | ||
| 15 | |||
| 16 | --- | ||
| 17 | include/libssh/config_parser.h | 11 ++++++++--- | ||
| 18 | src/config.c | 4 ++-- | ||
| 19 | src/config_parser.c | 16 +++++++++++----- | ||
| 20 | src/options.c | 10 ++-------- | ||
| 21 | 4 files changed, 23 insertions(+), 18 deletions(-) | ||
| 22 | |||
| 23 | diff --git a/include/libssh/config_parser.h b/include/libssh/config_parser.h | ||
| 24 | index a7dd42a2c..ca353432b 100644 | ||
| 25 | --- a/include/libssh/config_parser.h | ||
| 26 | +++ b/include/libssh/config_parser.h | ||
| 27 | @@ -26,6 +26,8 @@ | ||
| 28 | #ifndef CONFIG_PARSER_H_ | ||
| 29 | #define CONFIG_PARSER_H_ | ||
| 30 | |||
| 31 | +#include <stdbool.h> | ||
| 32 | + | ||
| 33 | char *ssh_config_get_cmd(char **str); | ||
| 34 | |||
| 35 | char *ssh_config_get_token(char **str); | ||
| 36 | @@ -45,13 +47,16 @@ int ssh_config_get_yesno(char **str, int notfound); | ||
| 37 | * be stored or NULL if we do not care about the result. | ||
| 38 | * @param[out] port Pointer to the location, where the new port will | ||
| 39 | * be stored or NULL if we do not care about the result. | ||
| 40 | + * @param[in] ignore_port Set to true if the we should not attempt to parse | ||
| 41 | + * port number. | ||
| 42 | * | ||
| 43 | * @returns SSH_OK if the provided string is in format of SSH URI, | ||
| 44 | * SSH_ERROR on failure | ||
| 45 | */ | ||
| 46 | int ssh_config_parse_uri(const char *tok, | ||
| 47 | - char **username, | ||
| 48 | - char **hostname, | ||
| 49 | - char **port); | ||
| 50 | + char **username, | ||
| 51 | + char **hostname, | ||
| 52 | + char **port, | ||
| 53 | + bool ignore_port); | ||
| 54 | |||
| 55 | #endif /* LIBSSH_CONFIG_H_ */ | ||
| 56 | diff --git a/src/config_parser.c b/src/config_parser.c | ||
| 57 | index b8b94611a..d4b2d2c3b 100644 | ||
| 58 | --- a/src/config_parser.c | ||
| 59 | +++ b/src/config_parser.c | ||
| 60 | @@ -162,9 +162,10 @@ int ssh_config_get_yesno(char **str, int notfound) | ||
| 61 | } | ||
| 62 | |||
| 63 | int ssh_config_parse_uri(const char *tok, | ||
| 64 | - char **username, | ||
| 65 | - char **hostname, | ||
| 66 | - char **port) | ||
| 67 | + char **username, | ||
| 68 | + char **hostname, | ||
| 69 | + char **port, | ||
| 70 | + bool ignore_port) | ||
| 71 | { | ||
| 72 | char *endp = NULL; | ||
| 73 | long port_n; | ||
| 74 | @@ -210,12 +211,17 @@ int ssh_config_parse_uri(const char *tok, | ||
| 75 | if (endp == NULL) { | ||
| 76 | goto error; | ||
| 77 | } | ||
| 78 | - } else { | ||
| 79 | - /* Hostnames or aliases expand to the last colon or to the end */ | ||
| 80 | + } else if (!ignore_port) { | ||
| 81 | + /* Hostnames or aliases expand to the last colon (if port is requested) | ||
| 82 | + * or to the end */ | ||
| 83 | endp = strrchr(tok, ':'); | ||
| 84 | if (endp == NULL) { | ||
| 85 | endp = strchr(tok, '\0'); | ||
| 86 | } | ||
| 87 | + } else { | ||
| 88 | + /* If no port is requested, expand to the end of line | ||
| 89 | + * (to accommodate the IPv6 addresses) */ | ||
| 90 | + endp = strchr(tok, '\0'); | ||
| 91 | } | ||
| 92 | if (tok == endp) { | ||
| 93 | /* Zero-length hostnames are not valid */ | ||
| 94 | diff --git a/src/options.c b/src/options.c | ||
| 95 | index 385114555..b3ecffe15 100644 | ||
| 96 | --- a/src/options.c | ||
| 97 | +++ b/src/options.c | ||
| 98 | @@ -416,17 +416,11 @@ int ssh_options_set(ssh_session session, enum ssh_options_e type, | ||
| 99 | ssh_set_error_invalid(session); | ||
| 100 | return -1; | ||
| 101 | } else { | ||
| 102 | - char *username = NULL, *hostname = NULL, *port = NULL; | ||
| 103 | - rc = ssh_config_parse_uri(value, &username, &hostname, &port); | ||
| 104 | + char *username = NULL, *hostname = NULL; | ||
| 105 | + rc = ssh_config_parse_uri(value, &username, &hostname, NULL, true); | ||
| 106 | if (rc != SSH_OK) { | ||
| 107 | return -1; | ||
| 108 | } | ||
| 109 | - if (port != NULL) { | ||
| 110 | - SAFE_FREE(username); | ||
| 111 | - SAFE_FREE(hostname); | ||
| 112 | - SAFE_FREE(port); | ||
| 113 | - return -1; | ||
| 114 | - } | ||
| 115 | if (username != NULL) { | ||
| 116 | SAFE_FREE(session->opts.username); | ||
| 117 | session->opts.username = username; | ||
diff --git a/meta-oe/recipes-support/libssh/libssh_0.8.9.bb b/meta-oe/recipes-support/libssh/libssh_0.8.9.bb index 530dda1f4a..98910d3068 100644 --- a/meta-oe/recipes-support/libssh/libssh_0.8.9.bb +++ b/meta-oe/recipes-support/libssh/libssh_0.8.9.bb | |||
| @@ -11,6 +11,13 @@ SRC_URI = "git://git.libssh.org/projects/libssh.git;protocol=https;branch=stable | |||
| 11 | file://CVE-2023-48795-1.patch \ | 11 | file://CVE-2023-48795-1.patch \ |
| 12 | file://CVE-2023-48795-2.patch \ | 12 | file://CVE-2023-48795-2.patch \ |
| 13 | file://CVE-2023-48795-3.patch \ | 13 | file://CVE-2023-48795-3.patch \ |
| 14 | file://0001-config-Move-common-parser-functions-to-config_parser.patch \ | ||
| 15 | file://001_CVE-2023-6004.patch \ | ||
| 16 | file://002_CVE-2023-6004.patch \ | ||
| 17 | file://003_CVE-2023-6004.patch \ | ||
| 18 | file://004_CVE-2023-6004.patch \ | ||
| 19 | file://005_CVE-2023-6004.patch \ | ||
| 20 | file://006_CVE-2023-6004.patch \ | ||
| 14 | " | 21 | " |
| 15 | SRCREV = "04685a74df9ce1db1bc116a83a0da78b4f4fa1f8" | 22 | SRCREV = "04685a74df9ce1db1bc116a83a0da78b4f4fa1f8" |
| 16 | 23 | ||
