diff options
author | Damien Miller <djm@mindrot.org> | 2016-08-29 11:47:07 +1000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2016-08-29 11:49:16 +1000 |
commit | b38b95f5bcc52278feb839afda2987933f68ff96 (patch) | |
tree | 9e030baa90932b0b45178423d4ca1e6c1f966ab8 /monitor.c | |
parent | dc664d1bd0fc91b24406a3e9575b81c285b8342b (diff) |
Tighten monitor state-machine flow for PAM calls
(attack surface reduction)
Diffstat (limited to 'monitor.c')
-rw-r--r-- | monitor.c | 21 |
1 files changed, 17 insertions, 4 deletions
@@ -208,9 +208,9 @@ struct mon_table mon_dispatch_proto20[] = { | |||
208 | #ifdef USE_PAM | 208 | #ifdef USE_PAM |
209 | {MONITOR_REQ_PAM_START, MON_ONCE, mm_answer_pam_start}, | 209 | {MONITOR_REQ_PAM_START, MON_ONCE, mm_answer_pam_start}, |
210 | {MONITOR_REQ_PAM_ACCOUNT, 0, mm_answer_pam_account}, | 210 | {MONITOR_REQ_PAM_ACCOUNT, 0, mm_answer_pam_account}, |
211 | {MONITOR_REQ_PAM_INIT_CTX, MON_ISAUTH, mm_answer_pam_init_ctx}, | 211 | {MONITOR_REQ_PAM_INIT_CTX, MON_ONCE, mm_answer_pam_init_ctx}, |
212 | {MONITOR_REQ_PAM_QUERY, MON_ISAUTH, mm_answer_pam_query}, | 212 | {MONITOR_REQ_PAM_QUERY, 0, mm_answer_pam_query}, |
213 | {MONITOR_REQ_PAM_RESPOND, MON_ISAUTH, mm_answer_pam_respond}, | 213 | {MONITOR_REQ_PAM_RESPOND, MON_ONCE, mm_answer_pam_respond}, |
214 | {MONITOR_REQ_PAM_FREE_CTX, MON_ONCE|MON_AUTHDECIDE, mm_answer_pam_free_ctx}, | 214 | {MONITOR_REQ_PAM_FREE_CTX, MON_ONCE|MON_AUTHDECIDE, mm_answer_pam_free_ctx}, |
215 | #endif | 215 | #endif |
216 | #ifdef SSH_AUDIT_EVENTS | 216 | #ifdef SSH_AUDIT_EVENTS |
@@ -990,6 +990,7 @@ mm_answer_pam_start(int sock, Buffer *m) | |||
990 | start_pam(authctxt); | 990 | start_pam(authctxt); |
991 | 991 | ||
992 | monitor_permit(mon_dispatch, MONITOR_REQ_PAM_ACCOUNT, 1); | 992 | monitor_permit(mon_dispatch, MONITOR_REQ_PAM_ACCOUNT, 1); |
993 | monitor_permit(mon_dispatch, MONITOR_REQ_PAM_INIT_CTX, 1); | ||
993 | 994 | ||
994 | return (0); | 995 | return (0); |
995 | } | 996 | } |
@@ -1019,11 +1020,14 @@ int | |||
1019 | mm_answer_pam_init_ctx(int sock, Buffer *m) | 1020 | mm_answer_pam_init_ctx(int sock, Buffer *m) |
1020 | { | 1021 | { |
1021 | debug3("%s", __func__); | 1022 | debug3("%s", __func__); |
1023 | if (sshpam_ctxt != NULL) | ||
1024 | fatal("%s: already called", __func__); | ||
1022 | sshpam_ctxt = (sshpam_device.init_ctx)(authctxt); | 1025 | sshpam_ctxt = (sshpam_device.init_ctx)(authctxt); |
1023 | sshpam_authok = NULL; | 1026 | sshpam_authok = NULL; |
1024 | buffer_clear(m); | 1027 | buffer_clear(m); |
1025 | if (sshpam_ctxt != NULL) { | 1028 | if (sshpam_ctxt != NULL) { |
1026 | monitor_permit(mon_dispatch, MONITOR_REQ_PAM_FREE_CTX, 1); | 1029 | monitor_permit(mon_dispatch, MONITOR_REQ_PAM_FREE_CTX, 1); |
1030 | monitor_permit(mon_dispatch, MONITOR_REQ_PAM_QUERY, 1); | ||
1027 | buffer_put_int(m, 1); | 1031 | buffer_put_int(m, 1); |
1028 | } else { | 1032 | } else { |
1029 | buffer_put_int(m, 0); | 1033 | buffer_put_int(m, 0); |
@@ -1041,11 +1045,14 @@ mm_answer_pam_query(int sock, Buffer *m) | |||
1041 | 1045 | ||
1042 | debug3("%s", __func__); | 1046 | debug3("%s", __func__); |
1043 | sshpam_authok = NULL; | 1047 | sshpam_authok = NULL; |
1048 | if (sshpam_ctxt == NULL) | ||
1049 | fatal("%s: no context", __func__); | ||
1044 | ret = (sshpam_device.query)(sshpam_ctxt, &name, &info, &num, &prompts, &echo_on); | 1050 | ret = (sshpam_device.query)(sshpam_ctxt, &name, &info, &num, &prompts, &echo_on); |
1045 | if (ret == 0 && num == 0) | 1051 | if (ret == 0 && num == 0) |
1046 | sshpam_authok = sshpam_ctxt; | 1052 | sshpam_authok = sshpam_ctxt; |
1047 | if (num > 1 || name == NULL || info == NULL) | 1053 | if (num > 1 || name == NULL || info == NULL) |
1048 | ret = -1; | 1054 | fatal("sshpam_device.query failed"); |
1055 | monitor_permit(mon_dispatch, MONITOR_REQ_PAM_RESPOND, 1); | ||
1049 | buffer_clear(m); | 1056 | buffer_clear(m); |
1050 | buffer_put_int(m, ret); | 1057 | buffer_put_int(m, ret); |
1051 | buffer_put_cstring(m, name); | 1058 | buffer_put_cstring(m, name); |
@@ -1075,6 +1082,8 @@ mm_answer_pam_respond(int sock, Buffer *m) | |||
1075 | int ret; | 1082 | int ret; |
1076 | 1083 | ||
1077 | debug3("%s", __func__); | 1084 | debug3("%s", __func__); |
1085 | if (sshpam_ctxt == NULL) | ||
1086 | fatal("%s: no context", __func__); | ||
1078 | sshpam_authok = NULL; | 1087 | sshpam_authok = NULL; |
1079 | num = buffer_get_int(m); | 1088 | num = buffer_get_int(m); |
1080 | if (num > 0) { | 1089 | if (num > 0) { |
@@ -1104,10 +1113,14 @@ mm_answer_pam_free_ctx(int sock, Buffer *m) | |||
1104 | int r = sshpam_authok != NULL && sshpam_authok == sshpam_ctxt; | 1113 | int r = sshpam_authok != NULL && sshpam_authok == sshpam_ctxt; |
1105 | 1114 | ||
1106 | debug3("%s", __func__); | 1115 | debug3("%s", __func__); |
1116 | if (sshpam_ctxt == NULL) | ||
1117 | fatal("%s: no context", __func__); | ||
1107 | (sshpam_device.free_ctx)(sshpam_ctxt); | 1118 | (sshpam_device.free_ctx)(sshpam_ctxt); |
1108 | sshpam_ctxt = sshpam_authok = NULL; | 1119 | sshpam_ctxt = sshpam_authok = NULL; |
1109 | buffer_clear(m); | 1120 | buffer_clear(m); |
1110 | mm_request_send(sock, MONITOR_ANS_PAM_FREE_CTX, m); | 1121 | mm_request_send(sock, MONITOR_ANS_PAM_FREE_CTX, m); |
1122 | /* Allow another attempt */ | ||
1123 | monitor_permit(mon_dispatch, MONITOR_REQ_PAM_INIT_CTX, 1); | ||
1111 | auth_method = "keyboard-interactive"; | 1124 | auth_method = "keyboard-interactive"; |
1112 | auth_submethod = "pam"; | 1125 | auth_submethod = "pam"; |
1113 | return r; | 1126 | return r; |