version 1.8, 2001/09/27 15:31:17 |
version 1.8.2.1, 2002/03/07 17:37:46 |
|
|
|
|
#include "ssh2.h" |
#include "ssh2.h" |
#include "auth.h" |
#include "auth.h" |
|
#include "buffer.h" |
#include "packet.h" |
#include "packet.h" |
#include "xmalloc.h" |
#include "xmalloc.h" |
#include "dispatch.h" |
#include "dispatch.h" |
|
|
|
|
static int auth2_challenge_start(Authctxt *); |
static int auth2_challenge_start(Authctxt *); |
static int send_userauth_info_request(Authctxt *); |
static int send_userauth_info_request(Authctxt *); |
static void input_userauth_info_response(int, int, void *); |
static void input_userauth_info_response(int, u_int32_t, void *); |
|
|
#ifdef BSD_AUTH |
#ifdef BSD_AUTH |
extern KbdintDevice bsdauth_device; |
extern KbdintDevice bsdauth_device; |
|
|
kbdint_alloc(const char *devs) |
kbdint_alloc(const char *devs) |
{ |
{ |
KbdintAuthctxt *kbdintctxt; |
KbdintAuthctxt *kbdintctxt; |
|
Buffer b; |
int i; |
int i; |
char buf[1024]; |
|
|
|
kbdintctxt = xmalloc(sizeof(KbdintAuthctxt)); |
kbdintctxt = xmalloc(sizeof(KbdintAuthctxt)); |
if (strcmp(devs, "") == 0) { |
if (strcmp(devs, "") == 0) { |
buf[0] = '\0'; |
buffer_init(&b); |
for (i = 0; devices[i]; i++) { |
for (i = 0; devices[i]; i++) { |
if (i != 0) |
if (buffer_len(&b) > 0) |
strlcat(buf, ",", sizeof(buf)); |
buffer_append(&b, ",", 1); |
strlcat(buf, devices[i]->name, sizeof(buf)); |
buffer_append(&b, devices[i]->name, |
|
strlen(devices[i]->name)); |
} |
} |
debug("kbdint_alloc: devices '%s'", buf); |
buffer_append(&b, "\0", 1); |
kbdintctxt->devices = xstrdup(buf); |
kbdintctxt->devices = xstrdup(buffer_ptr(&b)); |
|
buffer_free(&b); |
} else { |
} else { |
kbdintctxt->devices = xstrdup(devs); |
kbdintctxt->devices = xstrdup(devs); |
} |
} |
|
debug("kbdint_alloc: devices '%s'", kbdintctxt->devices); |
kbdintctxt->ctxt = NULL; |
kbdintctxt->ctxt = NULL; |
kbdintctxt->device = NULL; |
kbdintctxt->device = NULL; |
|
|
|
|
|
|
if (authctxt->user == NULL || !devs) |
if (authctxt->user == NULL || !devs) |
return 0; |
return 0; |
if (authctxt->kbdintctxt == NULL) |
if (authctxt->kbdintctxt == NULL) |
authctxt->kbdintctxt = kbdint_alloc(devs); |
authctxt->kbdintctxt = kbdint_alloc(devs); |
return auth2_challenge_start(authctxt); |
return auth2_challenge_start(authctxt); |
} |
} |
|
|
|
/* unregister kbd-int callbacks and context */ |
|
void |
|
auth2_challenge_stop(Authctxt *authctxt) |
|
{ |
|
/* unregister callback */ |
|
dispatch_set(SSH2_MSG_USERAUTH_INFO_RESPONSE, NULL); |
|
if (authctxt->kbdintctxt != NULL) { |
|
kbdint_free(authctxt->kbdintctxt); |
|
authctxt->kbdintctxt = NULL; |
|
} |
|
} |
|
|
/* side effect: sets authctxt->postponed if a reply was sent*/ |
/* side effect: sets authctxt->postponed if a reply was sent*/ |
static int |
static int |
auth2_challenge_start(Authctxt *authctxt) |
auth2_challenge_start(Authctxt *authctxt) |
|
|
kbdintctxt->devices ? kbdintctxt->devices : "<empty>"); |
kbdintctxt->devices ? kbdintctxt->devices : "<empty>"); |
|
|
if (kbdint_next_device(kbdintctxt) == 0) { |
if (kbdint_next_device(kbdintctxt) == 0) { |
kbdint_free(kbdintctxt); |
auth2_challenge_stop(authctxt); |
authctxt->kbdintctxt = NULL; |
|
return 0; |
return 0; |
} |
} |
debug("auth2_challenge_start: trying authentication method '%s'", |
debug("auth2_challenge_start: trying authentication method '%s'", |
kbdintctxt->device->name); |
kbdintctxt->device->name); |
|
|
if ((kbdintctxt->ctxt = kbdintctxt->device->init_ctx(authctxt)) == NULL) { |
if ((kbdintctxt->ctxt = kbdintctxt->device->init_ctx(authctxt)) == NULL) { |
kbdint_free(kbdintctxt); |
auth2_challenge_stop(authctxt); |
authctxt->kbdintctxt = NULL; |
|
return 0; |
return 0; |
} |
} |
if (send_userauth_info_request(authctxt) == 0) { |
if (send_userauth_info_request(authctxt) == 0) { |
kbdint_free(kbdintctxt); |
auth2_challenge_stop(authctxt); |
authctxt->kbdintctxt = NULL; |
|
return 0; |
return 0; |
} |
} |
dispatch_set(SSH2_MSG_USERAUTH_INFO_RESPONSE, |
dispatch_set(SSH2_MSG_USERAUTH_INFO_RESPONSE, |
|
|
} |
} |
|
|
static void |
static void |
input_userauth_info_response(int type, int plen, void *ctxt) |
input_userauth_info_response(int type, u_int32_t seq, void *ctxt) |
{ |
{ |
Authctxt *authctxt = ctxt; |
Authctxt *authctxt = ctxt; |
KbdintAuthctxt *kbdintctxt; |
KbdintAuthctxt *kbdintctxt; |
|
|
for (i = 0; i < nresp; i++) |
for (i = 0; i < nresp; i++) |
response[i] = packet_get_string(NULL); |
response[i] = packet_get_string(NULL); |
} |
} |
packet_done(); |
packet_check_eom(); |
|
|
if (authctxt->valid) { |
if (authctxt->valid) { |
res = kbdintctxt->device->respond(kbdintctxt->ctxt, |
res = kbdintctxt->device->respond(kbdintctxt->ctxt, |
|
|
break; |
break; |
case 1: |
case 1: |
/* Authentication needs further interaction */ |
/* Authentication needs further interaction */ |
authctxt->postponed = 1; |
if (send_userauth_info_request(authctxt) == 1) |
if (send_userauth_info_request(authctxt) == 0) { |
authctxt->postponed = 1; |
authctxt->postponed = 0; |
|
} |
|
break; |
break; |
default: |
default: |
/* Failure! */ |
/* Failure! */ |
|
|
len = strlen("keyboard-interactive") + 2 + |
len = strlen("keyboard-interactive") + 2 + |
strlen(kbdintctxt->device->name); |
strlen(kbdintctxt->device->name); |
method = xmalloc(len); |
method = xmalloc(len); |
method[0] = '\0'; |
snprintf(method, len, "keyboard-interactive/%s", |
strlcat(method, "keyboard-interactive", len); |
kbdintctxt->device->name); |
strlcat(method, "/", len); |
|
strlcat(method, kbdintctxt->device->name, len); |
|
|
|
if (!authctxt->postponed) { |
if (!authctxt->postponed) { |
/* unregister callback */ |
|
dispatch_set(SSH2_MSG_USERAUTH_INFO_RESPONSE, NULL); |
|
|
|
if (authenticated) { |
if (authenticated) { |
kbdint_free(kbdintctxt); |
auth2_challenge_stop(authctxt); |
authctxt->kbdintctxt = NULL; |
|
} else { |
} else { |
/* start next device */ |
/* start next device */ |
/* may set authctxt->postponed */ |
/* may set authctxt->postponed */ |