LCOV - app.info - extensions/auth/nsAuthGSSAPI.cpp

LCOV - code coverage report
| Current view: | directory - extensions/auth - nsAuthGSSAPI.cpp (source / functions) |  | Found | Hit | Coverage |
| Test: | app.info | Lines: | 182 | 0 | 0.0 %
| Date: | 2012-06-02 | Functions: | 12 | 0 | 0.0 %

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