Skip to content

Commit

Permalink
sshconnect2: Write keyboard-interactive service, info and instruction…
Browse files Browse the repository at this point in the history
…s as utf-8

As per the previous server change now the keyboard-interactive service
and instruction values could be reported as soon as they are available
and so they're not prompts anymore and not parsed like them.

While this was already supported by the SSH client, these messages were
not properly written as the escaped sequences they contained were not
correctly reported.

So for example a message containing "\" was represented as "\\" and
similarly for all the other C escape sequences.

This was leading to more problems when it come to utf-8 chars, as they
were only represented by their octal representation.

This was easily testable by adding a line like the one below to the
sshd PAM service:
  auth    requisite pam_echo.so Hello SSHD! Want some 🍕?

Which was causing this to be written instead:
  Hello SSHD! Want some \360\237\215\225?

To handle this, instead of simply using fmprintf, we're adding a parsing
function that that generates the output in a way can be exposed to
users.
  • Loading branch information
3v1n0 committed Dec 6, 2023
1 parent 5b32e45 commit f83744a
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 6 deletions.
25 changes: 25 additions & 0 deletions misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -3063,3 +3063,28 @@ lib_contains_symbol(const char *path, const char *s)
return ret;
#endif /* HAVE_NLIST_H */
}

char *
parse_ssh_string(const char *msg)
{
FILE *stream;
char *out = NULL;
size_t len = 0;
size_t msg_len = strlen(msg);

stream = open_memstream(&out, &len);
if (stream == NULL)
return NULL;

if (fwrite(msg, 1, msg_len, stream) != msg_len) {
free(out);
return NULL;
}

if (fclose(stream) != 0) {
free(out);
return NULL;
}

return out;
}
2 changes: 2 additions & 0 deletions misc.h
Original file line number Diff line number Diff line change
Expand Up @@ -247,4 +247,6 @@ sshsig_t ssh_signal(int, sshsig_t);
/* On OpenBSD time_t is int64_t which is long long. */
/* #define SSH_TIME_T_MAX LLONG_MAX */

char *parse_ssh_string(const char *msg);

#endif /* _MISC_H */
37 changes: 31 additions & 6 deletions sshconnect2.c
Original file line number Diff line number Diff line change
Expand Up @@ -1103,8 +1103,16 @@ input_userauth_passwd_changereq(int type, u_int32_t seqnr, struct ssh *ssh)
if ((r = sshpkt_get_cstring(ssh, &info, NULL)) != 0 ||
(r = sshpkt_get_cstring(ssh, &lang, NULL)) != 0)
goto out;
if (strlen(info) > 0)
logit("%s", info);
if (*info != '\0') {
char *msg = parse_ssh_string(info);
struct notifier_ctx *notifier = NULL;
debug_f("input_userauth_passwd_changereq info: %s", info);
if (msg == NULL)
goto out;
notifier = notify_start(0, "%s", msg);
notify_complete(notifier, NULL);
free(msg);
}
if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_REQUEST)) != 0 ||
(r = sshpkt_put_cstring(ssh, authctxt->server_user)) != 0 ||
(r = sshpkt_put_cstring(ssh, authctxt->service)) != 0 ||
Expand Down Expand Up @@ -1938,6 +1946,7 @@ input_userauth_info_req(int type, u_int32_t seq, struct ssh *ssh)
Authctxt *authctxt = ssh->authctxt;
char *name = NULL, *inst = NULL, *lang = NULL, *prompt = NULL;
char *display_prompt = NULL, *response = NULL;
struct notifier_ctx *notifier = NULL;
u_char echo = 0;
u_int num_prompts, i;
int r;
Expand All @@ -1953,10 +1962,26 @@ input_userauth_info_req(int type, u_int32_t seq, struct ssh *ssh)
(r = sshpkt_get_cstring(ssh, &inst, NULL)) != 0 ||
(r = sshpkt_get_cstring(ssh, &lang, NULL)) != 0)
goto out;
if (strlen(name) > 0)
logit("%s", name);
if (strlen(inst) > 0)
logit("%s", inst);
if (*name != '\0') {
char *msg = parse_ssh_string(name);
debug_f("kbd int name: %s", name);
if (msg == NULL)
goto out;
notifier = notify_start(0, "%s", msg);
notify_complete (notifier, NULL);
notifier = NULL;
free(msg);
}
if (*inst != '\0') {
char *msg = parse_ssh_string(inst);
debug_f("kbd int inst: %s", inst);
if (msg == NULL)
goto out;
notifier = notify_start(0, "%s", msg);
notify_complete (notifier, NULL);
notifier = NULL;
free(msg);
}

if ((r = sshpkt_get_u32(ssh, &num_prompts)) != 0)
goto out;
Expand Down

0 comments on commit f83744a

Please sign in to comment.