From 2cdff46d9803ee7186607562567f177375e66c31 Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Thu, 6 Dec 2018 18:35:27 +0000 Subject: [PATCH] Remove the old in_commasep_string system. It's just silly to have _two_ systems for traversing a string of comma-separated protocol ids. I think the new get_commasep_word technique for looping over the elements of a string is simpler and more general than the old membership-testing approach, and also it's necessary for the modern KEX untangling system (which has to be able to loop over one string, even if it used a membership test to check things in the other). So this commit rewrites the two remaining uses of in_commasep_string to use get_commasep_word instead, and deletes the former. --- ssh.h | 3 --- ssh2transport.c | 13 ++++++++----- ssh2userauth.c | 46 ++++++++++++++++++++++++++++------------------ sshcommon.c | 39 --------------------------------------- 4 files changed, 36 insertions(+), 65 deletions(-) diff --git a/ssh.h b/ssh.h index dea68867..691ed967 100644 --- a/ssh.h +++ b/ssh.h @@ -1529,9 +1529,6 @@ unsigned alloc_channel_id_general(tree234 *channels, size_t localid_offset); TYPECHECK(&((type *)0)->localid == (unsigned *)0, \ alloc_channel_id_general(tree, offsetof(type, localid))) -bool first_in_commasep_string(char const *needle, char const *haystack, - int haylen); -bool in_commasep_string(char const *needle, char const *haystack, int haylen); void add_to_commasep(strbuf *buf, const char *data); bool get_commasep_word(ptrlen *list, ptrlen *word); diff --git a/ssh2transport.c b/ssh2transport.c index e02205fd..bf9a24dc 100644 --- a/ssh2transport.c +++ b/ssh2transport.c @@ -940,11 +940,14 @@ static bool ssh2_scan_kexinits( */ *n_server_hostkeys = 0; - for (i = 0; i < lenof(ssh2_hostkey_algs); i++) - if (in_commasep_string(ssh2_hostkey_algs[i].alg->ssh_id, - slists[KEXLIST_HOSTKEY].ptr, - slists[KEXLIST_HOSTKEY].len)) - server_hostkeys[(*n_server_hostkeys)++] = i; + ptrlen list = slists[KEXLIST_HOSTKEY]; + for (ptrlen word; get_commasep_word(&list, &word) ;) { + for (i = 0; i < lenof(ssh2_hostkey_algs); i++) + if (ptrlen_eq_string(word, ssh2_hostkey_algs[i].alg->ssh_id)) { + server_hostkeys[(*n_server_hostkeys)++] = i; + break; + } + } } return true; diff --git a/ssh2userauth.c b/ssh2userauth.c index 033b0030..23015807 100644 --- a/ssh2userauth.c +++ b/ssh2userauth.c @@ -575,26 +575,36 @@ static void ssh2_userauth_process_queue(PacketProtocolLayer *ppl) /* * Scan it for method identifiers we know about. */ - s->can_pubkey = - in_commasep_string("publickey", methods.ptr, methods.len); - s->can_passwd = - in_commasep_string("password", methods.ptr, methods.len); - s->can_keyb_inter = - s->try_ki_auth && - in_commasep_string("keyboard-interactive", - methods.ptr, methods.len); + bool srv_pubkey = false, srv_passwd = false; + bool srv_keyb_inter = false, srv_gssapi = false; + bool srv_gssapi_keyex_auth = false; + + for (ptrlen method; get_commasep_word(&methods, &method) ;) { + if (ptrlen_eq_string(method, "publickey")) + srv_pubkey = true; + else if (ptrlen_eq_string(method, "password")) + srv_passwd = true; + else if (ptrlen_eq_string(method, "keyboard-interactive")) + srv_keyb_inter = true; + else if (ptrlen_eq_string(method, "gssapi-with-mic")) + srv_gssapi = true; + else if (ptrlen_eq_string(method, "gssapi-keyex")) + srv_gssapi_keyex_auth = true; + } + + /* + * And combine those flags with our own configuration + * and context to set the main can_foo variables. + */ + s->can_pubkey = srv_pubkey; + s->can_passwd = srv_passwd; + s->can_keyb_inter = s->try_ki_auth && srv_keyb_inter; #ifndef NO_GSSAPI - s->can_gssapi = - s->try_gssapi_auth && - in_commasep_string("gssapi-with-mic", - methods.ptr, methods.len) && + s->can_gssapi = s->try_gssapi_auth && srv_gssapi && s->shgss->libs->nlibraries > 0; - s->can_gssapi_keyex_auth = - s->try_gssapi_kex_auth && - in_commasep_string("gssapi-keyex", - methods.ptr, methods.len) && - s->shgss->libs->nlibraries > 0 && - s->shgss->ctx; + s->can_gssapi_keyex_auth = s->try_gssapi_kex_auth && + srv_gssapi_keyex_auth && + s->shgss->libs->nlibraries > 0 && s->shgss->ctx; #endif } diff --git a/sshcommon.c b/sshcommon.c index 563e4130..1117881b 100644 --- a/sshcommon.c +++ b/sshcommon.c @@ -687,45 +687,6 @@ unsigned alloc_channel_id_general(tree234 *channels, size_t localid_offset) * lists of protocol identifiers in SSH-2. */ -bool first_in_commasep_string(char const *needle, char const *haystack, - int haylen) -{ - int needlen; - if (!needle || !haystack) /* protect against null pointers */ - return false; - needlen = strlen(needle); - - if (haylen >= needlen && /* haystack is long enough */ - !memcmp(needle, haystack, needlen) && /* initial match */ - (haylen == needlen || haystack[needlen] == ',') - /* either , or EOS follows */ - ) - return true; - return false; -} - -bool in_commasep_string(char const *needle, char const *haystack, int haylen) -{ - char *p; - - if (!needle || !haystack) /* protect against null pointers */ - return false; - /* - * Is it at the start of the string? - */ - if (first_in_commasep_string(needle, haystack, haylen)) - return true; - /* - * If not, search for the next comma and resume after that. - * If no comma found, terminate. - */ - p = memchr(haystack, ',', haylen); - if (!p) - return false; - /* + 1 to skip over comma */ - return in_commasep_string(needle, p + 1, haylen - (p + 1 - haystack)); -} - void add_to_commasep(strbuf *buf, const char *data) { if (buf->len > 0)