summaryrefslogtreecommitdiff
path: root/monitor.c
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2007-06-12 16:16:35 +0000
committerColin Watson <cjwatson@debian.org>2007-06-12 16:16:35 +0000
commitb7e40fa9da0b5491534a429dadb321eab5a77558 (patch)
treebed1da11e9f829925797aa093e379fc0b5868ecd /monitor.c
parent4f84beedf1005e44ff33c854abd6b711ffc0adb7 (diff)
parent086ea76990b1e6287c24b6db74adffd4605eb3b0 (diff)
* New upstream release (closes: #395507, #397961, #420035). Important
changes not previously backported to 4.3p2: - 4.4/4.4p1 (http://www.openssh.org/txt/release-4.4): + On portable OpenSSH, fix a GSSAPI authentication abort that could be used to determine the validity of usernames on some platforms. + Implemented conditional configuration in sshd_config(5) using the "Match" directive. This allows some configuration options to be selectively overridden if specific criteria (based on user, group, hostname and/or address) are met. So far a useful subset of post-authentication options are supported and more are expected to be added in future releases. + Add support for Diffie-Hellman group exchange key agreement with a final hash of SHA256. + Added a "ForceCommand" directive to sshd_config(5). Similar to the command="..." option accepted in ~/.ssh/authorized_keys, this forces the execution of the specified command regardless of what the user requested. This is very useful in conjunction with the new "Match" option. + Add a "PermitOpen" directive to sshd_config(5). This mirrors the permitopen="..." authorized_keys option, allowing fine-grained control over the port-forwardings that a user is allowed to establish. + Add optional logging of transactions to sftp-server(8). + ssh(1) will now record port numbers for hosts stored in ~/.ssh/known_hosts when a non-standard port has been requested (closes: #50612). + Add an "ExitOnForwardFailure" option to cause ssh(1) to exit (with a non-zero exit code) when requested port forwardings could not be established. + Extend sshd_config(5) "SubSystem" declarations to allow the specification of command-line arguments. + Replacement of all integer overflow susceptible invocations of malloc(3) and realloc(3) with overflow-checking equivalents. + Many manpage fixes and improvements. + Add optional support for OpenSSL hardware accelerators (engines), enabled using the --with-ssl-engine configure option. + Tokens in configuration files may be double-quoted in order to contain spaces (closes: #319639). + Move a debug() call out of a SIGCHLD handler, fixing a hang when the session exits very quickly (closes: #307890). + Fix some incorrect buffer allocation calculations (closes: #410599). + ssh-add doesn't ask for a passphrase if key file permissions are too liberal (closes: #103677). + Likewise, ssh doesn't ask either (closes: #99675). - 4.6/4.6p1 (http://www.openssh.org/txt/release-4.6): + sshd now allows the enabling and disabling of authentication methods on a per user, group, host and network basis via the Match directive in sshd_config. + Fixed an inconsistent check for a terminal when displaying scp progress meter (closes: #257524). + Fix "hang on exit" when background processes are running at the time of exit on a ttyful/login session (closes: #88337). * Update to current GSSAPI patch from http://www.sxw.org.uk/computing/patches/openssh-4.6p1-gsskex-20070312.patch; install ChangeLog.gssapi.
Diffstat (limited to 'monitor.c')
-rw-r--r--monitor.c90
1 files changed, 66 insertions, 24 deletions
diff --git a/monitor.c b/monitor.c
index 867431ff1..5db4d52da 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1,3 +1,4 @@
1/* $OpenBSD: monitor.c,v 1.90 2007/02/19 10:45:58 dtucker Exp $ */
1/* 2/*
2 * Copyright 2002 Niels Provos <provos@citi.umich.edu> 3 * Copyright 2002 Niels Provos <provos@citi.umich.edu>
3 * Copyright 2002 Markus Friedl <markus@openbsd.org> 4 * Copyright 2002 Markus Friedl <markus@openbsd.org>
@@ -25,16 +26,38 @@
25 */ 26 */
26 27
27#include "includes.h" 28#include "includes.h"
28RCSID("$OpenBSD: monitor.c,v 1.64 2005/10/13 22:24:31 stevesk Exp $");
29 29
30#include <openssl/dh.h> 30#include <sys/types.h>
31#include <sys/param.h>
32#include <sys/socket.h>
33#include "openbsd-compat/sys-tree.h"
34#include <sys/wait.h>
35
36#include <errno.h>
37#include <fcntl.h>
38#ifdef HAVE_PATHS_H
39#include <paths.h>
40#endif
41#include <pwd.h>
42#include <signal.h>
43#include <stdarg.h>
44#include <stdlib.h>
45#include <string.h>
46#include <unistd.h>
31 47
32#ifdef SKEY 48#ifdef SKEY
33#include <skey.h> 49#include <skey.h>
34#endif 50#endif
35 51
52#include <openssl/dh.h>
53
54#include "xmalloc.h"
36#include "ssh.h" 55#include "ssh.h"
56#include "key.h"
57#include "buffer.h"
58#include "hostfile.h"
37#include "auth.h" 59#include "auth.h"
60#include "cipher.h"
38#include "kex.h" 61#include "kex.h"
39#include "dh.h" 62#include "dh.h"
40#ifdef TARGET_OS_MAC /* XXX Broken krb5 headers on Mac */ 63#ifdef TARGET_OS_MAC /* XXX Broken krb5 headers on Mac */
@@ -55,17 +78,16 @@ RCSID("$OpenBSD: monitor.c,v 1.64 2005/10/13 22:24:31 stevesk Exp $");
55#include "servconf.h" 78#include "servconf.h"
56#include "monitor.h" 79#include "monitor.h"
57#include "monitor_mm.h" 80#include "monitor_mm.h"
81#ifdef GSSAPI
82#include "ssh-gss.h"
83#endif
58#include "monitor_wrap.h" 84#include "monitor_wrap.h"
59#include "monitor_fdpass.h" 85#include "monitor_fdpass.h"
60#include "xmalloc.h"
61#include "misc.h" 86#include "misc.h"
62#include "buffer.h"
63#include "bufaux.h"
64#include "compat.h" 87#include "compat.h"
65#include "ssh2.h" 88#include "ssh2.h"
66 89
67#ifdef GSSAPI 90#ifdef GSSAPI
68#include "ssh-gss.h"
69static Gssctxt *gsscontext = NULL; 91static Gssctxt *gsscontext = NULL;
70#endif 92#endif
71 93
@@ -173,6 +195,7 @@ struct mon_table {
173#define MON_ISAUTH 0x0004 /* Required for Authentication */ 195#define MON_ISAUTH 0x0004 /* Required for Authentication */
174#define MON_AUTHDECIDE 0x0008 /* Decides Authentication */ 196#define MON_AUTHDECIDE 0x0008 /* Decides Authentication */
175#define MON_ONCE 0x0010 /* Disable after calling */ 197#define MON_ONCE 0x0010 /* Disable after calling */
198#define MON_ALOG 0x0020 /* Log auth attempt without authenticating */
176 199
177#define MON_AUTH (MON_ISAUTH|MON_AUTHDECIDE) 200#define MON_AUTH (MON_ISAUTH|MON_AUTHDECIDE)
178 201
@@ -199,7 +222,7 @@ struct mon_table mon_dispatch_proto20[] = {
199#endif 222#endif
200#ifdef BSD_AUTH 223#ifdef BSD_AUTH
201 {MONITOR_REQ_BSDAUTHQUERY, MON_ISAUTH, mm_answer_bsdauthquery}, 224 {MONITOR_REQ_BSDAUTHQUERY, MON_ISAUTH, mm_answer_bsdauthquery},
202 {MONITOR_REQ_BSDAUTHRESPOND, MON_AUTH,mm_answer_bsdauthrespond}, 225 {MONITOR_REQ_BSDAUTHRESPOND, MON_AUTH, mm_answer_bsdauthrespond},
203#endif 226#endif
204#ifdef SKEY 227#ifdef SKEY
205 {MONITOR_REQ_SKEYQUERY, MON_ISAUTH, mm_answer_skeyquery}, 228 {MONITOR_REQ_SKEYQUERY, MON_ISAUTH, mm_answer_skeyquery},
@@ -240,13 +263,13 @@ struct mon_table mon_dispatch_proto15[] = {
240 {MONITOR_REQ_SESSKEY, MON_ONCE, mm_answer_sesskey}, 263 {MONITOR_REQ_SESSKEY, MON_ONCE, mm_answer_sesskey},
241 {MONITOR_REQ_SESSID, MON_ONCE, mm_answer_sessid}, 264 {MONITOR_REQ_SESSID, MON_ONCE, mm_answer_sessid},
242 {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, 265 {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword},
243 {MONITOR_REQ_RSAKEYALLOWED, MON_ISAUTH, mm_answer_rsa_keyallowed}, 266 {MONITOR_REQ_RSAKEYALLOWED, MON_ISAUTH|MON_ALOG, mm_answer_rsa_keyallowed},
244 {MONITOR_REQ_KEYALLOWED, MON_ISAUTH, mm_answer_keyallowed}, 267 {MONITOR_REQ_KEYALLOWED, MON_ISAUTH|MON_ALOG, mm_answer_keyallowed},
245 {MONITOR_REQ_RSACHALLENGE, MON_ONCE, mm_answer_rsa_challenge}, 268 {MONITOR_REQ_RSACHALLENGE, MON_ONCE, mm_answer_rsa_challenge},
246 {MONITOR_REQ_RSARESPONSE, MON_ONCE|MON_AUTHDECIDE, mm_answer_rsa_response}, 269 {MONITOR_REQ_RSARESPONSE, MON_ONCE|MON_AUTHDECIDE, mm_answer_rsa_response},
247#ifdef BSD_AUTH 270#ifdef BSD_AUTH
248 {MONITOR_REQ_BSDAUTHQUERY, MON_ISAUTH, mm_answer_bsdauthquery}, 271 {MONITOR_REQ_BSDAUTHQUERY, MON_ISAUTH, mm_answer_bsdauthquery},
249 {MONITOR_REQ_BSDAUTHRESPOND, MON_AUTH,mm_answer_bsdauthrespond}, 272 {MONITOR_REQ_BSDAUTHRESPOND, MON_AUTH, mm_answer_bsdauthrespond},
250#endif 273#endif
251#ifdef SKEY 274#ifdef SKEY
252 {MONITOR_REQ_SKEYQUERY, MON_ISAUTH, mm_answer_skeyquery}, 275 {MONITOR_REQ_SKEYQUERY, MON_ISAUTH, mm_answer_skeyquery},
@@ -272,7 +295,7 @@ struct mon_table mon_dispatch_postauth15[] = {
272 {MONITOR_REQ_TERM, 0, mm_answer_term}, 295 {MONITOR_REQ_TERM, 0, mm_answer_term},
273#ifdef SSH_AUDIT_EVENTS 296#ifdef SSH_AUDIT_EVENTS
274 {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, 297 {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event},
275 {MONITOR_REQ_AUDIT_COMMAND, MON_ONCE, mm_answer_audit_command}, 298 {MONITOR_REQ_AUDIT_COMMAND, MON_PERMIT|MON_ONCE, mm_answer_audit_command},
276#endif 299#endif
277 {0, 0, NULL} 300 {0, 0, NULL}
278}; 301};
@@ -339,6 +362,7 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor)
339 362
340 /* The first few requests do not require asynchronous access */ 363 /* The first few requests do not require asynchronous access */
341 while (!authenticated) { 364 while (!authenticated) {
365 auth_method = "unknown";
342 authenticated = (monitor_read(pmonitor, mon_dispatch, &ent) == 1); 366 authenticated = (monitor_read(pmonitor, mon_dispatch, &ent) == 1);
343 if (authenticated) { 367 if (authenticated) {
344 if (!(ent->flags & MON_AUTHDECIDE)) 368 if (!(ent->flags & MON_AUTHDECIDE))
@@ -361,7 +385,7 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor)
361#endif 385#endif
362 } 386 }
363 387
364 if (ent->flags & MON_AUTHDECIDE) { 388 if (ent->flags & (MON_AUTHDECIDE|MON_ALOG)) {
365 auth_log(authctxt, authenticated, auth_method, 389 auth_log(authctxt, authenticated, auth_method,
366 compat20 ? " ssh2" : ""); 390 compat20 ? " ssh2" : "");
367 if (!authenticated) 391 if (!authenticated)
@@ -371,6 +395,8 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor)
371 395
372 if (!authctxt->valid) 396 if (!authctxt->valid)
373 fatal("%s: authenticated invalid user", __func__); 397 fatal("%s: authenticated invalid user", __func__);
398 if (strcmp(auth_method, "unknown") == 0)
399 fatal("%s: authentication method name unknown", __func__);
374 400
375 debug("%s: %s has been authenticated by privileged process", 401 debug("%s: %s has been authenticated by privileged process",
376 __func__, authctxt->user); 402 __func__, authctxt->user);
@@ -554,7 +580,11 @@ mm_answer_sign(int sock, Buffer *m)
554 keyid = buffer_get_int(m); 580 keyid = buffer_get_int(m);
555 p = buffer_get_string(m, &datlen); 581 p = buffer_get_string(m, &datlen);
556 582
557 if (datlen != 20) 583 /*
584 * Supported KEX types will only return SHA1 (20 byte) or
585 * SHA256 (32 byte) hashes
586 */
587 if (datlen != 20 && datlen != 32)
558 fatal("%s: data length incorrect: %u", __func__, datlen); 588 fatal("%s: data length incorrect: %u", __func__, datlen);
559 589
560 /* save session id, it will be passed on the first call */ 590 /* save session id, it will be passed on the first call */
@@ -629,6 +659,9 @@ mm_answer_pwnamallow(int sock, Buffer *m)
629#endif 659#endif
630 buffer_put_cstring(m, pwent->pw_dir); 660 buffer_put_cstring(m, pwent->pw_dir);
631 buffer_put_cstring(m, pwent->pw_shell); 661 buffer_put_cstring(m, pwent->pw_shell);
662 buffer_put_string(m, &options, sizeof(options));
663 if (options.banner != NULL)
664 buffer_put_cstring(m, options.banner);
632 665
633 out: 666 out:
634 debug3("%s: sending MONITOR_ANS_PWNAM: %d", __func__, allowed); 667 debug3("%s: sending MONITOR_ANS_PWNAM: %d", __func__, allowed);
@@ -648,9 +681,6 @@ mm_answer_pwnamallow(int sock, Buffer *m)
648 if (options.use_pam) 681 if (options.use_pam)
649 monitor_permit(mon_dispatch, MONITOR_REQ_PAM_START, 1); 682 monitor_permit(mon_dispatch, MONITOR_REQ_PAM_START, 1);
650#endif 683#endif
651#ifdef SSH_AUDIT_EVENTS
652 monitor_permit(mon_dispatch, MONITOR_REQ_AUDIT_COMMAND, 1);
653#endif
654 684
655 return (0); 685 return (0);
656} 686}
@@ -934,6 +964,7 @@ mm_answer_pam_query(int sock, Buffer *m)
934 xfree(prompts); 964 xfree(prompts);
935 if (echo_on != NULL) 965 if (echo_on != NULL)
936 xfree(echo_on); 966 xfree(echo_on);
967 auth_method = "keyboard-interactive/pam";
937 mm_request_send(sock, MONITOR_ANS_PAM_QUERY, m); 968 mm_request_send(sock, MONITOR_ANS_PAM_QUERY, m);
938 return (0); 969 return (0);
939} 970}
@@ -949,7 +980,7 @@ mm_answer_pam_respond(int sock, Buffer *m)
949 sshpam_authok = NULL; 980 sshpam_authok = NULL;
950 num = buffer_get_int(m); 981 num = buffer_get_int(m);
951 if (num > 0) { 982 if (num > 0) {
952 resp = xmalloc(num * sizeof(char *)); 983 resp = xcalloc(num, sizeof(char *));
953 for (i = 0; i < num; ++i) 984 for (i = 0; i < num; ++i)
954 resp[i] = buffer_get_string(m, NULL); 985 resp[i] = buffer_get_string(m, NULL);
955 ret = (sshpam_device.respond)(sshpam_ctxt, num, resp); 986 ret = (sshpam_device.respond)(sshpam_ctxt, num, resp);
@@ -976,6 +1007,7 @@ mm_answer_pam_free_ctx(int sock, Buffer *m)
976 (sshpam_device.free_ctx)(sshpam_ctxt); 1007 (sshpam_device.free_ctx)(sshpam_ctxt);
977 buffer_clear(m); 1008 buffer_clear(m);
978 mm_request_send(sock, MONITOR_ANS_PAM_FREE_CTX, m); 1009 mm_request_send(sock, MONITOR_ANS_PAM_FREE_CTX, m);
1010 auth_method = "keyboard-interactive/pam";
979 return (sshpam_authok == sshpam_ctxt); 1011 return (sshpam_authok == sshpam_ctxt);
980} 1012}
981#endif 1013#endif
@@ -1021,17 +1053,20 @@ mm_answer_keyallowed(int sock, Buffer *m)
1021 case MM_USERKEY: 1053 case MM_USERKEY:
1022 allowed = options.pubkey_authentication && 1054 allowed = options.pubkey_authentication &&
1023 user_key_allowed(authctxt->pw, key); 1055 user_key_allowed(authctxt->pw, key);
1056 auth_method = "publickey";
1024 break; 1057 break;
1025 case MM_HOSTKEY: 1058 case MM_HOSTKEY:
1026 allowed = options.hostbased_authentication && 1059 allowed = options.hostbased_authentication &&
1027 hostbased_key_allowed(authctxt->pw, 1060 hostbased_key_allowed(authctxt->pw,
1028 cuser, chost, key); 1061 cuser, chost, key);
1062 auth_method = "hostbased";
1029 break; 1063 break;
1030 case MM_RSAHOSTKEY: 1064 case MM_RSAHOSTKEY:
1031 key->type = KEY_RSA1; /* XXX */ 1065 key->type = KEY_RSA1; /* XXX */
1032 allowed = options.rhosts_rsa_authentication && 1066 allowed = options.rhosts_rsa_authentication &&
1033 auth_rhosts_rsa_key_allowed(authctxt->pw, 1067 auth_rhosts_rsa_key_allowed(authctxt->pw,
1034 cuser, chost, key); 1068 cuser, chost, key);
1069 auth_method = "rsa";
1035 break; 1070 break;
1036 default: 1071 default:
1037 fatal("%s: unknown key type %d", __func__, type); 1072 fatal("%s: unknown key type %d", __func__, type);
@@ -1051,6 +1086,12 @@ mm_answer_keyallowed(int sock, Buffer *m)
1051 key_blobtype = type; 1086 key_blobtype = type;
1052 hostbased_cuser = cuser; 1087 hostbased_cuser = cuser;
1053 hostbased_chost = chost; 1088 hostbased_chost = chost;
1089 } else {
1090 /* Log failed attempt */
1091 auth_log(authctxt, 0, auth_method, compat20 ? " ssh2" : "");
1092 xfree(blob);
1093 xfree(cuser);
1094 xfree(chost);
1054 } 1095 }
1055 1096
1056 debug3("%s: key %p is %s", 1097 debug3("%s: key %p is %s",
@@ -1252,7 +1293,7 @@ mm_record_login(Session *s, struct passwd *pw)
1252 fromlen = sizeof(from); 1293 fromlen = sizeof(from);
1253 if (packet_connection_is_on_socket()) { 1294 if (packet_connection_is_on_socket()) {
1254 if (getpeername(packet_get_connection_in(), 1295 if (getpeername(packet_get_connection_in(),
1255 (struct sockaddr *) & from, &fromlen) < 0) { 1296 (struct sockaddr *)&from, &fromlen) < 0) {
1256 debug("getpeername: %.100s", strerror(errno)); 1297 debug("getpeername: %.100s", strerror(errno));
1257 cleanup_exit(255); 1298 cleanup_exit(255);
1258 } 1299 }
@@ -1268,7 +1309,7 @@ mm_session_close(Session *s)
1268{ 1309{
1269 debug3("%s: session %d pid %ld", __func__, s->self, (long)s->pid); 1310 debug3("%s: session %d pid %ld", __func__, s->self, (long)s->pid);
1270 if (s->ttyfd != -1) { 1311 if (s->ttyfd != -1) {
1271 debug3("%s: tty %s ptyfd %d", __func__, s->tty, s->ptyfd); 1312 debug3("%s: tty %s ptyfd %d", __func__, s->tty, s->ptyfd);
1272 session_pty_cleanup2(s); 1313 session_pty_cleanup2(s);
1273 } 1314 }
1274 s->used = 0; 1315 s->used = 0;
@@ -1328,7 +1369,7 @@ mm_answer_pty(int sock, Buffer *m)
1328 /* no need to dup() because nobody closes ptyfd */ 1369 /* no need to dup() because nobody closes ptyfd */
1329 s->ptymaster = s->ptyfd; 1370 s->ptymaster = s->ptyfd;
1330 1371
1331 debug3("%s: tty %s ptyfd %d", __func__, s->tty, s->ttyfd); 1372 debug3("%s: tty %s ptyfd %d", __func__, s->tty, s->ttyfd);
1332 1373
1333 return (0); 1374 return (0);
1334 1375
@@ -1415,6 +1456,7 @@ mm_answer_rsa_keyallowed(int sock, Buffer *m)
1415 1456
1416 debug3("%s entering", __func__); 1457 debug3("%s entering", __func__);
1417 1458
1459 auth_method = "rsa";
1418 if (options.rsa_authentication && authctxt->valid) { 1460 if (options.rsa_authentication && authctxt->valid) {
1419 if ((client_n = BN_new()) == NULL) 1461 if ((client_n = BN_new()) == NULL)
1420 fatal("%s: BN_new", __func__); 1462 fatal("%s: BN_new", __func__);
@@ -1651,8 +1693,7 @@ mm_get_kex(Buffer *m)
1651 void *blob; 1693 void *blob;
1652 u_int bloblen; 1694 u_int bloblen;
1653 1695
1654 kex = xmalloc(sizeof(*kex)); 1696 kex = xcalloc(1, sizeof(*kex));
1655 memset(kex, 0, sizeof(*kex));
1656 kex->session_id = buffer_get_string(m, &kex->session_id_len); 1697 kex->session_id = buffer_get_string(m, &kex->session_id_len);
1657 if ((session_id2 == NULL) || 1698 if ((session_id2 == NULL) ||
1658 (kex->session_id_len != session_id2_len) || 1699 (kex->session_id_len != session_id2_len) ||
@@ -1662,8 +1703,10 @@ mm_get_kex(Buffer *m)
1662 kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server; 1703 kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server;
1663 kex->kex[KEX_DH_GRP14_SHA1] = kexdh_server; 1704 kex->kex[KEX_DH_GRP14_SHA1] = kexdh_server;
1664 kex->kex[KEX_DH_GEX_SHA1] = kexgex_server; 1705 kex->kex[KEX_DH_GEX_SHA1] = kexgex_server;
1706 kex->kex[KEX_DH_GEX_SHA256] = kexgex_server;
1665#ifdef GSSAPI 1707#ifdef GSSAPI
1666 kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server; 1708 kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server;
1709 kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server;
1667 kex->kex[KEX_GSS_GEX_SHA1] = kexgss_server; 1710 kex->kex[KEX_GSS_GEX_SHA1] = kexgss_server;
1668#endif 1711#endif
1669 kex->server = 1; 1712 kex->server = 1;
@@ -1825,9 +1868,8 @@ monitor_init(void)
1825 struct monitor *mon; 1868 struct monitor *mon;
1826 int pair[2]; 1869 int pair[2];
1827 1870
1828 mon = xmalloc(sizeof(*mon)); 1871 mon = xcalloc(1, sizeof(*mon));
1829 1872
1830 mon->m_pid = 0;
1831 monitor_socketpair(pair); 1873 monitor_socketpair(pair);
1832 1874
1833 mon->m_recvfd = pair[0]; 1875 mon->m_recvfd = pair[0];