LCOV - code coverage report
Current view: top level - extensions/auth - nsAuthGSSAPI.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 199 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 12 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* vim:set ts=4 sw=4 sts=4 et cindent: */
       2             : /* This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       5             : 
       6             : //
       7             : // GSSAPI Authentication Support Module
       8             : //
       9             : // Described by IETF Internet draft: draft-brezak-kerberos-http-00.txt
      10             : // (formerly draft-brezak-spnego-http-04.txt)
      11             : //
      12             : // Also described here:
      13             : // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnsecure/html/http-sso-1.asp
      14             : //
      15             : //
      16             : 
      17             : #include "mozilla/ArrayUtils.h"
      18             : #include "mozilla/IntegerPrintfMacros.h"
      19             : 
      20             : #include "prlink.h"
      21             : #include "nsCOMPtr.h"
      22             : #include "nsIPrefService.h"
      23             : #include "nsIPrefBranch.h"
      24             : #include "nsIServiceManager.h"
      25             : #include "nsNativeCharsetUtils.h"
      26             : #include "mozilla/Telemetry.h"
      27             : 
      28             : #include "nsAuthGSSAPI.h"
      29             : 
      30             : #ifdef XP_MACOSX
      31             : #include <Kerberos/Kerberos.h>
      32             : #endif
      33             : 
      34             : #ifdef XP_MACOSX
      35             : typedef KLStatus (*KLCacheHasValidTickets_type)(
      36             :     KLPrincipal,
      37             :     KLKerberosVersion,
      38             :     KLBoolean *,
      39             :     KLPrincipal *,
      40             :     char **);
      41             : #endif
      42             : 
      43             : #if defined(HAVE_RES_NINIT)
      44             : #include <sys/types.h>
      45             : #include <netinet/in.h>
      46             : #include <arpa/nameser.h>
      47             : #include <resolv.h>
      48             : #endif
      49             : 
      50             : using namespace mozilla;
      51             : 
      52             : //-----------------------------------------------------------------------------
      53             : 
      54             : // We define GSS_C_NT_HOSTBASED_SERVICE explicitly since it may be referenced
      55             : // by by a different name depending on the implementation of gss but always
      56             : // has the same value
      57             : 
      58             : static gss_OID_desc gss_c_nt_hostbased_service =
      59             :     { 10, (void *) "\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x04" };
      60             : 
      61             : static const char kNegotiateAuthGssLib[] =
      62             :     "network.negotiate-auth.gsslib";
      63             : static const char kNegotiateAuthNativeImp[] =
      64             :    "network.negotiate-auth.using-native-gsslib";
      65             : 
      66             : static struct GSSFunction {
      67             :     const char *str;
      68             :     PRFuncPtr func;
      69             : } gssFuncs[] = {
      70             :     { "gss_display_status", nullptr },
      71             :     { "gss_init_sec_context", nullptr },
      72             :     { "gss_indicate_mechs", nullptr },
      73             :     { "gss_release_oid_set", nullptr },
      74             :     { "gss_delete_sec_context", nullptr },
      75             :     { "gss_import_name", nullptr },
      76             :     { "gss_release_buffer", nullptr },
      77             :     { "gss_release_name", nullptr },
      78             :     { "gss_wrap", nullptr },
      79             :     { "gss_unwrap", nullptr }
      80             : };
      81             : 
      82             : static bool      gssNativeImp = true;
      83             : static PRLibrary* gssLibrary = nullptr;
      84             : 
      85             : #define gss_display_status_ptr      ((gss_display_status_type)*gssFuncs[0].func)
      86             : #define gss_init_sec_context_ptr    ((gss_init_sec_context_type)*gssFuncs[1].func)
      87             : #define gss_indicate_mechs_ptr      ((gss_indicate_mechs_type)*gssFuncs[2].func)
      88             : #define gss_release_oid_set_ptr     ((gss_release_oid_set_type)*gssFuncs[3].func)
      89             : #define gss_delete_sec_context_ptr  ((gss_delete_sec_context_type)*gssFuncs[4].func)
      90             : #define gss_import_name_ptr         ((gss_import_name_type)*gssFuncs[5].func)
      91             : #define gss_release_buffer_ptr      ((gss_release_buffer_type)*gssFuncs[6].func)
      92             : #define gss_release_name_ptr        ((gss_release_name_type)*gssFuncs[7].func)
      93             : #define gss_wrap_ptr                ((gss_wrap_type)*gssFuncs[8].func)
      94             : #define gss_unwrap_ptr              ((gss_unwrap_type)*gssFuncs[9].func)
      95             : 
      96             : #ifdef XP_MACOSX
      97             : static PRFuncPtr KLCacheHasValidTicketsPtr;
      98             : #define KLCacheHasValidTickets_ptr \
      99             :         ((KLCacheHasValidTickets_type)*KLCacheHasValidTicketsPtr)
     100             : #endif
     101             : 
     102             : static nsresult
     103           0 : gssInit()
     104             : {
     105           0 :     nsXPIDLCString libPath;
     106           0 :     nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
     107           0 :     if (prefs) {
     108           0 :         prefs->GetCharPref(kNegotiateAuthGssLib, getter_Copies(libPath));
     109           0 :         prefs->GetBoolPref(kNegotiateAuthNativeImp, &gssNativeImp);
     110             :     }
     111             : 
     112           0 :     PRLibrary *lib = nullptr;
     113             : 
     114           0 :     if (!libPath.IsEmpty()) {
     115           0 :         LOG(("Attempting to load user specified library [%s]\n", libPath.get()));
     116           0 :         gssNativeImp = false;
     117           0 :         lib = PR_LoadLibrary(libPath.get());
     118             :     }
     119             :     else {
     120             : #ifdef XP_WIN
     121             :         char *libName = PR_GetLibraryName(nullptr, "gssapi32");
     122             :         if (libName) {
     123             :             lib = PR_LoadLibrary("gssapi32");
     124             :             PR_FreeLibraryName(libName);
     125             :         }
     126             : #elif defined(__OpenBSD__)
     127             :         /* OpenBSD doesn't register inter-library dependencies in basesystem
     128             :          * libs therefor we need to load all the libraries gssapi depends on,
     129             :          * in the correct order and with LD_GLOBAL for GSSAPI auth to work
     130             :          * fine.
     131             :          */
     132             : 
     133             :         const char *const verLibNames[] = {
     134             :             "libasn1.so",
     135             :             "libcrypto.so",
     136             :             "libroken.so",
     137             :             "libheimbase.so",
     138             :             "libcom_err.so",
     139             :             "libkrb5.so",
     140             :             "libgssapi.so"
     141             :         };
     142             : 
     143             :         PRLibSpec libSpec;
     144             :         for (size_t i = 0; i < ArrayLength(verLibNames); ++i) {
     145             :             libSpec.type = PR_LibSpec_Pathname;
     146             :             libSpec.value.pathname = verLibNames[i];
     147             :             lib = PR_LoadLibraryWithFlags(libSpec, PR_LD_GLOBAL);
     148             :         }
     149             : 
     150             : #else
     151             : 
     152             :         const char *const libNames[] = {
     153             :             "gss",
     154             :             "gssapi_krb5",
     155             :             "gssapi"
     156           0 :         };
     157             : 
     158             :         const char *const verLibNames[] = {
     159             :             "libgssapi_krb5.so.2", /* MIT - FC, Suse10, Debian */
     160             :             "libgssapi.so.4",      /* Heimdal - Suse10, MDK */
     161             :             "libgssapi.so.1"       /* Heimdal - Suse9, CITI - FC, MDK, Suse10*/
     162           0 :         };
     163             : 
     164           0 :         for (size_t i = 0; i < ArrayLength(verLibNames) && !lib; ++i) {
     165           0 :             lib = PR_LoadLibrary(verLibNames[i]);
     166             : 
     167             :             /* The CITI libgssapi library calls exit() during
     168             :              * initialization if it's not correctly configured. Try to
     169             :              * ensure that we never use this library for our GSSAPI
     170             :              * support, as its just a wrapper library, anyway.
     171             :              * See Bugzilla #325433
     172             :              */
     173           0 :             if (lib &&
     174           0 :                 PR_FindFunctionSymbol(lib,
     175           0 :                                       "internal_krb5_gss_initialize") &&
     176           0 :                 PR_FindFunctionSymbol(lib, "gssd_pname_to_uid")) {
     177           0 :                 LOG(("CITI libgssapi found, which calls exit(). Skipping\n"));
     178           0 :                 PR_UnloadLibrary(lib);
     179           0 :                 lib = nullptr;
     180             :             }
     181             :         }
     182             : 
     183           0 :         for (size_t i = 0; i < ArrayLength(libNames) && !lib; ++i) {
     184           0 :             char *libName = PR_GetLibraryName(nullptr, libNames[i]);
     185           0 :             if (libName) {
     186           0 :                 lib = PR_LoadLibrary(libName);
     187           0 :                 PR_FreeLibraryName(libName);
     188             : 
     189           0 :                 if (lib &&
     190           0 :                     PR_FindFunctionSymbol(lib,
     191           0 :                                           "internal_krb5_gss_initialize") &&
     192           0 :                     PR_FindFunctionSymbol(lib, "gssd_pname_to_uid")) {
     193           0 :                     LOG(("CITI libgssapi found, which calls exit(). Skipping\n"));
     194           0 :                     PR_UnloadLibrary(lib);
     195           0 :                     lib = nullptr;
     196             :                 }
     197             :             }
     198             :         }
     199             : #endif
     200             :     }
     201             : 
     202           0 :     if (!lib) {
     203           0 :         LOG(("Fail to load gssapi library\n"));
     204           0 :         return NS_ERROR_FAILURE;
     205             :     }
     206             : 
     207           0 :     LOG(("Attempting to load gss functions\n"));
     208             : 
     209           0 :     for (size_t i = 0; i < ArrayLength(gssFuncs); ++i) {
     210           0 :         gssFuncs[i].func = PR_FindFunctionSymbol(lib, gssFuncs[i].str);
     211           0 :         if (!gssFuncs[i].func) {
     212           0 :             LOG(("Fail to load %s function from gssapi library\n", gssFuncs[i].str));
     213           0 :             PR_UnloadLibrary(lib);
     214           0 :             return NS_ERROR_FAILURE;
     215             :         }
     216             :     }
     217             : #ifdef XP_MACOSX
     218             :     if (gssNativeImp &&
     219             :             !(KLCacheHasValidTicketsPtr =
     220             :                PR_FindFunctionSymbol(lib, "KLCacheHasValidTickets"))) {
     221             :         LOG(("Fail to load KLCacheHasValidTickets function from gssapi library\n"));
     222             :         PR_UnloadLibrary(lib);
     223             :         return NS_ERROR_FAILURE;
     224             :     }
     225             : #endif
     226             : 
     227           0 :     gssLibrary = lib;
     228           0 :     return NS_OK;
     229             : }
     230             : 
     231             : // Generate proper GSSAPI error messages from the major and
     232             : // minor status codes.
     233             : void
     234           0 : LogGssError(OM_uint32 maj_stat, OM_uint32 min_stat, const char *prefix)
     235             : {
     236           0 :     if (!MOZ_LOG_TEST(gNegotiateLog, LogLevel::Debug)) {
     237           0 :         return;
     238             :     }
     239             : 
     240             :     OM_uint32 new_stat;
     241           0 :     OM_uint32 msg_ctx = 0;
     242             :     gss_buffer_desc status1_string;
     243             :     gss_buffer_desc status2_string;
     244             :     OM_uint32 ret;
     245           0 :     nsAutoCString errorStr;
     246           0 :     errorStr.Assign(prefix);
     247             : 
     248           0 :     if (!gssLibrary)
     249           0 :         return;
     250             : 
     251           0 :     errorStr += ": ";
     252           0 :     do {
     253           0 :         ret = gss_display_status_ptr(&new_stat,
     254             :                                      maj_stat,
     255             :                                      GSS_C_GSS_CODE,
     256             :                                      GSS_C_NULL_OID,
     257             :                                      &msg_ctx,
     258           0 :                                      &status1_string);
     259           0 :         errorStr.Append((const char *) status1_string.value, status1_string.length);
     260           0 :         gss_release_buffer_ptr(&new_stat, &status1_string);
     261             : 
     262           0 :         errorStr += '\n';
     263           0 :         ret = gss_display_status_ptr(&new_stat,
     264             :                                      min_stat,
     265             :                                      GSS_C_MECH_CODE,
     266             :                                      GSS_C_NULL_OID,
     267             :                                      &msg_ctx,
     268           0 :                                      &status2_string);
     269           0 :         errorStr.Append((const char *) status2_string.value, status2_string.length);
     270           0 :         errorStr += '\n';
     271           0 :     } while (!GSS_ERROR(ret) && msg_ctx != 0);
     272             : 
     273           0 :     LOG(("%s\n", errorStr.get()));
     274             : }
     275             : 
     276             : //-----------------------------------------------------------------------------
     277             : 
     278           0 : nsAuthGSSAPI::nsAuthGSSAPI(pType package)
     279           0 :     : mServiceFlags(REQ_DEFAULT)
     280             : {
     281             :     OM_uint32 minstat;
     282             :     OM_uint32 majstat;
     283             :     gss_OID_set mech_set;
     284             :     gss_OID item;
     285             : 
     286             :     unsigned int i;
     287             :     static gss_OID_desc gss_krb5_mech_oid_desc =
     288             :         { 9, (void *) "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02" };
     289             :     static gss_OID_desc gss_spnego_mech_oid_desc =
     290             :         { 6, (void *) "\x2b\x06\x01\x05\x05\x02" };
     291             : 
     292           0 :     LOG(("entering nsAuthGSSAPI::nsAuthGSSAPI()\n"));
     293             : 
     294           0 :     mComplete = false;
     295             : 
     296           0 :     if (!gssLibrary && NS_FAILED(gssInit()))
     297           0 :         return;
     298             : 
     299           0 :     mCtx = GSS_C_NO_CONTEXT;
     300           0 :     mMechOID = &gss_krb5_mech_oid_desc;
     301             : 
     302             :     // if the type is kerberos we accept it as default
     303             :     // and exit
     304             : 
     305           0 :     if (package == PACKAGE_TYPE_KERBEROS)
     306           0 :         return;
     307             : 
     308             :     // Now, look at the list of supported mechanisms,
     309             :     // if SPNEGO is found, then use it.
     310             :     // Otherwise, set the desired mechanism to
     311             :     // GSS_C_NO_OID and let the system try to use
     312             :     // the default mechanism.
     313             :     //
     314             :     // Using Kerberos directly (instead of negotiating
     315             :     // with SPNEGO) may work in some cases depending
     316             :     // on how smart the server side is.
     317             : 
     318           0 :     majstat = gss_indicate_mechs_ptr(&minstat, &mech_set);
     319           0 :     if (GSS_ERROR(majstat))
     320           0 :         return;
     321             : 
     322           0 :     if (mech_set) {
     323           0 :         for (i=0; i<mech_set->count; i++) {
     324           0 :             item = &mech_set->elements[i];
     325           0 :             if (item->length == gss_spnego_mech_oid_desc.length &&
     326           0 :                 !memcmp(item->elements, gss_spnego_mech_oid_desc.elements,
     327           0 :                 item->length)) {
     328             :                 // ok, we found it
     329           0 :                 mMechOID = &gss_spnego_mech_oid_desc;
     330           0 :                 break;
     331             :             }
     332             :         }
     333           0 :         gss_release_oid_set_ptr(&minstat, &mech_set);
     334             :     }
     335             : }
     336             : 
     337             : void
     338           0 : nsAuthGSSAPI::Reset()
     339             : {
     340           0 :     if (gssLibrary && mCtx != GSS_C_NO_CONTEXT) {
     341             :         OM_uint32 minor_status;
     342           0 :         gss_delete_sec_context_ptr(&minor_status, &mCtx, GSS_C_NO_BUFFER);
     343             :     }
     344           0 :     mCtx = GSS_C_NO_CONTEXT;
     345           0 :     mComplete = false;
     346           0 : }
     347             : 
     348             : /* static */ void
     349           0 : nsAuthGSSAPI::Shutdown()
     350             : {
     351           0 :     if (gssLibrary) {
     352           0 :         PR_UnloadLibrary(gssLibrary);
     353           0 :         gssLibrary = nullptr;
     354             :     }
     355           0 : }
     356             : 
     357             : /* Limitations apply to this class's thread safety. See the header file */
     358           0 : NS_IMPL_ISUPPORTS(nsAuthGSSAPI, nsIAuthModule)
     359             : 
     360             : NS_IMETHODIMP
     361           0 : nsAuthGSSAPI::Init(const char *serviceName,
     362             :                    uint32_t    serviceFlags,
     363             :                    const char16_t *domain,
     364             :                    const char16_t *username,
     365             :                    const char16_t *password)
     366             : {
     367             :     // we don't expect to be passed any user credentials
     368           0 :     NS_ASSERTION(!domain && !username && !password, "unexpected credentials");
     369             : 
     370             :     // it's critial that the caller supply a service name to be used
     371           0 :     NS_ENSURE_TRUE(serviceName && *serviceName, NS_ERROR_INVALID_ARG);
     372             : 
     373           0 :     LOG(("entering nsAuthGSSAPI::Init()\n"));
     374             : 
     375           0 :     if (!gssLibrary)
     376           0 :        return NS_ERROR_NOT_INITIALIZED;
     377             : 
     378           0 :     mServiceName = serviceName;
     379           0 :     mServiceFlags = serviceFlags;
     380             : 
     381             :     static bool sTelemetrySent = false;
     382           0 :     if (!sTelemetrySent) {
     383           0 :         mozilla::Telemetry::Accumulate(
     384             :             mozilla::Telemetry::NTLM_MODULE_USED_2,
     385           0 :             serviceFlags & nsIAuthModule::REQ_PROXY_AUTH
     386             :                 ? NTLM_MODULE_KERBEROS_PROXY
     387           0 :                 : NTLM_MODULE_KERBEROS_DIRECT);
     388           0 :         sTelemetrySent = true;
     389             :     }
     390             : 
     391           0 :     return NS_OK;
     392             : }
     393             : 
     394             : NS_IMETHODIMP
     395           0 : nsAuthGSSAPI::GetNextToken(const void *inToken,
     396             :                            uint32_t    inTokenLen,
     397             :                            void      **outToken,
     398             :                            uint32_t   *outTokenLen)
     399             : {
     400             :     OM_uint32 major_status, minor_status;
     401           0 :     OM_uint32 req_flags = 0;
     402           0 :     gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
     403           0 :     gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
     404           0 :     gss_buffer_t  in_token_ptr = GSS_C_NO_BUFFER;
     405             :     gss_name_t server;
     406           0 :     nsAutoCString userbuf;
     407             :     nsresult rv;
     408             : 
     409           0 :     LOG(("entering nsAuthGSSAPI::GetNextToken()\n"));
     410             : 
     411           0 :     if (!gssLibrary)
     412           0 :        return NS_ERROR_NOT_INITIALIZED;
     413             : 
     414             :     // If they've called us again after we're complete, reset to start afresh.
     415           0 :     if (mComplete)
     416           0 :         Reset();
     417             : 
     418           0 :     if (mServiceFlags & REQ_DELEGATE)
     419           0 :         req_flags |= GSS_C_DELEG_FLAG;
     420             : 
     421           0 :     if (mServiceFlags & REQ_MUTUAL_AUTH)
     422           0 :         req_flags |= GSS_C_MUTUAL_FLAG;
     423             : 
     424           0 :     input_token.value = (void *)mServiceName.get();
     425           0 :     input_token.length = mServiceName.Length() + 1;
     426             : 
     427             : #if defined(HAVE_RES_NINIT)
     428           0 :     res_ninit(&_res);
     429             : #endif
     430           0 :     major_status = gss_import_name_ptr(&minor_status,
     431             :                                    &input_token,
     432             :                                    &gss_c_nt_hostbased_service,
     433           0 :                                    &server);
     434           0 :     input_token.value = nullptr;
     435           0 :     input_token.length = 0;
     436           0 :     if (GSS_ERROR(major_status)) {
     437           0 :         LogGssError(major_status, minor_status, "gss_import_name() failed");
     438           0 :         return NS_ERROR_FAILURE;
     439             :     }
     440             : 
     441           0 :     if (inToken) {
     442           0 :         input_token.length = inTokenLen;
     443           0 :         input_token.value = (void *) inToken;
     444           0 :         in_token_ptr = &input_token;
     445             :     }
     446           0 :     else if (mCtx != GSS_C_NO_CONTEXT) {
     447             :         // If there is no input token, then we are starting a new
     448             :         // authentication sequence.  If we have already initialized our
     449             :         // security context, then we're in trouble because it means that the
     450             :         // first sequence failed.  We need to bail or else we might end up in
     451             :         // an infinite loop.
     452           0 :         LOG(("Cannot restart authentication sequence!"));
     453           0 :         return NS_ERROR_UNEXPECTED;
     454             :     }
     455             : 
     456             : #if defined(XP_MACOSX)
     457             :     // Suppress Kerberos prompts to get credentials.  See bug 240643.
     458             :     // We can only use Mac OS X specific kerb functions if we are using
     459             :     // the native lib
     460             :     KLBoolean found;
     461             :     bool doingMailTask = mServiceName.Find("imap@") ||
     462             :                            mServiceName.Find("pop@") ||
     463             :                            mServiceName.Find("smtp@") ||
     464             :                            mServiceName.Find("ldap@");
     465             : 
     466             :     if (!doingMailTask && (gssNativeImp &&
     467             :          (KLCacheHasValidTickets_ptr(nullptr, kerberosVersion_V5, &found, nullptr, nullptr) != klNoErr || !found)))
     468             :     {
     469             :         major_status = GSS_S_FAILURE;
     470             :         minor_status = 0;
     471             :     }
     472             :     else
     473             : #endif /* XP_MACOSX */
     474           0 :     major_status = gss_init_sec_context_ptr(&minor_status,
     475             :                                             GSS_C_NO_CREDENTIAL,
     476             :                                             &mCtx,
     477             :                                             server,
     478             :                                             mMechOID,
     479             :                                             req_flags,
     480             :                                             GSS_C_INDEFINITE,
     481             :                                             GSS_C_NO_CHANNEL_BINDINGS,
     482             :                                             in_token_ptr,
     483             :                                             nullptr,
     484             :                                             &output_token,
     485             :                                             nullptr,
     486           0 :                                             nullptr);
     487             : 
     488           0 :     if (GSS_ERROR(major_status)) {
     489           0 :         LogGssError(major_status, minor_status, "gss_init_sec_context() failed");
     490           0 :         Reset();
     491           0 :         rv = NS_ERROR_FAILURE;
     492           0 :         goto end;
     493             :     }
     494           0 :     if (major_status == GSS_S_COMPLETE) {
     495             :         // Mark ourselves as being complete, so that if we're called again
     496             :         // we know to start afresh.
     497           0 :         mComplete = true;
     498             :     }
     499             :     else if (major_status == GSS_S_CONTINUE_NEEDED) {
     500             :         //
     501             :         // The important thing is that we do NOT reset the
     502             :         // context here because it will be needed on the
     503             :         // next call.
     504             :         //
     505             :     }
     506             : 
     507           0 :     *outTokenLen = output_token.length;
     508           0 :     if (output_token.length != 0)
     509           0 :         *outToken = nsMemory::Clone(output_token.value, output_token.length);
     510             :     else
     511           0 :         *outToken = nullptr;
     512             : 
     513           0 :     gss_release_buffer_ptr(&minor_status, &output_token);
     514             : 
     515           0 :     if (major_status == GSS_S_COMPLETE)
     516           0 :         rv = NS_SUCCESS_AUTH_FINISHED;
     517             :     else
     518           0 :         rv = NS_OK;
     519             : 
     520             : end:
     521           0 :     gss_release_name_ptr(&minor_status, &server);
     522             : 
     523           0 :     LOG(("  leaving nsAuthGSSAPI::GetNextToken [rv=%" PRIx32 "]",
     524             :          static_cast<uint32_t>(rv)));
     525           0 :     return rv;
     526             : }
     527             : 
     528             : NS_IMETHODIMP
     529           0 : nsAuthGSSAPI::Unwrap(const void *inToken,
     530             :                      uint32_t    inTokenLen,
     531             :                      void      **outToken,
     532             :                      uint32_t   *outTokenLen)
     533             : {
     534             :     OM_uint32 major_status, minor_status;
     535             : 
     536             :     gss_buffer_desc input_token;
     537           0 :     gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
     538             : 
     539           0 :     input_token.value = (void *) inToken;
     540           0 :     input_token.length = inTokenLen;
     541             : 
     542           0 :     major_status = gss_unwrap_ptr(&minor_status,
     543             :                                   mCtx,
     544             :                                   &input_token,
     545             :                                   &output_token,
     546             :                                   nullptr,
     547           0 :                                   nullptr);
     548           0 :     if (GSS_ERROR(major_status)) {
     549           0 :         LogGssError(major_status, minor_status, "gss_unwrap() failed");
     550           0 :         Reset();
     551           0 :         gss_release_buffer_ptr(&minor_status, &output_token);
     552           0 :         return NS_ERROR_FAILURE;
     553             :     }
     554             : 
     555           0 :     *outTokenLen = output_token.length;
     556             : 
     557           0 :     if (output_token.length)
     558           0 :         *outToken = nsMemory::Clone(output_token.value, output_token.length);
     559             :     else
     560           0 :         *outToken = nullptr;
     561             : 
     562           0 :     gss_release_buffer_ptr(&minor_status, &output_token);
     563             : 
     564           0 :     return NS_OK;
     565             : }
     566             : 
     567             : NS_IMETHODIMP
     568           0 : nsAuthGSSAPI::Wrap(const void *inToken,
     569             :                    uint32_t    inTokenLen,
     570             :                    bool        confidential,
     571             :                    void      **outToken,
     572             :                    uint32_t   *outTokenLen)
     573             : {
     574             :     OM_uint32 major_status, minor_status;
     575             : 
     576             :     gss_buffer_desc input_token;
     577           0 :     gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
     578             : 
     579           0 :     input_token.value = (void *) inToken;
     580           0 :     input_token.length = inTokenLen;
     581             : 
     582           0 :     major_status = gss_wrap_ptr(&minor_status,
     583             :                                 mCtx,
     584             :                                 confidential,
     585             :                                 GSS_C_QOP_DEFAULT,
     586             :                                 &input_token,
     587             :                                 nullptr,
     588           0 :                                 &output_token);
     589             : 
     590           0 :     if (GSS_ERROR(major_status)) {
     591           0 :         LogGssError(major_status, minor_status, "gss_wrap() failed");
     592           0 :         Reset();
     593           0 :         gss_release_buffer_ptr(&minor_status, &output_token);
     594           0 :         return NS_ERROR_FAILURE;
     595             :     }
     596             : 
     597           0 :     *outTokenLen = output_token.length;
     598             : 
     599             :     /* it is not possible for output_token.length to be zero */
     600           0 :     *outToken = nsMemory::Clone(output_token.value, output_token.length);
     601           0 :     gss_release_buffer_ptr(&minor_status, &output_token);
     602             : 
     603           0 :     return NS_OK;
     604             : }
     605             : 

Generated by: LCOV version 1.13