1d059297112922cabb0c674840589be8db821fd9aAdam Langley/* $OpenBSD: auth2-gss.c,v 1.22 2015/01/19 20:07:45 markus Exp $ */ 2bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 3bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman/* 4bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. 5bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * 6bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * Redistribution and use in source and binary forms, with or without 7bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * modification, are permitted provided that the following conditions 8bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * are met: 9bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * 1. Redistributions of source code must retain the above copyright 10bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * notice, this list of conditions and the following disclaimer. 11bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * 2. Redistributions in binary form must reproduce the above copyright 12bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * notice, this list of conditions and the following disclaimer in the 13bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * documentation and/or other materials provided with the distribution. 14bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * 15bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AS IS'' AND ANY EXPRESS OR 16bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman */ 26bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 27bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "includes.h" 28bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 29bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#ifdef GSSAPI 30bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 31bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <sys/types.h> 32bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 33bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <stdarg.h> 34bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 35bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "xmalloc.h" 36bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "key.h" 37bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "hostfile.h" 38bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "auth.h" 39bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "ssh2.h" 40bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "log.h" 41bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "dispatch.h" 42bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "buffer.h" 43d059297112922cabb0c674840589be8db821fd9aAdam Langley#include "misc.h" 44bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "servconf.h" 45bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "packet.h" 46bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "ssh-gss.h" 47bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "monitor_wrap.h" 48bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 49bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanextern ServerOptions options; 50bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 51d059297112922cabb0c674840589be8db821fd9aAdam Langleystatic int input_gssapi_token(int type, u_int32_t plen, void *ctxt); 52d059297112922cabb0c674840589be8db821fd9aAdam Langleystatic int input_gssapi_mic(int type, u_int32_t plen, void *ctxt); 53d059297112922cabb0c674840589be8db821fd9aAdam Langleystatic int input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt); 54d059297112922cabb0c674840589be8db821fd9aAdam Langleystatic int input_gssapi_errtok(int, u_int32_t, void *); 55bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 56bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman/* 57bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * We only support those mechanisms that we know about (ie ones that we know 58bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * how to check local user kuserok and the like) 59bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman */ 60bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanstatic int 61bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanuserauth_gssapi(Authctxt *authctxt) 62bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 63bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman gss_OID_desc goid = {0, NULL}; 64bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman Gssctxt *ctxt = NULL; 65bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman int mechs; 66bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman int present; 67bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman OM_uint32 ms; 68bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman u_int len; 69bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman u_char *doid = NULL; 70bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 71bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (!authctxt->valid || authctxt->user == NULL) 72bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return (0); 73bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 74bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman mechs = packet_get_int(); 75bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (mechs == 0) { 76bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug("Mechanism negotiation is not supported"); 77bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return (0); 78bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 79bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 80bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman do { 81bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman mechs--; 82bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 83d059297112922cabb0c674840589be8db821fd9aAdam Langley free(doid); 84bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 85bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman present = 0; 86bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman doid = packet_get_string(&len); 87bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 88bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (len > 2 && doid[0] == SSH_GSS_OIDTYPE && 89bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman doid[1] == len - 2) { 90bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman goid.elements = doid + 2; 91bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman goid.length = len - 2; 92d059297112922cabb0c674840589be8db821fd9aAdam Langley ssh_gssapi_test_oid_supported(&ms, &goid, &present); 93bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } else { 94bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman logit("Badly formed OID received"); 95bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 96bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } while (mechs > 0 && !present); 97bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 98bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (!present) { 99d059297112922cabb0c674840589be8db821fd9aAdam Langley free(doid); 100bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman authctxt->server_caused_failure = 1; 101bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return (0); 102bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 103bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 104bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctxt, &goid)))) { 105bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (ctxt != NULL) 106bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman ssh_gssapi_delete_ctx(&ctxt); 107d059297112922cabb0c674840589be8db821fd9aAdam Langley free(doid); 108bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman authctxt->server_caused_failure = 1; 109bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return (0); 110bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 111bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 112bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman authctxt->methoddata = (void *)ctxt; 113bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 114bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_start(SSH2_MSG_USERAUTH_GSSAPI_RESPONSE); 115bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 116bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* Return the OID that we received */ 117bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_put_string(doid, len); 118bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 119bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_send(); 120d059297112922cabb0c674840589be8db821fd9aAdam Langley free(doid); 121bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 122bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, &input_gssapi_token); 123bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, &input_gssapi_errtok); 124bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman authctxt->postponed = 1; 125bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 126bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return (0); 127bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 128bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 129d059297112922cabb0c674840589be8db821fd9aAdam Langleystatic int 130bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmaninput_gssapi_token(int type, u_int32_t plen, void *ctxt) 131bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 132bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman Authctxt *authctxt = ctxt; 133bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman Gssctxt *gssctxt; 134bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; 135bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman gss_buffer_desc recv_tok; 136bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman OM_uint32 maj_status, min_status, flags; 137bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman u_int len; 138bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 139bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep)) 140bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman fatal("No authentication or GSSAPI context"); 141bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 142bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman gssctxt = authctxt->methoddata; 143bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman recv_tok.value = packet_get_string(&len); 144bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman recv_tok.length = len; /* u_int vs. size_t */ 145bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 146bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_check_eom(); 147bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 148bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman maj_status = PRIVSEP(ssh_gssapi_accept_ctx(gssctxt, &recv_tok, 149bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman &send_tok, &flags)); 150bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 151d059297112922cabb0c674840589be8db821fd9aAdam Langley free(recv_tok.value); 152bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 153bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (GSS_ERROR(maj_status)) { 154bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (send_tok.length != 0) { 155bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_start(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK); 156bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_put_string(send_tok.value, send_tok.length); 157bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_send(); 158bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 159bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman authctxt->postponed = 0; 160bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); 161d059297112922cabb0c674840589be8db821fd9aAdam Langley userauth_finish(authctxt, 0, "gssapi-with-mic", NULL); 162bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } else { 163bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (send_tok.length != 0) { 164bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN); 165bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_put_string(send_tok.value, send_tok.length); 166bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_send(); 167bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 168bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (maj_status == GSS_S_COMPLETE) { 169bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); 170bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (flags & GSS_C_INTEG_FLAG) 171bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_MIC, 172bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman &input_gssapi_mic); 173bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman else 174bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman dispatch_set( 175bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, 176bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman &input_gssapi_exchange_complete); 177bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 178bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 179bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 180bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman gss_release_buffer(&min_status, &send_tok); 181d059297112922cabb0c674840589be8db821fd9aAdam Langley return 0; 182bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 183bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 184d059297112922cabb0c674840589be8db821fd9aAdam Langleystatic int 185bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmaninput_gssapi_errtok(int type, u_int32_t plen, void *ctxt) 186bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 187bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman Authctxt *authctxt = ctxt; 188bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman Gssctxt *gssctxt; 189bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; 190bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman gss_buffer_desc recv_tok; 191bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman OM_uint32 maj_status; 192bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman u_int len; 193bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 194bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep)) 195bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman fatal("No authentication or GSSAPI context"); 196bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 197bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman gssctxt = authctxt->methoddata; 198bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman recv_tok.value = packet_get_string(&len); 199bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman recv_tok.length = len; 200bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 201bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_check_eom(); 202bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 203bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* Push the error token into GSSAPI to see what it says */ 204bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman maj_status = PRIVSEP(ssh_gssapi_accept_ctx(gssctxt, &recv_tok, 205bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman &send_tok, NULL)); 206bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 207d059297112922cabb0c674840589be8db821fd9aAdam Langley free(recv_tok.value); 208bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 209bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* We can't return anything to the client, even if we wanted to */ 210bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); 211bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL); 212bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 213bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* The client will have already moved on to the next auth */ 214bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 215bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman gss_release_buffer(&maj_status, &send_tok); 216d059297112922cabb0c674840589be8db821fd9aAdam Langley return 0; 217bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 218bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 219bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman/* 220bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * This is called when the client thinks we've completed authentication. 221bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * It should only be enabled in the dispatch handler by the function above, 222bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * which only enables it once the GSSAPI exchange is complete. 223bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman */ 224bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 225d059297112922cabb0c674840589be8db821fd9aAdam Langleystatic int 226bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmaninput_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt) 227bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 228bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman Authctxt *authctxt = ctxt; 229bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman int authenticated; 230bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 231bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep)) 232bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman fatal("No authentication or GSSAPI context"); 233bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 234bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* 235bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * We don't need to check the status, because we're only enabled in 236bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * the dispatcher once the exchange is complete 237bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman */ 238bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 239bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman packet_check_eom(); 240bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 241bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user)); 242bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 243bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman authctxt->postponed = 0; 244bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); 245bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL); 246bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_MIC, NULL); 247bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL); 248d059297112922cabb0c674840589be8db821fd9aAdam Langley userauth_finish(authctxt, authenticated, "gssapi-with-mic", NULL); 249d059297112922cabb0c674840589be8db821fd9aAdam Langley return 0; 250bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 251bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 252d059297112922cabb0c674840589be8db821fd9aAdam Langleystatic int 253bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmaninput_gssapi_mic(int type, u_int32_t plen, void *ctxt) 254bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 255bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman Authctxt *authctxt = ctxt; 256bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman Gssctxt *gssctxt; 257bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman int authenticated = 0; 258bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman Buffer b; 259bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman gss_buffer_desc mic, gssbuf; 260bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman u_int len; 261bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 262bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep)) 263bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman fatal("No authentication or GSSAPI context"); 264bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 265bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman gssctxt = authctxt->methoddata; 266bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 267bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman mic.value = packet_get_string(&len); 268bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman mic.length = len; 269bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 270bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman ssh_gssapi_buildmic(&b, authctxt->user, authctxt->service, 271bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman "gssapi-with-mic"); 272bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 273bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman gssbuf.value = buffer_ptr(&b); 274bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman gssbuf.length = buffer_len(&b); 275bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 276bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gssctxt, &gssbuf, &mic)))) 277bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user)); 278bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman else 279bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman logit("GSSAPI MIC check failed"); 280bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 281bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman buffer_free(&b); 282d059297112922cabb0c674840589be8db821fd9aAdam Langley free(mic.value); 283bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 284bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman authctxt->postponed = 0; 285bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); 286bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL); 287bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_MIC, NULL); 288bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL); 289d059297112922cabb0c674840589be8db821fd9aAdam Langley userauth_finish(authctxt, authenticated, "gssapi-with-mic", NULL); 290d059297112922cabb0c674840589be8db821fd9aAdam Langley return 0; 291bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 292bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 293bd77cf78387b72b7b3ea870459077672bf75c3b5Greg HartmanAuthmethod method_gssapi = { 294bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman "gssapi-with-mic", 295bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman userauth_gssapi, 296bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman &options.gss_authentication 297bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman}; 298bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 299bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#endif /* GSSAPI */ 300