X-Git-Url: http://www.project-moonshot.org/gitweb/?p=moonshot-firefox.git;a=blobdiff_plain;f=nsHttpMoonshot.cpp;h=a09a0cee71b1f4dfa6ba6a4c8027e172861ffe2b;hp=f67de0c4ea2d3a2c5d31ad1a26120d1d507000f5;hb=HEAD;hpb=05ccce99ee775c0422e3b8ef4e96ddb21d37ab96 diff --git a/nsHttpMoonshot.cpp b/nsHttpMoonshot.cpp index f67de0c..a09a0ce 100644 --- a/nsHttpMoonshot.cpp +++ b/nsHttpMoonshot.cpp @@ -35,6 +35,7 @@ #define FORCE_PR_LOG 1 #include +#include "nsAutoRef.h" #include "nsCOMPtr.h" #include "nsIHttpChannel.h" #include "nsIServiceManager.h" @@ -58,6 +59,7 @@ #include +#include "nsMoonshotSessionState.h" #include "nsHttpMoonshot.h" /* #define HAVE_GSS_C_NT_HOSTBASED_SERVICE 1 */ @@ -68,6 +70,14 @@ #endif #endif +NS_SPECIALIZE_TEMPLATE +class nsAutoRefTraits : public nsPointerRefTraits +{ +public: + static void Release(nsMoonshotSessionState *ptr) { ptr->Release(); } + static void AddRef(nsMoonshotSessionState *ptr) { ptr->AddRef(); } +}; + static gss_OID_desc gss_krb5_mech_oid_desc = {9, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x02"}; @@ -123,90 +133,15 @@ parse_oid(char *mechanism, gss_OID * oid) free(mechstr); } -class nsMoonshotSessionState : public nsISupports +gss_OID +GetOID() { -public: - NS_DECL_ISUPPORTS - - nsMoonshotSessionState(); - - virtual ~nsMoonshotSessionState() { - OM_uint32 minor_status; - if (mCtx != GSS_C_NO_CONTEXT) - (void)gss_delete_sec_context(&minor_status, &mCtx, GSS_C_NO_BUFFER); - mCtx = GSS_C_NO_CONTEXT; - mech_oid = GSS_C_NO_OID; - } - - NS_IMETHOD Reset() { - OM_uint32 minor_status; - if (mCtx != GSS_C_NO_CONTEXT) - (void)gss_delete_sec_context(&minor_status, &mCtx, GSS_C_NO_BUFFER); - mCtx = GSS_C_NO_CONTEXT; - context_state = 0; - return NS_OK; - } - gss_OID GetOID() { return (mech_oid); } + gss_OID mech_oid; - // TEST - int GetCount() { return ++count; } - - gss_ctx_id_t mCtx; - int context_state; -private: - gss_OID mech_oid; - int count; -}; - -nsMoonshotSessionState::nsMoonshotSessionState() -{ - OM_uint32 minstat, majstat; - //gss_buffer_desc buffer; - gss_OID_set mech_set; - //int mech_found = 0; - unsigned int i; - gss_OID item; - - - mCtx = GSS_C_NO_CONTEXT; - mech_oid = &gss_krb5_mech_oid_desc; - context_state = 0; - - // - // Now, look at the list of supported mechanisms, - // if SPNEGO is found, then use it. - // Otherwise, set the desired mechanism to krb5 - // - // Using Kerberos directly (instead of negotiating - // with SPNEGO) may work in some cases depending - // on how smart the server side is. - // - - // TEST - count = 0; - LOG(("nsMoonshotSessionState::nsMoonshotSessionState [count=%d]\n", count)); - - majstat = gss_indicate_mechs(&minstat, &mech_set); - if (GSS_ERROR(majstat)) - return; - - for (i=0; icount; i++) { - item = &mech_set->elements[i]; - if (item->length == gss_spnego_mech_oid_desc.length && - !memcmp(item->elements, gss_spnego_mech_oid_desc.elements, - item->length)) { - mech_oid = &gss_spnego_mech_oid_desc; - break; - } - } - (void) gss_release_oid_set(&minstat, &mech_set); -/* HACK: */ - parse_oid("{1 3 6 1 4 1 5322 22 1 18}", &mech_oid); + parse_oid("{1 3 6 1 4 1 5322 22 1 18}", &mech_oid); + return mech_oid; } -NS_IMPL_ISUPPORTS0(nsMoonshotSessionState) - -#if 1 nsHttpMoonshot::nsHttpMoonshot() { NS_INIT_ISUPPORTS(); @@ -217,34 +152,18 @@ nsHttpMoonshot::nsHttpMoonshot() #endif /* PR_LOGGING */ } -#endif -#if 1 nsHttpMoonshot::~nsHttpMoonshot() { } -#endif NS_IMETHODIMP nsHttpMoonshot::GetAuthFlags(PRUint32 *flags) { - // - // GSSAPI creds should not be reused across multiple requests. - // Only perform the negotiation when it is explicitly requested - // by the server. Thus, do *NOT* use the "REUSABLE_CREDENTIALS" - // flag here. - // *flags = REQUEST_BASED; return NS_OK; } -// -// Always set *identityInvalid == FALSE here. This -// will prevent the browser from popping up the authentication -// prompt window. Because GSSAPI does not have an API -// for fetching initial credentials (ex: A Kerberos TGT), -// there is no correct way to get the users credentials. -// NS_IMETHODIMP nsHttpMoonshot::ChallengeReceived(nsIHttpChannel *httpChannel, const char *challenge, @@ -254,21 +173,10 @@ nsHttpMoonshot::ChallengeReceived(nsIHttpChannel *httpChannel, PRBool *identityInvalid) { nsMoonshotSessionState *session = (nsMoonshotSessionState *) *sessionState; - - *identityInvalid = PR_FALSE; - // - // Use this opportunity to instantiate the session object - // that gets used later when we generate the credentials. - // - if (!session) { - session = new nsMoonshotSessionState(); - if (!session) - return(NS_ERROR_OUT_OF_MEMORY); - NS_ADDREF(*sessionState = session); - LOG(("nsHttpMoonshot::A new session context established\n")); - } else { - LOG(("nsHttpMoonshot::Still using context from previous request [ctx=%p]\n", session->mCtx)); - } + if (session==NULL) + session = (nsMoonshotSessionState *) *continuationState; + *identityInvalid = + ((session==NULL) || (session->gss_state == GSS_CTX_EMPTY)) ? PR_TRUE : PR_FALSE; return NS_OK; } @@ -368,9 +276,9 @@ nsHttpMoonshot::GenerateCredentials_1_9_2(nsIHttpChannel *httpChannel, gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER; gss_buffer_t in_token_ptr = GSS_C_NO_BUFFER; gss_name_t server; - nsMoonshotSessionState *session = (nsMoonshotSessionState *) *sessionState; - gss_cred_id_t cred = GSS_C_NO_CREDENTIAL; - + nsCountedRef session(static_cast(*sessionState)); + if (!session) + session = static_cast(*continuationState); nsCOMPtr uri; nsresult rv; @@ -394,7 +302,7 @@ nsHttpMoonshot::GenerateCredentials_1_9_2(nsIHttpChannel *httpChannel, service.get())); // TEST - LOG(("nsHttpMoonshot::Count [count=%d]\n", session->GetCount())); +// LOG(("nsHttpMoonshot::Count [count=%d]\n", session->GetCount())); // // The correct service name for IIS servers is "HTTP/f.q.d.n", so @@ -429,6 +337,16 @@ nsHttpMoonshot::GenerateCredentials_1_9_2(nsIHttpChannel *httpChannel, return NS_ERROR_FAILURE; } + // Create session state if none added yet. + if (!session) { + session = new nsMoonshotSessionState(); + if (!session) + return(NS_ERROR_OUT_OF_MEMORY); + LOG(("nsHttpMoonshot::A new session context established\n")); + } else { + LOG(("nsHttpMoonshot::Still using context from previous request\n")); + } + // // If the "Negotiate:" header had some data associated with it, // that data should be used as the input to this call. This may @@ -497,14 +415,21 @@ nsHttpMoonshot::GenerateCredentials_1_9_2(nsIHttpChannel *httpChannel, //} } - /* HACK */ + if (session->gss_cred == GSS_C_NO_CREDENTIAL) { OM_uint32 maj_stat, min_stat; gss_buffer_desc tmp_token; gss_name_t gss_username = GSS_C_NO_NAME; gss_OID_set_desc mechs, *mechsp = GSS_C_NO_OID_SET; + const char *p, *u; + + u = strdup(NS_LossyConvertUTF16toASCII(username).get()); + p = strdup(NS_LossyConvertUTF16toASCII(password).get()); + + LOG(("Acquiring credentials for user '%s' using password '%s'\n", + u, p)); - tmp_token.value = (void *) "steve@local"; + tmp_token.value = (void *) u; tmp_token.length = strlen((const char *)tmp_token.value); maj_stat = gss_import_name(&min_stat, &tmp_token, GSS_C_NT_USER_NAME, @@ -516,28 +441,31 @@ nsHttpMoonshot::GenerateCredentials_1_9_2(nsIHttpChannel *httpChannel, return NS_ERROR_FAILURE; } - mechs.elements = session->GetOID(); + mechs.elements = GetOID(); mechs.count = 1; mechsp = &mechs; - tmp_token.value = (void *)"testing"; - tmp_token.length = strlen((const char*)tmp_token.value); + tmp_token.value = (void *) p; + tmp_token.length = strlen(p);//strlen((const char*)tmp_token.value); maj_stat = gss_acquire_cred_with_password(&min_stat, gss_username, &tmp_token, 0, mechsp, GSS_C_INITIATE, - &cred, NULL, NULL); + &session->gss_cred, NULL, NULL); if (GSS_ERROR(maj_stat)) { LogGssError(maj_stat, min_stat, "gss_acquire_cred_with_password()"); session->Reset(); return NS_ERROR_FAILURE; } + + LOG(("Acquired credential for user '%s' using password '%s'\n", + u, p)); } major_status = gss_init_sec_context(&minor_status, - cred, - &session->mCtx, + session->gss_cred, + &session->gss_ctx, server, - session->GetOID(), + GetOID(), GSS_C_MUTUAL_FLAG, /* GSS_C_INDEFINITE */ 0, GSS_C_NO_CHANNEL_BINDINGS, @@ -550,7 +478,7 @@ nsHttpMoonshot::GenerateCredentials_1_9_2(nsIHttpChannel *httpChannel, if (GSS_ERROR(major_status)) { LogGssError(major_status, minor_status, "gss_init_sec_context() failed"); (void) gss_release_name(&minor_status, &server); - gss_release_cred(&minor_status, &cred); +// gss_release_cred(&minor_status, &cred); session->Reset(); if (input_token.length > 0 && input_token.value != NULL) (void) gss_release_buffer(&minor_status, &input_token); @@ -563,7 +491,14 @@ nsHttpMoonshot::GenerateCredentials_1_9_2(nsIHttpChannel *httpChannel, // // TEST // session->Reset(); - session->context_state = 2; + session->gss_state = GSS_CTX_ESTABLISHED; + if (*sessionState != session) + { + NS_ADDREF(*sessionState = session); + // clean up continuation state + if (*continuationState) + NS_RELEASE(*continuationState); + } LOG(("GSS Auth done")); } else if (major_status == GSS_S_CONTINUE_NEEDED) { // @@ -575,7 +510,12 @@ nsHttpMoonshot::GenerateCredentials_1_9_2(nsIHttpChannel *httpChannel, // next call. // // TEST - session->context_state = 1; + session->gss_state = GSS_CTX_IN_PROGRESS; + if (*continuationState != session) + { + // Assert continuationState==NULL + NS_ADDREF(*continuationState = session); + } LOG(("GSS Auth continuing")); } @@ -586,7 +526,7 @@ nsHttpMoonshot::GenerateCredentials_1_9_2(nsIHttpChannel *httpChannel, if (output_token.length == 0) { LOG(("No GSS output token to send, exiting")); (void) gss_release_name(&minor_status, &server); - gss_release_cred(&minor_status, &cred); +// gss_release_cred(&minor_status, &cred); return NS_ERROR_FAILURE; } @@ -601,19 +541,19 @@ nsHttpMoonshot::GenerateCredentials_1_9_2(nsIHttpChannel *httpChannel, if (!encoded_token) { (void) gss_release_buffer(&minor_status, &output_token); (void) gss_release_name(&minor_status, &server); - gss_release_cred(&minor_status, &cred); +// gss_release_cred(&minor_status, &cred); return NS_ERROR_OUT_OF_MEMORY; } LOG(("Sending a token of length %d\n", output_token.length)); // allocate a buffer sizeof("Negotiate" + " " + b64output_token + "\0") - *creds = (char *) malloc (strlen(NEGOTIATE_AUTH) + 1 + strlen(encoded_token) + 1); + *creds = (char *) PR_Malloc (strlen(NEGOTIATE_AUTH) + 1 + strlen(encoded_token) + 1); if (!(*creds)) { PR_Free(encoded_token); (void) gss_release_buffer(&minor_status, &output_token); (void) gss_release_name(&minor_status, &server); - gss_release_cred(&minor_status, &cred); +// gss_release_cred(&minor_status, &cred); return NS_ERROR_OUT_OF_MEMORY; } @@ -622,18 +562,9 @@ nsHttpMoonshot::GenerateCredentials_1_9_2(nsIHttpChannel *httpChannel, (void) gss_release_buffer(&minor_status, &output_token); (void) gss_release_name(&minor_status, &server); - gss_release_cred(&minor_status, &cred); +// gss_release_cred(&minor_status, &cred); LOG(("returning the call")); return NS_OK; } - -#if 0 -static NS_METHOD -nsMoonshotConstructor(nsISupports *outer, REFNSIID iid, void **result) -{ - if (outer) - return NS_ERROR_NO_AGGREGATION; -} -#endif