summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--auth-rh-rsa.c4
-rw-r--r--auth-rsa.c202
-rw-r--r--auth.h4
4 files changed, 125 insertions, 90 deletions
diff --git a/ChangeLog b/ChangeLog
index bf0776610..7db349fd6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -15,6 +15,9 @@
15 - markus@cvs.openbsd.org 2002/03/14 16:38:26 15 - markus@cvs.openbsd.org 2002/03/14 16:38:26
16 [sshd.c] 16 [sshd.c]
17 split out ssh1 session key decryption; ok provos@ 17 split out ssh1 session key decryption; ok provos@
18 - markus@cvs.openbsd.org 2002/03/14 16:56:33
19 [auth-rh-rsa.c auth-rsa.c auth.h]
20 split auth_rsa() for better readability and privsep; ok provos@
18 21
1920020317 2220020317
20 - (tim) [configure.ac] Assume path given with --with-pid-dir=PATH is wanted, 23 - (tim) [configure.ac] Assume path given with --with-pid-dir=PATH is wanted,
@@ -7861,4 +7864,4 @@
7861 - Wrote replacements for strlcpy and mkdtemp 7864 - Wrote replacements for strlcpy and mkdtemp
7862 - Released 1.0pre1 7865 - Released 1.0pre1
7863 7866
7864$Id: ChangeLog,v 1.1928 2002/03/22 01:10:21 mouring Exp $ 7867$Id: ChangeLog,v 1.1929 2002/03/22 01:12:58 mouring Exp $
diff --git a/auth-rh-rsa.c b/auth-rh-rsa.c
index d1b7ae996..397b0a55c 100644
--- a/auth-rh-rsa.c
+++ b/auth-rh-rsa.c
@@ -13,7 +13,7 @@
13 */ 13 */
14 14
15#include "includes.h" 15#include "includes.h"
16RCSID("$OpenBSD: auth-rh-rsa.c,v 1.29 2002/03/04 12:43:06 markus Exp $"); 16RCSID("$OpenBSD: auth-rh-rsa.c,v 1.30 2002/03/14 16:56:33 markus Exp $");
17 17
18#include "packet.h" 18#include "packet.h"
19#include "uidswap.h" 19#include "uidswap.h"
@@ -63,7 +63,7 @@ auth_rhosts_rsa(struct passwd *pw, const char *client_user, Key *client_host_key
63 /* A matching host key was found and is known. */ 63 /* A matching host key was found and is known. */
64 64
65 /* Perform the challenge-response dialog with the client for the host key. */ 65 /* Perform the challenge-response dialog with the client for the host key. */
66 if (!auth_rsa_challenge_dialog(client_host_key->rsa)) { 66 if (!auth_rsa_challenge_dialog(client_host_key)) {
67 log("Client on %.800s failed to respond correctly to host authentication.", 67 log("Client on %.800s failed to respond correctly to host authentication.",
68 canonical_hostname); 68 canonical_hostname);
69 return 0; 69 return 0;
diff --git a/auth-rsa.c b/auth-rsa.c
index f7ae03cfd..ff9bf3b64 100644
--- a/auth-rsa.c
+++ b/auth-rsa.c
@@ -14,7 +14,7 @@
14 */ 14 */
15 15
16#include "includes.h" 16#include "includes.h"
17RCSID("$OpenBSD: auth-rsa.c,v 1.50 2001/12/28 14:50:54 markus Exp $"); 17RCSID("$OpenBSD: auth-rsa.c,v 1.51 2002/03/14 16:56:33 markus Exp $");
18 18
19#include <openssl/rsa.h> 19#include <openssl/rsa.h>
20#include <openssl/md5.h> 20#include <openssl/md5.h>
@@ -52,6 +52,51 @@ extern u_char session_id[16];
52 * description of the options. 52 * description of the options.
53 */ 53 */
54 54
55static BIGNUM *
56auth_rsa_generate_challenge(Key *key)
57{
58 BIGNUM *challenge;
59 BN_CTX *ctx;
60
61 if ((challenge = BN_new()) == NULL)
62 fatal("auth_rsa_generate_challenge: BN_new() failed");
63 /* Generate a random challenge. */
64 BN_rand(challenge, 256, 0, 0);
65 if ((ctx = BN_CTX_new()) == NULL)
66 fatal("auth_rsa_generate_challenge: BN_CTX_new() failed");
67 BN_mod(challenge, challenge, key->rsa->n, ctx);
68 BN_CTX_free(ctx);
69
70 return challenge;
71}
72
73static int
74auth_rsa_verify_response(Key *key, BIGNUM *challenge, u_char response[16])
75{
76 u_char buf[32], mdbuf[16];
77 MD5_CTX md;
78 int len;
79
80 /* The response is MD5 of decrypted challenge plus session id. */
81 len = BN_num_bytes(challenge);
82 if (len <= 0 || len > 32)
83 fatal("auth_rsa_verify_response: bad challenge length %d", len);
84 memset(buf, 0, 32);
85 BN_bn2bin(challenge, buf + 32 - len);
86 MD5_Init(&md);
87 MD5_Update(&md, buf, 32);
88 MD5_Update(&md, session_id, 16);
89 MD5_Final(mdbuf, &md);
90
91 /* Verify that the response is the original challenge. */
92 if (memcmp(response, mdbuf, 16) != 0) {
93 /* Wrong answer. */
94 return (0);
95 }
96 /* Correct answer. */
97 return (1);
98}
99
55/* 100/*
56 * Performs the RSA authentication challenge-response dialog with the client, 101 * Performs the RSA authentication challenge-response dialog with the client,
57 * and returns true (non-zero) if the client gave the correct answer to 102 * and returns true (non-zero) if the client gave the correct answer to
@@ -59,29 +104,19 @@ extern u_char session_id[16];
59 */ 104 */
60 105
61int 106int
62auth_rsa_challenge_dialog(RSA *pk) 107auth_rsa_challenge_dialog(Key *key)
63{ 108{
64 BIGNUM *challenge, *encrypted_challenge; 109 BIGNUM *challenge, *encrypted_challenge;
65 BN_CTX *ctx; 110 u_char response[16];
66 u_char buf[32], mdbuf[16], response[16]; 111 int i, success;
67 MD5_CTX md;
68 u_int i;
69 int len;
70 112
71 if ((encrypted_challenge = BN_new()) == NULL) 113 if ((encrypted_challenge = BN_new()) == NULL)
72 fatal("auth_rsa_challenge_dialog: BN_new() failed"); 114 fatal("auth_rsa_challenge_dialog: BN_new() failed");
73 if ((challenge = BN_new()) == NULL)
74 fatal("auth_rsa_challenge_dialog: BN_new() failed");
75 115
76 /* Generate a random challenge. */ 116 challenge = auth_rsa_generate_challenge(key);
77 BN_rand(challenge, 256, 0, 0);
78 if ((ctx = BN_CTX_new()) == NULL)
79 fatal("auth_rsa_challenge_dialog: BN_CTX_new() failed");
80 BN_mod(challenge, challenge, pk->n, ctx);
81 BN_CTX_free(ctx);
82 117
83 /* Encrypt the challenge with the public key. */ 118 /* Encrypt the challenge with the public key. */
84 rsa_public_encrypt(encrypted_challenge, challenge, pk); 119 rsa_public_encrypt(encrypted_challenge, challenge, key->rsa);
85 120
86 /* Send the encrypted challenge to the client. */ 121 /* Send the encrypted challenge to the client. */
87 packet_start(SSH_SMSG_AUTH_RSA_CHALLENGE); 122 packet_start(SSH_SMSG_AUTH_RSA_CHALLENGE);
@@ -96,48 +131,26 @@ auth_rsa_challenge_dialog(RSA *pk)
96 response[i] = packet_get_char(); 131 response[i] = packet_get_char();
97 packet_check_eom(); 132 packet_check_eom();
98 133
99 /* The response is MD5 of decrypted challenge plus session id. */ 134 success = auth_rsa_verify_response(key, challenge, response);
100 len = BN_num_bytes(challenge);
101 if (len <= 0 || len > 32)
102 fatal("auth_rsa_challenge_dialog: bad challenge length %d", len);
103 memset(buf, 0, 32);
104 BN_bn2bin(challenge, buf + 32 - len);
105 MD5_Init(&md);
106 MD5_Update(&md, buf, 32);
107 MD5_Update(&md, session_id, 16);
108 MD5_Final(mdbuf, &md);
109 BN_clear_free(challenge); 135 BN_clear_free(challenge);
110 136 return (success);
111 /* Verify that the response is the original challenge. */
112 if (memcmp(response, mdbuf, 16) != 0) {
113 /* Wrong answer. */
114 return 0;
115 }
116 /* Correct answer. */
117 return 1;
118} 137}
119 138
120/* 139/*
121 * Performs the RSA authentication dialog with the client. This returns 140 * check if there's user key matching client_n,
122 * 0 if the client could not be authenticated, and 1 if authentication was 141 * return key if login is allowed, NULL otherwise
123 * successful. This may exit if there is a serious protocol violation.
124 */ 142 */
125 143
126int 144static int
127auth_rsa(struct passwd *pw, BIGNUM *client_n) 145auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey)
128{ 146{
129 char line[8192], *file; 147 char line[8192], *file;
130 int authenticated; 148 int allowed;
131 u_int bits; 149 u_int bits;
132 FILE *f; 150 FILE *f;
133 u_long linenum = 0; 151 u_long linenum = 0;
134 struct stat st; 152 struct stat st;
135 Key *key; 153 Key *key;
136 char *fp;
137
138 /* no user given */
139 if (pw == NULL)
140 return 0;
141 154
142 /* Temporarily use the user's uid. */ 155 /* Temporarily use the user's uid. */
143 temporarily_use_uid(pw); 156 temporarily_use_uid(pw);
@@ -151,29 +164,27 @@ auth_rsa(struct passwd *pw, BIGNUM *client_n)
151 /* Restore the privileged uid. */ 164 /* Restore the privileged uid. */
152 restore_uid(); 165 restore_uid();
153 xfree(file); 166 xfree(file);
154 return 0; 167 return (NULL);
155 } 168 }
156 /* Open the file containing the authorized keys. */ 169 /* Open the file containing the authorized keys. */
157 f = fopen(file, "r"); 170 f = fopen(file, "r");
158 if (!f) { 171 if (!f) {
159 /* Restore the privileged uid. */ 172 /* Restore the privileged uid. */
160 restore_uid(); 173 restore_uid();
161 packet_send_debug("Could not open %.900s for reading.", file);
162 packet_send_debug("If your home is on an NFS volume, it may need to be world-readable.");
163 xfree(file); 174 xfree(file);
164 return 0; 175 return (NULL);
165 } 176 }
166 if (options.strict_modes && 177 if (options.strict_modes &&
167 secure_filename(f, file, pw, line, sizeof(line)) != 0) { 178 secure_filename(f, file, pw, line, sizeof(line)) != 0) {
168 xfree(file); 179 xfree(file);
169 fclose(f); 180 fclose(f);
170 log("Authentication refused: %s", line); 181 log("Authentication refused: %s", line);
171 packet_send_debug("Authentication refused: %s", line);
172 restore_uid(); 182 restore_uid();
173 return 0; 183 return (NULL);
174 } 184 }
175 /* Flag indicating whether authentication has succeeded. */ 185
176 authenticated = 0; 186 /* Flag indicating whether the key is allowed. */
187 allowed = 0;
177 188
178 key = key_new(KEY_RSA1); 189 key = key_new(KEY_RSA1);
179 190
@@ -238,32 +249,8 @@ auth_rsa(struct passwd *pw, BIGNUM *client_n)
238 if (!auth_parse_options(pw, options, file, linenum)) 249 if (!auth_parse_options(pw, options, file, linenum))
239 continue; 250 continue;
240 251
241 /* Perform the challenge-response dialog for this key. */ 252 /* break out, this key is allowed */
242 if (!auth_rsa_challenge_dialog(key->rsa)) { 253 allowed = 1;
243 /* Wrong response. */
244 verbose("Wrong response to RSA authentication challenge.");
245 packet_send_debug("Wrong response to RSA authentication challenge.");
246 /*
247 * Break out of the loop. Otherwise we might send
248 * another challenge and break the protocol.
249 */
250 break;
251 }
252 /*
253 * Correct response. The client has been successfully
254 * authenticated. Note that we have not yet processed the
255 * options; this will be reset if the options cause the
256 * authentication to be rejected.
257 * Break out of the loop if authentication was successful;
258 * otherwise continue searching.
259 */
260 authenticated = 1;
261
262 fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
263 verbose("Found matching %s key: %s",
264 key_type(key), fp);
265 xfree(fp);
266
267 break; 254 break;
268 } 255 }
269 256
@@ -274,13 +261,58 @@ auth_rsa(struct passwd *pw, BIGNUM *client_n)
274 xfree(file); 261 xfree(file);
275 fclose(f); 262 fclose(f);
276 263
277 key_free(key); 264 /* return key if allowed */
278 265 if (allowed && rkey != NULL)
279 if (authenticated) 266 *rkey = key;
280 packet_send_debug("RSA authentication accepted.");
281 else 267 else
268 key_free(key);
269 return (allowed);
270}
271
272/*
273 * Performs the RSA authentication dialog with the client. This returns
274 * 0 if the client could not be authenticated, and 1 if authentication was
275 * successful. This may exit if there is a serious protocol violation.
276 */
277int
278auth_rsa(struct passwd *pw, BIGNUM *client_n)
279{
280 Key *key;
281 char *fp;
282
283 /* no user given */
284 if (pw == NULL)
285 return 0;
286
287 if (auth_rsa_key_allowed(pw, client_n, &key) == 0) {
282 auth_clear_options(); 288 auth_clear_options();
289 return (0);
290 }
291
292 /* Perform the challenge-response dialog for this key. */
293 if (!auth_rsa_challenge_dialog(key)) {
294 /* Wrong response. */
295 verbose("Wrong response to RSA authentication challenge.");
296 packet_send_debug("Wrong response to RSA authentication challenge.");
297 /*
298 * Break out of the loop. Otherwise we might send
299 * another challenge and break the protocol.
300 */
301 key_free(key);
302 return (0);
303 }
304 /*
305 * Correct response. The client has been successfully
306 * authenticated. Note that we have not yet processed the
307 * options; this will be reset if the options cause the
308 * authentication to be rejected.
309 */
310 fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
311 verbose("Found matching %s key: %s",
312 key_type(key), fp);
313 xfree(fp);
314 key_free(key);
283 315
284 /* Return authentication result. */ 316 packet_send_debug("RSA authentication accepted.");
285 return authenticated; 317 return (1);
286} 318}
diff --git a/auth.h b/auth.h
index c7175405d..7689b28d7 100644
--- a/auth.h
+++ b/auth.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth.h,v 1.29 2002/03/04 17:27:39 stevesk Exp $ */ 1/* $OpenBSD: auth.h,v 1.30 2002/03/14 16:56:33 markus Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2000 Markus Friedl. All rights reserved. 4 * Copyright (c) 2000 Markus Friedl. All rights reserved.
@@ -95,7 +95,7 @@ auth_rhosts2(struct passwd *, const char *, const char *, const char *);
95int auth_rhosts_rsa(struct passwd *, const char *, Key *); 95int auth_rhosts_rsa(struct passwd *, const char *, Key *);
96int auth_password(Authctxt *, const char *); 96int auth_password(Authctxt *, const char *);
97int auth_rsa(struct passwd *, BIGNUM *); 97int auth_rsa(struct passwd *, BIGNUM *);
98int auth_rsa_challenge_dialog(RSA *); 98int auth_rsa_challenge_dialog(Key *);
99 99
100#ifdef KRB4 100#ifdef KRB4
101#include <krb.h> 101#include <krb.h>