diff --git a/network.h b/network.h index 068e6cc6..851e1738 100644 --- a/network.h +++ b/network.h @@ -224,6 +224,10 @@ static inline void plug_log( { p->vt->log(p, type, addr, port, msg, code); } static inline void plug_closing(Plug *p, const char *msg, int code) { p->vt->closing(p, msg, code); } +static inline void plug_closing_normal(Plug *p) +{ p->vt->closing(p, NULL, 0); } +static inline void plug_closing_error(Plug *p, const char *msg) +{ p->vt->closing(p, msg, 0); } static inline void plug_receive(Plug *p, int urg, const char *data, size_t len) { p->vt->receive(p, urg, data, len); } static inline void plug_sent (Plug *p, size_t bufsize) diff --git a/proxy/cproxy.c b/proxy/cproxy.c index d187ffec..e58c344b 100644 --- a/proxy/cproxy.c +++ b/proxy/cproxy.c @@ -65,15 +65,13 @@ int proxy_socks5_handlechap (ProxySocket *p) * number of attributes */ if (data[0] != 0x01) { - plug_closing(p->plug, "Proxy error: SOCKS proxy wants" - " a different CHAP version", - PROXY_ERROR_GENERAL); + plug_closing_error(p->plug, "Proxy error: SOCKS proxy wants " + "a different CHAP version"); return 1; } if (data[1] == 0x00) { - plug_closing(p->plug, "Proxy error: SOCKS proxy won't" - " negotiate CHAP with us", - PROXY_ERROR_GENERAL); + plug_closing_error(p->plug, "Proxy error: SOCKS proxy won't " + "negotiate CHAP with us"); return 1; } p->chap_num_attributes = data[1]; @@ -103,9 +101,8 @@ int proxy_socks5_handlechap (ProxySocket *p) if (data[0] == 0x00) p->state = 2; else { - plug_closing(p->plug, "Proxy error: SOCKS proxy" - " refused CHAP authentication", - PROXY_ERROR_GENERAL); + plug_closing_error(p->plug, "Proxy error: SOCKS proxy " + "refused CHAP authentication"); return 1; } break; @@ -122,10 +119,9 @@ int proxy_socks5_handlechap (ProxySocket *p) case 0x11: /* Chose a protocol */ if (data[0] != 0x85) { - plug_closing(p->plug, "Proxy error: Server chose " - "CHAP of other than HMAC-MD5 but we " - "didn't offer it!", - PROXY_ERROR_GENERAL); + plug_closing_error(p->plug, "Proxy error: Server chose " + "CHAP of other than HMAC-MD5 but we " + "didn't offer it!"); return 1; } break; @@ -172,8 +168,7 @@ int proxy_socks5_selectchap(ProxySocket *p) p->state = 8; } else - plug_closing(p->plug, "Proxy error: Server chose " - "CHAP authentication but we didn't offer it!", - PROXY_ERROR_GENERAL); + plug_closing_error(p->plug, "Proxy error: Server chose " + "CHAP authentication but we didn't offer it!"); return 1; } diff --git a/proxy/nocproxy.c b/proxy/nocproxy.c index cdc28a39..ed9c3ffd 100644 --- a/proxy/nocproxy.c +++ b/proxy/nocproxy.c @@ -17,19 +17,16 @@ void proxy_socks5_offerencryptedauth(BinarySink *bs) /* For telnet, don't add any new encrypted authentication routines */ } -int proxy_socks5_handlechap (ProxySocket *p) +int proxy_socks5_handlechap(ProxySocket *p) { - - plug_closing(p->plug, "Proxy error: Trying to handle a SOCKS5 CHAP request" - " in telnet-only build", - PROXY_ERROR_GENERAL); + plug_closing_error(p->plug, "Proxy error: Trying to handle a " + "SOCKS5 CHAP request in telnet-only build"); return 1; } int proxy_socks5_selectchap(ProxySocket *p) { - plug_closing(p->plug, "Proxy error: Trying to handle a SOCKS5 CHAP request" - " in telnet-only build", - PROXY_ERROR_GENERAL); + plug_closing_error(p->plug, "Proxy error: Trying to handle a " + "SOCKS5 CHAP request in telnet-only build"); return 1; } diff --git a/proxy/proxy.c b/proxy/proxy.c index 69b32866..d4963db4 100644 --- a/proxy/proxy.c +++ b/proxy/proxy.c @@ -671,8 +671,8 @@ int proxy_http_negotiate (ProxySocket *p, int change) /* We can't rely on whether the %n incremented the sscanf return */ if (sscanf((char *)data, "HTTP/%i.%i %n", &maj_ver, &min_ver, &status) < 2 || status == -1) { - plug_closing(p->plug, "Proxy error: HTTP response was absent", - PROXY_ERROR_GENERAL); + plug_closing_error(p->plug, "Proxy error: " + "HTTP response was absent"); sfree(data); return 1; } @@ -687,7 +687,7 @@ int proxy_http_negotiate (ProxySocket *p, int change) (data[eol-1] == '\r' || data[eol-1] == '\n')) data[--eol] = '\0'; buf = dupprintf("Proxy error: %s", data+status); - plug_closing(p->plug, buf, PROXY_ERROR_GENERAL); + plug_closing_error(p->plug, buf); sfree(buf); sfree(data); return 1; @@ -737,8 +737,7 @@ int proxy_http_negotiate (ProxySocket *p, int change) } } - plug_closing(p->plug, "Proxy error: unexpected proxy error", - PROXY_ERROR_UNEXPECTED); + plug_closing_error(p->plug, "Proxy error: unexpected proxy error"); return 1; } @@ -854,9 +853,9 @@ int proxy_socks4_negotiate (ProxySocket *p, int change) bufchain_fetch(&p->pending_input_data, data, 8); if (data[0] != 0) { - plug_closing(p->plug, "Proxy error: SOCKS proxy responded with " - "unexpected reply code version", - PROXY_ERROR_GENERAL); + plug_closing_error(p->plug, "Proxy error: SOCKS proxy " + "responded with unexpected " + "reply code version"); return 1; } @@ -864,17 +863,17 @@ int proxy_socks4_negotiate (ProxySocket *p, int change) switch (data[1]) { case 92: - plug_closing(p->plug, "Proxy error: SOCKS server wanted IDENTD on client", - PROXY_ERROR_GENERAL); + plug_closing_error(p->plug, "Proxy error: SOCKS server " + "wanted IDENTD on client"); break; case 93: - plug_closing(p->plug, "Proxy error: Username and IDENTD on client don't agree", - PROXY_ERROR_GENERAL); + plug_closing_error(p->plug, "Proxy error: Username and " + "IDENTD on client don't agree"); break; case 91: default: - plug_closing(p->plug, "Proxy error: Error while communicating with proxy", - PROXY_ERROR_GENERAL); + plug_closing_error(p->plug, "Proxy error: Error while " + "communicating with proxy"); break; } @@ -890,8 +889,7 @@ int proxy_socks4_negotiate (ProxySocket *p, int change) } } - plug_closing(p->plug, "Proxy error: unexpected proxy error", - PROXY_ERROR_UNEXPECTED); + plug_closing_error(p->plug, "Proxy error: unexpected proxy error"); return 1; } @@ -996,8 +994,8 @@ int proxy_socks5_negotiate (ProxySocket *p, int change) bufchain_fetch(&p->pending_input_data, data, 2); if (data[0] != 5) { - plug_closing(p->plug, "Proxy error: SOCKS proxy returned unexpected version", - PROXY_ERROR_GENERAL); + plug_closing_error(p->plug, "Proxy error: SOCKS proxy " + "returned unexpected version"); return 1; } @@ -1006,8 +1004,8 @@ int proxy_socks5_negotiate (ProxySocket *p, int change) else if (data[1] == 0x02) p->state = 5; /* username/password authentication */ else if (data[1] == 0x03) p->state = 6; /* CHAP authentication */ else { - plug_closing(p->plug, "Proxy error: SOCKS proxy did not accept our authentication", - PROXY_ERROR_GENERAL); + plug_closing_error(p->plug, "Proxy error: SOCKS proxy did not " + "accept our authentication"); return 1; } bufchain_consume(&p->pending_input_data, 2); @@ -1030,17 +1028,15 @@ int proxy_socks5_negotiate (ProxySocket *p, int change) bufchain_fetch(&p->pending_input_data, data, 2); if (data[0] != 1) { - plug_closing(p->plug, "Proxy error: SOCKS password " - "subnegotiation contained wrong version number", - PROXY_ERROR_GENERAL); + plug_closing_error(p->plug, "Proxy error: SOCKS password " + "subnegotiation contained wrong version " + "number"); return 1; } if (data[1] != 0) { - - plug_closing(p->plug, "Proxy error: SOCKS proxy refused" - " password authentication", - PROXY_ERROR_GENERAL); + plug_closing_error(p->plug, "Proxy error: SOCKS proxy refused " + "password authentication"); return 1; } @@ -1142,8 +1138,8 @@ int proxy_socks5_negotiate (ProxySocket *p, int change) bufchain_fetch(&p->pending_input_data, data, 5); if (data[0] != 5) { - plug_closing(p->plug, "Proxy error: SOCKS proxy returned wrong version number", - PROXY_ERROR_GENERAL); + plug_closing_error(p->plug, "Proxy error: SOCKS proxy " + "returned wrong version number"); return 1; } @@ -1166,7 +1162,7 @@ int proxy_socks5_negotiate (ProxySocket *p, int change) data[1]); break; } - plug_closing(p->plug, buf, PROXY_ERROR_GENERAL); + plug_closing_error(p->plug, buf); return 1; } @@ -1180,9 +1176,8 @@ int proxy_socks5_negotiate (ProxySocket *p, int change) case 4: len += 16; break;/* IPv6 address */ case 3: len += 1+(unsigned char)data[4]; break; /* domain name */ default: - plug_closing(p->plug, "Proxy error: SOCKS proxy returned " - "unrecognised address format", - PROXY_ERROR_GENERAL); + plug_closing_error(p->plug, "Proxy error: SOCKS proxy " + "returned unrecognised address format"); return 1; } if (bufchain_size(&p->pending_input_data) < len) @@ -1196,8 +1191,8 @@ int proxy_socks5_negotiate (ProxySocket *p, int change) if (p->state == 4) { /* TODO: Handle GSSAPI authentication */ - plug_closing(p->plug, "Proxy error: We don't support GSSAPI authentication", - PROXY_ERROR_GENERAL); + plug_closing_error(p->plug, "Proxy error: We don't support " + "GSSAPI authentication"); return 1; } @@ -1223,10 +1218,9 @@ int proxy_socks5_negotiate (ProxySocket *p, int change) strbuf_free(auth); p->state = 7; } else - plug_closing(p->plug, "Proxy error: Server chose " - "username/password authentication but we " - "didn't offer it!", - PROXY_ERROR_GENERAL); + plug_closing_error(p->plug, "Proxy error: Server chose " + "username/password authentication " + "but we didn't offer it!"); return 1; } @@ -1238,8 +1232,7 @@ int proxy_socks5_negotiate (ProxySocket *p, int change) } - plug_closing(p->plug, "Proxy error: Unexpected proxy error", - PROXY_ERROR_UNEXPECTED); + plug_closing_error(p->plug, "Proxy error: Unexpected proxy error"); return 1; } @@ -1509,7 +1502,6 @@ int proxy_telnet_negotiate (ProxySocket *p, int change) return 1; } - plug_closing(p->plug, "Proxy error: Unexpected proxy error", - PROXY_ERROR_UNEXPECTED); + plug_closing_error(p->plug, "Proxy error: Unexpected proxy error"); return 1; } diff --git a/proxy/proxy.h b/proxy/proxy.h index 9dca87d1..3ec3261c 100644 --- a/proxy/proxy.h +++ b/proxy/proxy.h @@ -10,9 +10,6 @@ #ifndef PUTTY_PROXY_H #define PUTTY_PROXY_H -#define PROXY_ERROR_GENERAL 8000 -#define PROXY_ERROR_UNEXPECTED 8001 - typedef struct ProxySocket ProxySocket; struct ProxySocket { diff --git a/proxy/sshproxy.c b/proxy/sshproxy.c index c3785bd0..fd9afc4e 100644 --- a/proxy/sshproxy.c +++ b/proxy/sshproxy.c @@ -234,7 +234,7 @@ static void try_send_ssh_to_socket(void *ctx) if (sp->rcvd_eof_ssh_to_socket && !sp->sent_eof_ssh_to_socket) { sp->sent_eof_ssh_to_socket = true; - plug_closing(sp->plug, sp->errmsg, 0); + plug_closing_normal(sp->plug); } } @@ -316,7 +316,10 @@ static void sshproxy_send_close(SshProxy *sp) plug_log(sp->plug, PLUGLOG_CONNECT_FAILED, sp->addr, sp->port, sp->errmsg, 0); - plug_closing(sp->plug, sp->errmsg, 0); + if (sp->errmsg) + plug_closing_error(sp->plug, sp->errmsg); + else + plug_closing_normal(sp->plug); } static void sshproxy_notify_remote_disconnect_callback(void *vctx) diff --git a/unix/fd-socket.c b/unix/fd-socket.c index 48d7dc8b..013c5361 100644 --- a/unix/fd-socket.c +++ b/unix/fd-socket.c @@ -158,7 +158,7 @@ static void fdsocket_error_callback(void *vs) /* * An error has occurred on this socket. Pass it to the plug. */ - plug_closing(fds->plug, strerror(fds->pending_error), fds->pending_error); + plug_closing_errno(fds->plug, fds->pending_error); } static int fdsocket_try_send(FdSocket *fds) @@ -270,9 +270,9 @@ static void fdsocket_select_result_input(int fd, int event) fds->infd = -1; if (retd < 0) { - plug_closing(fds->plug, strerror(errno), errno); + plug_closing_errno(fds->plug, errno); } else { - plug_closing(fds->plug, NULL, 0); + plug_closing_normal(fds->plug); } } } diff --git a/unix/network.c b/unix/network.c index d2d426ed..32cc3c9e 100644 --- a/unix/network.c +++ b/unix/network.c @@ -1084,6 +1084,11 @@ void *sk_getxdmdata(Socket *sock, int *lenp) return buf; } +void plug_closing_errno(Plug *plug, int error) +{ + plug_closing(plug, strerror(error), error); +} + /* * Deal with socket errors detected in try_send(). */ @@ -1101,7 +1106,7 @@ static void socket_error_callback(void *vs) /* * An error has occurred on this socket. Pass it to the plug. */ - plug_closing(s->plug, strerror(s->pending_error), s->pending_error); + plug_closing_errno(s->plug, s->pending_error); } /* @@ -1295,10 +1300,10 @@ static void net_select_result(int fd, int event) */ ret = recv(s->s, buf, sizeof(buf), MSG_OOB); noise_ultralight(NOISE_SOURCE_IOLEN, ret); - if (ret <= 0) { - plug_closing(s->plug, - ret == 0 ? "Internal networking trouble" : - strerror(errno), errno); + if (ret == 0) { + plug_closing_error(s->plug, "Internal networking trouble"); + } else if (ret < 0) { + plug_closing_errno(s->plug, errno); } else { /* * Receiving actual data on a socket means we can @@ -1384,11 +1389,11 @@ static void net_select_result(int fd, int event) } } if (ret < 0) { - plug_closing(s->plug, strerror(errno), errno); + plug_closing_errno(s->plug, errno); } else if (0 == ret) { s->incomingeof = true; /* stop trying to read now */ uxsel_tell(s); - plug_closing(s->plug, NULL, 0); + plug_closing_normal(s->plug); } else { /* * Receiving actual data on a socket means we can @@ -1438,7 +1443,7 @@ static void net_select_result(int fd, int event) err = try_connect(s); } if (err) { - plug_closing(s->plug, strerror(err), err); + plug_closing_errno(s->plug, err); return; /* socket is now presumably defunct */ } if (!s->connected) diff --git a/unix/platform.h b/unix/platform.h index b4f5a008..79b171ca 100644 --- a/unix/platform.h +++ b/unix/platform.h @@ -458,4 +458,7 @@ bool cliloop_no_pw_setup(void *ctx, pollwrapper *pw); void cliloop_no_pw_check(void *ctx, pollwrapper *pw); bool cliloop_always_continue(void *ctx, bool, bool); +/* network.c: network error reporting helper taking an OS error code */ +void plug_closing_errno(Plug *plug, int error); + #endif /* PUTTY_UNIX_PLATFORM_H */ diff --git a/windows/handle-socket.c b/windows/handle-socket.c index 066d2373..32479d64 100644 --- a/windows/handle-socket.c +++ b/windows/handle-socket.c @@ -53,10 +53,10 @@ static size_t handle_gotdata( HandleSocket *hs = (HandleSocket *)handle_get_privdata(h); if (err) { - plug_closing(hs->plug, "Read error from handle", 0); + plug_closing_error(hs->plug, "Read error from handle"); return 0; } else if (len == 0) { - plug_closing(hs->plug, NULL, 0); + plug_closing_normal(hs->plug); return 0; } else { assert(hs->frozen != FROZEN && hs->frozen != THAWING); @@ -107,7 +107,7 @@ static void handle_sentdata(struct handle *h, size_t new_backlog, int err, } if (err) { - plug_closing(hs->plug, win_strerror(err), err); + plug_closing_system_error(hs->plug, err); return; } diff --git a/windows/network.c b/windows/network.c index 17c80cb4..b5b5ab0e 100644 --- a/windows/network.c +++ b/windows/network.c @@ -1335,6 +1335,16 @@ static void sk_net_close(Socket *sock) sfree(s); } +void plug_closing_system_error(Plug *plug, DWORD error) +{ + plug_closing(plug, win_strerror(error), error); +} + +void plug_closing_winsock_error(Plug *plug, DWORD error) +{ + plug_closing(plug, winsock_error_string(error), error); +} + /* * Deal with socket errors detected in try_send(). */ @@ -1352,8 +1362,7 @@ static void socket_error_callback(void *vs) /* * An error has occurred on this socket. Pass it to the plug. */ - plug_closing(s->plug, winsock_error_string(s->pending_error), - s->pending_error); + plug_closing_winsock_error(s->plug, s->pending_error); } /* @@ -1528,7 +1537,7 @@ void select_result(WPARAM wParam, LPARAM lParam) } } if (err != 0) - plug_closing(s->plug, winsock_error_string(err), err); + plug_closing_winsock_error(s->plug, err); return; } @@ -1590,9 +1599,9 @@ void select_result(WPARAM wParam, LPARAM lParam) } } if (ret < 0) { - plug_closing(s->plug, winsock_error_string(err), err); + plug_closing_winsock_error(s->plug, err); } else if (0 == ret) { - plug_closing(s->plug, NULL, 0); + plug_closing_normal(s->plug); } else { plug_receive(s->plug, atmark ? 0 : 1, buf, ret); } @@ -1608,7 +1617,7 @@ void select_result(WPARAM wParam, LPARAM lParam) noise_ultralight(NOISE_SOURCE_IOLEN, ret); if (ret <= 0) { int err = p_WSAGetLastError(); - plug_closing(s->plug, winsock_error_string(err), err); + plug_closing_winsock_error(s->plug, err); } else { plug_receive(s->plug, 2, buf, ret); } @@ -1631,12 +1640,12 @@ void select_result(WPARAM wParam, LPARAM lParam) err = p_WSAGetLastError(); if (err == WSAEWOULDBLOCK) break; - plug_closing(s->plug, winsock_error_string(err), err); + plug_closing_winsock_error(s->plug, err); } else { if (ret) plug_receive(s->plug, 0, buf, ret); else - plug_closing(s->plug, NULL, 0); + plug_closing_normal(s->plug); } } while (ret > 0); return; diff --git a/windows/platform.h b/windows/platform.h index cf76566b..0a1a6ef7 100644 --- a/windows/platform.h +++ b/windows/platform.h @@ -730,4 +730,8 @@ char *handle_restrict_acl_cmdline_prefix(char *cmdline); bool handle_special_sessionname_cmdline(char *cmdline, Conf *conf); bool handle_special_filemapping_cmdline(char *cmdline, Conf *conf); +/* network.c: network error reporting helpers taking OS error code */ +void plug_closing_system_error(Plug *plug, DWORD error); +void plug_closing_winsock_error(Plug *plug, DWORD error); + #endif /* PUTTY_WINDOWS_PLATFORM_H */