*/
#include "includes.h"
-RCSID("$OpenBSD: sshconnect2.c,v 1.130 2003/11/14 13:19:09 markus Exp $");
+RCSID("$OpenBSD: sshconnect2.c,v 1.146 2006/02/20 17:19:54 stevesk Exp $");
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/queue.h>
+#include <sys/stat.h>
#include "openbsd-compat/sys-queue.h"
#include "authfd.h"
#include "log.h"
#include "readconf.h"
-#include "readpass.h"
+#include "misc.h"
#include "match.h"
#include "dispatch.h"
#include "canohost.h"
compat_cipher_proposal(myproposal[PROPOSAL_ENC_ALGS_STOC]);
if (options.compression) {
myproposal[PROPOSAL_COMP_ALGS_CTOS] =
- myproposal[PROPOSAL_COMP_ALGS_STOC] = "zlib,none";
+ myproposal[PROPOSAL_COMP_ALGS_STOC] = "zlib@openssh.com,zlib,none";
} else {
myproposal[PROPOSAL_COMP_ALGS_CTOS] =
- myproposal[PROPOSAL_COMP_ALGS_STOC] = "none,zlib";
+ myproposal[PROPOSAL_COMP_ALGS_STOC] = "none,zlib@openssh.com,zlib";
}
if (options.macs != NULL) {
myproposal[PROPOSAL_MAC_ALGS_CTOS] =
/* start key exchange */
kex = kex_setup(myproposal);
kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client;
+ kex->kex[KEX_DH_GRP14_SHA1] = kexdh_client;
kex->kex[KEX_DH_GEX_SHA1] = kexgex_client;
kex->client_version_string=client_version_string;
kex->server_version_string=server_version_string;
Authmethod authmethods[] = {
#ifdef GSSAPI
- {"gssapi",
+ {"gssapi-with-mic",
userauth_gssapi,
&options.gss_authentication,
NULL},
input_userauth_error(int type, u_int32_t seq, void *ctxt)
{
fatal("input_userauth_error: bad message during authentication: "
- "type %d", type);
+ "type %d", type);
}
void
* moved to the end of the queue. this also avoids confusion by
* duplicate keys
*/
- TAILQ_FOREACH_REVERSE(id, &authctxt->keys, next, idlist) {
+ TAILQ_FOREACH_REVERSE(id, &authctxt->keys, idlist, next) {
if (key_equal(key, id->key)) {
sent = sign_and_send_pubkey(authctxt, id);
break;
}
#ifdef GSSAPI
-int
+int
userauth_gssapi(Authctxt *authctxt)
{
Gssctxt *gssctxt = NULL;
static gss_OID_set gss_supported = NULL;
- static int mech = 0;
+ static u_int mech = 0;
OM_uint32 min;
int ok = 0;
}
}
- if (!ok) return 0;
+ if (!ok)
+ return 0;
authctxt->methoddata=(void *)gssctxt;
Authctxt *authctxt = ctxt;
Gssctxt *gssctxt = authctxt->methoddata;
gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
- OM_uint32 status, ms;
-
+ gss_buffer_desc mic = GSS_C_EMPTY_BUFFER;
+ gss_buffer_desc gssbuf;
+ OM_uint32 status, ms, flags;
+ Buffer b;
+
status = ssh_gssapi_init_ctx(gssctxt, options.gss_deleg_creds,
- recv_tok, &send_tok, NULL);
+ recv_tok, &send_tok, &flags);
if (send_tok.length > 0) {
if (GSS_ERROR(status))
packet_start(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK);
else
packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN);
-
+
packet_put_string(send_tok.value, send_tok.length);
packet_send();
gss_release_buffer(&ms, &send_tok);
}
-
+
if (status == GSS_S_COMPLETE) {
- /* If that succeeded, send a exchange complete message */
- packet_start(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE);
- packet_send();
+ /* send either complete or MIC, depending on mechanism */
+ if (!(flags & GSS_C_INTEG_FLAG)) {
+ packet_start(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE);
+ packet_send();
+ } else {
+ ssh_gssapi_buildmic(&b, authctxt->server_user,
+ authctxt->service, "gssapi-with-mic");
+
+ gssbuf.value = buffer_ptr(&b);
+ gssbuf.length = buffer_len(&b);
+
+ status = ssh_gssapi_sign(gssctxt, &gssbuf, &mic);
+
+ if (!GSS_ERROR(status)) {
+ packet_start(SSH2_MSG_USERAUTH_GSSAPI_MIC);
+ packet_put_string(mic.value, mic.length);
+
+ packet_send();
+ }
+
+ buffer_free(&b);
+ gss_release_buffer(&ms, &mic);
+ }
}
-
+
return status;
}
/* Stick it into GSSAPI and see what it says */
status = ssh_gssapi_init_ctx(gssctxt, options.gss_deleg_creds,
- &recv_tok, &send_tok, NULL);
+ &recv_tok, &send_tok, NULL);
xfree(recv_tok.value);
gss_release_buffer(&ms, &send_tok);
packet_check_eom();
- debug("Server GSSAPI Error:\n%s\n", msg);
+ debug("Server GSSAPI Error:\n%s", msg);
xfree(msg);
xfree(lang);
}
key = ssh_get_next_identity(ac, &comment, 2)) {
found = 0;
TAILQ_FOREACH(id, &files, next) {
- /* agent keys from the config file are preferred */
+ /* agent keys from the config file are preferred */
if (key_equal(key, id->key)) {
key_free(key);
xfree(comment);
break;
}
}
- if (!found) {
+ if (!found && !options.identities_only) {
id = xmalloc(sizeof(*id));
memset(id, 0, sizeof(*id));
id->key = key;
buffer_init(&b);
buffer_put_int(&b, packet_get_connection_in()); /* send # of socket */
buffer_put_string(&b, data, datalen);
- ssh_msg_send(to[1], version, &b);
+ if (ssh_msg_send(to[1], version, &b) == -1)
+ fatal("ssh_keysign: couldn't send request");
if (ssh_msg_recv(from[0], &b) < 0) {
error("ssh_keysign: no reply");
- buffer_clear(&b);
+ buffer_free(&b);
return -1;
}
close(from[0]);
if (buffer_get_char(&b) != version) {
error("ssh_keysign: bad version");
- buffer_clear(&b);
+ buffer_free(&b);
return -1;
}
*sigp = buffer_get_string(&b, lenp);
- buffer_clear(&b);
+ buffer_free(&b);
return 0;
}