openssh-7.4_p1-GSSAPI-dns.patch 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. http://bugs.gentoo.org/165444
  2. https://bugzilla.mindrot.org/show_bug.cgi?id=1008
  3. --- a/readconf.c
  4. +++ b/readconf.c
  5. @@ -148,6 +148,7 @@
  6. oClearAllForwardings, oNoHostAuthenticationForLocalhost,
  7. oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
  8. oAddressFamily, oGssAuthentication, oGssDelegateCreds,
  9. + oGssTrustDns,
  10. oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
  11. oSendEnv, oControlPath, oControlMaster, oControlPersist,
  12. oHashKnownHosts,
  13. @@ -194,9 +195,11 @@
  14. #if defined(GSSAPI)
  15. { "gssapiauthentication", oGssAuthentication },
  16. { "gssapidelegatecredentials", oGssDelegateCreds },
  17. + { "gssapitrustdns", oGssTrustDns },
  18. #else
  19. { "gssapiauthentication", oUnsupported },
  20. { "gssapidelegatecredentials", oUnsupported },
  21. + { "gssapitrustdns", oUnsupported },
  22. #endif
  23. { "fallbacktorsh", oDeprecated },
  24. { "usersh", oDeprecated },
  25. @@ -930,6 +933,10 @@
  26. intptr = &options->gss_deleg_creds;
  27. goto parse_flag;
  28. + case oGssTrustDns:
  29. + intptr = &options->gss_trust_dns;
  30. + goto parse_flag;
  31. +
  32. case oBatchMode:
  33. intptr = &options->batch_mode;
  34. goto parse_flag;
  35. @@ -1649,6 +1656,7 @@
  36. options->challenge_response_authentication = -1;
  37. options->gss_authentication = -1;
  38. options->gss_deleg_creds = -1;
  39. + options->gss_trust_dns = -1;
  40. options->password_authentication = -1;
  41. options->kbd_interactive_authentication = -1;
  42. options->kbd_interactive_devices = NULL;
  43. @@ -1779,6 +1787,8 @@
  44. options->gss_authentication = 0;
  45. if (options->gss_deleg_creds == -1)
  46. options->gss_deleg_creds = 0;
  47. + if (options->gss_trust_dns == -1)
  48. + options->gss_trust_dns = 0;
  49. if (options->password_authentication == -1)
  50. options->password_authentication = 1;
  51. if (options->kbd_interactive_authentication == -1)
  52. --- a/readconf.h
  53. +++ b/readconf.h
  54. @@ -46,6 +46,7 @@
  55. /* Try S/Key or TIS, authentication. */
  56. int gss_authentication; /* Try GSS authentication */
  57. int gss_deleg_creds; /* Delegate GSS credentials */
  58. + int gss_trust_dns; /* Trust DNS for GSS canonicalization */
  59. int password_authentication; /* Try password
  60. * authentication. */
  61. int kbd_interactive_authentication; /* Try keyboard-interactive auth. */
  62. --- a/ssh_config.5
  63. +++ b/ssh_config.5
  64. @@ -830,6 +830,16 @@
  65. Forward (delegate) credentials to the server.
  66. The default is
  67. .Cm no .
  68. +Note that this option applies to protocol version 2 connections using GSSAPI.
  69. +.It Cm GSSAPITrustDns
  70. +Set to
  71. +.Dq yes to indicate that the DNS is trusted to securely canonicalize
  72. +the name of the host being connected to. If
  73. +.Dq no, the hostname entered on the
  74. +command line will be passed untouched to the GSSAPI library.
  75. +The default is
  76. +.Dq no .
  77. +This option only applies to protocol version 2 connections using GSSAPI.
  78. .It Cm HashKnownHosts
  79. Indicates that
  80. .Xr ssh 1
  81. --- a/sshconnect2.c
  82. +++ b/sshconnect2.c
  83. @@ -656,6 +656,13 @@
  84. static u_int mech = 0;
  85. OM_uint32 min;
  86. int ok = 0;
  87. + const char *gss_host;
  88. +
  89. + if (options.gss_trust_dns) {
  90. + extern const char *auth_get_canonical_hostname(struct ssh *ssh, int use_dns);
  91. + gss_host = auth_get_canonical_hostname(active_state, 1);
  92. + } else
  93. + gss_host = authctxt->host;
  94. /* Try one GSSAPI method at a time, rather than sending them all at
  95. * once. */
  96. @@ -668,7 +674,7 @@
  97. /* My DER encoding requires length<128 */
  98. if (gss_supported->elements[mech].length < 128 &&
  99. ssh_gssapi_check_mechanism(&gssctxt,
  100. - &gss_supported->elements[mech], authctxt->host)) {
  101. + &gss_supported->elements[mech], gss_host)) {
  102. ok = 1; /* Mechanism works */
  103. } else {
  104. mech++;
  105. need to move these two funcs back to canohost so they're available to clients
  106. and the server. auth.c is only used in the server.
  107. --- a/auth.c
  108. +++ b/auth.c
  109. @@ -784,117 +784,3 @@ fakepw(void)
  110. return (&fake);
  111. }
  112. -
  113. -/*
  114. - * Returns the remote DNS hostname as a string. The returned string must not
  115. - * be freed. NB. this will usually trigger a DNS query the first time it is
  116. - * called.
  117. - * This function does additional checks on the hostname to mitigate some
  118. - * attacks on legacy rhosts-style authentication.
  119. - * XXX is RhostsRSAAuthentication vulnerable to these?
  120. - * XXX Can we remove these checks? (or if not, remove RhostsRSAAuthentication?)
  121. - */
  122. -
  123. -static char *
  124. -remote_hostname(struct ssh *ssh)
  125. -{
  126. - struct sockaddr_storage from;
  127. - socklen_t fromlen;
  128. - struct addrinfo hints, *ai, *aitop;
  129. - char name[NI_MAXHOST], ntop2[NI_MAXHOST];
  130. - const char *ntop = ssh_remote_ipaddr(ssh);
  131. -
  132. - /* Get IP address of client. */
  133. - fromlen = sizeof(from);
  134. - memset(&from, 0, sizeof(from));
  135. - if (getpeername(ssh_packet_get_connection_in(ssh),
  136. - (struct sockaddr *)&from, &fromlen) < 0) {
  137. - debug("getpeername failed: %.100s", strerror(errno));
  138. - return strdup(ntop);
  139. - }
  140. -
  141. - ipv64_normalise_mapped(&from, &fromlen);
  142. - if (from.ss_family == AF_INET6)
  143. - fromlen = sizeof(struct sockaddr_in6);
  144. -
  145. - debug3("Trying to reverse map address %.100s.", ntop);
  146. - /* Map the IP address to a host name. */
  147. - if (getnameinfo((struct sockaddr *)&from, fromlen, name, sizeof(name),
  148. - NULL, 0, NI_NAMEREQD) != 0) {
  149. - /* Host name not found. Use ip address. */
  150. - return strdup(ntop);
  151. - }
  152. -
  153. - /*
  154. - * if reverse lookup result looks like a numeric hostname,
  155. - * someone is trying to trick us by PTR record like following:
  156. - * 1.1.1.10.in-addr.arpa. IN PTR 2.3.4.5
  157. - */
  158. - memset(&hints, 0, sizeof(hints));
  159. - hints.ai_socktype = SOCK_DGRAM; /*dummy*/
  160. - hints.ai_flags = AI_NUMERICHOST;
  161. - if (getaddrinfo(name, NULL, &hints, &ai) == 0) {
  162. - logit("Nasty PTR record \"%s\" is set up for %s, ignoring",
  163. - name, ntop);
  164. - freeaddrinfo(ai);
  165. - return strdup(ntop);
  166. - }
  167. -
  168. - /* Names are stored in lowercase. */
  169. - lowercase(name);
  170. -
  171. - /*
  172. - * Map it back to an IP address and check that the given
  173. - * address actually is an address of this host. This is
  174. - * necessary because anyone with access to a name server can
  175. - * define arbitrary names for an IP address. Mapping from
  176. - * name to IP address can be trusted better (but can still be
  177. - * fooled if the intruder has access to the name server of
  178. - * the domain).
  179. - */
  180. - memset(&hints, 0, sizeof(hints));
  181. - hints.ai_family = from.ss_family;
  182. - hints.ai_socktype = SOCK_STREAM;
  183. - if (getaddrinfo(name, NULL, &hints, &aitop) != 0) {
  184. - logit("reverse mapping checking getaddrinfo for %.700s "
  185. - "[%s] failed.", name, ntop);
  186. - return strdup(ntop);
  187. - }
  188. - /* Look for the address from the list of addresses. */
  189. - for (ai = aitop; ai; ai = ai->ai_next) {
  190. - if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop2,
  191. - sizeof(ntop2), NULL, 0, NI_NUMERICHOST) == 0 &&
  192. - (strcmp(ntop, ntop2) == 0))
  193. - break;
  194. - }
  195. - freeaddrinfo(aitop);
  196. - /* If we reached the end of the list, the address was not there. */
  197. - if (ai == NULL) {
  198. - /* Address not found for the host name. */
  199. - logit("Address %.100s maps to %.600s, but this does not "
  200. - "map back to the address.", ntop, name);
  201. - return strdup(ntop);
  202. - }
  203. - return strdup(name);
  204. -}
  205. -
  206. -/*
  207. - * Return the canonical name of the host in the other side of the current
  208. - * connection. The host name is cached, so it is efficient to call this
  209. - * several times.
  210. - */
  211. -
  212. -const char *
  213. -auth_get_canonical_hostname(struct ssh *ssh, int use_dns)
  214. -{
  215. - static char *dnsname;
  216. -
  217. - if (!use_dns)
  218. - return ssh_remote_ipaddr(ssh);
  219. - else if (dnsname != NULL)
  220. - return dnsname;
  221. - else {
  222. - dnsname = remote_hostname(ssh);
  223. - return dnsname;
  224. - }
  225. -}
  226. --- a/canohost.c
  227. +++ b/canohost.c
  228. @@ -202,3 +202,117 @@ get_local_port(int sock)
  229. {
  230. return get_sock_port(sock, 1);
  231. }
  232. +
  233. +/*
  234. + * Returns the remote DNS hostname as a string. The returned string must not
  235. + * be freed. NB. this will usually trigger a DNS query the first time it is
  236. + * called.
  237. + * This function does additional checks on the hostname to mitigate some
  238. + * attacks on legacy rhosts-style authentication.
  239. + * XXX is RhostsRSAAuthentication vulnerable to these?
  240. + * XXX Can we remove these checks? (or if not, remove RhostsRSAAuthentication?)
  241. + */
  242. +
  243. +static char *
  244. +remote_hostname(struct ssh *ssh)
  245. +{
  246. + struct sockaddr_storage from;
  247. + socklen_t fromlen;
  248. + struct addrinfo hints, *ai, *aitop;
  249. + char name[NI_MAXHOST], ntop2[NI_MAXHOST];
  250. + const char *ntop = ssh_remote_ipaddr(ssh);
  251. +
  252. + /* Get IP address of client. */
  253. + fromlen = sizeof(from);
  254. + memset(&from, 0, sizeof(from));
  255. + if (getpeername(ssh_packet_get_connection_in(ssh),
  256. + (struct sockaddr *)&from, &fromlen) < 0) {
  257. + debug("getpeername failed: %.100s", strerror(errno));
  258. + return strdup(ntop);
  259. + }
  260. +
  261. + ipv64_normalise_mapped(&from, &fromlen);
  262. + if (from.ss_family == AF_INET6)
  263. + fromlen = sizeof(struct sockaddr_in6);
  264. +
  265. + debug3("Trying to reverse map address %.100s.", ntop);
  266. + /* Map the IP address to a host name. */
  267. + if (getnameinfo((struct sockaddr *)&from, fromlen, name, sizeof(name),
  268. + NULL, 0, NI_NAMEREQD) != 0) {
  269. + /* Host name not found. Use ip address. */
  270. + return strdup(ntop);
  271. + }
  272. +
  273. + /*
  274. + * if reverse lookup result looks like a numeric hostname,
  275. + * someone is trying to trick us by PTR record like following:
  276. + * 1.1.1.10.in-addr.arpa. IN PTR 2.3.4.5
  277. + */
  278. + memset(&hints, 0, sizeof(hints));
  279. + hints.ai_socktype = SOCK_DGRAM; /*dummy*/
  280. + hints.ai_flags = AI_NUMERICHOST;
  281. + if (getaddrinfo(name, NULL, &hints, &ai) == 0) {
  282. + logit("Nasty PTR record \"%s\" is set up for %s, ignoring",
  283. + name, ntop);
  284. + freeaddrinfo(ai);
  285. + return strdup(ntop);
  286. + }
  287. +
  288. + /* Names are stored in lowercase. */
  289. + lowercase(name);
  290. +
  291. + /*
  292. + * Map it back to an IP address and check that the given
  293. + * address actually is an address of this host. This is
  294. + * necessary because anyone with access to a name server can
  295. + * define arbitrary names for an IP address. Mapping from
  296. + * name to IP address can be trusted better (but can still be
  297. + * fooled if the intruder has access to the name server of
  298. + * the domain).
  299. + */
  300. + memset(&hints, 0, sizeof(hints));
  301. + hints.ai_family = from.ss_family;
  302. + hints.ai_socktype = SOCK_STREAM;
  303. + if (getaddrinfo(name, NULL, &hints, &aitop) != 0) {
  304. + logit("reverse mapping checking getaddrinfo for %.700s "
  305. + "[%s] failed.", name, ntop);
  306. + return strdup(ntop);
  307. + }
  308. + /* Look for the address from the list of addresses. */
  309. + for (ai = aitop; ai; ai = ai->ai_next) {
  310. + if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop2,
  311. + sizeof(ntop2), NULL, 0, NI_NUMERICHOST) == 0 &&
  312. + (strcmp(ntop, ntop2) == 0))
  313. + break;
  314. + }
  315. + freeaddrinfo(aitop);
  316. + /* If we reached the end of the list, the address was not there. */
  317. + if (ai == NULL) {
  318. + /* Address not found for the host name. */
  319. + logit("Address %.100s maps to %.600s, but this does not "
  320. + "map back to the address.", ntop, name);
  321. + return strdup(ntop);
  322. + }
  323. + return strdup(name);
  324. +}
  325. +
  326. +/*
  327. + * Return the canonical name of the host in the other side of the current
  328. + * connection. The host name is cached, so it is efficient to call this
  329. + * several times.
  330. + */
  331. +
  332. +const char *
  333. +auth_get_canonical_hostname(struct ssh *ssh, int use_dns)
  334. +{
  335. + static char *dnsname;
  336. +
  337. + if (!use_dns)
  338. + return ssh_remote_ipaddr(ssh);
  339. + else if (dnsname != NULL)
  340. + return dnsname;
  341. + else {
  342. + dnsname = remote_hostname(ssh);
  343. + return dnsname;
  344. + }
  345. +}