diff options
Diffstat (limited to 'monitor.c')
-rw-r--r-- | monitor.c | 90 |
1 files changed, 66 insertions, 24 deletions
@@ -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" |
28 | RCSID("$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" | ||
69 | static Gssctxt *gsscontext = NULL; | 91 | static 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]; |