summaryrefslogtreecommitdiff
path: root/sshconnect2.c
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2009-12-29 21:38:40 +0000
committerColin Watson <cjwatson@debian.org>2009-12-29 21:38:40 +0000
commit1b816ea846aca3ee89e7995373ace609e9518424 (patch)
treeb41cdc8495cae7fa9c2e0f98a5f2e71656b61f9a /sshconnect2.c
parentfa585019a79ebcb4e0202b1c33f87ff1c5c9ce1c (diff)
parent086ea76990b1e6287c24b6db74adffd4605eb3b0 (diff)
import openssh-4.6p1-gsskex-20070312.patch
Diffstat (limited to 'sshconnect2.c')
-rw-r--r--sshconnect2.c111
1 files changed, 63 insertions, 48 deletions
diff --git a/sshconnect2.c b/sshconnect2.c
index 1a69c6b2b..5190b07e5 100644
--- a/sshconnect2.c
+++ b/sshconnect2.c
@@ -1,3 +1,4 @@
1/* $OpenBSD: sshconnect2.c,v 1.162 2006/08/30 00:06:51 dtucker Exp $ */
1/* 2/*
2 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
3 * 4 *
@@ -23,18 +24,30 @@
23 */ 24 */
24 25
25#include "includes.h" 26#include "includes.h"
26RCSID("$OpenBSD: sshconnect2.c,v 1.143 2005/10/14 02:17:59 stevesk Exp $"); 27
28#include <sys/types.h>
29#include <sys/socket.h>
30#include <sys/wait.h>
31#include <sys/stat.h>
32
33#include <errno.h>
34#include <pwd.h>
35#include <signal.h>
36#include <stdarg.h>
37#include <stdio.h>
38#include <string.h>
39#include <unistd.h>
27 40
28#include "openbsd-compat/sys-queue.h" 41#include "openbsd-compat/sys-queue.h"
29 42
43#include "xmalloc.h"
30#include "ssh.h" 44#include "ssh.h"
31#include "ssh2.h" 45#include "ssh2.h"
32#include "xmalloc.h"
33#include "buffer.h" 46#include "buffer.h"
34#include "packet.h" 47#include "packet.h"
35#include "compat.h" 48#include "compat.h"
36#include "bufaux.h"
37#include "cipher.h" 49#include "cipher.h"
50#include "key.h"
38#include "kex.h" 51#include "kex.h"
39#include "myproposal.h" 52#include "myproposal.h"
40#include "sshconnect.h" 53#include "sshconnect.h"
@@ -49,6 +62,7 @@ RCSID("$OpenBSD: sshconnect2.c,v 1.143 2005/10/14 02:17:59 stevesk Exp $");
49#include "canohost.h" 62#include "canohost.h"
50#include "msg.h" 63#include "msg.h"
51#include "pathnames.h" 64#include "pathnames.h"
65#include "uidswap.h"
52 66
53#ifdef GSSAPI 67#ifdef GSSAPI
54#include "ssh-gss.h" 68#include "ssh-gss.h"
@@ -85,30 +99,30 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
85 Kex *kex; 99 Kex *kex;
86 100
87#ifdef GSSAPI 101#ifdef GSSAPI
88 char *orig, *gss; 102 char *orig = NULL, *gss = NULL;
89 int len; 103 char *gss_host = NULL;
90 char *gss_host;
91#endif 104#endif
92 105
93 xxx_host = host; 106 xxx_host = host;
94 xxx_hostaddr = hostaddr; 107 xxx_hostaddr = hostaddr;
95 108
96#ifdef GSSAPI 109#ifdef GSSAPI
97 /* Add the GSSAPI mechanisms currently supported on this client to 110 if (options.gss_keyex) {
98 * the key exchange algorithm proposal */ 111 /* Add the GSSAPI mechanisms currently supported on this
99 orig = myproposal[PROPOSAL_KEX_ALGS]; 112 * client to the key exchange algorithm proposal */
100 if (options.gss_trust_dns) 113 orig = myproposal[PROPOSAL_KEX_ALGS];
101 gss_host = (char *)get_canonical_hostname(1); 114
102 else 115 if (options.gss_trust_dns)
103 gss_host = host; 116 gss_host = (char *)get_canonical_hostname(1);
104 117 else
105 gss = ssh_gssapi_client_mechanisms(gss_host); 118 gss_host = host;
106 if (gss) { 119
107 debug("Offering GSSAPI proposal: %s", gss); 120 gss = ssh_gssapi_client_mechanisms(gss_host);
108 len = strlen(orig) + strlen(gss) + 2; 121 if (gss) {
109 myproposal[PROPOSAL_KEX_ALGS] = xmalloc(len); 122 debug("Offering GSSAPI proposal: %s", gss);
110 snprintf(myproposal[PROPOSAL_KEX_ALGS], len, "%s,%s", gss, 123 xasprintf(&myproposal[PROPOSAL_KEX_ALGS],
111 orig); 124 "%s,%s", gss, orig);
125 }
112 } 126 }
113#endif 127#endif
114 128
@@ -142,11 +156,9 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
142#ifdef GSSAPI 156#ifdef GSSAPI
143 /* If we've got GSSAPI algorithms, then we also support the 157 /* If we've got GSSAPI algorithms, then we also support the
144 * 'null' hostkey, as a last resort */ 158 * 'null' hostkey, as a last resort */
145 if (gss) { 159 if (options.gss_keyex && gss) {
146 orig = myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]; 160 orig = myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS];
147 len = strlen(orig) + sizeof(",null"); 161 xasprintf(&myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS],
148 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = xmalloc(len);
149 snprintf(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS], len,
150 "%s,null", orig); 162 "%s,null", orig);
151 } 163 }
152#endif 164#endif
@@ -159,8 +171,10 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
159 kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client; 171 kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client;
160 kex->kex[KEX_DH_GRP14_SHA1] = kexdh_client; 172 kex->kex[KEX_DH_GRP14_SHA1] = kexdh_client;
161 kex->kex[KEX_DH_GEX_SHA1] = kexgex_client; 173 kex->kex[KEX_DH_GEX_SHA1] = kexgex_client;
174 kex->kex[KEX_DH_GEX_SHA256] = kexgex_client;
162#ifdef GSSAPI 175#ifdef GSSAPI
163 kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_client; 176 kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_client;
177 kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_client;
164 kex->kex[KEX_GSS_GEX_SHA1] = kexgss_client; 178 kex->kex[KEX_GSS_GEX_SHA1] = kexgss_client;
165#endif 179#endif
166 kex->client_version_string=client_version_string; 180 kex->client_version_string=client_version_string;
@@ -415,7 +429,7 @@ input_userauth_banner(int type, u_int32_t seq, void *ctxt)
415 debug3("input_userauth_banner"); 429 debug3("input_userauth_banner");
416 msg = packet_get_string(NULL); 430 msg = packet_get_string(NULL);
417 lang = packet_get_string(NULL); 431 lang = packet_get_string(NULL);
418 if (options.log_level > SYSLOG_LEVEL_QUIET) 432 if (options.log_level >= SYSLOG_LEVEL_INFO)
419 fprintf(stderr, "%s", msg); 433 fprintf(stderr, "%s", msg);
420 xfree(msg); 434 xfree(msg);
421 xfree(lang); 435 xfree(lang);
@@ -537,6 +551,12 @@ userauth_gssapi(Authctxt *authctxt)
537 static u_int mech = 0; 551 static u_int mech = 0;
538 OM_uint32 min; 552 OM_uint32 min;
539 int ok = 0; 553 int ok = 0;
554 char *gss_host = NULL;
555
556 if (options.gss_trust_dns)
557 gss_host = (char *)get_canonical_hostname(1);
558 else
559 gss_host = (char *)authctxt->host;
540 560
541 /* Try one GSSAPI method at a time, rather than sending them all at 561 /* Try one GSSAPI method at a time, rather than sending them all at
542 * once. */ 562 * once. */
@@ -546,15 +566,10 @@ userauth_gssapi(Authctxt *authctxt)
546 566
547 /* Check to see if the mechanism is usable before we offer it */ 567 /* Check to see if the mechanism is usable before we offer it */
548 while (mech < gss_supported->count && !ok) { 568 while (mech < gss_supported->count && !ok) {
549 if (gssctxt)
550 ssh_gssapi_delete_ctx(&gssctxt);
551 ssh_gssapi_build_ctx(&gssctxt);
552 ssh_gssapi_set_oid(gssctxt, &gss_supported->elements[mech]);
553
554 /* My DER encoding requires length<128 */ 569 /* My DER encoding requires length<128 */
555 if (gss_supported->elements[mech].length < 128 && 570 if (gss_supported->elements[mech].length < 128 &&
556 !GSS_ERROR(ssh_gssapi_import_name(gssctxt, 571 ssh_gssapi_check_mechanism(&gssctxt,
557 authctxt->host))) { 572 &gss_supported->elements[mech], gss_host)) {
558 ok = 1; /* Mechanism works */ 573 ok = 1; /* Mechanism works */
559 } else { 574 } else {
560 mech++; 575 mech++;
@@ -650,8 +665,8 @@ input_gssapi_response(int type, u_int32_t plen, void *ctxt)
650{ 665{
651 Authctxt *authctxt = ctxt; 666 Authctxt *authctxt = ctxt;
652 Gssctxt *gssctxt; 667 Gssctxt *gssctxt;
653 int oidlen; 668 u_int oidlen;
654 char *oidv; 669 u_char *oidv;
655 670
656 if (authctxt == NULL) 671 if (authctxt == NULL)
657 fatal("input_gssapi_response: no authentication context"); 672 fatal("input_gssapi_response: no authentication context");
@@ -1057,14 +1072,16 @@ load_identity_file(char *filename)
1057{ 1072{
1058 Key *private; 1073 Key *private;
1059 char prompt[300], *passphrase; 1074 char prompt[300], *passphrase;
1060 int quit, i; 1075 int perm_ok, quit, i;
1061 struct stat st; 1076 struct stat st;
1062 1077
1063 if (stat(filename, &st) < 0) { 1078 if (stat(filename, &st) < 0) {
1064 debug3("no such identity: %s", filename); 1079 debug3("no such identity: %s", filename);
1065 return NULL; 1080 return NULL;
1066 } 1081 }
1067 private = key_load_private_type(KEY_UNSPEC, filename, "", NULL); 1082 private = key_load_private_type(KEY_UNSPEC, filename, "", NULL, &perm_ok);
1083 if (!perm_ok)
1084 return NULL;
1068 if (private == NULL) { 1085 if (private == NULL) {
1069 if (options.batch_mode) 1086 if (options.batch_mode)
1070 return NULL; 1087 return NULL;
@@ -1073,8 +1090,8 @@ load_identity_file(char *filename)
1073 for (i = 0; i < options.number_of_password_prompts; i++) { 1090 for (i = 0; i < options.number_of_password_prompts; i++) {
1074 passphrase = read_passphrase(prompt, 0); 1091 passphrase = read_passphrase(prompt, 0);
1075 if (strcmp(passphrase, "") != 0) { 1092 if (strcmp(passphrase, "") != 0) {
1076 private = key_load_private_type(KEY_UNSPEC, filename, 1093 private = key_load_private_type(KEY_UNSPEC,
1077 passphrase, NULL); 1094 filename, passphrase, NULL, NULL);
1078 quit = 0; 1095 quit = 0;
1079 } else { 1096 } else {
1080 debug2("no passphrase given, try next key"); 1097 debug2("no passphrase given, try next key");
@@ -1117,8 +1134,7 @@ pubkey_prepare(Authctxt *authctxt)
1117 if (key && key->type == KEY_RSA1) 1134 if (key && key->type == KEY_RSA1)
1118 continue; 1135 continue;
1119 options.identity_keys[i] = NULL; 1136 options.identity_keys[i] = NULL;
1120 id = xmalloc(sizeof(*id)); 1137 id = xcalloc(1, sizeof(*id));
1121 memset(id, 0, sizeof(*id));
1122 id->key = key; 1138 id->key = key;
1123 id->filename = xstrdup(options.identity_files[i]); 1139 id->filename = xstrdup(options.identity_files[i]);
1124 TAILQ_INSERT_TAIL(&files, id, next); 1140 TAILQ_INSERT_TAIL(&files, id, next);
@@ -1142,8 +1158,7 @@ pubkey_prepare(Authctxt *authctxt)
1142 } 1158 }
1143 } 1159 }
1144 if (!found && !options.identities_only) { 1160 if (!found && !options.identities_only) {
1145 id = xmalloc(sizeof(*id)); 1161 id = xcalloc(1, sizeof(*id));
1146 memset(id, 0, sizeof(*id));
1147 id->key = key; 1162 id->key = key;
1148 id->filename = comment; 1163 id->filename = comment;
1149 id->ac = ac; 1164 id->ac = ac;
@@ -1339,8 +1354,7 @@ ssh_keysign(Key *key, u_char **sigp, u_int *lenp,
1339 return -1; 1354 return -1;
1340 } 1355 }
1341 if (pid == 0) { 1356 if (pid == 0) {
1342 seteuid(getuid()); 1357 permanently_drop_suid(getuid());
1343 setuid(getuid());
1344 close(from[0]); 1358 close(from[0]);
1345 if (dup2(from[1], STDOUT_FILENO) < 0) 1359 if (dup2(from[1], STDOUT_FILENO) < 0)
1346 fatal("ssh_keysign: dup2: %s", strerror(errno)); 1360 fatal("ssh_keysign: dup2: %s", strerror(errno));
@@ -1420,12 +1434,11 @@ userauth_hostbased(Authctxt *authctxt)
1420 if (p == NULL) { 1434 if (p == NULL) {
1421 error("userauth_hostbased: cannot get local ipaddr/name"); 1435 error("userauth_hostbased: cannot get local ipaddr/name");
1422 key_free(private); 1436 key_free(private);
1437 xfree(blob);
1423 return 0; 1438 return 0;
1424 } 1439 }
1425 len = strlen(p) + 2; 1440 len = strlen(p) + 2;
1426 chost = xmalloc(len); 1441 xasprintf(&chost, "%s.", p);
1427 strlcpy(chost, p, len);
1428 strlcat(chost, ".", len);
1429 debug2("userauth_hostbased: chost %s", chost); 1442 debug2("userauth_hostbased: chost %s", chost);
1430 xfree(p); 1443 xfree(p);
1431 1444
@@ -1458,6 +1471,7 @@ userauth_hostbased(Authctxt *authctxt)
1458 error("key_sign failed"); 1471 error("key_sign failed");
1459 xfree(chost); 1472 xfree(chost);
1460 xfree(pkalg); 1473 xfree(pkalg);
1474 xfree(blob);
1461 return 0; 1475 return 0;
1462 } 1476 }
1463 packet_start(SSH2_MSG_USERAUTH_REQUEST); 1477 packet_start(SSH2_MSG_USERAUTH_REQUEST);
@@ -1473,6 +1487,7 @@ userauth_hostbased(Authctxt *authctxt)
1473 xfree(signature); 1487 xfree(signature);
1474 xfree(chost); 1488 xfree(chost);
1475 xfree(pkalg); 1489 xfree(pkalg);
1490 xfree(blob);
1476 1491
1477 packet_send(); 1492 packet_send();
1478 return 1; 1493 return 1;