@@ -3032,6 +3032,13 @@ kex_method_extension_negotiation = {
30323032 0 ,
30333033};
30343034
3035+ static const LIBSSH2_KEX_METHOD
3036+ kex_method_strict_client_extension = {
3037+ "kex-strict-c-v00@openssh.com" ,
3038+ NULL ,
3039+ 0 ,
3040+ };
3041+
30353042static const LIBSSH2_KEX_METHOD * libssh2_kex_methods [] = {
30363043#if LIBSSH2_ED25519
30373044 & kex_method_ssh_curve25519_sha256 ,
@@ -3050,6 +3057,7 @@ static const LIBSSH2_KEX_METHOD *libssh2_kex_methods[] = {
30503057 & kex_method_diffie_helman_group1_sha1 ,
30513058 & kex_method_diffie_helman_group_exchange_sha1 ,
30523059 & kex_method_extension_negotiation ,
3060+ & kex_method_strict_client_extension ,
30533061 NULL
30543062};
30553063
@@ -3302,13 +3310,13 @@ static int kexinit(LIBSSH2_SESSION * session)
33023310 return 0 ;
33033311}
33043312
3305- /* kex_agree_instr
3313+ /* _libssh2_kex_agree_instr
33063314 * Kex specific variant of strstr()
33073315 * Needle must be preceded by BOL or ',', and followed by ',' or EOL
33083316 */
3309- static unsigned char *
3310- kex_agree_instr (unsigned char * haystack , size_t haystack_len ,
3311- const unsigned char * needle , size_t needle_len )
3317+ unsigned char *
3318+ _libssh2_kex_agree_instr (unsigned char * haystack , size_t haystack_len ,
3319+ const unsigned char * needle , size_t needle_len )
33123320{
33133321 unsigned char * s ;
33143322 unsigned char * end_haystack ;
@@ -3393,7 +3401,7 @@ static int kex_agree_hostkey(LIBSSH2_SESSION * session,
33933401 while (s && * s ) {
33943402 unsigned char * p = (unsigned char * ) strchr ((char * ) s , ',' );
33953403 size_t method_len = (p ? (size_t )(p - s ) : strlen ((char * ) s ));
3396- if (kex_agree_instr (hostkey , hostkey_len , s , method_len )) {
3404+ if (_libssh2_kex_agree_instr (hostkey , hostkey_len , s , method_len )) {
33973405 const LIBSSH2_HOSTKEY_METHOD * method =
33983406 (const LIBSSH2_HOSTKEY_METHOD * )
33993407 kex_get_method_by_name ((char * ) s , method_len ,
@@ -3427,9 +3435,9 @@ static int kex_agree_hostkey(LIBSSH2_SESSION * session,
34273435 }
34283436
34293437 while (hostkeyp && (* hostkeyp ) && (* hostkeyp )-> name ) {
3430- s = kex_agree_instr (hostkey , hostkey_len ,
3431- (unsigned char * ) (* hostkeyp )-> name ,
3432- strlen ((* hostkeyp )-> name ));
3438+ s = _libssh2_kex_agree_instr (hostkey , hostkey_len ,
3439+ (unsigned char * ) (* hostkeyp )-> name ,
3440+ strlen ((* hostkeyp )-> name ));
34333441 if (s ) {
34343442 /* So far so good, but does it suit our purposes? (Encrypting vs
34353443 Signing) */
@@ -3463,14 +3471,20 @@ static int kex_agree_kex_hostkey(LIBSSH2_SESSION * session, unsigned char *kex,
34633471{
34643472 const LIBSSH2_KEX_METHOD * * kexp = libssh2_kex_methods ;
34653473 unsigned char * s ;
3474+ const unsigned char * strict =
3475+ (unsigned char * )"kex-strict-s-v00@openssh.com" ;
3476+
3477+ if (_libssh2_kex_agree_instr (kex , kex_len , strict , 28 )) {
3478+ session -> kex_strict = 1 ;
3479+ }
34663480
34673481 if (session -> kex_prefs ) {
34683482 s = (unsigned char * ) session -> kex_prefs ;
34693483
34703484 while (s && * s ) {
34713485 unsigned char * q , * p = (unsigned char * ) strchr ((char * ) s , ',' );
34723486 size_t method_len = (p ? (size_t )(p - s ) : strlen ((char * ) s ));
3473- q = kex_agree_instr (kex , kex_len , s , method_len );
3487+ q = _libssh2_kex_agree_instr (kex , kex_len , s , method_len );
34743488 if (q ) {
34753489 const LIBSSH2_KEX_METHOD * method = (const LIBSSH2_KEX_METHOD * )
34763490 kex_get_method_by_name ((char * ) s , method_len ,
@@ -3504,9 +3518,9 @@ static int kex_agree_kex_hostkey(LIBSSH2_SESSION * session, unsigned char *kex,
35043518 }
35053519
35063520 while (* kexp && (* kexp )-> name ) {
3507- s = kex_agree_instr (kex , kex_len ,
3508- (unsigned char * ) (* kexp )-> name ,
3509- strlen ((* kexp )-> name ));
3521+ s = _libssh2_kex_agree_instr (kex , kex_len ,
3522+ (unsigned char * ) (* kexp )-> name ,
3523+ strlen ((* kexp )-> name ));
35103524 if (s ) {
35113525 /* We've agreed on a key exchange method,
35123526 * Can we agree on a hostkey that works with this kex?
@@ -3550,7 +3564,7 @@ static int kex_agree_crypt(LIBSSH2_SESSION * session,
35503564 unsigned char * p = (unsigned char * ) strchr ((char * ) s , ',' );
35513565 size_t method_len = (p ? (size_t )(p - s ) : strlen ((char * ) s ));
35523566
3553- if (kex_agree_instr (crypt , crypt_len , s , method_len )) {
3567+ if (_libssh2_kex_agree_instr (crypt , crypt_len , s , method_len )) {
35543568 const LIBSSH2_CRYPT_METHOD * method =
35553569 (const LIBSSH2_CRYPT_METHOD * )
35563570 kex_get_method_by_name ((char * ) s , method_len ,
@@ -3572,9 +3586,9 @@ static int kex_agree_crypt(LIBSSH2_SESSION * session,
35723586 }
35733587
35743588 while (* cryptp && (* cryptp )-> name ) {
3575- s = kex_agree_instr (crypt , crypt_len ,
3576- (unsigned char * ) (* cryptp )-> name ,
3577- strlen ((* cryptp )-> name ));
3589+ s = _libssh2_kex_agree_instr (crypt , crypt_len ,
3590+ (unsigned char * ) (* cryptp )-> name ,
3591+ strlen ((* cryptp )-> name ));
35783592 if (s ) {
35793593 endpoint -> crypt = * cryptp ;
35803594 return 0 ;
@@ -3614,7 +3628,7 @@ static int kex_agree_mac(LIBSSH2_SESSION * session,
36143628 unsigned char * p = (unsigned char * ) strchr ((char * ) s , ',' );
36153629 size_t method_len = (p ? (size_t )(p - s ) : strlen ((char * ) s ));
36163630
3617- if (kex_agree_instr (mac , mac_len , s , method_len )) {
3631+ if (_libssh2_kex_agree_instr (mac , mac_len , s , method_len )) {
36183632 const LIBSSH2_MAC_METHOD * method = (const LIBSSH2_MAC_METHOD * )
36193633 kex_get_method_by_name ((char * ) s , method_len ,
36203634 (const LIBSSH2_COMMON_METHOD * * )
@@ -3635,8 +3649,9 @@ static int kex_agree_mac(LIBSSH2_SESSION * session,
36353649 }
36363650
36373651 while (* macp && (* macp )-> name ) {
3638- s = kex_agree_instr (mac , mac_len , (unsigned char * ) (* macp )-> name ,
3639- strlen ((* macp )-> name ));
3652+ s = _libssh2_kex_agree_instr (mac , mac_len ,
3653+ (unsigned char * ) (* macp )-> name ,
3654+ strlen ((* macp )-> name ));
36403655 if (s ) {
36413656 endpoint -> mac = * macp ;
36423657 return 0 ;
@@ -3667,7 +3682,7 @@ static int kex_agree_comp(LIBSSH2_SESSION *session,
36673682 unsigned char * p = (unsigned char * ) strchr ((char * ) s , ',' );
36683683 size_t method_len = (p ? (size_t )(p - s ) : strlen ((char * ) s ));
36693684
3670- if (kex_agree_instr (comp , comp_len , s , method_len )) {
3685+ if (_libssh2_kex_agree_instr (comp , comp_len , s , method_len )) {
36713686 const LIBSSH2_COMP_METHOD * method =
36723687 (const LIBSSH2_COMP_METHOD * )
36733688 kex_get_method_by_name ((char * ) s , method_len ,
@@ -3689,8 +3704,9 @@ static int kex_agree_comp(LIBSSH2_SESSION *session,
36893704 }
36903705
36913706 while (* compp && (* compp )-> name ) {
3692- s = kex_agree_instr (comp , comp_len , (unsigned char * ) (* compp )-> name ,
3693- strlen ((* compp )-> name ));
3707+ s = _libssh2_kex_agree_instr (comp , comp_len ,
3708+ (unsigned char * ) (* compp )-> name ,
3709+ strlen ((* compp )-> name ));
36943710 if (s ) {
36953711 endpoint -> comp = * compp ;
36963712 return 0 ;
@@ -3871,6 +3887,7 @@ _libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange,
38713887 session -> local .kexinit = key_state -> oldlocal ;
38723888 session -> local .kexinit_len = key_state -> oldlocal_len ;
38733889 key_state -> state = libssh2_NB_state_idle ;
3890+ session -> state &= ~LIBSSH2_STATE_INITIAL_KEX ;
38743891 session -> state &= ~LIBSSH2_STATE_KEX_ACTIVE ;
38753892 session -> state &= ~LIBSSH2_STATE_EXCHANGING_KEYS ;
38763893 return -1 ;
@@ -3896,6 +3913,7 @@ _libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange,
38963913 session -> local .kexinit = key_state -> oldlocal ;
38973914 session -> local .kexinit_len = key_state -> oldlocal_len ;
38983915 key_state -> state = libssh2_NB_state_idle ;
3916+ session -> state &= ~LIBSSH2_STATE_INITIAL_KEX ;
38993917 session -> state &= ~LIBSSH2_STATE_KEX_ACTIVE ;
39003918 session -> state &= ~LIBSSH2_STATE_EXCHANGING_KEYS ;
39013919 return -1 ;
@@ -3944,6 +3962,7 @@ _libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange,
39443962 session -> remote .kexinit = NULL ;
39453963 }
39463964
3965+ session -> state &= ~LIBSSH2_STATE_INITIAL_KEX ;
39473966 session -> state &= ~LIBSSH2_STATE_KEX_ACTIVE ;
39483967 session -> state &= ~LIBSSH2_STATE_EXCHANGING_KEYS ;
39493968
0 commit comments