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