#include "log.h"
#include "compat.h"
#include "monitor_wrap.h"
+#include "canohost.h"
#include <netdb.h>
/* All this effort to report an error ... */
static void
-ssh_gssapi_error_ex(OM_uint32 major_status,OM_uint32 minor_status,
+ssh_gssapi_error_ex(gss_OID mech, OM_uint32 major_status,
+ OM_uint32 minor_status,
int send_packet) {
OM_uint32 lmaj, lmin;
gss_buffer_desc msg = {0,NULL};
do {
lmaj = gss_display_status(&lmin, major_status,
GSS_C_GSS_CODE,
- GSS_C_NULL_OID,
+ mech,
&ctx, &msg);
if (lmaj == GSS_S_COMPLETE) {
debug((char *)msg.value);
do {
lmaj = gss_display_status(&lmin, minor_status,
GSS_C_MECH_CODE,
- GSS_C_NULL_OID,
+ mech,
&ctx, &msg);
if (lmaj == GSS_S_COMPLETE) {
debug((char *)msg.value);
}
void
-ssh_gssapi_error(OM_uint32 major_status,OM_uint32 minor_status) {
- ssh_gssapi_error_ex(major_status, minor_status, 0);
+ssh_gssapi_error(gss_OID mech,OM_uint32 major_status,OM_uint32 minor_status) {
+ ssh_gssapi_error_ex(mech, major_status, minor_status, 0);
}
void
-ssh_gssapi_send_error(OM_uint32 major_status,OM_uint32 minor_status) {
- ssh_gssapi_error_ex(major_status, minor_status, 1);
+ssh_gssapi_send_error(gss_OID mech,
+ OM_uint32 major_status,OM_uint32 minor_status) {
+ ssh_gssapi_error_ex(mech, major_status, minor_status, 1);
}
NULL);
ctx->status=maj_status;
if (GSS_ERROR(maj_status)) {
- ssh_gssapi_error(maj_status,min_status);
+ ssh_gssapi_error(ctx->oid,maj_status,min_status);
}
return(maj_status);
}
gss_buffer_desc *send_tok, OM_uint32 *flags)
{
OM_uint32 maj_status, min_status;
- gss_OID mech;
maj_status=gss_accept_sec_context(&min_status,
&ctx->context,
recv_tok,
GSS_C_NO_CHANNEL_BINDINGS,
&ctx->client,
- &mech,
+ &ctx->oid,
send_tok,
flags,
NULL,
&ctx->client_creds);
if (GSS_ERROR(maj_status)) {
- ssh_gssapi_send_error(maj_status,min_status);
+ ssh_gssapi_send_error(ctx->oid,maj_status,min_status);
}
if (ctx->client_creds) {
ssh_gssapi_import_name(Gssctxt *ctx, const char *host) {
gss_buffer_desc gssbuf = {0,NULL};
OM_uint32 maj_status, min_status;
- struct hostent *hostinfo = NULL;
- char *xhost, *addr;
+ char *xhost;
/* Make a copy of the host name, in case it was returned by a
* previous call to gethostbyname(). */
xhost = xstrdup(host);
- /* Make sure we have the FQDN. Some GSSAPI implementations don't do
+ /* If xhost is the loopback interface, switch it to our
+ true local hostname. */
+ resolve_localhost(&xhost);
+
+ /* Make sure we have the FQHN. Some GSSAPI implementations don't do
* this for us themselves */
- hostinfo = gethostbyname(xhost);
-
- /* Use local hostname when coming in on loopback interface because
- we won't have 'localhost' credentials. */
- if (hostinfo &&
- hostinfo->h_addrtype == AF_INET) {
- struct in_addr addr;
- addr = *(struct in_addr *)(hostinfo->h_addr);
- if (ntohl(addr.s_addr) == INADDR_LOOPBACK) {
- char buf[4096];
- if (gethostname(buf, 4096) == 0) {
- hostinfo = gethostbyname(buf);
- }
- }
- }
+ make_fqhn(&xhost);
- /* Go to the resolver to get the official hostname for our target.
- WARNING: This makes us vulnerable to DNS spoofing. */
- if ((hostinfo == NULL) || (hostinfo->h_name == NULL)) {
- debug("Unable to get FQDN for \"%s\"", xhost);
- } else {
- addr = xmalloc(hostinfo->h_length);
- memcpy(addr, hostinfo->h_addr, hostinfo->h_length);
- hostinfo = gethostbyaddr(addr, hostinfo->h_length,
- hostinfo->h_addrtype);
- xfree(addr);
- if ((hostinfo == NULL) || (hostinfo->h_name == NULL)) {
- debug("Unable to get FQDN for \"%s\"", xhost);
- } else {
- xfree(xhost);
- xhost = xstrdup(hostinfo->h_name);
- }
- }
-
gssbuf.length = sizeof("host@")+strlen(xhost);
gssbuf.value = xmalloc(gssbuf.length);
&gssbuf,
GSS_C_NT_HOSTBASED_SERVICE,
&ctx->name))) {
- ssh_gssapi_error(maj_status,min_status);
+ ssh_gssapi_error(ctx->oid, maj_status,min_status);
}
xfree(xhost);
&ctx->creds,
NULL,
NULL))) {
- ssh_gssapi_error(maj_status,min_status);
+ ssh_gssapi_error(GSS_C_NO_OID,maj_status,min_status);
}
gss_release_oid_set(&min_status, &oidset);
*type=ssh_gssapi_get_ctype(ctx);
if ((maj_status=gss_display_name(&min_status,ctx->client,name,NULL))) {
- ssh_gssapi_error(maj_status,min_status);
+ ssh_gssapi_error(GSS_C_NO_OID,maj_status,min_status);
}
/* This is icky. There appears to be no way to copy this structure,
buffer,
NULL,
hash)))
- ssh_gssapi_error(maj_status,min_status);
+ ssh_gssapi_error(ctx->oid,maj_status,min_status);
}
else
if ((maj_status=gss_get_mic(&min_status,ctx->context,
GSS_C_QOP_DEFAULT, buffer, hash))) {
- ssh_gssapi_error(maj_status,min_status);
+ ssh_gssapi_error(ctx->oid,maj_status,min_status);
}
return(maj_status);