summaryrefslogtreecommitdiff
path: root/clientloop.c
diff options
context:
space:
mode:
Diffstat (limited to 'clientloop.c')
-rw-r--r--clientloop.c106
1 files changed, 73 insertions, 33 deletions
diff --git a/clientloop.c b/clientloop.c
index edd801440..c40f2c303 100644
--- a/clientloop.c
+++ b/clientloop.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: clientloop.c,v 1.189 2008/05/08 12:02:23 djm Exp $ */ 1/* $OpenBSD: clientloop.c,v 1.190 2008/05/08 13:06:10 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -173,6 +173,11 @@ struct confirm_ctx {
173 char **env; 173 char **env;
174}; 174};
175 175
176struct channel_reply_ctx {
177 const char *request_type;
178 int id, do_close;
179};
180
176/*XXX*/ 181/*XXX*/
177extern Kex *xxx_kex; 182extern Kex *xxx_kex;
178 183
@@ -645,25 +650,60 @@ client_process_net_input(fd_set *readset)
645} 650}
646 651
647static void 652static void
648client_subsystem_reply(int type, u_int32_t seq, void *ctxt) 653client_status_confirm(int type, Channel *c, void *ctx)
649{ 654{
650 int id; 655 struct channel_reply_ctx *cr = (struct channel_reply_ctx *)ctx;
651 Channel *c; 656 char errmsg[256];
657 int tochan;
658
659 /* XXX supress on mux _client_ quietmode */
660 tochan = options.log_level >= SYSLOG_LEVEL_ERROR &&
661 c->ctl_fd != -1 && c->extended_usage == CHAN_EXTENDED_WRITE;
662
663 if (type == SSH2_MSG_CHANNEL_SUCCESS) {
664 debug2("%s request accepted on channel %d",
665 cr->request_type, c->self);
666 } else if (type == SSH2_MSG_CHANNEL_FAILURE) {
667 if (tochan) {
668 snprintf(errmsg, sizeof(errmsg),
669 "%s request failed\r\n", cr->request_type);
670 } else {
671 snprintf(errmsg, sizeof(errmsg),
672 "%s request failed on channel %d",
673 cr->request_type, c->self);
674 }
675 /* If error occurred on primary session channel, then exit */
676 if (cr->do_close && c->self == session_ident)
677 fatal("%s", errmsg);
678 /* If error occurred on mux client, append to their stderr */
679 if (tochan)
680 buffer_append(&c->extended, errmsg, strlen(errmsg));
681 else
682 error("%s", errmsg);
683 if (cr->do_close) {
684 chan_read_failed(c);
685 chan_write_failed(c);
686 }
687 }
688 xfree(cr);
689}
652 690
653 id = packet_get_int(); 691static void
654 packet_check_eom(); 692client_abandon_status_confirm(Channel *c, void *ctx)
693{
694 xfree(ctx);
695}
655 696
656 if ((c = channel_lookup(id)) == NULL) { 697static void
657 error("%s: no channel for id %d", __func__, id); 698client_expect_confirm(int id, const char *request, int do_close)
658 return; 699{
659 } 700 struct channel_reply_ctx *cr = xmalloc(sizeof(*cr));
660 701
661 if (type == SSH2_MSG_CHANNEL_SUCCESS) 702 cr->request_type = request;
662 debug2("Request suceeded on channel %d", id); 703 cr->do_close = do_close;
663 else if (type == SSH2_MSG_CHANNEL_FAILURE) { 704
664 error("Request failed on channel %d", id); 705 channel_register_status_confirm(id, client_status_confirm,
665 channel_free(c); 706 client_abandon_status_confirm, cr);
666 }
667} 707}
668 708
669static void 709static void
@@ -698,8 +738,7 @@ client_extra_session2_setup(int id, void *arg)
698 } 738 }
699 739
700 client_session2_setup(id, cctx->want_tty, cctx->want_subsys, 740 client_session2_setup(id, cctx->want_tty, cctx->want_subsys,
701 cctx->term, &cctx->tio, c->rfd, &cctx->cmd, cctx->env, 741 cctx->term, &cctx->tio, c->rfd, &cctx->cmd, cctx->env);
702 client_subsystem_reply);
703 742
704 c->open_confirm_ctx = NULL; 743 c->open_confirm_ctx = NULL;
705 buffer_free(&cctx->cmd); 744 buffer_free(&cctx->cmd);
@@ -1366,7 +1405,9 @@ client_process_buffered_input_packets(void)
1366static int 1405static int
1367simple_escape_filter(Channel *c, char *buf, int len) 1406simple_escape_filter(Channel *c, char *buf, int len)
1368{ 1407{
1369 /* XXX we assume c->extended is writeable */ 1408 if (c->extended_usage != CHAN_EXTENDED_WRITE)
1409 return 0;
1410
1370 return process_escapes(&c->input, &c->output, &c->extended, buf, len); 1411 return process_escapes(&c->input, &c->output, &c->extended, buf, len);
1371} 1412}
1372 1413
@@ -1962,8 +2003,7 @@ client_input_global_request(int type, u_int32_t seq, void *ctxt)
1962 2003
1963void 2004void
1964client_session2_setup(int id, int want_tty, int want_subsystem, 2005client_session2_setup(int id, int want_tty, int want_subsystem,
1965 const char *term, struct termios *tiop, int in_fd, Buffer *cmd, char **env, 2006 const char *term, struct termios *tiop, int in_fd, Buffer *cmd, char **env)
1966 dispatch_fn *subsys_repl)
1967{ 2007{
1968 int len; 2008 int len;
1969 Channel *c = NULL; 2009 Channel *c = NULL;
@@ -1981,7 +2021,8 @@ client_session2_setup(int id, int want_tty, int want_subsystem,
1981 if (ioctl(in_fd, TIOCGWINSZ, &ws) < 0) 2021 if (ioctl(in_fd, TIOCGWINSZ, &ws) < 0)
1982 memset(&ws, 0, sizeof(ws)); 2022 memset(&ws, 0, sizeof(ws));
1983 2023
1984 channel_request_start(id, "pty-req", 0); 2024 channel_request_start(id, "pty-req", 1);
2025 client_expect_confirm(id, "PTY allocation", 0);
1985 packet_put_cstring(term != NULL ? term : ""); 2026 packet_put_cstring(term != NULL ? term : "");
1986 packet_put_int((u_int)ws.ws_col); 2027 packet_put_int((u_int)ws.ws_col);
1987 packet_put_int((u_int)ws.ws_row); 2028 packet_put_int((u_int)ws.ws_row);
@@ -2036,22 +2077,21 @@ client_session2_setup(int id, int want_tty, int want_subsystem,
2036 if (len > 900) 2077 if (len > 900)
2037 len = 900; 2078 len = 900;
2038 if (want_subsystem) { 2079 if (want_subsystem) {
2039 debug("Sending subsystem: %.*s", len, (u_char*)buffer_ptr(cmd)); 2080 debug("Sending subsystem: %.*s",
2040 channel_request_start(id, "subsystem", subsys_repl != NULL); 2081 len, (u_char*)buffer_ptr(cmd));
2041 if (subsys_repl != NULL) { 2082 channel_request_start(id, "subsystem", 1);
2042 /* register callback for reply */ 2083 client_expect_confirm(id, "subsystem", 1);
2043 /* XXX we assume that client_loop has already been called */
2044 dispatch_set(SSH2_MSG_CHANNEL_FAILURE, subsys_repl);
2045 dispatch_set(SSH2_MSG_CHANNEL_SUCCESS, subsys_repl);
2046 }
2047 } else { 2084 } else {
2048 debug("Sending command: %.*s", len, (u_char*)buffer_ptr(cmd)); 2085 debug("Sending command: %.*s",
2049 channel_request_start(id, "exec", 0); 2086 len, (u_char*)buffer_ptr(cmd));
2087 channel_request_start(id, "exec", 1);
2088 client_expect_confirm(id, "exec", 1);
2050 } 2089 }
2051 packet_put_string(buffer_ptr(cmd), buffer_len(cmd)); 2090 packet_put_string(buffer_ptr(cmd), buffer_len(cmd));
2052 packet_send(); 2091 packet_send();
2053 } else { 2092 } else {
2054 channel_request_start(id, "shell", 0); 2093 channel_request_start(id, "shell", 1);
2094 client_expect_confirm(id, "shell", 1);
2055 packet_send(); 2095 packet_send();
2056 } 2096 }
2057} 2097}