version 1.146, 2006/02/20 17:19:54 |
version 1.146.2.1, 2006/09/30 04:06:51 |
|
|
|
/* $OpenBSD$ */ |
/* |
/* |
* Copyright (c) 2000 Markus Friedl. All rights reserved. |
* Copyright (c) 2000 Markus Friedl. All rights reserved. |
* |
* |
|
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
*/ |
|
|
#include "includes.h" |
|
RCSID("$OpenBSD$"); |
|
|
|
#include <sys/types.h> |
#include <sys/types.h> |
|
#include <sys/socket.h> |
#include <sys/wait.h> |
#include <sys/wait.h> |
#include <sys/queue.h> |
#include <sys/queue.h> |
#include <sys/stat.h> |
#include <sys/stat.h> |
|
|
|
#include <errno.h> |
|
#include <stdio.h> |
|
#include <string.h> |
|
#include <signal.h> |
|
#include <pwd.h> |
|
#include <unistd.h> |
|
|
|
#include "xmalloc.h" |
#include "ssh.h" |
#include "ssh.h" |
#include "ssh2.h" |
#include "ssh2.h" |
#include "xmalloc.h" |
|
#include "buffer.h" |
#include "buffer.h" |
#include "packet.h" |
#include "packet.h" |
#include "compat.h" |
#include "compat.h" |
#include "bufaux.h" |
|
#include "cipher.h" |
#include "cipher.h" |
|
#include "key.h" |
#include "kex.h" |
#include "kex.h" |
#include "myproposal.h" |
#include "myproposal.h" |
#include "sshconnect.h" |
#include "sshconnect.h" |
|
|
#include "canohost.h" |
#include "canohost.h" |
#include "msg.h" |
#include "msg.h" |
#include "pathnames.h" |
#include "pathnames.h" |
|
#include "uidswap.h" |
|
|
#ifdef GSSAPI |
#ifdef GSSAPI |
#include "ssh-gss.h" |
#include "ssh-gss.h" |
|
|
kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client; |
kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client; |
kex->kex[KEX_DH_GRP14_SHA1] = kexdh_client; |
kex->kex[KEX_DH_GRP14_SHA1] = kexdh_client; |
kex->kex[KEX_DH_GEX_SHA1] = kexgex_client; |
kex->kex[KEX_DH_GEX_SHA1] = kexgex_client; |
|
kex->kex[KEX_DH_GEX_SHA256] = kexgex_client; |
kex->client_version_string=client_version_string; |
kex->client_version_string=client_version_string; |
kex->server_version_string=server_version_string; |
kex->server_version_string=server_version_string; |
kex->verify_host_key=&verify_host_key_callback; |
kex->verify_host_key=&verify_host_key_callback; |
|
|
debug3("input_userauth_banner"); |
debug3("input_userauth_banner"); |
msg = packet_get_string(NULL); |
msg = packet_get_string(NULL); |
lang = packet_get_string(NULL); |
lang = packet_get_string(NULL); |
if (options.log_level > SYSLOG_LEVEL_QUIET) |
if (options.log_level >= SYSLOG_LEVEL_INFO) |
fprintf(stderr, "%s", msg); |
fprintf(stderr, "%s", msg); |
xfree(msg); |
xfree(msg); |
xfree(lang); |
xfree(lang); |
|
|
|
|
/* Check to see if the mechanism is usable before we offer it */ |
/* Check to see if the mechanism is usable before we offer it */ |
while (mech < gss_supported->count && !ok) { |
while (mech < gss_supported->count && !ok) { |
if (gssctxt) |
|
ssh_gssapi_delete_ctx(&gssctxt); |
|
ssh_gssapi_build_ctx(&gssctxt); |
|
ssh_gssapi_set_oid(gssctxt, &gss_supported->elements[mech]); |
|
|
|
/* My DER encoding requires length<128 */ |
/* My DER encoding requires length<128 */ |
if (gss_supported->elements[mech].length < 128 && |
if (gss_supported->elements[mech].length < 128 && |
!GSS_ERROR(ssh_gssapi_import_name(gssctxt, |
ssh_gssapi_check_mechanism(&gssctxt, |
authctxt->host))) { |
&gss_supported->elements[mech], authctxt->host)) { |
ok = 1; /* Mechanism works */ |
ok = 1; /* Mechanism works */ |
} else { |
} else { |
mech++; |
mech++; |
|
|
* parse PASSWD_CHANGEREQ, prompt user and send SSH2_MSG_USERAUTH_REQUEST |
* parse PASSWD_CHANGEREQ, prompt user and send SSH2_MSG_USERAUTH_REQUEST |
*/ |
*/ |
void |
void |
input_userauth_passwd_changereq(int type, uint32_t seqnr, void *ctxt) |
input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt) |
{ |
{ |
Authctxt *authctxt = ctxt; |
Authctxt *authctxt = ctxt; |
char *info, *lang, *password = NULL, *retype = NULL; |
char *info, *lang, *password = NULL, *retype = NULL; |
|
|
{ |
{ |
Key *private; |
Key *private; |
char prompt[300], *passphrase; |
char prompt[300], *passphrase; |
int quit, i; |
int perm_ok, quit, i; |
struct stat st; |
struct stat st; |
|
|
if (stat(filename, &st) < 0) { |
if (stat(filename, &st) < 0) { |
debug3("no such identity: %s", filename); |
debug3("no such identity: %s", filename); |
return NULL; |
return NULL; |
} |
} |
private = key_load_private_type(KEY_UNSPEC, filename, "", NULL); |
private = key_load_private_type(KEY_UNSPEC, filename, "", NULL, &perm_ok); |
|
if (!perm_ok) |
|
return NULL; |
if (private == NULL) { |
if (private == NULL) { |
if (options.batch_mode) |
if (options.batch_mode) |
return NULL; |
return NULL; |
|
|
for (i = 0; i < options.number_of_password_prompts; i++) { |
for (i = 0; i < options.number_of_password_prompts; i++) { |
passphrase = read_passphrase(prompt, 0); |
passphrase = read_passphrase(prompt, 0); |
if (strcmp(passphrase, "") != 0) { |
if (strcmp(passphrase, "") != 0) { |
private = key_load_private_type(KEY_UNSPEC, filename, |
private = key_load_private_type(KEY_UNSPEC, |
passphrase, NULL); |
filename, passphrase, NULL, NULL); |
quit = 0; |
quit = 0; |
} else { |
} else { |
debug2("no passphrase given, try next key"); |
debug2("no passphrase given, try next key"); |
|
|
if (key && key->type == KEY_RSA1) |
if (key && key->type == KEY_RSA1) |
continue; |
continue; |
options.identity_keys[i] = NULL; |
options.identity_keys[i] = NULL; |
id = xmalloc(sizeof(*id)); |
id = xcalloc(1, sizeof(*id)); |
memset(id, 0, sizeof(*id)); |
|
id->key = key; |
id->key = key; |
id->filename = xstrdup(options.identity_files[i]); |
id->filename = xstrdup(options.identity_files[i]); |
TAILQ_INSERT_TAIL(&files, id, next); |
TAILQ_INSERT_TAIL(&files, id, next); |
|
|
} |
} |
} |
} |
if (!found && !options.identities_only) { |
if (!found && !options.identities_only) { |
id = xmalloc(sizeof(*id)); |
id = xcalloc(1, sizeof(*id)); |
memset(id, 0, sizeof(*id)); |
|
id->key = key; |
id->key = key; |
id->filename = comment; |
id->filename = comment; |
id->ac = ac; |
id->ac = ac; |
|
|
return -1; |
return -1; |
} |
} |
if (pid == 0) { |
if (pid == 0) { |
seteuid(getuid()); |
permanently_drop_suid(getuid()); |
setuid(getuid()); |
|
close(from[0]); |
close(from[0]); |
if (dup2(from[1], STDOUT_FILENO) < 0) |
if (dup2(from[1], STDOUT_FILENO) < 0) |
fatal("ssh_keysign: dup2: %s", strerror(errno)); |
fatal("ssh_keysign: dup2: %s", strerror(errno)); |
|
|
if (p == NULL) { |
if (p == NULL) { |
error("userauth_hostbased: cannot get local ipaddr/name"); |
error("userauth_hostbased: cannot get local ipaddr/name"); |
key_free(private); |
key_free(private); |
|
xfree(blob); |
return 0; |
return 0; |
} |
} |
len = strlen(p) + 2; |
len = strlen(p) + 2; |
chost = xmalloc(len); |
xasprintf(&chost, "%s.", p); |
strlcpy(chost, p, len); |
|
strlcat(chost, ".", len); |
|
debug2("userauth_hostbased: chost %s", chost); |
debug2("userauth_hostbased: chost %s", chost); |
xfree(p); |
xfree(p); |
|
|
|
|
error("key_sign failed"); |
error("key_sign failed"); |
xfree(chost); |
xfree(chost); |
xfree(pkalg); |
xfree(pkalg); |
|
xfree(blob); |
return 0; |
return 0; |
} |
} |
packet_start(SSH2_MSG_USERAUTH_REQUEST); |
packet_start(SSH2_MSG_USERAUTH_REQUEST); |
|
|
xfree(signature); |
xfree(signature); |
xfree(chost); |
xfree(chost); |
xfree(pkalg); |
xfree(pkalg); |
|
xfree(blob); |
|
|
packet_send(); |
packet_send(); |
return 1; |
return 1; |