version 1.294, 2019/01/19 21:34:45 |
version 1.295, 2019/01/19 21:40:21 |
|
|
#include "ssh-gss.h" |
#include "ssh-gss.h" |
#endif |
#endif |
|
|
#include "opacket.h" /* XXX */ |
|
extern struct ssh *active_state; /* XXX */ |
|
|
|
/* import */ |
/* import */ |
extern char *client_version_string; |
extern char *client_version_string; |
extern char *server_version_string; |
extern char *server_version_string; |
|
|
|
|
struct cauthmethod { |
struct cauthmethod { |
char *name; /* string to compare against server's list */ |
char *name; /* string to compare against server's list */ |
int (*userauth)(Authctxt *authctxt); |
int (*userauth)(struct ssh *ssh); |
void (*cleanup)(Authctxt *authctxt); |
void (*cleanup)(struct ssh *ssh); |
int *enabled; /* flag in option struct that enables method */ |
int *enabled; /* flag in option struct that enables method */ |
int *batch_flag; /* flag in option struct that disables method */ |
int *batch_flag; /* flag in option struct that disables method */ |
}; |
}; |
|
|
int input_userauth_pk_ok(int, u_int32_t, struct ssh *); |
int input_userauth_pk_ok(int, u_int32_t, struct ssh *); |
int input_userauth_passwd_changereq(int, u_int32_t, struct ssh *); |
int input_userauth_passwd_changereq(int, u_int32_t, struct ssh *); |
|
|
int userauth_none(Authctxt *); |
int userauth_none(struct ssh *); |
int userauth_pubkey(Authctxt *); |
int userauth_pubkey(struct ssh *); |
int userauth_passwd(Authctxt *); |
int userauth_passwd(struct ssh *); |
int userauth_kbdint(Authctxt *); |
int userauth_kbdint(struct ssh *); |
int userauth_hostbased(Authctxt *); |
int userauth_hostbased(struct ssh *); |
|
|
#ifdef GSSAPI |
#ifdef GSSAPI |
int userauth_gssapi(Authctxt *authctxt); |
int userauth_gssapi(struct ssh *); |
int input_gssapi_response(int type, u_int32_t, struct ssh *); |
int input_gssapi_response(int type, u_int32_t, struct ssh *); |
int input_gssapi_token(int type, u_int32_t, struct ssh *); |
int input_gssapi_token(int type, u_int32_t, struct ssh *); |
int input_gssapi_hash(int type, u_int32_t, struct ssh *); |
int input_gssapi_hash(int type, u_int32_t, struct ssh *); |
|
|
int input_gssapi_errtok(int, u_int32_t, struct ssh *); |
int input_gssapi_errtok(int, u_int32_t, struct ssh *); |
#endif |
#endif |
|
|
void userauth(Authctxt *, char *); |
void userauth(struct ssh *, char *); |
|
|
static int sign_and_send_pubkey(struct ssh *ssh, Authctxt *, Identity *); |
static int sign_and_send_pubkey(struct ssh *ssh, Identity *); |
static void pubkey_prepare(Authctxt *); |
static void pubkey_prepare(Authctxt *); |
static void pubkey_cleanup(Authctxt *); |
static void pubkey_cleanup(Authctxt *); |
static void pubkey_reset(Authctxt *); |
static void pubkey_reset(Authctxt *); |
|
|
int |
int |
input_userauth_service_accept(int type, u_int32_t seq, struct ssh *ssh) |
input_userauth_service_accept(int type, u_int32_t seq, struct ssh *ssh) |
{ |
{ |
Authctxt *authctxt = ssh->authctxt; |
|
int r; |
int r; |
|
|
if (ssh_packet_remaining(ssh) > 0) { |
if (ssh_packet_remaining(ssh) > 0) { |
|
|
debug("SSH2_MSG_SERVICE_ACCEPT received"); |
debug("SSH2_MSG_SERVICE_ACCEPT received"); |
|
|
/* initial userauth request */ |
/* initial userauth request */ |
userauth_none(authctxt); |
userauth_none(ssh); |
|
|
ssh_dispatch_set(ssh, SSH2_MSG_EXT_INFO, &input_userauth_error); |
ssh_dispatch_set(ssh, SSH2_MSG_EXT_INFO, &input_userauth_error); |
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_SUCCESS, &input_userauth_success); |
ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_SUCCESS, &input_userauth_success); |
|
|
} |
} |
|
|
void |
void |
userauth(Authctxt *authctxt, char *authlist) |
userauth(struct ssh *ssh, char *authlist) |
{ |
{ |
struct ssh *ssh = active_state; /* XXX */ |
Authctxt *authctxt = (Authctxt *)ssh->authctxt; |
|
|
if (authctxt->method != NULL && authctxt->method->cleanup != NULL) |
if (authctxt->method != NULL && authctxt->method->cleanup != NULL) |
authctxt->method->cleanup(authctxt); |
authctxt->method->cleanup(ssh); |
|
|
free(authctxt->methoddata); |
free(authctxt->methoddata); |
authctxt->methoddata = NULL; |
authctxt->methoddata = NULL; |
|
|
SSH2_MSG_USERAUTH_PER_METHOD_MAX, NULL); |
SSH2_MSG_USERAUTH_PER_METHOD_MAX, NULL); |
|
|
/* and try new method */ |
/* and try new method */ |
if (method->userauth(authctxt) != 0) { |
if (method->userauth(ssh) != 0) { |
debug2("we sent a %s packet, wait for reply", method->name); |
debug2("we sent a %s packet, wait for reply", method->name); |
break; |
break; |
} else { |
} else { |
|
|
int |
int |
input_userauth_error(int type, u_int32_t seq, struct ssh *ssh) |
input_userauth_error(int type, u_int32_t seq, struct ssh *ssh) |
{ |
{ |
fatal("input_userauth_error: bad message during authentication: " |
fatal("%s: bad message during authentication: type %d", __func__, type); |
"type %d", type); |
|
return 0; |
return 0; |
} |
} |
|
|
|
|
int |
int |
input_userauth_banner(int type, u_int32_t seq, struct ssh *ssh) |
input_userauth_banner(int type, u_int32_t seq, struct ssh *ssh) |
{ |
{ |
char *msg = NULL, *lang = NULL; |
char *msg = NULL; |
size_t len; |
size_t len; |
int r; |
int r; |
|
|
debug3("%s", __func__); |
debug3("%s", __func__); |
if ((r = sshpkt_get_cstring(ssh, &msg, &len)) != 0 || |
if ((r = sshpkt_get_cstring(ssh, &msg, &len)) != 0 || |
(r = sshpkt_get_cstring(ssh, &lang, NULL)) != 0) |
(r = sshpkt_get_cstring(ssh, NULL, NULL)) != 0) |
goto out; |
goto out; |
if (len > 0 && options.log_level >= SYSLOG_LEVEL_INFO) |
if (len > 0 && options.log_level >= SYSLOG_LEVEL_INFO) |
fmprintf(stderr, "%s", msg); |
fmprintf(stderr, "%s", msg); |
r = 0; |
r = 0; |
out: |
out: |
free(msg); |
free(msg); |
free(lang); |
|
return r; |
return r; |
} |
} |
|
|
|
|
Authctxt *authctxt = ssh->authctxt; |
Authctxt *authctxt = ssh->authctxt; |
|
|
if (authctxt == NULL) |
if (authctxt == NULL) |
fatal("input_userauth_success: no authentication context"); |
fatal("%s: no authentication context", __func__); |
free(authctxt->authlist); |
free(authctxt->authlist); |
authctxt->authlist = NULL; |
authctxt->authlist = NULL; |
if (authctxt->method != NULL && authctxt->method->cleanup != NULL) |
if (authctxt->method != NULL && authctxt->method->cleanup != NULL) |
authctxt->method->cleanup(authctxt); |
authctxt->method->cleanup(ssh); |
free(authctxt->methoddata); |
free(authctxt->methoddata); |
authctxt->methoddata = NULL; |
authctxt->methoddata = NULL; |
authctxt->success = 1; /* break out */ |
authctxt->success = 1; /* break out */ |
|
|
} |
} |
debug("Authentications that can continue: %s", authlist); |
debug("Authentications that can continue: %s", authlist); |
|
|
userauth(authctxt, authlist); |
userauth(ssh, authlist); |
authlist = NULL; |
authlist = NULL; |
out: |
out: |
free(authlist); |
free(authlist); |
|
|
} |
} |
ident = format_identity(id); |
ident = format_identity(id); |
debug("Server accepts key: %s", ident); |
debug("Server accepts key: %s", ident); |
sent = sign_and_send_pubkey(ssh, authctxt, id); |
sent = sign_and_send_pubkey(ssh, id); |
r = 0; |
r = 0; |
done: |
done: |
sshkey_free(key); |
sshkey_free(key); |
|
|
|
|
/* try another method if we did not send a packet */ |
/* try another method if we did not send a packet */ |
if (r == 0 && sent == 0) |
if (r == 0 && sent == 0) |
userauth(authctxt, NULL); |
userauth(ssh, NULL); |
return r; |
return r; |
} |
} |
|
|
#ifdef GSSAPI |
#ifdef GSSAPI |
int |
int |
userauth_gssapi(Authctxt *authctxt) |
userauth_gssapi(struct ssh *ssh) |
{ |
{ |
struct ssh *ssh = active_state; /* XXX */ |
Authctxt *authctxt = (Authctxt *)ssh->authctxt; |
Gssctxt *gssctxt = NULL; |
Gssctxt *gssctxt = NULL; |
static gss_OID_set gss_supported = NULL; |
static gss_OID_set gss_supported = NULL; |
static u_int mech = 0; |
static u_int mech = 0; |
|
|
#endif /* GSSAPI */ |
#endif /* GSSAPI */ |
|
|
int |
int |
userauth_none(Authctxt *authctxt) |
userauth_none(struct ssh *ssh) |
{ |
{ |
struct ssh *ssh = active_state; /* XXX */ |
Authctxt *authctxt = (Authctxt *)ssh->authctxt; |
int r; |
int r; |
|
|
/* initial userauth request */ |
/* initial userauth request */ |
|
|
} |
} |
|
|
int |
int |
userauth_passwd(Authctxt *authctxt) |
userauth_passwd(struct ssh *ssh) |
{ |
{ |
struct ssh *ssh = active_state; /* XXX */ |
Authctxt *authctxt = (Authctxt *)ssh->authctxt; |
char *password, *prompt = NULL; |
char *password, *prompt = NULL; |
const char *host = options.host_key_alias ? options.host_key_alias : |
const char *host = options.host_key_alias ? options.host_key_alias : |
authctxt->host; |
authctxt->host; |
|
|
} |
} |
|
|
static int |
static int |
sign_and_send_pubkey(struct ssh *ssh, Authctxt *authctxt, Identity *id) |
sign_and_send_pubkey(struct ssh *ssh, Identity *id) |
{ |
{ |
|
Authctxt *authctxt = (Authctxt *)ssh->authctxt; |
struct sshbuf *b = NULL; |
struct sshbuf *b = NULL; |
Identity *private_id, *sign_id = NULL; |
Identity *private_id, *sign_id = NULL; |
u_char *signature = NULL; |
u_char *signature = NULL; |
|
|
} |
} |
|
|
static int |
static int |
send_pubkey_test(struct ssh *ssh, Authctxt *authctxt, Identity *id) |
send_pubkey_test(struct ssh *ssh, Identity *id) |
{ |
{ |
|
Authctxt *authctxt = (Authctxt *)ssh->authctxt; |
u_char *blob = NULL; |
u_char *blob = NULL; |
char *alg = NULL; |
char *alg = NULL; |
size_t bloblen; |
size_t bloblen; |
|
|
} |
} |
|
|
int |
int |
userauth_pubkey(Authctxt *authctxt) |
userauth_pubkey(struct ssh *ssh) |
{ |
{ |
struct ssh *ssh = active_state; /* XXX */ |
Authctxt *authctxt = (Authctxt *)ssh->authctxt; |
Identity *id; |
Identity *id; |
int sent = 0; |
int sent = 0; |
char *ident; |
char *ident; |
|
|
ident = format_identity(id); |
ident = format_identity(id); |
debug("Offering public key: %s", ident); |
debug("Offering public key: %s", ident); |
free(ident); |
free(ident); |
sent = send_pubkey_test(ssh, authctxt, id); |
sent = send_pubkey_test(ssh, id); |
} |
} |
} else { |
} else { |
debug("Trying private key: %s", id->filename); |
debug("Trying private key: %s", id->filename); |
|
|
if (id->key != NULL) { |
if (id->key != NULL) { |
if (try_identity(id)) { |
if (try_identity(id)) { |
id->isprivate = 1; |
id->isprivate = 1; |
sent = sign_and_send_pubkey(ssh, |
sent = sign_and_send_pubkey(ssh, id); |
authctxt, id); |
|
} |
} |
sshkey_free(id->key); |
sshkey_free(id->key); |
id->key = NULL; |
id->key = NULL; |
|
|
* Send userauth request message specifying keyboard-interactive method. |
* Send userauth request message specifying keyboard-interactive method. |
*/ |
*/ |
int |
int |
userauth_kbdint(Authctxt *authctxt) |
userauth_kbdint(struct ssh *ssh) |
{ |
{ |
struct ssh *ssh = active_state; /* XXX */ |
Authctxt *authctxt = (Authctxt *)ssh->authctxt; |
int r; |
int r; |
|
|
if (authctxt->attempt_kbdint++ >= options.number_of_password_prompts) |
if (authctxt->attempt_kbdint++ >= options.number_of_password_prompts) |
|
|
struct sshbuf *b; |
struct sshbuf *b; |
struct stat st; |
struct stat st; |
pid_t pid; |
pid_t pid; |
int i, r, to[2], from[2], status, sock = ssh_packet_get_connection_in(ssh); |
int i, r, to[2], from[2], status; |
|
int sock = ssh_packet_get_connection_in(ssh); |
u_char rversion = 0, version = 2; |
u_char rversion = 0, version = 2; |
void (*osigchld)(int); |
void (*osigchld)(int); |
|
|
|
|
} |
} |
|
|
int |
int |
userauth_hostbased(Authctxt *authctxt) |
userauth_hostbased(struct ssh *ssh) |
{ |
{ |
struct ssh *ssh = active_state; /* XXX */ |
Authctxt *authctxt = (Authctxt *)ssh->authctxt; |
struct sshkey *private = NULL; |
struct sshkey *private = NULL; |
struct sshbuf *b = NULL; |
struct sshbuf *b = NULL; |
u_char *sig = NULL, *keyblob = NULL; |
u_char *sig = NULL, *keyblob = NULL; |
|
|
__func__, sshkey_ssh_name(private), fp); |
__func__, sshkey_ssh_name(private), fp); |
|
|
/* figure out a name for the client host */ |
/* figure out a name for the client host */ |
if ((lname = get_local_name(ssh_packet_get_connection_in(ssh))) == NULL) { |
lname = get_local_name(ssh_packet_get_connection_in(ssh)); |
|
if (lname == NULL) { |
error("%s: cannot get local ipaddr/name", __func__); |
error("%s: cannot get local ipaddr/name", __func__); |
goto out; |
goto out; |
} |
} |