mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-09 17:38:00 +00:00
Uppity: add a stunt mode --close-after-banner.
A user reported yesterday that PuTTY can fail to print a userauth banner message if the server sends one and then immediately slams the connection shut. The first step to fixing this is making a convenient way to reproduce that server behaviour. (Apparently the real use case has to do with account expiry - the server in question presumably doesn't have enough layer violations to be able to put the text "Your account has expired" into an SSH_MSG_DISCONNECT, so instead it does the next best thing and sends it as a userauth banner immediately before disconnection.)
This commit is contained in:
parent
62b69a4f16
commit
fe63b5d57e
@ -502,6 +502,7 @@ void ssh_sw_abort(Ssh *ssh, const char *fmt, ...)
|
|||||||
void ssh_user_close(Ssh *ssh, const char *fmt, ...)
|
void ssh_user_close(Ssh *ssh, const char *fmt, ...)
|
||||||
{
|
{
|
||||||
server *srv = container_of(ssh, server, ssh);
|
server *srv = container_of(ssh, server, ssh);
|
||||||
|
ssh_bpp_handle_output(srv->bpp);
|
||||||
LOG_FORMATTED_MSG(srv->logctx, fmt);
|
LOG_FORMATTED_MSG(srv->logctx, fmt);
|
||||||
queue_toplevel_callback(ssh_server_free_callback, srv);
|
queue_toplevel_callback(ssh_server_free_callback, srv);
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,7 @@ struct SshServerConfig {
|
|||||||
bool stunt_open_unconditional_agent_socket;
|
bool stunt_open_unconditional_agent_socket;
|
||||||
bool stunt_allow_trivial_ki_auth;
|
bool stunt_allow_trivial_ki_auth;
|
||||||
bool stunt_return_success_to_pubkey_offer;
|
bool stunt_return_success_to_pubkey_offer;
|
||||||
|
bool stunt_close_after_banner;
|
||||||
};
|
};
|
||||||
|
|
||||||
Plug *ssh_server_plug(
|
Plug *ssh_server_plug(
|
||||||
|
@ -113,6 +113,21 @@ static void ssh2_userauth_server_add_session_id(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ssh2_userauth_server_close_after_banner(void *vctx)
|
||||||
|
{
|
||||||
|
struct ssh2_userauth_server_state *s =
|
||||||
|
(struct ssh2_userauth_server_state *)vctx;
|
||||||
|
|
||||||
|
if (pq_peek(s->ppl.out_pq)) {
|
||||||
|
/* Don't close the connection until we've passed on our final banner
|
||||||
|
* packet to the lower layer */
|
||||||
|
queue_toplevel_callback(ssh2_userauth_server_close_after_banner, s);
|
||||||
|
} else {
|
||||||
|
ssh_user_close(s->ppl.ssh, "Closing connection on request due to "
|
||||||
|
"--close-after-banner");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void ssh2_userauth_server_process_queue(PacketProtocolLayer *ppl)
|
static void ssh2_userauth_server_process_queue(PacketProtocolLayer *ppl)
|
||||||
{
|
{
|
||||||
struct ssh2_userauth_server_state *s =
|
struct ssh2_userauth_server_state *s =
|
||||||
@ -131,6 +146,11 @@ static void ssh2_userauth_server_process_queue(PacketProtocolLayer *ppl)
|
|||||||
pq_push(s->ppl.out_pq, pktout);
|
pq_push(s->ppl.out_pq, pktout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (s->ssc->stunt_close_after_banner) {
|
||||||
|
queue_toplevel_callback(ssh2_userauth_server_close_after_banner, s);
|
||||||
|
crReturnV;
|
||||||
|
}
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
crMaybeWaitUntilV((pktin = ssh2_userauth_server_pop(s)) != NULL);
|
crMaybeWaitUntilV((pktin = ssh2_userauth_server_pop(s)) != NULL);
|
||||||
if (pktin->type != SSH2_MSG_USERAUTH_REQUEST) {
|
if (pktin->type != SSH2_MSG_USERAUTH_REQUEST) {
|
||||||
|
@ -924,6 +924,8 @@ int main(int argc, char **argv)
|
|||||||
ci->ssc.stunt_allow_trivial_ki_auth = true;
|
ci->ssc.stunt_allow_trivial_ki_auth = true;
|
||||||
} else if (!strcmp(arg, "--return-success-to-pubkey-offer")) {
|
} else if (!strcmp(arg, "--return-success-to-pubkey-offer")) {
|
||||||
ci->ssc.stunt_return_success_to_pubkey_offer = true;
|
ci->ssc.stunt_return_success_to_pubkey_offer = true;
|
||||||
|
} else if (!strcmp(arg, "--close-after-banner")) {
|
||||||
|
ci->ssc.stunt_close_after_banner = true;
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "%s: unrecognised option '%s'\n", appname, arg);
|
fprintf(stderr, "%s: unrecognised option '%s'\n", appname, arg);
|
||||||
exit(1);
|
exit(1);
|
||||||
|
Loading…
Reference in New Issue
Block a user