version 1.4, 2005/07/17 07:17:55 |
version 1.4.2.2, 2006/10/06 03:19:32 |
|
|
/* $OpenBSD$ */ |
/* $OpenBSD$ */ |
|
|
/* |
/* |
* Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. |
* Copyright (c) 2001-2006 Simon Wilkinson. All rights reserved. |
* |
* |
* Redistribution and use in source and binary forms, with or without |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* modification, are permitted provided that the following conditions |
|
|
* 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" |
|
|
|
#ifdef GSSAPI |
#ifdef GSSAPI |
|
|
|
#include <sys/param.h> |
|
|
|
#include <string.h> |
|
#include <stdarg.h> |
|
|
#include "xmalloc.h" |
#include "xmalloc.h" |
#include "bufaux.h" |
#include "buffer.h" |
#include "compat.h" |
|
#include "log.h" |
#include "log.h" |
#include "monitor_wrap.h" |
|
#include "ssh2.h" |
#include "ssh2.h" |
|
|
#include "ssh-gss.h" |
#include "ssh-gss.h" |
|
|
void |
void |
ssh_gssapi_error(Gssctxt *ctxt) |
ssh_gssapi_error(Gssctxt *ctxt) |
{ |
{ |
debug("%s", ssh_gssapi_last_error(ctxt, NULL, NULL)); |
char *s; |
|
|
|
s = ssh_gssapi_last_error(ctxt, NULL, NULL); |
|
debug("%s", s); |
|
xfree(s); |
} |
} |
|
|
char * |
char * |
|
|
void |
void |
ssh_gssapi_build_ctx(Gssctxt **ctx) |
ssh_gssapi_build_ctx(Gssctxt **ctx) |
{ |
{ |
*ctx = xmalloc(sizeof (Gssctxt)); |
*ctx = xcalloc(1, sizeof (Gssctxt)); |
(*ctx)->major = 0; |
|
(*ctx)->minor = 0; |
|
(*ctx)->context = GSS_C_NO_CONTEXT; |
(*ctx)->context = GSS_C_NO_CONTEXT; |
(*ctx)->name = GSS_C_NO_NAME; |
(*ctx)->name = GSS_C_NO_NAME; |
(*ctx)->oid = GSS_C_NO_OID; |
(*ctx)->oid = GSS_C_NO_OID; |
|
|
ssh_gssapi_import_name(Gssctxt *ctx, const char *host) |
ssh_gssapi_import_name(Gssctxt *ctx, const char *host) |
{ |
{ |
gss_buffer_desc gssbuf; |
gss_buffer_desc gssbuf; |
|
char *val; |
|
|
gssbuf.length = sizeof("host@") + strlen(host); |
xasprintf(&val, "host@%s", host); |
gssbuf.value = xmalloc(gssbuf.length); |
gssbuf.value = val; |
snprintf(gssbuf.value, gssbuf.length, "host@%s", host); |
gssbuf.length = strlen(gssbuf.value); |
|
|
if ((ctx->major = gss_import_name(&ctx->minor, |
if ((ctx->major = gss_import_name(&ctx->minor, |
&gssbuf, GSS_C_NT_HOSTBASED_SERVICE, &ctx->name))) |
&gssbuf, GSS_C_NT_HOSTBASED_SERVICE, &ctx->name))) |
|
|
gss_create_empty_oid_set(&status, &oidset); |
gss_create_empty_oid_set(&status, &oidset); |
gss_add_oid_set_member(&status, ctx->oid, &oidset); |
gss_add_oid_set_member(&status, ctx->oid, &oidset); |
|
|
if (gethostname(lname, MAXHOSTNAMELEN)) |
if (gethostname(lname, MAXHOSTNAMELEN)) { |
|
gss_release_oid_set(&status, &oidset); |
return (-1); |
return (-1); |
|
} |
|
|
if (GSS_ERROR(ssh_gssapi_import_name(ctx, lname))) |
if (GSS_ERROR(ssh_gssapi_import_name(ctx, lname))) { |
|
gss_release_oid_set(&status, &oidset); |
return (ctx->major); |
return (ctx->major); |
|
} |
|
|
if ((ctx->major = gss_acquire_cred(&ctx->minor, |
if ((ctx->major = gss_acquire_cred(&ctx->minor, |
ctx->name, 0, oidset, GSS_C_ACCEPT, &ctx->creds, NULL, NULL))) |
ctx->name, 0, oidset, GSS_C_ACCEPT, &ctx->creds, NULL, NULL))) |
|
|
} |
} |
|
|
OM_uint32 |
OM_uint32 |
ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID oid) { |
ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID oid) |
|
{ |
if (*ctx) |
if (*ctx) |
ssh_gssapi_delete_ctx(ctx); |
ssh_gssapi_delete_ctx(ctx); |
ssh_gssapi_build_ctx(ctx); |
ssh_gssapi_build_ctx(ctx); |
ssh_gssapi_set_oid(*ctx, oid); |
ssh_gssapi_set_oid(*ctx, oid); |
return (ssh_gssapi_acquire_cred(*ctx)); |
return (ssh_gssapi_acquire_cred(*ctx)); |
|
} |
|
|
|
int |
|
ssh_gssapi_check_mechanism(Gssctxt **ctx, gss_OID oid, const char *host) |
|
{ |
|
gss_buffer_desc token = GSS_C_EMPTY_BUFFER; |
|
OM_uint32 major, minor; |
|
gss_OID_desc spnego_oid = {6, (void *)"\x2B\x06\x01\x05\x05\x02"}; |
|
|
|
/* RFC 4462 says we MUST NOT do SPNEGO */ |
|
if (oid->length == spnego_oid.length && |
|
(memcmp(oid->elements, spnego_oid.elements, oid->length) == 0)) |
|
return 0; /* false */ |
|
|
|
ssh_gssapi_build_ctx(ctx); |
|
ssh_gssapi_set_oid(*ctx, oid); |
|
major = ssh_gssapi_import_name(*ctx, host); |
|
if (!GSS_ERROR(major)) { |
|
major = ssh_gssapi_init_ctx(*ctx, 0, GSS_C_NO_BUFFER, &token, |
|
NULL); |
|
gss_release_buffer(&minor, &token); |
|
if ((*ctx)->context != GSS_C_NO_CONTEXT) |
|
gss_delete_sec_context(&minor, &(*ctx)->context, |
|
GSS_C_NO_BUFFER); |
|
} |
|
|
|
if (GSS_ERROR(major)) |
|
ssh_gssapi_delete_ctx(ctx); |
|
|
|
return (!GSS_ERROR(major)); |
} |
} |
|
|
#endif /* GSSAPI */ |
#endif /* GSSAPI */ |