version 1.20, 2000/10/14 12:16:56 |
version 1.21, 2000/11/12 19:50:37 |
|
|
#include "key.h" |
#include "key.h" |
#include "kex.h" |
#include "kex.h" |
|
|
#include "dsa.h" |
|
#include "uidswap.h" |
#include "uidswap.h" |
#include "auth-options.h" |
#include "auth-options.h" |
|
|
|
|
/* helper */ |
/* helper */ |
Authmethod *authmethod_lookup(const char *name); |
Authmethod *authmethod_lookup(const char *name); |
struct passwd *pwcopy(struct passwd *pw); |
struct passwd *pwcopy(struct passwd *pw); |
int user_dsa_key_allowed(struct passwd *pw, Key *key); |
int user_key_allowed(struct passwd *pw, Key *key); |
char *authmethods_get(void); |
char *authmethods_get(void); |
|
|
/* auth */ |
/* auth */ |
|
|
&one}, |
&one}, |
{"publickey", |
{"publickey", |
userauth_pubkey, |
userauth_pubkey, |
&options.dsa_authentication}, |
&options.pubkey_authentication}, |
{"keyboard-interactive", |
{"keyboard-interactive", |
userauth_kbdint, |
userauth_kbdint, |
&options.kbd_interactive_authentication}, |
&options.kbd_interactive_authentication}, |
|
|
Key *key; |
Key *key; |
char *pkalg, *pkblob, *sig; |
char *pkalg, *pkblob, *sig; |
unsigned int alen, blen, slen; |
unsigned int alen, blen, slen; |
int have_sig; |
int have_sig, pktype; |
int authenticated = 0; |
int authenticated = 0; |
|
|
if (!authctxt->valid) { |
if (!authctxt->valid) { |
|
|
} |
} |
have_sig = packet_get_char(); |
have_sig = packet_get_char(); |
pkalg = packet_get_string(&alen); |
pkalg = packet_get_string(&alen); |
if (strcmp(pkalg, KEX_DSS) != 0) { |
pktype = key_type_from_name(pkalg); |
log("bad pkalg %s", pkalg); /*XXX*/ |
if (pktype == KEY_UNSPEC) { |
|
log("bad pkalg %s", pkalg); |
xfree(pkalg); |
xfree(pkalg); |
return 0; |
return 0; |
} |
} |
pkblob = packet_get_string(&blen); |
pkblob = packet_get_string(&blen); |
key = dsa_key_from_blob(pkblob, blen); |
key = key_from_blob(pkblob, blen); |
if (key != NULL) { |
if (key != NULL) { |
if (have_sig) { |
if (have_sig) { |
sig = packet_get_string(&slen); |
sig = packet_get_string(&slen); |
|
|
authctxt->service); |
authctxt->service); |
buffer_put_cstring(&b, "publickey"); |
buffer_put_cstring(&b, "publickey"); |
buffer_put_char(&b, have_sig); |
buffer_put_char(&b, have_sig); |
buffer_put_cstring(&b, KEX_DSS); |
buffer_put_cstring(&b, key_ssh_name(key)); |
buffer_put_string(&b, pkblob, blen); |
buffer_put_string(&b, pkblob, blen); |
#ifdef DEBUG_DSS |
#ifdef DEBUG_PK |
buffer_dump(&b); |
buffer_dump(&b); |
#endif |
#endif |
/* test for correct signature */ |
/* test for correct signature */ |
if (user_dsa_key_allowed(authctxt->pw, key) && |
if (user_key_allowed(authctxt->pw, key) && |
dsa_verify(key, sig, slen, buffer_ptr(&b), buffer_len(&b)) == 1) |
key_verify(key, sig, slen, buffer_ptr(&b), buffer_len(&b)) == 1) |
authenticated = 1; |
authenticated = 1; |
buffer_clear(&b); |
buffer_clear(&b); |
xfree(sig); |
xfree(sig); |
|
|
* if a user is not allowed to login. is this an |
* if a user is not allowed to login. is this an |
* issue? -markus |
* issue? -markus |
*/ |
*/ |
if (user_dsa_key_allowed(authctxt->pw, key)) { |
if (user_key_allowed(authctxt->pw, key)) { |
packet_start(SSH2_MSG_USERAUTH_PK_OK); |
packet_start(SSH2_MSG_USERAUTH_PK_OK); |
packet_put_string(pkalg, alen); |
packet_put_string(pkalg, alen); |
packet_put_string(pkblob, blen); |
packet_put_string(pkblob, blen); |
|
|
auth_clear_options(); |
auth_clear_options(); |
key_free(key); |
key_free(key); |
} |
} |
|
debug2("userauth_pubkey: authenticated %d pkalg %s", authenticated, pkalg); |
xfree(pkalg); |
xfree(pkalg); |
xfree(pkblob); |
xfree(pkblob); |
return authenticated; |
return authenticated; |
|
|
|
|
/* return 1 if user allows given key */ |
/* return 1 if user allows given key */ |
int |
int |
user_dsa_key_allowed(struct passwd *pw, Key *key) |
user_key_allowed(struct passwd *pw, Key *key) |
{ |
{ |
char line[8192], file[1024]; |
char line[8192], file[1024]; |
int found_key = 0; |
int found_key = 0; |
unsigned int bits = -1; |
|
FILE *f; |
FILE *f; |
unsigned long linenum = 0; |
unsigned long linenum = 0; |
struct stat st; |
struct stat st; |
|
|
if (!*cp || *cp == '\n' || *cp == '#') |
if (!*cp || *cp == '\n' || *cp == '#') |
continue; |
continue; |
|
|
bits = key_read(found, &cp); |
if (key_read(found, &cp) == -1) { |
if (bits == 0) { |
|
/* no key? check if there are options for this key */ |
/* no key? check if there are options for this key */ |
int quoted = 0; |
int quoted = 0; |
|
debug2("user_key_allowed: check options: '%s'", cp); |
options = cp; |
options = cp; |
for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) { |
for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) { |
if (*cp == '\\' && cp[1] == '"') |
if (*cp == '\\' && cp[1] == '"') |
|
|
/* Skip remaining whitespace. */ |
/* Skip remaining whitespace. */ |
for (; *cp == ' ' || *cp == '\t'; cp++) |
for (; *cp == ' ' || *cp == '\t'; cp++) |
; |
; |
bits = key_read(found, &cp); |
if (key_read(found, &cp) == -1) { |
if (bits == 0) { |
debug2("user_key_allowed: advance: '%s'", cp); |
/* still no key? advance to next line*/ |
/* still no key? advance to next line*/ |
continue; |
continue; |
} |
} |