1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
|
From: terrafrost <terrafrost@php.net>
Date: Tue, 21 Nov 2023 23:02:42 -0600
Subject: SSH2: add support for RFC8308
Origin: upstream, https://github.com/phpseclib/phpseclib/commit/356ab5f76abb1cadd2461e6aae01767b511090a3
---
phpseclib/Net/SSH2.php | 45 ++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 44 insertions(+), 1 deletion(-)
diff --git a/phpseclib/Net/SSH2.php b/phpseclib/Net/SSH2.php
index c1cfbbc..4d8e625 100644
--- a/phpseclib/Net/SSH2.php
+++ b/phpseclib/Net/SSH2.php
@@ -338,6 +338,15 @@ class SSH2
*/
var $languages_client_to_server = false;
+ /**
+ * Server Signature Algorithms
+ *
+ * @link https://www.rfc-editor.org/rfc/rfc8308.html#section-3.1
+ * @var array|false
+ * @access private
+ */
+ var $server_sig_algs = false;
+
/**
* Preferred Algorithms
*
@@ -1011,6 +1020,7 @@ class SSH2
4 => 'NET_SSH2_MSG_DEBUG',
5 => 'NET_SSH2_MSG_SERVICE_REQUEST',
6 => 'NET_SSH2_MSG_SERVICE_ACCEPT',
+ 7 => 'NET_SSH2_MSG_EXT_INFO', // RFC 8308
20 => 'NET_SSH2_MSG_KEXINIT',
21 => 'NET_SSH2_MSG_NEWKEYS',
30 => 'NET_SSH2_MSG_KEXDH_INIT',
@@ -1393,6 +1403,8 @@ class SSH2
$preferred['client_to_server']['comp'] :
$this->getSupportedCompressionAlgorithms();
+ $kex_algorithms = array_merge($kex_algorithms, array('ext-info-c'));
+
// some SSH servers have buggy implementations of some of the above algorithms
switch (true) {
case $this->server_identifier == 'SSH-2.0-SSHD':
@@ -2240,6 +2252,35 @@ class SSH2
}
extract(unpack('Ctype', $this->_string_shift($response, 1)));
+ if ($type == NET_SSH2_MSG_EXT_INFO) {
+ if (strlen($response) < 4) {
+ return false;
+ }
+ $nr_extensions = unpack('Nlength', $this->_string_shift($response, 4));
+ for ($i = 0; $i < $nr_extensions['length']; $i++) {
+ if (strlen($response) < 4) {
+ return false;
+ }
+ $temp = unpack('Nlength', $this->_string_shift($response, 4));
+ $extension_name = $this->_string_shift($response, $temp['length']);
+ if ($extension_name == 'server-sig-algs') {
+ if (strlen($response) < 4) {
+ return false;
+ }
+ $temp = unpack('Nlength', $this->_string_shift($response, 4));
+ $this->server_sig_algs = explode(',', $this->_string_shift($response, $temp['length']));
+ }
+ }
+
+ $response = $this->_get_binary_packet();
+ if ($response === false) {
+ $this->bitmap = 0;
+ user_error('Connection closed by server');
+ return false;
+ }
+ extract(unpack('Ctype', $this->_string_shift($response, 1)));
+ }
+
if ($type != NET_SSH2_MSG_SERVICE_ACCEPT) {
user_error('Expected SSH_MSG_SERVICE_ACCEPT');
return false;
@@ -2606,7 +2647,9 @@ class SSH2
);
$algos = array('rsa-sha2-256', 'rsa-sha2-512', 'ssh-rsa');
- if (isset($this->preferred['hostkey'])) {
+ if ($this->server_sig_algs) {
+ $algos = array_intersect($this->server_sig_algs, $algos);
+ } elseif (isset($this->preferred['hostkey'])) {
$algos = array_intersect($this->preferred['hostkey'], $algos);
}
$algo = $this->_array_intersect_first($algos, $this->supported_private_key_algorithms);
|