#include <ctype.h>
+#include "nsMoonshotSessionState.h"
#include "nsHttpMoonshot.h"
/* #define HAVE_GSS_C_NT_HOSTBASED_SERVICE 1 */
free(mechstr);
}
-class nsMoonshotSessionState : public nsISupports
+gss_OID
+GetOID()
{
-public:
- NS_DECL_ISUPPORTS
+ gss_OID mech_oid;
- 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); }
-
- // 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; i<mech_set->count; 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();
#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,
{
nsMoonshotSessionState *session = (nsMoonshotSessionState *) *sessionState;
- *identityInvalid = PR_FALSE;
//
// Use this opportunity to instantiate the session object
// that gets used later when we generate the credentials.
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));
+ LOG(("nsHttpMoonshot::Still using context from previous request\n"));
}
+ LOG(("nsHttpMoonshot:: gss_state = %d\n", session->gss_state));
+
+ *identityInvalid =
+ (session->gss_state == GSS_CTX_EMPTY) ? PR_TRUE : PR_FALSE;
+
return NS_OK;
}
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;
nsCOMPtr<nsIURI> uri;
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
//}
}
- /* 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());
- tmp_token.value = (void *) "steve@local";
+ LOG(("Acquiring credentials for user '%s' using password '%s'\n",
+ u, p));
+
+ 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,
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,
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);
//
// TEST
// session->Reset();
- session->context_state = 2;
+ session->gss_state = GSS_CTX_ESTABLISHED;
LOG(("GSS Auth done"));
} else if (major_status == GSS_S_CONTINUE_NEEDED) {
//
// next call.
//
// TEST
- session->context_state = 1;
+ session->gss_state = GSS_CTX_IN_PROGRESS;
LOG(("GSS Auth continuing"));
}
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;
}
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;
}
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;
}
(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