1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/http/http_auth_gssapi_posix.h" 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <limits> 8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <string> 9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/base64.h" 11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/file_path.h" 12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/format_macros.h" 13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/logging.h" 14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/string_util.h" 153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/stringprintf.h" 163f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/threading/thread_restrictions.h" 17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/net_errors.h" 18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/net_util.h" 19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// These are defined for the GSSAPI library: 21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Paraphrasing the comments from gssapi.h: 22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// "The implementation must reserve static storage for a 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// gss_OID_desc object for each constant. That constant 24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// should be initialized to point to that gss_OID_desc." 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace { 26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic gss_OID_desc GSS_C_NT_USER_NAME_VAL = { 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 10, 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const_cast<char*>("\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x01") 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic gss_OID_desc GSS_C_NT_MACHINE_UID_NAME_VAL = { 32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 10, 33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const_cast<char*>("\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x02") 34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic gss_OID_desc GSS_C_NT_STRING_UID_NAME_VAL = { 36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 10, 37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const_cast<char*>("\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x03") 38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic gss_OID_desc GSS_C_NT_HOSTBASED_SERVICE_X_VAL = { 40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6, 41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const_cast<char*>("\x2b\x06\x01\x05\x06\x02") 42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic gss_OID_desc GSS_C_NT_HOSTBASED_SERVICE_VAL = { 44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 10, 45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const_cast<char*>("\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x04") 46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic gss_OID_desc GSS_C_NT_ANONYMOUS_VAL = { 48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6, 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const_cast<char*>("\x2b\x06\01\x05\x06\x03") 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic gss_OID_desc GSS_C_NT_EXPORT_NAME_VAL = { 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6, 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const_cast<char*>("\x2b\x06\x01\x05\x06\x04") 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgss_OID GSS_C_NT_USER_NAME = &GSS_C_NT_USER_NAME_VAL; 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgss_OID GSS_C_NT_MACHINE_UID_NAME = &GSS_C_NT_MACHINE_UID_NAME_VAL; 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgss_OID GSS_C_NT_STRING_UID_NAME = &GSS_C_NT_STRING_UID_NAME_VAL; 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgss_OID GSS_C_NT_HOSTBASED_SERVICE_X = &GSS_C_NT_HOSTBASED_SERVICE_X_VAL; 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgss_OID GSS_C_NT_HOSTBASED_SERVICE = &GSS_C_NT_HOSTBASED_SERVICE_VAL; 63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgss_OID GSS_C_NT_ANONYMOUS = &GSS_C_NT_ANONYMOUS_VAL; 64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgss_OID GSS_C_NT_EXPORT_NAME = &GSS_C_NT_EXPORT_NAME_VAL; 65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace net { 67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// These are encoded using ASN.1 BER encoding. 69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// This one is used by Firefox's nsAuthGSSAPI class. 71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgss_OID_desc CHROME_GSS_KRB5_MECH_OID_DESC_VAL = { 72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 9, 73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const_cast<char*>("\x2a\x86\x48\x86\xf7\x12\x01\x02\x02") 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgss_OID_desc CHROME_GSS_C_NT_HOSTBASED_SERVICE_X_VAL = { 77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6, 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const_cast<char*>("\x2b\x06\x01\x05\x06\x02") 79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgss_OID_desc CHROME_GSS_C_NT_HOSTBASED_SERVICE_VAL = { 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 10, 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const_cast<char*>("\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x04") 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgss_OID CHROME_GSS_C_NT_HOSTBASED_SERVICE_X = 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &CHROME_GSS_C_NT_HOSTBASED_SERVICE_X_VAL; 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgss_OID CHROME_GSS_C_NT_HOSTBASED_SERVICE = 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &CHROME_GSS_C_NT_HOSTBASED_SERVICE_VAL; 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgss_OID CHROME_GSS_KRB5_MECH_OID_DESC = 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &CHROME_GSS_KRB5_MECH_OID_DESC_VAL; 92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Debugging helpers. 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace { 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstd::string DisplayStatus(OM_uint32 major_status, 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OM_uint32 minor_status) { 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (major_status == GSS_S_COMPLETE) 99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return "OK"; 1003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return base::StringPrintf("0x%08X 0x%08X", major_status, minor_status); 101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstd::string DisplayCode(GSSAPILibrary* gssapi_lib, 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OM_uint32 status, 105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OM_uint32 status_code_type) { 106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const int kMaxDisplayIterations = 8; 107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const size_t kMaxMsgLength = 4096; 108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // msg_ctx needs to be outside the loop because it is invoked multiple times. 109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OM_uint32 msg_ctx = 0; 1103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string rv = base::StringPrintf("(0x%08X)", status); 111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // This loop should continue iterating until msg_ctx is 0 after the first 113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // iteration. To be cautious and prevent an infinite loop, it stops after 114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // a finite number of iterations as well. As an added sanity check, no 115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // individual message may exceed |kMaxMsgLength|, and the final result 116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // will not exceed |kMaxMsgLength|*2-1. 117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (int i = 0; i < kMaxDisplayIterations && rv.size() < kMaxMsgLength; 1183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ++i) { 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OM_uint32 min_stat; 120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gss_buffer_desc_struct msg = GSS_C_EMPTY_BUFFER; 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OM_uint32 maj_stat = 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gssapi_lib->display_status(&min_stat, status, status_code_type, 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GSS_C_NULL_OID, &msg_ctx, &msg); 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (maj_stat == GSS_S_COMPLETE) { 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int msg_len = (msg.length > kMaxMsgLength) ? 126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static_cast<int>(kMaxMsgLength) : 127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static_cast<int>(msg.length); 128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (msg_len > 0 && msg.value != NULL) { 1293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv += base::StringPrintf(" %.*s", msg_len, 1303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick static_cast<char*>(msg.value)); 131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gssapi_lib->release_buffer(&min_stat, &msg); 134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!msg_ctx) 135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return rv; 138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstd::string DisplayExtendedStatus(GSSAPILibrary* gssapi_lib, 141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OM_uint32 major_status, 142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OM_uint32 minor_status) { 143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (major_status == GSS_S_COMPLETE) 144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return "OK"; 145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string major = DisplayCode(gssapi_lib, major_status, GSS_C_GSS_CODE); 146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string minor = DisplayCode(gssapi_lib, minor_status, GSS_C_MECH_CODE); 1473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return base::StringPrintf("Major: %s | Minor: %s", major.c_str(), 1483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick minor.c_str()); 149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// ScopedName releases a gss_name_t when it goes out of scope. 152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass ScopedName { 153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ScopedName(gss_name_t name, 155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GSSAPILibrary* gssapi_lib) 156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : name_(name), 157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gssapi_lib_(gssapi_lib) { 158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(gssapi_lib_); 159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ~ScopedName() { 162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (name_ != GSS_C_NO_NAME) { 163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OM_uint32 minor_status = 0; 164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OM_uint32 major_status = 165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gssapi_lib_->release_name(&minor_status, &name_); 166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (major_status != GSS_S_COMPLETE) { 167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LOG(WARNING) << "Problem releasing name. " 168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch << DisplayStatus(major_status, minor_status); 169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch name_ = GSS_C_NO_NAME; 171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gss_name_t name_; 176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GSSAPILibrary* gssapi_lib_; 177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DISALLOW_COPY_AND_ASSIGN(ScopedName); 179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// ScopedBuffer releases a gss_buffer_t when it goes out of scope. 182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass ScopedBuffer { 183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ScopedBuffer(gss_buffer_t buffer, 185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GSSAPILibrary* gssapi_lib) 186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : buffer_(buffer), 187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gssapi_lib_(gssapi_lib) { 188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(gssapi_lib_); 189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ~ScopedBuffer() { 192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (buffer_ != GSS_C_NO_BUFFER) { 193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OM_uint32 minor_status = 0; 194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OM_uint32 major_status = 195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gssapi_lib_->release_buffer(&minor_status, buffer_); 196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (major_status != GSS_S_COMPLETE) { 197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LOG(WARNING) << "Problem releasing buffer. " 198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch << DisplayStatus(major_status, minor_status); 199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch buffer_ = GSS_C_NO_BUFFER; 201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gss_buffer_t buffer_; 206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GSSAPILibrary* gssapi_lib_; 207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DISALLOW_COPY_AND_ASSIGN(ScopedBuffer); 209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace { 212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstd::string AppendIfPredefinedValue(gss_OID oid, 214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gss_OID predefined_oid, 215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char* predefined_oid_name) { 216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(oid); 217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(predefined_oid); 218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(predefined_oid_name); 219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string output; 220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (oid->length != predefined_oid->length) 221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return output; 222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (0 != memcmp(oid->elements, 223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch predefined_oid->elements, 224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch predefined_oid->length)) 225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return output; 226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch output += " ("; 228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch output += predefined_oid_name; 229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch output += ")"; 230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return output; 231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace 234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstd::string DescribeOid(GSSAPILibrary* gssapi_lib, const gss_OID oid) { 236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!oid) 237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return "<NULL>"; 238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string output; 239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const size_t kMaxCharsToPrint = 1024; 240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OM_uint32 byte_length = oid->length; 241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch size_t char_length = byte_length / sizeof(char); 242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (char_length > kMaxCharsToPrint) { 243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // This might be a plain ASCII string. 244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Check if the first |kMaxCharsToPrint| characters 245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // contain only printable characters and are NULL terminated. 246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char* str = reinterpret_cast<const char*>(oid); 247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool is_printable = true; 248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch size_t str_length = 0; 249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for ( ; str_length < kMaxCharsToPrint; ++str_length) { 250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!str[str_length]) 251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!isprint(str[str_length])) { 253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch is_printable = false; 254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!str[str_length]) { 2583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick output += base::StringPrintf("\"%s\"", str); 259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return output; 260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 2623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick output = base::StringPrintf("(%u) \"", byte_length); 263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!oid->elements) { 264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch output += "<NULL>"; 265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return output; 266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const unsigned char* elements = 268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch reinterpret_cast<const unsigned char*>(oid->elements); 269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Don't print more than |kMaxCharsToPrint| characters. 270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch size_t i = 0; 271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for ( ; (i < byte_length) && (i < kMaxCharsToPrint); ++i) { 2723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick output += base::StringPrintf("\\x%02X", elements[i]); 273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (i >= kMaxCharsToPrint) 275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch output += "..."; 276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch output += "\""; 277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Check if the OID is one of the predefined values. 279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch output += AppendIfPredefinedValue(oid, 280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GSS_C_NT_USER_NAME, 281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "GSS_C_NT_USER_NAME"); 282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch output += AppendIfPredefinedValue(oid, 283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GSS_C_NT_MACHINE_UID_NAME, 284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "GSS_C_NT_MACHINE_UID_NAME"); 285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch output += AppendIfPredefinedValue(oid, 286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GSS_C_NT_STRING_UID_NAME, 287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "GSS_C_NT_STRING_UID_NAME"); 288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch output += AppendIfPredefinedValue(oid, 289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GSS_C_NT_HOSTBASED_SERVICE_X, 290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "GSS_C_NT_HOSTBASED_SERVICE_X"); 291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch output += AppendIfPredefinedValue(oid, 292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GSS_C_NT_HOSTBASED_SERVICE, 293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "GSS_C_NT_HOSTBASED_SERVICE"); 294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch output += AppendIfPredefinedValue(oid, 295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GSS_C_NT_ANONYMOUS, 296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "GSS_C_NT_ANONYMOUS"); 297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch output += AppendIfPredefinedValue(oid, 298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GSS_C_NT_EXPORT_NAME, 299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "GSS_C_NT_EXPORT_NAME"); 300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return output; 302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstd::string DescribeName(GSSAPILibrary* gssapi_lib, const gss_name_t name) { 305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OM_uint32 major_status = 0; 306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OM_uint32 minor_status = 0; 307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gss_buffer_desc_struct output_name_buffer = GSS_C_EMPTY_BUFFER; 308c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gss_OID_desc output_name_type_desc = GSS_C_EMPTY_BUFFER; 309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gss_OID output_name_type = &output_name_type_desc; 310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch major_status = gssapi_lib->display_name(&minor_status, 311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch name, 312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &output_name_buffer, 313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &output_name_type); 314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ScopedBuffer scoped_output_name(&output_name_buffer, gssapi_lib); 315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (major_status != GSS_S_COMPLETE) { 316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string error = 3173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick base::StringPrintf("Unable to describe name 0x%p, %s", 3183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick name, 3193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DisplayExtendedStatus(gssapi_lib, 3203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick major_status, 3213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick minor_status).c_str()); 322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return error; 323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int len = output_name_buffer.length; 3253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string description = base::StringPrintf( 3263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "%*s (Type %s)", 3273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick len, 3283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick reinterpret_cast<const char*>(output_name_buffer.value), 3293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DescribeOid(gssapi_lib, output_name_type).c_str()); 330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return description; 331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstd::string DescribeContext(GSSAPILibrary* gssapi_lib, 334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const gss_ctx_id_t context_handle) { 335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OM_uint32 major_status = 0; 336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OM_uint32 minor_status = 0; 337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gss_name_t src_name = GSS_C_NO_NAME; 338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gss_name_t targ_name = GSS_C_NO_NAME; 339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OM_uint32 lifetime_rec = 0; 340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gss_OID mech_type = GSS_C_NO_OID; 341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OM_uint32 ctx_flags = 0; 342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int locally_initiated = 0; 343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int open = 0; 344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch major_status = gssapi_lib->inquire_context(&minor_status, 345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch context_handle, 346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &src_name, 347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &targ_name, 348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &lifetime_rec, 349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &mech_type, 350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &ctx_flags, 351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &locally_initiated, 352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &open); 353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ScopedName(src_name, gssapi_lib); 354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ScopedName(targ_name, gssapi_lib); 355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (major_status != GSS_S_COMPLETE) { 356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string error = 3573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick base::StringPrintf("Unable to describe context 0x%p, %s", 3583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick context_handle, 3593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DisplayExtendedStatus(gssapi_lib, 3603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick major_status, 3613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick minor_status).c_str()); 362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return error; 363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string source(DescribeName(gssapi_lib, src_name)); 365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string target(DescribeName(gssapi_lib, targ_name)); 3663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string description = base::StringPrintf("Context 0x%p: " 3673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Source \"%s\", " 3683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "Target \"%s\", " 3693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "lifetime %d, " 3703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "mechanism %s, " 3713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "flags 0x%08X, " 3723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "local %d, " 3733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "open %d", 3743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick context_handle, 3753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick source.c_str(), 3763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick target.c_str(), 3773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick lifetime_rec, 3783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DescribeOid(gssapi_lib, 3793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick mech_type).c_str(), 3803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ctx_flags, 3813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick locally_initiated, 3823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick open); 383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return description; 384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace 387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3884a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben MurdochGSSAPISharedLibrary::GSSAPISharedLibrary(const std::string& gssapi_library_name) 389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : initialized_(false), 3904a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch gssapi_library_name_(gssapi_library_name), 391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gssapi_library_(NULL), 392c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch import_name_(NULL), 393c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch release_name_(NULL), 394c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch release_buffer_(NULL), 395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch display_name_(NULL), 396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch display_status_(NULL), 397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch init_sec_context_(NULL), 398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch wrap_size_limit_(NULL), 399c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch delete_sec_context_(NULL), 400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch inquire_context_(NULL) { 401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 402c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 403c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochGSSAPISharedLibrary::~GSSAPISharedLibrary() { 404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (gssapi_library_) { 405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base::UnloadNativeLibrary(gssapi_library_); 406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gssapi_library_ = NULL; 407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool GSSAPISharedLibrary::Init() { 411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!initialized_) 412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch InitImpl(); 413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return initialized_; 414c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 416c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool GSSAPISharedLibrary::InitImpl() { 417c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(!initialized_); 418c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gssapi_library_ = LoadSharedLibrary(); 419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (gssapi_library_ == NULL) 420c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch initialized_ = true; 422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 424c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbase::NativeLibrary GSSAPISharedLibrary::LoadSharedLibrary() { 4264a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch const char** library_names; 4274a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch size_t num_lib_names; 4284a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch const char* user_specified_library[1]; 4294a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch if (!gssapi_library_name_.empty()) { 4304a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch user_specified_library[0] = gssapi_library_name_.c_str(); 4314a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch library_names = user_specified_library; 4324a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch num_lib_names = 1; 4334a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch } else { 4344a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch static const char* kDefaultLibraryNames[] = { 435c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_MACOSX) 4364a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch "libgssapi_krb5.dylib" // MIT Kerberos 437c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#else 4384a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch "libgssapi_krb5.so.2", // MIT Kerberos - FC, Suse10, Debian 4394a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch "libgssapi.so.4", // Heimdal - Suse10, MDK 440ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen "libgssapi.so.2", // Heimdal - Gentoo 4414a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch "libgssapi.so.1" // Heimdal - Suse9, CITI - FC, MDK, Suse10 442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif 4434a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch }; 4444a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch library_names = kDefaultLibraryNames; 4454a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch num_lib_names = arraysize(kDefaultLibraryNames); 4464a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch } 447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 448c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t i = 0; i < num_lib_names; ++i) { 4494a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch const char* library_name = library_names[i]; 450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FilePath file_path(library_name); 45121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 45221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // TODO(asanka): Move library loading to a separate thread. 45321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // http://crbug.com/66702 45421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen base::ThreadRestrictions::ScopedAllowIO allow_io_temporarily; 455ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::NativeLibrary lib = base::LoadNativeLibrary(file_path, NULL); 456c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (lib) { 457c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Only return this library if we can bind the functions we need. 458c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (BindMethods(lib)) 459c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return lib; 460c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base::UnloadNativeLibrary(lib); 461c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 462c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 463c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LOG(WARNING) << "Unable to find a compatible GSSAPI library"; 464c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return NULL; 465c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 466c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#define BIND(lib, x) \ 4683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick gss_##x##_type x = reinterpret_cast<gss_##x##_type>( \ 4693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick base::GetFunctionPointerFromNativeLibrary(lib, "gss_" #x)); \ 4703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (x == NULL) { \ 4713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick LOG(WARNING) << "Unable to bind function \"" << "gss_" #x << "\""; \ 4723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return false; \ 473c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 474c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 475c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool GSSAPISharedLibrary::BindMethods(base::NativeLibrary lib) { 476c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(lib != NULL); 477c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BIND(lib, import_name); 4793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BIND(lib, release_name); 4803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BIND(lib, release_buffer); 4813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BIND(lib, display_name); 4823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BIND(lib, display_status); 4833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BIND(lib, init_sec_context); 4843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BIND(lib, wrap_size_limit); 4853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BIND(lib, delete_sec_context); 4863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BIND(lib, inquire_context); 487c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 488c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch import_name_ = import_name; 489c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch release_name_ = release_name; 490c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch release_buffer_ = release_buffer; 491c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch display_name_ = display_name; 492c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch display_status_ = display_status; 493c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch init_sec_context_ = init_sec_context; 494c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch wrap_size_limit_ = wrap_size_limit; 495c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch delete_sec_context_ = delete_sec_context; 496c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch inquire_context_ = inquire_context; 497c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 498c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 499c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 500c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 501c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#undef BIND 502c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 503c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochOM_uint32 GSSAPISharedLibrary::import_name( 504c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OM_uint32* minor_status, 505c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const gss_buffer_t input_name_buffer, 506c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const gss_OID input_name_type, 507c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gss_name_t* output_name) { 508c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(initialized_); 509c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return import_name_(minor_status, input_name_buffer, input_name_type, 510c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch output_name); 511c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 512c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 513c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochOM_uint32 GSSAPISharedLibrary::release_name( 514c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OM_uint32* minor_status, 515c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gss_name_t* input_name) { 516c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(initialized_); 517c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return release_name_(minor_status, input_name); 518c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 519c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 520c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochOM_uint32 GSSAPISharedLibrary::release_buffer( 521c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OM_uint32* minor_status, 522c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gss_buffer_t buffer) { 523c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(initialized_); 524c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return release_buffer_(minor_status, buffer); 525c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 526c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 527c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochOM_uint32 GSSAPISharedLibrary::display_name( 528c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OM_uint32* minor_status, 529c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const gss_name_t input_name, 530c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gss_buffer_t output_name_buffer, 531c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gss_OID* output_name_type) { 532c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(initialized_); 533c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return display_name_(minor_status, 534c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch input_name, 535c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch output_name_buffer, 536c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch output_name_type); 537c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 538c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 539c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochOM_uint32 GSSAPISharedLibrary::display_status( 540c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OM_uint32* minor_status, 541c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OM_uint32 status_value, 542c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int status_type, 543c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const gss_OID mech_type, 544c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OM_uint32* message_context, 545c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gss_buffer_t status_string) { 546c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(initialized_); 547c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return display_status_(minor_status, status_value, status_type, mech_type, 548c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch message_context, status_string); 549c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 550c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 551c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochOM_uint32 GSSAPISharedLibrary::init_sec_context( 552c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OM_uint32* minor_status, 553c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const gss_cred_id_t initiator_cred_handle, 554c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gss_ctx_id_t* context_handle, 555c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const gss_name_t target_name, 556c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const gss_OID mech_type, 557c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OM_uint32 req_flags, 558c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OM_uint32 time_req, 559c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const gss_channel_bindings_t input_chan_bindings, 560c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const gss_buffer_t input_token, 561c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gss_OID* actual_mech_type, 562c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gss_buffer_t output_token, 563c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OM_uint32* ret_flags, 564c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OM_uint32* time_rec) { 565c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(initialized_); 566c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return init_sec_context_(minor_status, 567c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch initiator_cred_handle, 568c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch context_handle, 569c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch target_name, 570c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch mech_type, 571c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch req_flags, 572c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch time_req, 573c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch input_chan_bindings, 574c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch input_token, 575c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch actual_mech_type, 576c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch output_token, 577c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ret_flags, 578c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch time_rec); 579c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 580c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 581c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochOM_uint32 GSSAPISharedLibrary::wrap_size_limit( 582c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OM_uint32* minor_status, 583c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const gss_ctx_id_t context_handle, 584c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int conf_req_flag, 585c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gss_qop_t qop_req, 586c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OM_uint32 req_output_size, 587c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OM_uint32* max_input_size) { 588c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(initialized_); 589c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return wrap_size_limit_(minor_status, 590c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch context_handle, 591c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch conf_req_flag, 592c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch qop_req, 593c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch req_output_size, 594c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch max_input_size); 595c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 596c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 597c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochOM_uint32 GSSAPISharedLibrary::delete_sec_context( 598c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OM_uint32* minor_status, 599c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gss_ctx_id_t* context_handle, 600c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gss_buffer_t output_token) { 601c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // This is called from the owner class' destructor, even if 602c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Init() is not called, so we can't assume |initialized_| 603c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // is set. 604c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!initialized_) 605c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return 0; 606c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return delete_sec_context_(minor_status, 607c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch context_handle, 608c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch output_token); 609c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 610c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 611c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochOM_uint32 GSSAPISharedLibrary::inquire_context( 612c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OM_uint32* minor_status, 613c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const gss_ctx_id_t context_handle, 614c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gss_name_t* src_name, 615c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gss_name_t* targ_name, 616c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OM_uint32* lifetime_rec, 617c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gss_OID* mech_type, 618c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OM_uint32* ctx_flags, 619c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int* locally_initiated, 620c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int* open) { 621c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(initialized_); 622c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return inquire_context_(minor_status, 6233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick context_handle, 6243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick src_name, 6253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick targ_name, 6263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick lifetime_rec, 6273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick mech_type, 6283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ctx_flags, 6293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick locally_initiated, 6303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick open); 631c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 632c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 633c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochScopedSecurityContext::ScopedSecurityContext(GSSAPILibrary* gssapi_lib) 634c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : security_context_(GSS_C_NO_CONTEXT), 635c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gssapi_lib_(gssapi_lib) { 636c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(gssapi_lib_); 637c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 638c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 639c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochScopedSecurityContext::~ScopedSecurityContext() { 640c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (security_context_ != GSS_C_NO_CONTEXT) { 641c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER; 642c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OM_uint32 minor_status = 0; 643c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OM_uint32 major_status = gssapi_lib_->delete_sec_context( 644c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &minor_status, &security_context_, &output_token); 645c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (major_status != GSS_S_COMPLETE) { 646c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LOG(WARNING) << "Problem releasing security_context. " 647c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch << DisplayStatus(major_status, minor_status); 648c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 649c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch security_context_ = GSS_C_NO_CONTEXT; 650c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 651c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 652c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 653c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochHttpAuthGSSAPI::HttpAuthGSSAPI(GSSAPILibrary* library, 654c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::string& scheme, 655c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gss_OID gss_oid) 656c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : scheme_(scheme), 657c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gss_oid_(gss_oid), 658c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch library_(library), 6593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_sec_context_(library), 6603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick can_delegate_(false) { 661c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(library_); 662c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 663c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 664c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochHttpAuthGSSAPI::~HttpAuthGSSAPI() { 665c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 666c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 667c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool HttpAuthGSSAPI::Init() { 668c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!library_) 669c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 670c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return library_->Init(); 671c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 672c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 673c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool HttpAuthGSSAPI::NeedsIdentity() const { 674c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return decoded_server_auth_token_.empty(); 675c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 676c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid HttpAuthGSSAPI::Delegate() { 6783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick can_delegate_ = true; 679c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 680c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 6813345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickHttpAuth::AuthorizationResult HttpAuthGSSAPI::ParseChallenge( 6823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HttpAuth::ChallengeTokenizer* tok) { 683c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Verify the challenge's auth-scheme. 684731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!LowerCaseEqualsASCII(tok->scheme(), StringToLowerASCII(scheme_).c_str())) 6853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return HttpAuth::AUTHORIZATION_RESULT_INVALID; 686c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 687731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick std::string encoded_auth_token = tok->base64_param(); 688731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 689731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (encoded_auth_token.empty()) { 6903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // If a context has already been established, an empty Negotiate challenge 6913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // should be treated as a rejection of the current attempt. 6923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (scoped_sec_context_.get() != GSS_C_NO_CONTEXT) 6933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return HttpAuth::AUTHORIZATION_RESULT_REJECT; 6943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK(decoded_server_auth_token_.empty()); 6953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return HttpAuth::AUTHORIZATION_RESULT_ACCEPT; 6963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } else { 6973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // If a context has not already been established, additional tokens should 6983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // not be present in the auth challenge. 6993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (scoped_sec_context_.get() == GSS_C_NO_CONTEXT) 7003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return HttpAuth::AUTHORIZATION_RESULT_INVALID; 701c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 702c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Make sure the additional token is base64 encoded. 704c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string decoded_auth_token; 705c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool base64_rv = base::Base64Decode(encoded_auth_token, &decoded_auth_token); 7063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!base64_rv) 7073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return HttpAuth::AUTHORIZATION_RESULT_INVALID; 708c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch decoded_server_auth_token_ = decoded_auth_token; 7093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return HttpAuth::AUTHORIZATION_RESULT_ACCEPT; 710c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 711c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickint HttpAuthGSSAPI::GenerateAuthToken(const string16* username, 7133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const string16* password, 714c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::wstring& spn, 715c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string* auth_token) { 716c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(auth_token); 7173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK(username == NULL && password == NULL); 718c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 719c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER; 720c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch input_token.length = decoded_server_auth_token_.length(); 7213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick input_token.value = (input_token.length > 0) ? 7223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const_cast<char*>(decoded_server_auth_token_.data()) : 7233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NULL; 724c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER; 725c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ScopedBuffer scoped_output_token(&output_token, library_); 726c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = GetNextSecurityToken(spn, &input_token, &output_token); 727c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (rv != OK) 728c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return rv; 729c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 730c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Base64 encode data in output buffer and prepend the scheme. 731c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string encode_input(static_cast<char*>(output_token.value), 732c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch output_token.length); 733c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string encode_output; 7343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick bool base64_rv = base::Base64Encode(encode_input, &encode_output); 7353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!base64_rv) { 7363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick LOG(ERROR) << "Base64 encoding of auth token failed."; 7373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return ERR_ENCODING_CONVERSION_FAILED; 7383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 739c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *auth_token = scheme_ + " " + encode_output; 740c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return OK; 741c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 742c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 7443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merricknamespace { 7453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 7463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// GSSAPI status codes consist of a calling error (essentially, a programmer 7473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// bug), a routine error (defined by the RFC), and supplementary information, 7483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// all bitwise-or'ed together in different regions of the 32 bit return value. 7493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// This means a simple switch on the return codes is not sufficient. 7503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 7513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickint MapImportNameStatusToError(OM_uint32 major_status) { 752731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick VLOG(1) << "import_name returned 0x" << std::hex << major_status; 7533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (major_status == GSS_S_COMPLETE) 7543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return OK; 7553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (GSS_CALLING_ERROR(major_status) != 0) 7563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return ERR_UNEXPECTED; 7573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick OM_uint32 routine_error = GSS_ROUTINE_ERROR(major_status); 7583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick switch (routine_error) { 7593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick case GSS_S_FAILURE: 7603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Looking at the MIT Kerberos implementation, this typically is returned 7613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // when memory allocation fails. However, the API does not guarantee 7623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // that this is the case, so using ERR_UNEXPECTED rather than 7633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // ERR_OUT_OF_MEMORY. 7643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return ERR_UNEXPECTED_SECURITY_LIBRARY_STATUS; 7653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick case GSS_S_BAD_NAME: 7663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick case GSS_S_BAD_NAMETYPE: 7673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return ERR_MALFORMED_IDENTITY; 7683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick case GSS_S_DEFECTIVE_TOKEN: 7693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Not mentioned in the API, but part of code. 7703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return ERR_UNEXPECTED_SECURITY_LIBRARY_STATUS; 7713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick case GSS_S_BAD_MECH: 7723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return ERR_UNSUPPORTED_AUTH_SCHEME; 7733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick default: 7743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS; 775c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 7763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 7773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 7783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickint MapInitSecContextStatusToError(OM_uint32 major_status) { 779731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick VLOG(1) << "init_sec_context returned 0x" << std::hex << major_status; 7803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Although GSS_S_CONTINUE_NEEDED is an additional bit, it seems like 7813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // other code just checks if major_status is equivalent to it to indicate 7823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // that there are no other errors included. 7833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (major_status == GSS_S_COMPLETE || major_status == GSS_S_CONTINUE_NEEDED) 7843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return OK; 7853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (GSS_CALLING_ERROR(major_status) != 0) 7863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return ERR_UNEXPECTED; 7873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick OM_uint32 routine_status = GSS_ROUTINE_ERROR(major_status); 7883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick switch (routine_status) { 7893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick case GSS_S_DEFECTIVE_TOKEN: 7903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return ERR_INVALID_RESPONSE; 7913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick case GSS_S_DEFECTIVE_CREDENTIAL: 7923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Not expected since this implementation uses the default credential. 7933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return ERR_UNEXPECTED_SECURITY_LIBRARY_STATUS; 7943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick case GSS_S_BAD_SIG: 7953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Probably won't happen, but it's a bad response. 7963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return ERR_INVALID_RESPONSE; 7973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick case GSS_S_NO_CRED: 7983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return ERR_INVALID_AUTH_CREDENTIALS; 7993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick case GSS_S_CREDENTIALS_EXPIRED: 8003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return ERR_INVALID_AUTH_CREDENTIALS; 8013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick case GSS_S_BAD_BINDINGS: 8023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // This only happens with mutual authentication. 8033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return ERR_UNEXPECTED_SECURITY_LIBRARY_STATUS; 8043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick case GSS_S_NO_CONTEXT: 8053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return ERR_UNEXPECTED_SECURITY_LIBRARY_STATUS; 8063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick case GSS_S_BAD_NAMETYPE: 8073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return ERR_UNSUPPORTED_AUTH_SCHEME; 8083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick case GSS_S_BAD_NAME: 8093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return ERR_UNSUPPORTED_AUTH_SCHEME; 8103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick case GSS_S_BAD_MECH: 8113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return ERR_UNEXPECTED_SECURITY_LIBRARY_STATUS; 8123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick case GSS_S_FAILURE: 8133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // This should be an "Unexpected Security Status" according to the 8143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // GSSAPI documentation, but it's typically used to indicate that 8153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // credentials are not correctly set up on a user machine, such 8163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // as a missing credential cache or hitting this after calling 8173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // kdestroy. 8183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // TODO(cbentzel): Use minor code for even better mapping? 8193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return ERR_MISSING_AUTH_CREDENTIALS; 8203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick default: 8213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (routine_status != 0) 8223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS; 8233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick break; 8243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 8253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick OM_uint32 supplemental_status = GSS_SUPPLEMENTARY_INFO(major_status); 8263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Replays could indicate an attack. 8273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (supplemental_status & (GSS_S_DUPLICATE_TOKEN | GSS_S_OLD_TOKEN | 8283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick GSS_S_UNSEQ_TOKEN | GSS_S_GAP_TOKEN)) 8293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return ERR_INVALID_RESPONSE; 8303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 8313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // At this point, every documented status has been checked. 8323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS; 8333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 8343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 835c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 836c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 837c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint HttpAuthGSSAPI::GetNextSecurityToken(const std::wstring& spn, 838c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gss_buffer_t in_token, 839c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gss_buffer_t out_token) { 840c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Create a name for the principal 841c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // TODO(cbentzel): Just do this on the first pass? 842c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string spn_principal = WideToASCII(spn); 843c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gss_buffer_desc spn_buffer = GSS_C_EMPTY_BUFFER; 844c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spn_buffer.value = const_cast<char*>(spn_principal.c_str()); 845c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spn_buffer.length = spn_principal.size() + 1; 846c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OM_uint32 minor_status = 0; 847c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gss_name_t principal_name = GSS_C_NO_NAME; 848c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OM_uint32 major_status = library_->import_name( 849c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &minor_status, 850c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &spn_buffer, 851c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CHROME_GSS_C_NT_HOSTBASED_SERVICE, 852c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &principal_name); 8533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int rv = MapImportNameStatusToError(major_status); 8543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (rv != OK) { 855c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LOG(ERROR) << "Problem importing name from " 856731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick << "spn \"" << spn_principal << "\"\n" 857731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick << DisplayExtendedStatus(library_, major_status, minor_status); 8583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return rv; 859c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 860c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ScopedName scoped_name(principal_name, library_); 861c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 862c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Continue creating a security context. 863c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch OM_uint32 req_flags = 0; 8643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (can_delegate_) 8653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick req_flags |= GSS_C_DELEG_FLAG; 866c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch major_status = library_->init_sec_context( 867c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &minor_status, 868c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GSS_C_NO_CREDENTIAL, 869c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_sec_context_.receive(), 870c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch principal_name, 871c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gss_oid_, 872c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch req_flags, 873c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GSS_C_INDEFINITE, 874c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GSS_C_NO_CHANNEL_BINDINGS, 875c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch in_token, 876c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL, // actual_mech_type 877c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch out_token, 878c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL, // ret flags 879c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NULL); 8803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick rv = MapInitSecContextStatusToError(major_status); 8813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (rv != OK) { 882731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick LOG(ERROR) << "Problem initializing context. \n" 883731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick << DisplayExtendedStatus(library_, major_status, minor_status) 884731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick << '\n' 885c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch << DescribeContext(library_, scoped_sec_context_.get()); 886c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 887731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return rv; 888c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 889c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 890c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace net 891