diff options
-rw-r--r-- | auth2-hostbased.c | 6 | ||||
-rw-r--r-- | auth2-pubkey.c | 194 | ||||
-rw-r--r-- | monitor.c | 41 | ||||
-rw-r--r-- | monitor_wrap.c | 14 | ||||
-rw-r--r-- | monitor_wrap.h | 5 |
5 files changed, 148 insertions, 112 deletions
diff --git a/auth2-hostbased.c b/auth2-hostbased.c index 92ac20d90..eddf797fe 100644 --- a/auth2-hostbased.c +++ b/auth2-hostbased.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: auth2-hostbased.c,v 1.27 2017/05/30 08:52:19 markus Exp $ */ | 1 | /* $OpenBSD: auth2-hostbased.c,v 1.28 2017/05/30 14:10:53 markus Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
@@ -138,8 +138,8 @@ userauth_hostbased(Authctxt *authctxt) | |||
138 | /* test for allowed key and correct signature */ | 138 | /* test for allowed key and correct signature */ |
139 | authenticated = 0; | 139 | authenticated = 0; |
140 | if (PRIVSEP(hostbased_key_allowed(authctxt->pw, cuser, chost, key)) && | 140 | if (PRIVSEP(hostbased_key_allowed(authctxt->pw, cuser, chost, key)) && |
141 | PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b), | 141 | PRIVSEP(sshkey_verify(key, sig, slen, buffer_ptr(&b), |
142 | buffer_len(&b))) == 1) | 142 | buffer_len(&b), 0)) == 0) |
143 | authenticated = 1; | 143 | authenticated = 1; |
144 | 144 | ||
145 | buffer_free(&b); | 145 | buffer_free(&b); |
diff --git a/auth2-pubkey.c b/auth2-pubkey.c index 38940a6d9..a4a091113 100644 --- a/auth2-pubkey.c +++ b/auth2-pubkey.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: auth2-pubkey.c,v 1.63 2017/05/30 08:52:19 markus Exp $ */ | 1 | /* $OpenBSD: auth2-pubkey.c,v 1.64 2017/05/30 14:10:53 markus Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
@@ -52,7 +52,7 @@ | |||
52 | #include "misc.h" | 52 | #include "misc.h" |
53 | #include "servconf.h" | 53 | #include "servconf.h" |
54 | #include "compat.h" | 54 | #include "compat.h" |
55 | #include "key.h" | 55 | #include "sshkey.h" |
56 | #include "hostfile.h" | 56 | #include "hostfile.h" |
57 | #include "auth.h" | 57 | #include "auth.h" |
58 | #include "pathnames.h" | 58 | #include "pathnames.h" |
@@ -77,40 +77,50 @@ extern u_int session_id2_len; | |||
77 | static int | 77 | static int |
78 | userauth_pubkey(Authctxt *authctxt) | 78 | userauth_pubkey(Authctxt *authctxt) |
79 | { | 79 | { |
80 | Buffer b; | 80 | struct ssh *ssh = active_state; /* XXX */ |
81 | struct sshbuf *b; | ||
81 | struct sshkey *key = NULL; | 82 | struct sshkey *key = NULL; |
82 | char *pkalg, *userstyle, *fp = NULL; | 83 | char *pkalg, *userstyle = NULL, *fp = NULL; |
83 | u_char *pkblob, *sig; | 84 | u_char *pkblob, *sig, have_sig; |
84 | u_int alen, blen, slen; | 85 | size_t blen, slen; |
85 | int have_sig, pktype; | 86 | int r, pktype; |
86 | int authenticated = 0; | 87 | int authenticated = 0; |
87 | 88 | ||
88 | if (!authctxt->valid) { | 89 | if (!authctxt->valid) { |
89 | debug2("%s: disabled because of invalid user", __func__); | 90 | debug2("%s: disabled because of invalid user", __func__); |
90 | return 0; | 91 | return 0; |
91 | } | 92 | } |
92 | have_sig = packet_get_char(); | 93 | if ((r = sshpkt_get_u8(ssh, &have_sig)) != 0) |
93 | if (datafellows & SSH_BUG_PKAUTH) { | 94 | fatal("%s: sshpkt_get_u8 failed: %s", __func__, ssh_err(r)); |
95 | if (ssh->compat & SSH_BUG_PKAUTH) { | ||
94 | debug2("%s: SSH_BUG_PKAUTH", __func__); | 96 | debug2("%s: SSH_BUG_PKAUTH", __func__); |
97 | if ((b = sshbuf_new()) == NULL) | ||
98 | fatal("%s: sshbuf_new failed", __func__); | ||
95 | /* no explicit pkalg given */ | 99 | /* no explicit pkalg given */ |
96 | pkblob = packet_get_string(&blen); | ||
97 | buffer_init(&b); | ||
98 | buffer_append(&b, pkblob, blen); | ||
99 | /* so we have to extract the pkalg from the pkblob */ | 100 | /* so we have to extract the pkalg from the pkblob */ |
100 | pkalg = buffer_get_string(&b, &alen); | 101 | /* XXX use sshbuf_from() */ |
101 | buffer_free(&b); | 102 | if ((r = sshpkt_get_string(ssh, &pkblob, &blen)) != 0 || |
103 | (r = sshbuf_put(b, pkblob, blen)) != 0 || | ||
104 | (r = sshbuf_get_cstring(b, &pkalg, NULL)) != 0) | ||
105 | fatal("%s: failed: %s", __func__, ssh_err(r)); | ||
106 | sshbuf_free(b); | ||
102 | } else { | 107 | } else { |
103 | pkalg = packet_get_string(&alen); | 108 | if ((r = sshpkt_get_cstring(ssh, &pkalg, NULL)) != 0 || |
104 | pkblob = packet_get_string(&blen); | 109 | (r = sshpkt_get_string(ssh, &pkblob, &blen)) != 0) |
110 | fatal("%s: sshpkt_get_cstring failed: %s", | ||
111 | __func__, ssh_err(r)); | ||
105 | } | 112 | } |
106 | pktype = key_type_from_name(pkalg); | 113 | pktype = sshkey_type_from_name(pkalg); |
107 | if (pktype == KEY_UNSPEC) { | 114 | if (pktype == KEY_UNSPEC) { |
108 | /* this is perfectly legal */ | 115 | /* this is perfectly legal */ |
109 | logit("%s: unsupported public key algorithm: %s", | 116 | logit("%s: unsupported public key algorithm: %s", |
110 | __func__, pkalg); | 117 | __func__, pkalg); |
111 | goto done; | 118 | goto done; |
112 | } | 119 | } |
113 | key = key_from_blob(pkblob, blen); | 120 | if ((r = sshkey_from_blob(pkblob, blen, &key)) != 0) { |
121 | error("%s: could not parse key: %s", __func__, ssh_err(r)); | ||
122 | goto done; | ||
123 | } | ||
114 | if (key == NULL) { | 124 | if (key == NULL) { |
115 | error("%s: cannot decode key: %s", __func__, pkalg); | 125 | error("%s: cannot decode key: %s", __func__, pkalg); |
116 | goto done; | 126 | goto done; |
@@ -120,15 +130,15 @@ userauth_pubkey(Authctxt *authctxt) | |||
120 | "(received %d, expected %d)", __func__, key->type, pktype); | 130 | "(received %d, expected %d)", __func__, key->type, pktype); |
121 | goto done; | 131 | goto done; |
122 | } | 132 | } |
123 | if (key_type_plain(key->type) == KEY_RSA && | 133 | if (sshkey_type_plain(key->type) == KEY_RSA && |
124 | (datafellows & SSH_BUG_RSASIGMD5) != 0) { | 134 | (ssh->compat & SSH_BUG_RSASIGMD5) != 0) { |
125 | logit("Refusing RSA key because client uses unsafe " | 135 | logit("Refusing RSA key because client uses unsafe " |
126 | "signature scheme"); | 136 | "signature scheme"); |
127 | goto done; | 137 | goto done; |
128 | } | 138 | } |
129 | fp = sshkey_fingerprint(key, options.fingerprint_hash, SSH_FP_DEFAULT); | 139 | fp = sshkey_fingerprint(key, options.fingerprint_hash, SSH_FP_DEFAULT); |
130 | if (auth2_userkey_already_used(authctxt, key)) { | 140 | if (auth2_userkey_already_used(authctxt, key)) { |
131 | logit("refusing previously-used %s key", key_type(key)); | 141 | logit("refusing previously-used %s key", sshkey_type(key)); |
132 | goto done; | 142 | goto done; |
133 | } | 143 | } |
134 | if (match_pattern_list(sshkey_ssh_name(key), | 144 | if (match_pattern_list(sshkey_ssh_name(key), |
@@ -141,54 +151,68 @@ userauth_pubkey(Authctxt *authctxt) | |||
141 | if (have_sig) { | 151 | if (have_sig) { |
142 | debug3("%s: have signature for %s %s", | 152 | debug3("%s: have signature for %s %s", |
143 | __func__, sshkey_type(key), fp); | 153 | __func__, sshkey_type(key), fp); |
144 | sig = packet_get_string(&slen); | 154 | if ((r = sshpkt_get_string(ssh, &sig, &slen)) != 0 || |
145 | packet_check_eom(); | 155 | (r = sshpkt_get_end(ssh)) != 0) |
146 | buffer_init(&b); | 156 | fatal("%s: %s", __func__, ssh_err(r)); |
147 | if (datafellows & SSH_OLD_SESSIONID) { | 157 | if ((b = sshbuf_new()) == NULL) |
148 | buffer_append(&b, session_id2, session_id2_len); | 158 | fatal("%s: sshbuf_new failed", __func__); |
159 | if (ssh->compat & SSH_OLD_SESSIONID) { | ||
160 | if ((r = sshbuf_put(b, session_id2, | ||
161 | session_id2_len)) != 0) | ||
162 | fatal("%s: sshbuf_put session id: %s", | ||
163 | __func__, ssh_err(r)); | ||
149 | } else { | 164 | } else { |
150 | buffer_put_string(&b, session_id2, session_id2_len); | 165 | if ((r = sshbuf_put_string(b, session_id2, |
166 | session_id2_len)) != 0) | ||
167 | fatal("%s: sshbuf_put_string session id: %s", | ||
168 | __func__, ssh_err(r)); | ||
151 | } | 169 | } |
152 | /* reconstruct packet */ | 170 | /* reconstruct packet */ |
153 | buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); | ||
154 | xasprintf(&userstyle, "%s%s%s", authctxt->user, | 171 | xasprintf(&userstyle, "%s%s%s", authctxt->user, |
155 | authctxt->style ? ":" : "", | 172 | authctxt->style ? ":" : "", |
156 | authctxt->style ? authctxt->style : ""); | 173 | authctxt->style ? authctxt->style : ""); |
157 | buffer_put_cstring(&b, userstyle); | 174 | if ((r = sshbuf_put_u8(b, SSH2_MSG_USERAUTH_REQUEST)) != 0 || |
158 | free(userstyle); | 175 | (r = sshbuf_put_cstring(b, userstyle)) != 0 || |
159 | buffer_put_cstring(&b, | 176 | (r = sshbuf_put_cstring(b, ssh->compat & SSH_BUG_PKSERVICE ? |
160 | datafellows & SSH_BUG_PKSERVICE ? | 177 | "ssh-userauth" : authctxt->service)) != 0) |
161 | "ssh-userauth" : | 178 | fatal("%s: build packet failed: %s", |
162 | authctxt->service); | 179 | __func__, ssh_err(r)); |
163 | if (datafellows & SSH_BUG_PKAUTH) { | 180 | if (ssh->compat & SSH_BUG_PKAUTH) { |
164 | buffer_put_char(&b, have_sig); | 181 | if ((r = sshbuf_put_u8(b, have_sig)) != 0) |
182 | fatal("%s: build packet failed: %s", | ||
183 | __func__, ssh_err(r)); | ||
165 | } else { | 184 | } else { |
166 | buffer_put_cstring(&b, "publickey"); | 185 | if ((r = sshbuf_put_cstring(b, "publickey")) != 0 || |
167 | buffer_put_char(&b, have_sig); | 186 | (r = sshbuf_put_u8(b, have_sig)) != 0 || |
168 | buffer_put_cstring(&b, pkalg); | 187 | (r = sshbuf_put_cstring(b, pkalg) != 0)) |
188 | fatal("%s: build packet failed: %s", | ||
189 | __func__, ssh_err(r)); | ||
169 | } | 190 | } |
170 | buffer_put_string(&b, pkblob, blen); | 191 | if ((r = sshbuf_put_string(b, pkblob, blen)) != 0) |
192 | fatal("%s: build packet failed: %s", | ||
193 | __func__, ssh_err(r)); | ||
171 | #ifdef DEBUG_PK | 194 | #ifdef DEBUG_PK |
172 | buffer_dump(&b); | 195 | sshbuf_dump(b, stderr); |
173 | #endif | 196 | #endif |
174 | pubkey_auth_info(authctxt, key, NULL); | 197 | pubkey_auth_info(authctxt, key, NULL); |
175 | 198 | ||
176 | /* test for correct signature */ | 199 | /* test for correct signature */ |
177 | authenticated = 0; | 200 | authenticated = 0; |
178 | if (PRIVSEP(user_key_allowed(authctxt->pw, key, 1)) && | 201 | if (PRIVSEP(user_key_allowed(authctxt->pw, key, 1)) && |
179 | PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b), | 202 | PRIVSEP(sshkey_verify(key, sig, slen, sshbuf_ptr(b), |
180 | buffer_len(&b))) == 1) { | 203 | sshbuf_len(b), ssh->compat)) == 0) { |
181 | authenticated = 1; | 204 | authenticated = 1; |
182 | /* Record the successful key to prevent reuse */ | 205 | /* Record the successful key to prevent reuse */ |
183 | auth2_record_userkey(authctxt, key); | 206 | auth2_record_userkey(authctxt, key); |
184 | key = NULL; /* Don't free below */ | 207 | key = NULL; /* Don't free below */ |
185 | } | 208 | } |
186 | buffer_free(&b); | 209 | sshbuf_free(b); |
187 | free(sig); | 210 | free(sig); |
188 | } else { | 211 | } else { |
189 | debug("%s: test whether pkalg/pkblob are acceptable for %s %s", | 212 | debug("%s: test whether pkalg/pkblob are acceptable for %s %s", |
190 | __func__, sshkey_type(key), fp); | 213 | __func__, sshkey_type(key), fp); |
191 | packet_check_eom(); | 214 | if ((r = sshpkt_get_end(ssh)) != 0) |
215 | fatal("%s: %s", __func__, ssh_err(r)); | ||
192 | 216 | ||
193 | /* XXX fake reply and always send PK_OK ? */ | 217 | /* XXX fake reply and always send PK_OK ? */ |
194 | /* | 218 | /* |
@@ -199,11 +223,13 @@ userauth_pubkey(Authctxt *authctxt) | |||
199 | * issue? -markus | 223 | * issue? -markus |
200 | */ | 224 | */ |
201 | if (PRIVSEP(user_key_allowed(authctxt->pw, key, 0))) { | 225 | if (PRIVSEP(user_key_allowed(authctxt->pw, key, 0))) { |
202 | packet_start(SSH2_MSG_USERAUTH_PK_OK); | 226 | if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_PK_OK)) |
203 | packet_put_string(pkalg, alen); | 227 | != 0 || |
204 | packet_put_string(pkblob, blen); | 228 | (r = sshpkt_put_cstring(ssh, pkalg)) != 0 || |
205 | packet_send(); | 229 | (r = sshpkt_put_string(ssh, pkblob, blen)) != 0 || |
206 | packet_write_wait(); | 230 | (r = sshpkt_send(ssh)) != 0) |
231 | fatal("%s: %s", __func__, ssh_err(r)); | ||
232 | ssh_packet_write_wait(ssh); | ||
207 | authctxt->postponed = 1; | 233 | authctxt->postponed = 1; |
208 | } | 234 | } |
209 | } | 235 | } |
@@ -212,7 +238,8 @@ userauth_pubkey(Authctxt *authctxt) | |||
212 | done: | 238 | done: |
213 | debug2("%s: authenticated %d pkalg %s", __func__, authenticated, pkalg); | 239 | debug2("%s: authenticated %d pkalg %s", __func__, authenticated, pkalg); |
214 | if (key != NULL) | 240 | if (key != NULL) |
215 | key_free(key); | 241 | sshkey_free(key); |
242 | free(userstyle); | ||
216 | free(pkalg); | 243 | free(pkalg); |
217 | free(pkblob); | 244 | free(pkblob); |
218 | free(fp); | 245 | free(fp); |
@@ -233,23 +260,23 @@ pubkey_auth_info(Authctxt *authctxt, const struct sshkey *key, | |||
233 | i = vasprintf(&extra, fmt, ap); | 260 | i = vasprintf(&extra, fmt, ap); |
234 | va_end(ap); | 261 | va_end(ap); |
235 | if (i < 0 || extra == NULL) | 262 | if (i < 0 || extra == NULL) |
236 | fatal("%s: vasprintf failed", __func__); | 263 | fatal("%s: vasprintf failed", __func__); |
237 | } | 264 | } |
238 | 265 | ||
239 | if (key_is_cert(key)) { | 266 | if (sshkey_is_cert(key)) { |
240 | fp = sshkey_fingerprint(key->cert->signature_key, | 267 | fp = sshkey_fingerprint(key->cert->signature_key, |
241 | options.fingerprint_hash, SSH_FP_DEFAULT); | 268 | options.fingerprint_hash, SSH_FP_DEFAULT); |
242 | auth_info(authctxt, "%s ID %s (serial %llu) CA %s %s%s%s", | 269 | auth_info(authctxt, "%s ID %s (serial %llu) CA %s %s%s%s", |
243 | key_type(key), key->cert->key_id, | 270 | sshkey_type(key), key->cert->key_id, |
244 | (unsigned long long)key->cert->serial, | 271 | (unsigned long long)key->cert->serial, |
245 | key_type(key->cert->signature_key), | 272 | sshkey_type(key->cert->signature_key), |
246 | fp == NULL ? "(null)" : fp, | 273 | fp == NULL ? "(null)" : fp, |
247 | extra == NULL ? "" : ", ", extra == NULL ? "" : extra); | 274 | extra == NULL ? "" : ", ", extra == NULL ? "" : extra); |
248 | free(fp); | 275 | free(fp); |
249 | } else { | 276 | } else { |
250 | fp = sshkey_fingerprint(key, options.fingerprint_hash, | 277 | fp = sshkey_fingerprint(key, options.fingerprint_hash, |
251 | SSH_FP_DEFAULT); | 278 | SSH_FP_DEFAULT); |
252 | auth_info(authctxt, "%s %s%s%s", key_type(key), | 279 | auth_info(authctxt, "%s %s%s%s", sshkey_type(key), |
253 | fp == NULL ? "(null)" : fp, | 280 | fp == NULL ? "(null)" : fp, |
254 | extra == NULL ? "" : ", ", extra == NULL ? "" : extra); | 281 | extra == NULL ? "" : ", ", extra == NULL ? "" : extra); |
255 | free(fp); | 282 | free(fp); |
@@ -762,16 +789,13 @@ match_principals_command(struct passwd *user_pw, const struct sshkey *key) | |||
762 | * returns 1 if the key is allowed or 0 otherwise. | 789 | * returns 1 if the key is allowed or 0 otherwise. |
763 | */ | 790 | */ |
764 | static int | 791 | static int |
765 | check_authkeys_file(FILE *f, char *file, struct sshkey* key, struct passwd *pw) | 792 | check_authkeys_file(FILE *f, char *file, struct sshkey *key, struct passwd *pw) |
766 | { | 793 | { |
767 | char line[SSH_MAX_PUBKEY_BYTES]; | 794 | char line[SSH_MAX_PUBKEY_BYTES]; |
768 | int found_key = 0; | 795 | int found_key = 0; |
769 | u_long linenum = 0; | 796 | u_long linenum = 0; |
770 | struct sshkey *found; | 797 | struct sshkey *found = NULL; |
771 | |||
772 | found_key = 0; | ||
773 | 798 | ||
774 | found = NULL; | ||
775 | while (read_keyfile_line(f, file, line, sizeof(line), &linenum) != -1) { | 799 | while (read_keyfile_line(f, file, line, sizeof(line), &linenum) != -1) { |
776 | char *cp, *key_options = NULL, *fp = NULL; | 800 | char *cp, *key_options = NULL, *fp = NULL; |
777 | const char *reason = NULL; | 801 | const char *reason = NULL; |
@@ -780,8 +804,10 @@ check_authkeys_file(FILE *f, char *file, struct sshkey* key, struct passwd *pw) | |||
780 | if (found_key) | 804 | if (found_key) |
781 | continue; | 805 | continue; |
782 | if (found != NULL) | 806 | if (found != NULL) |
783 | key_free(found); | 807 | sshkey_free(found); |
784 | found = key_new(key_is_cert(key) ? KEY_UNSPEC : key->type); | 808 | found = sshkey_new(sshkey_is_cert(key) ? KEY_UNSPEC : key->type); |
809 | if (found == NULL) | ||
810 | goto done; | ||
785 | auth_clear_options(); | 811 | auth_clear_options(); |
786 | 812 | ||
787 | /* Skip leading whitespace, empty and comment lines. */ | 813 | /* Skip leading whitespace, empty and comment lines. */ |
@@ -790,7 +816,7 @@ check_authkeys_file(FILE *f, char *file, struct sshkey* key, struct passwd *pw) | |||
790 | if (!*cp || *cp == '\n' || *cp == '#') | 816 | if (!*cp || *cp == '\n' || *cp == '#') |
791 | continue; | 817 | continue; |
792 | 818 | ||
793 | if (key_read(found, &cp) != 1) { | 819 | if (sshkey_read(found, &cp) != 0) { |
794 | /* no key? check if there are options for this key */ | 820 | /* no key? check if there are options for this key */ |
795 | int quoted = 0; | 821 | int quoted = 0; |
796 | debug2("user_key_allowed: check options: '%s'", cp); | 822 | debug2("user_key_allowed: check options: '%s'", cp); |
@@ -804,14 +830,14 @@ check_authkeys_file(FILE *f, char *file, struct sshkey* key, struct passwd *pw) | |||
804 | /* Skip remaining whitespace. */ | 830 | /* Skip remaining whitespace. */ |
805 | for (; *cp == ' ' || *cp == '\t'; cp++) | 831 | for (; *cp == ' ' || *cp == '\t'; cp++) |
806 | ; | 832 | ; |
807 | if (key_read(found, &cp) != 1) { | 833 | if (sshkey_read(found, &cp) != 0) { |
808 | debug2("user_key_allowed: advance: '%s'", cp); | 834 | debug2("user_key_allowed: advance: '%s'", cp); |
809 | /* still no key? advance to next line*/ | 835 | /* still no key? advance to next line*/ |
810 | continue; | 836 | continue; |
811 | } | 837 | } |
812 | } | 838 | } |
813 | if (key_is_cert(key)) { | 839 | if (sshkey_is_cert(key)) { |
814 | if (!key_equal(found, key->cert->signature_key)) | 840 | if (!sshkey_equal(found, key->cert->signature_key)) |
815 | continue; | 841 | continue; |
816 | if (auth_parse_options(pw, key_options, file, | 842 | if (auth_parse_options(pw, key_options, file, |
817 | linenum) != 1) | 843 | linenum) != 1) |
@@ -822,7 +848,7 @@ check_authkeys_file(FILE *f, char *file, struct sshkey* key, struct passwd *pw) | |||
822 | options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) | 848 | options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) |
823 | continue; | 849 | continue; |
824 | debug("matching CA found: file %s, line %lu, %s %s", | 850 | debug("matching CA found: file %s, line %lu, %s %s", |
825 | file, linenum, key_type(found), fp); | 851 | file, linenum, sshkey_type(found), fp); |
826 | /* | 852 | /* |
827 | * If the user has specified a list of principals as | 853 | * If the user has specified a list of principals as |
828 | * a key option, then prefer that list to matching | 854 | * a key option, then prefer that list to matching |
@@ -839,7 +865,7 @@ check_authkeys_file(FILE *f, char *file, struct sshkey* key, struct passwd *pw) | |||
839 | auth_debug_add("%s", reason); | 865 | auth_debug_add("%s", reason); |
840 | continue; | 866 | continue; |
841 | } | 867 | } |
842 | if (key_cert_check_authority(key, 0, 0, | 868 | if (sshkey_cert_check_authority(key, 0, 0, |
843 | authorized_principals == NULL ? pw->pw_name : NULL, | 869 | authorized_principals == NULL ? pw->pw_name : NULL, |
844 | &reason) != 0) | 870 | &reason) != 0) |
845 | goto fail_reason; | 871 | goto fail_reason; |
@@ -848,11 +874,11 @@ check_authkeys_file(FILE *f, char *file, struct sshkey* key, struct passwd *pw) | |||
848 | verbose("Accepted certificate ID \"%s\" (serial %llu) " | 874 | verbose("Accepted certificate ID \"%s\" (serial %llu) " |
849 | "signed by %s CA %s via %s", key->cert->key_id, | 875 | "signed by %s CA %s via %s", key->cert->key_id, |
850 | (unsigned long long)key->cert->serial, | 876 | (unsigned long long)key->cert->serial, |
851 | key_type(found), fp, file); | 877 | sshkey_type(found), fp, file); |
852 | free(fp); | 878 | free(fp); |
853 | found_key = 1; | 879 | found_key = 1; |
854 | break; | 880 | break; |
855 | } else if (key_equal(found, key)) { | 881 | } else if (sshkey_equal(found, key)) { |
856 | if (auth_parse_options(pw, key_options, file, | 882 | if (auth_parse_options(pw, key_options, file, |
857 | linenum) != 1) | 883 | linenum) != 1) |
858 | continue; | 884 | continue; |
@@ -862,14 +888,15 @@ check_authkeys_file(FILE *f, char *file, struct sshkey* key, struct passwd *pw) | |||
862 | options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) | 888 | options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) |
863 | continue; | 889 | continue; |
864 | debug("matching key found: file %s, line %lu %s %s", | 890 | debug("matching key found: file %s, line %lu %s %s", |
865 | file, linenum, key_type(found), fp); | 891 | file, linenum, sshkey_type(found), fp); |
866 | free(fp); | 892 | free(fp); |
867 | found_key = 1; | 893 | found_key = 1; |
868 | continue; | 894 | continue; |
869 | } | 895 | } |
870 | } | 896 | } |
897 | done: | ||
871 | if (found != NULL) | 898 | if (found != NULL) |
872 | key_free(found); | 899 | sshkey_free(found); |
873 | if (!found_key) | 900 | if (!found_key) |
874 | debug2("key not found"); | 901 | debug2("key not found"); |
875 | return found_key; | 902 | return found_key; |
@@ -881,20 +908,20 @@ user_cert_trusted_ca(struct passwd *pw, struct sshkey *key) | |||
881 | { | 908 | { |
882 | char *ca_fp, *principals_file = NULL; | 909 | char *ca_fp, *principals_file = NULL; |
883 | const char *reason; | 910 | const char *reason; |
884 | int ret = 0, found_principal = 0, use_authorized_principals; | 911 | int r, ret = 0, found_principal = 0, use_authorized_principals; |
885 | 912 | ||
886 | if (!key_is_cert(key) || options.trusted_user_ca_keys == NULL) | 913 | if (!sshkey_is_cert(key) || options.trusted_user_ca_keys == NULL) |
887 | return 0; | 914 | return 0; |
888 | 915 | ||
889 | if ((ca_fp = sshkey_fingerprint(key->cert->signature_key, | 916 | if ((ca_fp = sshkey_fingerprint(key->cert->signature_key, |
890 | options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) | 917 | options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) |
891 | return 0; | 918 | return 0; |
892 | 919 | ||
893 | if (sshkey_in_file(key->cert->signature_key, | 920 | if ((r = sshkey_in_file(key->cert->signature_key, |
894 | options.trusted_user_ca_keys, 1, 0) != 0) { | 921 | options.trusted_user_ca_keys, 1, 0)) != 0) { |
895 | debug2("%s: CA %s %s is not listed in %s", __func__, | 922 | debug2("%s: CA %s %s is not listed in %s: %s", __func__, |
896 | key_type(key->cert->signature_key), ca_fp, | 923 | sshkey_type(key->cert->signature_key), ca_fp, |
897 | options.trusted_user_ca_keys); | 924 | options.trusted_user_ca_keys, ssh_err(r)); |
898 | goto out; | 925 | goto out; |
899 | } | 926 | } |
900 | /* | 927 | /* |
@@ -919,7 +946,7 @@ user_cert_trusted_ca(struct passwd *pw, struct sshkey *key) | |||
919 | auth_debug_add("%s", reason); | 946 | auth_debug_add("%s", reason); |
920 | goto out; | 947 | goto out; |
921 | } | 948 | } |
922 | if (key_cert_check_authority(key, 0, 1, | 949 | if (sshkey_cert_check_authority(key, 0, 1, |
923 | use_authorized_principals ? NULL : pw->pw_name, &reason) != 0) | 950 | use_authorized_principals ? NULL : pw->pw_name, &reason) != 0) |
924 | goto fail_reason; | 951 | goto fail_reason; |
925 | if (auth_cert_options(key, pw, &reason) != 0) | 952 | if (auth_cert_options(key, pw, &reason) != 0) |
@@ -928,7 +955,7 @@ user_cert_trusted_ca(struct passwd *pw, struct sshkey *key) | |||
928 | verbose("Accepted certificate ID \"%s\" (serial %llu) signed by " | 955 | verbose("Accepted certificate ID \"%s\" (serial %llu) signed by " |
929 | "%s CA %s via %s", key->cert->key_id, | 956 | "%s CA %s via %s", key->cert->key_id, |
930 | (unsigned long long)key->cert->serial, | 957 | (unsigned long long)key->cert->serial, |
931 | key_type(key->cert->signature_key), ca_fp, | 958 | sshkey_type(key->cert->signature_key), ca_fp, |
932 | options.trusted_user_ca_keys); | 959 | options.trusted_user_ca_keys); |
933 | ret = 1; | 960 | ret = 1; |
934 | 961 | ||
@@ -1096,7 +1123,8 @@ user_key_allowed(struct passwd *pw, struct sshkey *key, int auth_attempt) | |||
1096 | 1123 | ||
1097 | if (auth_key_is_revoked(key)) | 1124 | if (auth_key_is_revoked(key)) |
1098 | return 0; | 1125 | return 0; |
1099 | if (key_is_cert(key) && auth_key_is_revoked(key->cert->signature_key)) | 1126 | if (sshkey_is_cert(key) && |
1127 | auth_key_is_revoked(key->cert->signature_key)) | ||
1100 | return 0; | 1128 | return 0; |
1101 | 1129 | ||
1102 | success = user_cert_trusted_ca(pw, key); | 1130 | success = user_cert_trusted_ca(pw, key); |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: monitor.c,v 1.168 2017/05/30 08:52:19 markus Exp $ */ | 1 | /* $OpenBSD: monitor.c,v 1.169 2017/05/30 14:10:53 markus Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright 2002 Niels Provos <provos@citi.umich.edu> | 3 | * Copyright 2002 Niels Provos <provos@citi.umich.edu> |
4 | * Copyright 2002 Markus Friedl <markus@openbsd.org> | 4 | * Copyright 2002 Markus Friedl <markus@openbsd.org> |
@@ -1330,25 +1330,25 @@ monitor_valid_hostbasedblob(u_char *data, u_int datalen, char *cuser, | |||
1330 | } | 1330 | } |
1331 | 1331 | ||
1332 | int | 1332 | int |
1333 | mm_answer_keyverify(int sock, Buffer *m) | 1333 | mm_answer_keyverify(int sock, struct sshbuf *m) |
1334 | { | 1334 | { |
1335 | struct sshkey *key; | 1335 | struct sshkey *key; |
1336 | u_char *signature, *data, *blob; | 1336 | u_char *signature, *data, *blob; |
1337 | u_int signaturelen, datalen, bloblen; | 1337 | size_t signaturelen, datalen, bloblen; |
1338 | int verified = 0; | 1338 | int r, ret, valid_data = 0, encoded_ret; |
1339 | int valid_data = 0; | ||
1340 | 1339 | ||
1341 | blob = buffer_get_string(m, &bloblen); | 1340 | if ((r = sshbuf_get_string(m, &blob, &bloblen)) != 0 || |
1342 | signature = buffer_get_string(m, &signaturelen); | 1341 | (r = sshbuf_get_string(m, &signature, &signaturelen)) != 0 || |
1343 | data = buffer_get_string(m, &datalen); | 1342 | (r = sshbuf_get_string(m, &data, &datalen)) != 0) |
1343 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
1344 | 1344 | ||
1345 | if (hostbased_cuser == NULL || hostbased_chost == NULL || | 1345 | if (hostbased_cuser == NULL || hostbased_chost == NULL || |
1346 | !monitor_allowed_key(blob, bloblen)) | 1346 | !monitor_allowed_key(blob, bloblen)) |
1347 | fatal("%s: bad key, not previously allowed", __func__); | 1347 | fatal("%s: bad key, not previously allowed", __func__); |
1348 | 1348 | ||
1349 | key = key_from_blob(blob, bloblen); | 1349 | /* XXX use sshkey_froms here; need to change key_blob, etc. */ |
1350 | if (key == NULL) | 1350 | if ((r = sshkey_from_blob(blob, bloblen, &key)) != 0) |
1351 | fatal("%s: bad public key blob", __func__); | 1351 | fatal("%s: bad public key blob: %s", __func__, ssh_err(r)); |
1352 | 1352 | ||
1353 | switch (key_blobtype) { | 1353 | switch (key_blobtype) { |
1354 | case MM_USERKEY: | 1354 | case MM_USERKEY: |
@@ -1365,15 +1365,16 @@ mm_answer_keyverify(int sock, Buffer *m) | |||
1365 | if (!valid_data) | 1365 | if (!valid_data) |
1366 | fatal("%s: bad signature data blob", __func__); | 1366 | fatal("%s: bad signature data blob", __func__); |
1367 | 1367 | ||
1368 | verified = key_verify(key, signature, signaturelen, data, datalen); | 1368 | ret = sshkey_verify(key, signature, signaturelen, data, datalen, |
1369 | active_state->compat); | ||
1369 | debug3("%s: key %p signature %s", | 1370 | debug3("%s: key %p signature %s", |
1370 | __func__, key, (verified == 1) ? "verified" : "unverified"); | 1371 | __func__, key, (ret == 0) ? "verified" : "unverified"); |
1371 | 1372 | ||
1372 | /* If auth was successful then record key to ensure it isn't reused */ | 1373 | /* If auth was successful then record key to ensure it isn't reused */ |
1373 | if (verified == 1 && key_blobtype == MM_USERKEY) | 1374 | if (ret == 0 && key_blobtype == MM_USERKEY) |
1374 | auth2_record_userkey(authctxt, key); | 1375 | auth2_record_userkey(authctxt, key); |
1375 | else | 1376 | else |
1376 | key_free(key); | 1377 | sshkey_free(key); |
1377 | 1378 | ||
1378 | free(blob); | 1379 | free(blob); |
1379 | free(signature); | 1380 | free(signature); |
@@ -1383,11 +1384,15 @@ mm_answer_keyverify(int sock, Buffer *m) | |||
1383 | 1384 | ||
1384 | monitor_reset_key_state(); | 1385 | monitor_reset_key_state(); |
1385 | 1386 | ||
1386 | buffer_clear(m); | 1387 | sshbuf_reset(m); |
1387 | buffer_put_int(m, verified); | 1388 | |
1389 | /* encode ret != 0 as positive integer, since we're sending u32 */ | ||
1390 | encoded_ret = (ret != 0); | ||
1391 | if ((r = sshbuf_put_u32(m, encoded_ret)) != 0) | ||
1392 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
1388 | mm_request_send(sock, MONITOR_ANS_KEYVERIFY, m); | 1393 | mm_request_send(sock, MONITOR_ANS_KEYVERIFY, m); |
1389 | 1394 | ||
1390 | return (verified == 1); | 1395 | return ret == 0; |
1391 | } | 1396 | } |
1392 | 1397 | ||
1393 | static void | 1398 | static void |
diff --git a/monitor_wrap.c b/monitor_wrap.c index 0710a10b0..25f3e9678 100644 --- a/monitor_wrap.c +++ b/monitor_wrap.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: monitor_wrap.c,v 1.91 2017/05/30 08:52:19 markus Exp $ */ | 1 | /* $OpenBSD: monitor_wrap.c,v 1.92 2017/05/30 14:10:53 markus Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright 2002 Niels Provos <provos@citi.umich.edu> | 3 | * Copyright 2002 Niels Provos <provos@citi.umich.edu> |
4 | * Copyright 2002 Markus Friedl <markus@openbsd.org> | 4 | * Copyright 2002 Markus Friedl <markus@openbsd.org> |
@@ -436,13 +436,13 @@ mm_key_allowed(enum mm_keytype type, const char *user, const char *host, | |||
436 | */ | 436 | */ |
437 | 437 | ||
438 | int | 438 | int |
439 | mm_key_verify(struct sshkey *key, u_char *sig, u_int siglen, u_char *data, | 439 | mm_sshkey_verify(const struct sshkey *key, const u_char *sig, size_t siglen, |
440 | u_int datalen) | 440 | const u_char *data, size_t datalen, u_int compat) |
441 | { | 441 | { |
442 | Buffer m; | 442 | Buffer m; |
443 | u_char *blob; | 443 | u_char *blob; |
444 | u_int len; | 444 | u_int len; |
445 | int verified = 0; | 445 | u_int encoded_ret = 0; |
446 | 446 | ||
447 | debug3("%s entering", __func__); | 447 | debug3("%s entering", __func__); |
448 | 448 | ||
@@ -461,11 +461,13 @@ mm_key_verify(struct sshkey *key, u_char *sig, u_int siglen, u_char *data, | |||
461 | debug3("%s: waiting for MONITOR_ANS_KEYVERIFY", __func__); | 461 | debug3("%s: waiting for MONITOR_ANS_KEYVERIFY", __func__); |
462 | mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_KEYVERIFY, &m); | 462 | mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_KEYVERIFY, &m); |
463 | 463 | ||
464 | verified = buffer_get_int(&m); | 464 | encoded_ret = buffer_get_int(&m); |
465 | 465 | ||
466 | buffer_free(&m); | 466 | buffer_free(&m); |
467 | 467 | ||
468 | return (verified); | 468 | if (encoded_ret != 0) |
469 | return SSH_ERR_SIGNATURE_INVALID; | ||
470 | return 0; | ||
469 | } | 471 | } |
470 | 472 | ||
471 | void | 473 | void |
diff --git a/monitor_wrap.h b/monitor_wrap.h index a1552d0c9..958cdbc92 100644 --- a/monitor_wrap.h +++ b/monitor_wrap.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: monitor_wrap.h,v 1.33 2017/05/30 08:52:19 markus Exp $ */ | 1 | /* $OpenBSD: monitor_wrap.h,v 1.34 2017/05/30 14:10:53 markus Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Copyright 2002 Niels Provos <provos@citi.umich.edu> | 4 | * Copyright 2002 Niels Provos <provos@citi.umich.edu> |
@@ -51,7 +51,8 @@ int mm_key_allowed(enum mm_keytype, const char *, const char *, struct sshkey *, | |||
51 | int mm_user_key_allowed(struct passwd *, struct sshkey *, int); | 51 | int mm_user_key_allowed(struct passwd *, struct sshkey *, int); |
52 | int mm_hostbased_key_allowed(struct passwd *, const char *, | 52 | int mm_hostbased_key_allowed(struct passwd *, const char *, |
53 | const char *, struct sshkey *); | 53 | const char *, struct sshkey *); |
54 | int mm_key_verify(struct sshkey *, u_char *, u_int, u_char *, u_int); | 54 | int mm_sshkey_verify(const struct sshkey *, const u_char *, size_t, |
55 | const u_char *, size_t, u_int); | ||
55 | 56 | ||
56 | #ifdef GSSAPI | 57 | #ifdef GSSAPI |
57 | OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID); | 58 | OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID); |