|
From: <co...@us...> - 2008-05-16 00:27:11
|
Update of /cvsroot/aolserver/knspnego/src In directory sc8-pr-cvs11.sourceforge.net:/tmp/cvs-serv7639/src Added Files: decode.c knspnego.cpp mod_spnego.cpp unix-env.cpp win32-env.cpp Log Message: First version of port of Apache's "mod_spnego" to AOLServer. Works, but is difficult to configure (relies on environment variables the way Apache does, instead of ns_section/ns_param) and needs some work for integration into the AOLServer "configure" environment. --- NEW FILE: decode.c --- /* base64 encoder/decoder. Originally part of main/util.c * but moved here so that support/ab and apr_sha1.c could * use it. This meant removing the apr_palloc()s and adding * ugly 'len' functions, which is quite a nasty cost. */ #include "base64.h" #if APR_CHARSET_EBCDIC #include "apr_xlate.h" #endif /* APR_CHARSET_EBCDIC */ static const unsigned char pr2six[256] = { //AMX #if !APR_CHARSET_EBCDIC /* ASCII table */ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64, 64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64, 64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 }; /* #if 0 #else /*APR_CHARSET_EBCDIC /* EBCDIC table 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 63, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 64, 64, 64, 64, 64, 64, 64, 35, 36, 37, 38, 39, 40, 41, 42, 43, 64, 64, 64, 64, 64, 64, 64, 64, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 64, 64, 64, 64, 64, 64, 64, 9, 10, 11, 12, 13, 14, 15, 16, 17, 64, 64, 64, 64, 64, 64, 64, 64, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64, 64, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64 }; #endif /*APR_CHARSET_EBCDIC*/ #if APR_CHARSET_EBCDIC static apr_xlate_t *xlate_to_ebcdic; static unsigned char os_toascii[256]; APU_DECLARE(apr_status_t) base64init_ebcdic(apr_xlate_t *to_ascii, DEBUG_BREAK apr_xlate_t *to_ebcdic) { int i; apr_size_t inbytes_left, outbytes_left; apr_status_t rv; int onoff; /* Only single-byte conversion is supported. */ rv = apr_xlate_sb_get(to_ascii, &onoff); if (rv) { return rv; } if (!onoff) { /* If conversion is not single-byte-only */ return APR_EINVAL; } rv = apr_xlate_sb_get(to_ebcdic, &onoff); if (rv) { return rv; } if (!onoff) { /* If conversion is not single-byte-only */ return APR_EINVAL; } xlate_to_ebcdic = to_ebcdic; for (i = 0; i < sizeof(os_toascii); i++) { os_toascii[i] = i; } inbytes_left = outbytes_left = sizeof(os_toascii); apr_xlate_conv_buffer(to_ascii, os_toascii, &inbytes_left, os_toascii, &outbytes_left); return APR_SUCCESS; } #endif /*APR_CHARSET_EBCDIC*/ int base64_decode_len(const char *bufcoded) { int nbytesdecoded; register const unsigned char *bufin; register int nprbytes; bufin = (const unsigned char *) bufcoded; while (pr2six[*(bufin++)] <= 63); nprbytes = (bufin - (const unsigned char *) bufcoded) - 1; nbytesdecoded = ((nprbytes + 3) / 4) * 3; return nbytesdecoded + 1; } int base64_decode(char *bufplain, const char *bufcoded) { //#if APR_CHARSET_EBCDIC // apr_size_t inbytes_left, outbytes_left; //#endif /* APR_CHARSET_EBCDIC */ int len; len = base64_decode_binary((unsigned char *) bufplain, bufcoded); #if 0 #if APR_CHARSET_EBCDIC inbytes_left = outbytes_left = len; apr_xlate_conv_buffer(xlate_to_ebcdic, bufplain, &inbytes_left, bufplain, &outbytes_left); #endif /* APR_CHARSET_EBCDIC */ #endif bufplain[len] = '\0'; return len; } /* This is the same as base64_decode() except on EBCDIC machines, where * the conversion of the output to ebcdic is left out. */ int base64_decode_binary(unsigned char *bufplain, const char *bufcoded) { int nbytesdecoded; register const unsigned char *bufin; register unsigned char *bufout; register int nprbytes; bufin = (const unsigned char *) bufcoded; while (pr2six[*(bufin++)] <= 63); nprbytes = (bufin - (const unsigned char *) bufcoded) - 1; nbytesdecoded = ((nprbytes + 3) / 4) * 3; bufout = (unsigned char *) bufplain; bufin = (const unsigned char *) bufcoded; while (nprbytes > 4) { *(bufout++) = (unsigned char) (pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4); *(bufout++) = (unsigned char) (pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2); *(bufout++) = (unsigned char) (pr2six[bufin[2]] << 6 | pr2six[bufin[3]]); bufin += 4; nprbytes -= 4; } /* Note: (nprbytes == 1) would be an error, so just ingore that case */ if (nprbytes > 1) { *(bufout++) = (unsigned char) (pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4); } if (nprbytes > 2) { *(bufout++) = (unsigned char) (pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2); } if (nprbytes > 3) { *(bufout++) = (unsigned char) (pr2six[bufin[2]] << 6 | pr2six[bufin[3]]); } nbytesdecoded -= (4 - nprbytes) & 3; return nbytesdecoded; } static const char basis_64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; int base64_encode_len(int len) { return ((len + 2) / 3 * 4) + 1; } int base64_encode(char *encoded, const char *string, int len) { #if !APR_CHARSET_EBCDIC return base64_encode_binary(encoded, (const unsigned char *) string, len); #else /* APR_CHARSET_EBCDIC */ int i; char *p; p = encoded; for (i = 0; i < len - 2; i += 3) { *p++ = basis_64[(os_toascii[string[i]] >> 2) & 0x3F]; *p++ = basis_64[((os_toascii[string[i]] & 0x3) << 4) | ((int) (os_toascii[string[i + 1]] & 0xF0) >> 4)]; *p++ = basis_64[((os_toascii[string[i + 1]] & 0xF) << 2) | ((int) (os_toascii[string[i + 2]] & 0xC0) >> 6)]; *p++ = basis_64[os_toascii[string[i + 2]] & 0x3F]; } if (i < len) { *p++ = basis_64[(os_toascii[string[i]] >> 2) & 0x3F]; if (i == (len - 1)) { *p++ = basis_64[((os_toascii[string[i]] & 0x3) << 4)]; *p++ = '='; } else { *p++ = basis_64[((os_toascii[string[i]] & 0x3) << 4) | ((int) (os_toascii[string[i + 1]] & 0xF0) >> 4)]; *p++ = basis_64[((os_toascii[string[i + 1]] & 0xF) << 2)]; } *p++ = '='; } *p++ = '\0'; return p - encoded; #endif /* APR_CHARSET_EBCDIC */ } /* This is the same as base64_encode() except on EBCDIC machines, where * the conversion of the input to ascii is left out. */ int base64_encode_binary(char *encoded, const unsigned char *string, int len) { int i; char *p; p = encoded; for (i = 0; i < len - 2; i += 3) { *p++ = basis_64[(string[i] >> 2) & 0x3F]; *p++ = basis_64[((string[i] & 0x3) << 4) | ((int) (string[i + 1] & 0xF0) >> 4)]; *p++ = basis_64[((string[i + 1] & 0xF) << 2) | ((int) (string[i + 2] & 0xC0) >> 6)]; *p++ = basis_64[string[i + 2] & 0x3F]; } if (i < len) { *p++ = basis_64[(string[i] >> 2) & 0x3F]; if (i == (len - 1)) { *p++ = basis_64[((string[i] & 0x3) << 4)]; *p++ = '='; } else { *p++ = basis_64[((string[i] & 0x3) << 4) | ((int) (string[i + 1] & 0xF0) >> 4)]; *p++ = basis_64[((string[i + 1] & 0xF) << 2)]; } *p++ = '='; } *p++ = '\0'; return p - encoded; } --- NEW FILE: knspnego.cpp --- /* /** * (c) Copyright 2008 KnowNow, Inc., Sunnyvale CA * * @KNOWNOW_LICENSE_START@ * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name "KnowNow" is a trademark of KnowNow, Inc. and may not * be used to endorse or promote any product without prior written * permission from KnowNow, Inc. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL KNOWNOW, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * @KNOWNOW_LICENSE_END@ **/ * */ #include "knexportlibraryknspnegomodule.h" #include "ns.h" #include "spnegoconfig.h" #include <string.h> #include <fcntl.h> #include <sys/stat.h> #include <time.h> #define bzero(dst,len) memset(dst,0,len) #define bcopy(src,dst,len) memcpy(dst,src,len) extern "C" { //NS_EXPORT int Ns_ModuleVersion = 1; EXPORT_LIBRARY_KNSPNEGO int KnSpnego_ModInit(char *server, char *module); } #define b64_sizeof(x) (((sizeof(x) + 2) / 3) * 4) #define b64_size(x) (((x + 2) / 3) * 4) #define BADARGS(nl,nh,example) \ if ((argc<(nl)) || (argc>(nh))) { \ Tcl_AppendResult(interp,"wrong # args: should be \"",argv[0], \ (example),"\"",NULL); \ return NS_ERROR; \ // } #define ENC_HEADER_LEN 128 #define MIN_ENCODED_STR_LEN 59 int authenticateUser (char** authUser, const char *authToken); SPNEGO_CONFIG *spConfig = NULL; static Ns_Callback ModuleCleanup; static int spnegoInterpInit(Tcl_Interp * interp, void *context); static int kn_spnego(ClientData context, Tcl_Interp * interp, int argc, char **argv); /* *---------------------------------------------------------------------- * * KnSpnego_ModInit -- * * This is the knspnego module's entry point. AOLserver runs * this function right after the module is loaded. It is used to * read configuration data, initialize data structures, kick off * the Tcl initialization function (if any), and do other things * at startup. * * Results: * NS_OK or NS_ERROR * *---------------------------------------------------------------------- */ EXPORT_LIBRARY_KNSPNEGO int KnSpnego_ModInit(char *hServer, char * hModule) { FILE *fd = NULL; Ns_DString ds; char *publickeyfile = NULL; char *privatekeyfile = NULL; char *path = NULL; Ns_Log(Notice, "KN_SPNEGO_*****_ nit(): serv = %s module = %s", hServer, hModule ); Ns_DStringInit(&ds); SPNEGO_CONFIG *spConfig = (SPNEGO_CONFIG *)ns_malloc(sizeof(SPNEGO_CONFIG)); spConfig->directoryConfig = (DIRECTORY_CONFIG *)ns_malloc(sizeof(DIRECTORY_CONFIG)); spConfig->serverConfig = (SERVER_CONFIG *)ns_malloc(sizeof(SERVER_CONFIG)); path = Ns_ConfigGetPath(hServer, hModule, NULL); if (path) { spConfig->directoryConfig->setKrb5ServiceName( Ns_ConfigGet(path, "Krb5ServiceName")); spConfig->directoryConfig->setKrb5KeyTabFile (Ns_ConfigGet(path, "Krb5KeyTabFile")); spConfig->setAuthType(Ns_ConfigGet(path, "AuthType")); } return (Ns_TclInitInterps(hServer, spnegoInterpInit, NULL)); } /* *---------------------------------------------------------------------- * * ModuleCleanup -- * * Deallocates allocated resources. * * Results: * None * *---------------------------------------------------------------------- */ static void ModuleCleanup(void *ignored) { } /* *---------------------------------------------------------------------- * * spnegoInterpInit -- * * Register new commands with the Tcl interpreter. * * Results: * NS_OK or NS_ERROR * *---------------------------------------------------------------------- */ static int spnegoInterpInit(Tcl_Interp * interp, void *context) { Tcl_CreateCommand(interp, "kn_spnego", kn_spnego, NULL, NULL); return NS_OK; } /* *---------------------------------------------------------------------- * * kn_spnego -- * * Gets the authentication token and calls the authenticateUser() * function. Send the authentication results back to the tcl filter. * * Results: * NS_OK * *---------------------------------------------------------------------- */ static int kn_spnego(ClientData context, Tcl_Interp * interp, int argc, char **argv) { FILE *fd = NULL; int keybits = 0; int firstarg = 1; char *token = NULL; Ns_Log(Notice, "KN_SPNEGO_**********_ kn_spneg(): argsnmb = %d", argc ); // DebugBreak(); token = argv[firstarg]; char *authUser =NULL; authenticateUser (/*connPtr,*/&authUser, (const char *)token); Ns_Log(Notice, "knspnego - ***AUTHENTICATED USER Before sending IS %s", authUser); Tcl_AppendResult(interp, authUser, NULL); if(authUser) { ns_free(authUser); } return TCL_OK; } --- NEW FILE: mod_spnego.cpp --- /* ----------------------------------------------------------------------------- * mod_spnego.cpp - is modified version of mod_spnego.c to support * authentication for AOLServer, via the RFC 2478 SPNEGO GSS-API mechanism. * * Original mod_spnego.c was supporting GSS-API authentication mechanism for * Apache web server * * Assumes use from a TCL-based pre-auth filter. * * Author: Avet Mnatsakanian * Authors of original module: Frank Balluffi and Markus Moeller * */ /* Copyright 2000-2005 The Apache Software Foundation or its licensors, as * applicable. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "ns.h" #include "string.h" #undef strcasecmp #undef strncasecmp #ifdef HEIMDAL #include <gssapi.h> #define gss_nt_service_name GSS_C_NT_HOSTBASED_SERVICE #elif defined(SEAM) #include <gssapi/gssapi.h> #define gss_nt_service_name GSS_C_NT_HOSTBASED_SERVICE #else #include <gssapi_generic.h> #endif #include "spnegohelp.h" #include "krb5help.h" #include "spnegoconfig.h" #include "base64.h" #include <errno.h> static char * connectionUser; DIRECTORY_CONFIG* SPNEGO_CONFIG::directoryConfig = NULL; SERVER_CONFIG* SPNEGO_CONFIG::serverConfig = NULL; const char *SPNEGO_CONFIG::authType=NULL; static int handleKerberosToken (char **authUser, const unsigned char * inputKerberosToken, size_t inputKerberosTokenLength, unsigned char ** outputKerberosToken, size_t * outputKerberosTokenLength) { gss_buffer_desc buffer = GSS_C_EMPTY_BUFFER; gss_buffer_desc serviceBuffer = GSS_C_EMPTY_BUFFER; gss_name_t clientName = GSS_C_NO_NAME; gss_ctx_id_t context = GSS_C_NO_CONTEXT; gss_cred_id_t credential = GSS_C_NO_CREDENTIAL; gss_buffer_desc inputToken = GSS_C_EMPTY_BUFFER; OM_uint32 majorStatus; OM_uint32 minorStatus1; OM_uint32 minorStatus2; gss_buffer_desc outputToken = GSS_C_EMPTY_BUFFER; int rc = TCL_OK; gss_name_t serverName = GSS_C_NO_NAME; char * ServiceName = NULL; char * Krb5ServiceName = NULL; const char * Krb5KeyTabFile = NULL; errno = 0; Krb5ServiceName = (char *)(SPNEGO_CONFIG::getDirConfig())->getKrb5ServiceName(); ServiceName = strtok(Krb5ServiceName," "); while ( ServiceName != NULL ) { serviceBuffer.value = ns_strdup(ServiceName); serviceBuffer.length = sizeof (serviceBuffer.value) ; Ns_Log(Notice, "mod_SPNEGO - handleKerberosToken_1 ServiceName=%s",ServiceName); if (strchr(ServiceName,'/')) { Ns_Log(Notice, "mod_SPNEGO - handleKerberosToken_2 "); majorStatus = gss_import_name (&minorStatus1, &serviceBuffer, (gss_OID) GSS_C_NULL_OID, &serverName); } else { Ns_Log(Notice, "mod_SPNEGO - handleKerberosToken_3 gss_nt_service_name=%s",gss_nt_service_name); Ns_Log(Notice, "mod_SPNEGO - handleKerberosToken_3 gss_nt_service_name=%s",(char *)&serverName); majorStatus = gss_import_name (&minorStatus1, &serviceBuffer, (gss_OID) gss_nt_service_name, &serverName); } ServiceName = strtok(NULL," "); if (majorStatus != GSS_S_COMPLETE) { Ns_Log(Notice, "mod_SPNEGO - handleKerberosToken_4;GSS_S_COMPLETE - not"); return HTTP_INTERNAL_SERVER_ERROR; } /* Optionally, set environment variable KRB5_KTNAME. */ Krb5KeyTabFile = (const char *)(SPNEGO_CONFIG::getDirConfig())->getKrb5KeyTabFile(); //#ifdef _WINDOWS if (Krb5KeyTabFile) { if(apr_env_set("KRB5_KTNAME", Krb5KeyTabFile ) != APR_SUCCESS) { Ns_Log(Error, "mod_SPNEGO_*******handleKerberosToken unable to set KRB5_KTNAME to %s", Krb5KeyTabFile); } else #ifdef HEIMDAL gsskrb5_register_acceptor_identity(Krb5KeyTabFile); #endif Ns_Log(Notice, "mod_SPNEGO_*******handleKerberosToken set KRB5_KTNAME to %s", Krb5KeyTabFile); ; } //#endif majorStatus = gss_acquire_cred (&minorStatus1, serverName, 0, GSS_C_NULL_OID_SET, GSS_C_ACCEPT, &credential, NULL, NULL); if (serverName != GSS_C_NO_NAME) { Ns_Log(Notice, "mod_SPNEGO - handleKerberosToken_5;GSS_C_NO_NAME - not"); gss_release_name (&minorStatus2, &serverName); serverName = GSS_C_NO_NAME; } Ns_Log(Notice, "mod_SPNEGO - handleKerberosToken_1xx majorStatus_acquire_cred=%u",majorStatus); if (majorStatus != GSS_S_COMPLETE) { // logGssApiError (APLOG_MARK, APLOG_ERR, r, "mod_spnego: gss_acquire_cred failed", majorStatus, minorStatus1); Ns_Log(Notice, "mod_SPNEGO - handleKerberosToken_6;GSS_S_COMPLETE - not"); rc = HTTP_INTERNAL_SERVER_ERROR; continue; } /* Normally, gss_accept_sec_context returns GSS_S_CONTINUE_NEEDED if it needs to be called again. In this context, gss_accept_sec_context should not return GSS_S_CONTINUE_NEEDED. If gss_accept_sec_context returns GSS_S_CONTINUE_NEEDED, the decision to release clientName is based on it's value (GSS_C_NO_NAME or not GSS_C_NO_NAME) and outputToken is delegated to gss_release_buffer -- RFC 2744 is not clear about this case. */ inputToken.value = (unsigned char *) inputKerberosToken; inputToken.length = inputKerberosTokenLength; majorStatus = gss_accept_sec_context (&minorStatus1, &context, credential, &inputToken, GSS_C_NO_CHANNEL_BINDINGS, &clientName, NULL, &outputToken, NULL, NULL, NULL); if (credential != GSS_C_NO_CREDENTIAL) { Ns_Log(Notice, "mod_SPNEGO - handleKerberosToken_7 GSS_C_NO_CREDENTIAL"); gss_release_cred (&minorStatus2, &credential); credential = GSS_C_NO_CREDENTIAL; } if (context != GSS_C_NO_CONTEXT) { Ns_Log(Notice, "mod_SPNEGO - handleKerberosToken_8 GSS_C_NO_CONTEXT"); gss_delete_sec_context (&minorStatus2, &context, GSS_C_NO_BUFFER); context = GSS_C_NO_CONTEXT; } if (majorStatus != GSS_S_COMPLETE) { // logGssApiError (APLOG_MARK, APLOG_ERR, r, "mod_spnego: gss_accept_sec_context failed", majorStatus, minorStatus1); Ns_Log(Notice, "mod_SPNEGO - handleKerberosToken_9 GSS_C_NO_CONTEXT"); rc = HTTP_INTERNAL_SERVER_ERROR; continue; } /* Pass client (or user) name to authorization hook. */ Ns_Log(Notice, "mod_SPNEGO - handleKerberosToken buffe_10r is %s", buffer); majorStatus = gss_display_name (&minorStatus1, clientName, &buffer, NULL); if (majorStatus != GSS_S_COMPLETE) { // logGssApiError (APLOG_MARK, APLOG_ERR, r, "mod_spnego: gss_display_name failed", majorStatus, minorStatus1); rc = HTTP_INTERNAL_SERVER_ERROR; goto cleanup; } /* http://httpd.apache.org/docs/misc/API.html says, "You can also see how some bugs have manifested themself, such as setting connection->user to a value from r->pool -- in this case connection exists for the lifetime of ptrans, which is longer than r->pool (especially if r->pool is a subrequest!). So the correct thing to do is to allocate from connection->pool." Apache 1.3 stores user in connection substructure of request_rec. Apache 2.0 stores user in request_rec. */ // connPtr->authUser = ns_strdup((const char*)buffer.value); *authUser = ns_strdup((const char*)buffer.value); Ns_Log(Notice, "mod_SPNEGO_*******AUTHENTICATED USER IS %s", *authUser); gss_release_buffer (&minorStatus1, &buffer); if (outputToken.length) { *outputKerberosToken = (unsigned char*)ns_malloc (outputToken.length); if (!*outputKerberosToken) { rc = HTTP_INTERNAL_SERVER_ERROR; goto cleanup; } memcpy (*outputKerberosToken, outputToken.value, outputToken.length); *outputKerberosTokenLength = outputToken.length; } rc = APR_SUCCESS;// rc = OK; goto cleanup; } ns_free(serviceBuffer.value); cleanup: if (clientName != GSS_C_NO_NAME) { gss_release_name (&minorStatus1, &clientName); clientName = GSS_C_NO_NAME; } gss_release_buffer (&minorStatus1, &outputToken); return rc; } /* ----------------------------------------------------------------------------- * handleSpnegoToken handles an RFC 2478 SPNEGO GSS-API token. * * If handleSpnegoToken is successful, call free (outputSpnegoToken), where * outputSpnegoToken is of type unsigned char *, to free the memory allocated by * handleSpnegoToken. * * Returns an Apache response code. * ----------------------------------------------------------------------------- */ static int handleSpnegoToken (/*Conn *connPtr,*/ char** authUser, const unsigned char * inputSpnegoToken, size_t inputSpnegoTokenLength, unsigned char ** outputSpnegoToken, size_t * outputSpnegoTokenLength) { /* Patch by Frank Taylor */ int brokenOID = 0; unsigned char * inputKerberosToken = NULL; size_t inputKerberosTokenLength = 0; long negResult; unsigned char * outputKerberosToken = NULL; size_t outputKerberosTokenLength = 0; int rc; errno = 0; #ifdef _DEBUG DebugBreak(); #endif if (!parseSpnegoInitialToken (inputSpnegoToken, inputSpnegoTokenLength, &krb5GssApi, &inputKerberosToken, &inputKerberosTokenLength)) { Ns_Log(Notice, "mod_SPNEGO_**********parseSpnegoInitialToken failed for 1.2.840.113554.1.2.2"); /* The correct mechanism OID does not work, let's just check the broken MS one in case this is an old W2K client. - Frank Taylor */ if (inputKerberosToken) ns_free ((void *)inputKerberosToken); inputKerberosToken = NULL; if (!parseSpnegoInitialToken (inputSpnegoToken, inputSpnegoTokenLength, &msKrb5GssApiLegacy, &inputKerberosToken, &inputKerberosTokenLength)) { Ns_Log(Notice, "mod_SPNEGO_**********parseSpnegoInitialToken failed for 1.2.840.48018.1.2.2"); /* Ideally, handleKerberosToken should be called by authenticateUser, not by handleSpnegoToken. For more information, see comment in authenticateUser. */ rc = handleKerberosToken (authUser, inputSpnegoToken, inputSpnegoTokenLength, outputSpnegoToken, outputSpnegoTokenLength); Ns_Log(Notice, "mod_SPNEGO_********** After -1 calling handleKerberosToken"); if (inputKerberosToken) ns_free ((void *)inputKerberosToken); inputKerberosToken = NULL; return rc; } //AMX: repl by NS_Log ap_log_rerror (APLOG_MARK, PORTABLE_APLOG_INFO, r, "mod_spnego: parseSpnegoInitialToken succeeded for 1.2.840.48018.1.2.2 -- probably Windows 2000 client"); brokenOID = 1; } Ns_Log(Notice, "mod_SPNEGO_********** before -2 calling handleKerberosToken"); rc = handleKerberosToken (authUser, inputKerberosToken, inputKerberosTokenLength, &outputKerberosToken, &outputKerberosTokenLength); Ns_Log(Notice, "mod_SPNEGO_********** After -2 calling handleKerberosToken outputKerberosToken=%s",&outputKerberosToken); if (inputKerberosToken) free ((void *)inputKerberosToken); negResult = 0; if (!makeSpnegoTargetToken (&negResult, /* Frank Taylor */ (brokenOID ? &msKrb5GssApiLegacy : &krb5GssApi), outputKerberosToken, outputKerberosTokenLength, NULL, 0, outputSpnegoToken, outputSpnegoTokenLength)) { Ns_Log(Notice, "mod_SPNEGO_********** After -3 calling makeSpnegoTargetToken outputSpnegoToken=%s",&outputSpnegoToken); return HTTP_INTERNAL_SERVER_ERROR; } return rc; } /* ----------------------------------------------------------------------------- * authenticateUser authenticates a user (or Apache client). * * Returns an Apache response code. * ----------------------------------------------------------------------------- */ //static int authenticateUser (Conn * conPtr) int authenticateUser (char **authUser, const char *authToken) { static unsigned char ntlmProtocol [] = {'N', 'T', 'L', 'M', 'S', 'S', 'P', 0}; const char * authType = NULL; unsigned char * inputToken = NULL; size_t inputTokenLength = NULL; //sizeof (authToken); //AMX: auth token already decoded in tcl; unsigned char * outputToken = NULL; size_t outputTokenLength = 0; int rc; char * string = NULL; errno = 0; /* Get AuthType. */ authType = SPNEGO_CONFIG::getAuthType(); //getting authType from config params if (!authType || strcasecmp (authType, "SPNEGO")) { //AMX: repl by NS_Log ap_log_rerror (APLOG_MARK, PORTABLE_APLOG_INFO, r, "mod_spnego: unrecognized AuthType \'%s\'", authType ? authType : "NULL"); return -1;// DECLINED; } //AMX: The request for already authenticatedUser (... [truncated message content] |