зеркало из https://github.com/mozilla/gecko-dev.git
553 строки
11 KiB
C++
Executable File
553 строки
11 KiB
C++
Executable File
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
*
|
|
* The contents of this file are subject to the Netscape Public License
|
|
* Version 1.0 (the "NPL"); you may not use this file except in
|
|
* compliance with the NPL. You may obtain a copy of the NPL at
|
|
* http://www.mozilla.org/NPL/
|
|
*
|
|
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
|
* for the specific language governing rights and limitations under the
|
|
* NPL.
|
|
*
|
|
* The Initial Developer of this code under the NPL is Netscape
|
|
* Communications Corporation. Portions created by Netscape are
|
|
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
|
* Reserved.
|
|
*/
|
|
/* ****************************************************************************
|
|
*
|
|
*/
|
|
#include "stdafx.h"
|
|
#include <windows.h>
|
|
#include <ole2.h>
|
|
#include "DAIntf.h"
|
|
#include "xp.h"
|
|
|
|
#include <initguid.h>
|
|
#include "DAIntf.h"
|
|
|
|
|
|
/* ****************************************************************************
|
|
*
|
|
*/
|
|
class CDALoader
|
|
{
|
|
IDAProcess *m_pIDAProcess;
|
|
|
|
public:
|
|
|
|
CDALoader(void);
|
|
~CDALoader(void);
|
|
|
|
IDAProcess *Load(void);
|
|
|
|
IDAProcess *Interface(void) { return m_pIDAProcess; }
|
|
};
|
|
|
|
|
|
/* ****************************************************************************
|
|
*
|
|
*/
|
|
CDALoader::CDALoader(void)
|
|
: m_pIDAProcess(NULL)
|
|
{
|
|
}
|
|
|
|
|
|
/* ****************************************************************************
|
|
*
|
|
*/
|
|
CDALoader::~CDALoader(void)
|
|
{
|
|
if (m_pIDAProcess)
|
|
{
|
|
m_pIDAProcess->Release();
|
|
|
|
CoUninitialize();
|
|
}
|
|
}
|
|
|
|
|
|
/* ****************************************************************************
|
|
*
|
|
*/
|
|
IDAProcess * CDALoader::Load(void)
|
|
{
|
|
static tried_once = FALSE;
|
|
|
|
|
|
if (m_pIDAProcess)
|
|
{
|
|
return m_pIDAProcess;
|
|
}
|
|
|
|
if(tried_once)
|
|
return NULL;
|
|
else
|
|
tried_once = TRUE;
|
|
|
|
if (SUCCEEDED(CoInitialize(NULL)))
|
|
{
|
|
if (SUCCEEDED(CoCreateInstance(CLSID_DA,
|
|
NULL,
|
|
CLSCTX_INPROC_SERVER,
|
|
IID_IDAProcess,
|
|
(LPVOID *)&m_pIDAProcess)))
|
|
{
|
|
return m_pIDAProcess;
|
|
}
|
|
|
|
CoUninitialize();
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
/* ****************************************************************************
|
|
*
|
|
*/
|
|
PRIVATE XP_List * address_auth_list = 0;
|
|
static CDALoader g_DA;
|
|
|
|
/* ****************************************************************************
|
|
*
|
|
*/
|
|
class CDAPacket : public IDAPacket
|
|
{
|
|
LONG m_cRef;
|
|
char * m_pPassedInHeader;
|
|
|
|
public:
|
|
CDAPacket(char *pHeader);
|
|
~CDAPacket(void);
|
|
|
|
char * m_pNewHeaders;
|
|
|
|
// IUnknown methods.
|
|
STDMETHOD_(ULONG, AddRef)(THIS);
|
|
STDMETHOD_(ULONG, Release)(THIS);
|
|
STDMETHOD(QueryInterface)(THIS_
|
|
REFIID riid,
|
|
LPVOID *ppvObject);
|
|
|
|
// IDAPacket methods.
|
|
STDMETHOD(AddNameValue)(THIS_
|
|
const TCHAR *pszName,
|
|
const TCHAR *pszValue);
|
|
|
|
STDMETHOD(FindValue)(THIS_
|
|
const TCHAR *pszName,
|
|
const TCHAR *pszSubName,
|
|
TCHAR * pszValue,
|
|
DWORD cbValue) const;
|
|
|
|
STDMETHOD(ReplaceNameValue)(THIS_
|
|
const TCHAR *pszName,
|
|
const TCHAR *pszValue);
|
|
};
|
|
|
|
/* ****************************************************************************
|
|
*
|
|
*/
|
|
struct address_auth_assoc {
|
|
char *address;
|
|
CDAPacket *auth;
|
|
};
|
|
|
|
|
|
/* ****************************************************************************
|
|
*
|
|
*/
|
|
CDAPacket::CDAPacket(char *pPassedInHeader)
|
|
: m_cRef(1),
|
|
m_pNewHeaders(NULL)
|
|
{
|
|
m_pPassedInHeader = pPassedInHeader;
|
|
}
|
|
|
|
|
|
/* ****************************************************************************
|
|
*
|
|
*/
|
|
CDAPacket::~CDAPacket(void)
|
|
{
|
|
if(m_pNewHeaders)
|
|
XP_FREE(m_pNewHeaders);
|
|
}
|
|
|
|
|
|
/* ****************************************************************************
|
|
*
|
|
*/
|
|
STDMETHODIMP_(ULONG) CDAPacket::AddRef(void)
|
|
{
|
|
#ifdef WIN32
|
|
return InterlockedIncrement(&m_cRef);
|
|
#else
|
|
return ++m_cRef;
|
|
#endif
|
|
}
|
|
|
|
|
|
/* ****************************************************************************
|
|
*
|
|
*/
|
|
STDMETHODIMP_(ULONG) CDAPacket::Release(void)
|
|
{
|
|
#ifdef WIN32
|
|
return InterlockedDecrement(&m_cRef);
|
|
#else
|
|
return --m_cRef;
|
|
#endif
|
|
}
|
|
|
|
|
|
/* ****************************************************************************
|
|
*
|
|
*/
|
|
STDMETHODIMP CDAPacket::QueryInterface
|
|
(
|
|
REFIID riid,
|
|
LPVOID * ppvObject
|
|
)
|
|
{
|
|
if (!ppvObject)
|
|
{
|
|
return ResultFromScode(E_INVALIDARG);
|
|
}
|
|
|
|
*ppvObject = NULL;
|
|
|
|
if (riid == IID_IDAPacket)
|
|
{
|
|
*ppvObject = (IDAPacket *)this;
|
|
} else if (riid == IID_IUnknown)
|
|
{
|
|
*ppvObject = (IUnknown *)this;
|
|
}
|
|
else
|
|
{
|
|
return ResultFromScode(E_NOINTERFACE);
|
|
}
|
|
|
|
AddRef();
|
|
|
|
return NOERROR;
|
|
}
|
|
|
|
|
|
/* ****************************************************************************
|
|
*
|
|
*/
|
|
STDMETHODIMP CDAPacket::AddNameValue
|
|
(
|
|
const TCHAR *pszName,
|
|
const TCHAR *pszValue
|
|
)
|
|
{
|
|
if (!pszName || !pszValue)
|
|
{
|
|
return ResultFromScode(E_FAIL);
|
|
}
|
|
|
|
if(m_pNewHeaders)
|
|
{
|
|
char * tmp = m_pNewHeaders;
|
|
m_pNewHeaders = PR_smprintf("%s%s: %s"CRLF,
|
|
tmp ? tmp : "",
|
|
pszName,
|
|
pszValue);
|
|
XP_FREE(tmp);
|
|
}
|
|
else
|
|
{
|
|
m_pNewHeaders = PR_smprintf("%s: %s"CRLF,
|
|
pszName,
|
|
pszValue);
|
|
}
|
|
|
|
return NOERROR;
|
|
}
|
|
|
|
|
|
/* ****************************************************************************
|
|
*
|
|
*/
|
|
STDMETHODIMP CDAPacket::FindValue
|
|
(
|
|
const TCHAR *pszName,
|
|
const TCHAR *pszSubName,
|
|
TCHAR * pszValue,
|
|
DWORD cbValue
|
|
) const
|
|
{
|
|
|
|
#define WWW_AUTHENTICATE "WWW-Authenticate"
|
|
|
|
if(strncasecomp(pszName, WWW_AUTHENTICATE, sizeof(WWW_AUTHENTICATE) - 1))
|
|
return ResultFromScode(E_FAIL); /* not a valid name */
|
|
|
|
if(pszSubName == NULL)
|
|
{
|
|
strncpy(pszValue, "Remote-Passphrase", CASTSIZE_T(cbValue));
|
|
pszValue[cbValue-1] = '\0';
|
|
return (NOERROR);
|
|
}
|
|
|
|
char *token;
|
|
|
|
while((token = strcasestr(m_pPassedInHeader, pszSubName)))
|
|
{
|
|
/* look for an immediate equal and then a quote
|
|
*/
|
|
char *cp = token;
|
|
char *end_of_value;
|
|
|
|
cp += XP_STRLEN(pszSubName);
|
|
|
|
while(isspace(*cp)) cp++;
|
|
|
|
if(*cp != '=')
|
|
continue;
|
|
|
|
while(isspace(*cp)) cp++;
|
|
|
|
if(*++cp != '"')
|
|
continue;
|
|
|
|
end_of_value = strchr(++cp, '"');
|
|
|
|
if(!end_of_value)
|
|
return ResultFromScode(E_FAIL);
|
|
|
|
*end_of_value = '\0';
|
|
|
|
if(end_of_value - cp > (ptrdiff_t)cbValue)
|
|
{
|
|
*end_of_value = '"';
|
|
return ResultFromScode(E_FAIL);
|
|
}
|
|
|
|
XP_STRCPY(pszValue, cp);
|
|
|
|
*end_of_value = '"';
|
|
|
|
return (NOERROR);
|
|
}
|
|
|
|
return ResultFromScode(E_FAIL);
|
|
}
|
|
|
|
|
|
/* ****************************************************************************
|
|
*
|
|
*/
|
|
STDMETHODIMP CDAPacket::ReplaceNameValue
|
|
(
|
|
const TCHAR *pszName,
|
|
const TCHAR *pszValue
|
|
)
|
|
{
|
|
return ResultFromScode(E_NOTIMPL);
|
|
}
|
|
|
|
|
|
/* ****************************************************************************
|
|
*
|
|
*/
|
|
PRIVATE char *GetMethod(URL_Struct *URL_s)
|
|
{
|
|
if(URL_s->method == URL_POST_METHOD)
|
|
return XP_STRDUP("POST");
|
|
else if(URL_s->method == URL_HEAD_METHOD)
|
|
return XP_STRDUP("HEAD");
|
|
else
|
|
return XP_STRDUP("GET");
|
|
}
|
|
|
|
|
|
/* ****************************************************************************
|
|
*
|
|
*/
|
|
extern "C" int
|
|
WFE_DoCompuserveAuthenticate(MWContext *context,
|
|
URL_Struct *URL_s,
|
|
char *authenticate_header_value)
|
|
{
|
|
struct address_auth_assoc * assoc_obj = 0;
|
|
struct address_auth_assoc * cur_assoc_ptr;
|
|
CDAPacket *auth;
|
|
XP_List *list_ptr;
|
|
char *host;
|
|
HRESULT status;
|
|
|
|
// Load the DA OLE server if it hasn't already been loaded.
|
|
IDAProcess *pIDAProcess = g_DA.Interface();
|
|
|
|
if (!pIDAProcess)
|
|
{
|
|
return NET_AUTH_FAILED_DISPLAY_DOCUMENT;
|
|
}
|
|
|
|
if(!address_auth_list)
|
|
{
|
|
address_auth_list = XP_ListNew();
|
|
if(!address_auth_list)
|
|
return NET_AUTH_FAILED_DISPLAY_DOCUMENT;
|
|
}
|
|
|
|
/* search for an existing association */
|
|
list_ptr = address_auth_list;
|
|
while((cur_assoc_ptr = (address_auth_assoc *)XP_ListNextObject(list_ptr)))
|
|
{
|
|
if(!XP_STRCMP(cur_assoc_ptr->address, URL_s->address))
|
|
{
|
|
assoc_obj = cur_assoc_ptr;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(assoc_obj)
|
|
{
|
|
XP_ListRemoveObject(address_auth_list, assoc_obj);
|
|
delete assoc_obj->auth;
|
|
XP_FREE(assoc_obj->address);
|
|
XP_FREE(assoc_obj);
|
|
}
|
|
|
|
if(URL_s->server_status != 200
|
|
&& URL_s->server_status != 401)
|
|
return(FALSE);
|
|
|
|
|
|
auth = new CDAPacket(authenticate_header_value);
|
|
|
|
auth->m_pNewHeaders = XP_STRDUP("Extension: Security/Remote-Passphrase"CRLF);
|
|
|
|
host = NET_ParseURL(URL_s->address, GET_HOST_PART);
|
|
|
|
if(URL_s->server_status == 401)
|
|
{
|
|
struct SDAAuthData auth_data_struct;
|
|
char username[256] = "";
|
|
char password[256] = "";
|
|
char realm[256] = "";
|
|
char * path = NET_ParseURL(URL_s->address, GET_PATH_PART | GET_SEARCH_PART);
|
|
|
|
auth_data_struct.pIDAPacketIn = auth;
|
|
auth_data_struct.pszHost = host;
|
|
auth_data_struct.pszURI = path;
|
|
auth_data_struct.pszMethod = GetMethod(URL_s);
|
|
auth_data_struct.pIDAPacketOut = auth;
|
|
auth_data_struct.bShowDialog = 1;
|
|
auth_data_struct.hParent = NULL;
|
|
auth_data_struct.pszUsername = username;
|
|
auth_data_struct.wMaxUsername = sizeof(username) - 1;
|
|
auth_data_struct.pszRealmname = realm;
|
|
auth_data_struct.pszPassword = password;
|
|
auth_data_struct.wMaxPassword = sizeof(password) - 1;
|
|
auth_data_struct.pIDAPassword = NULL;
|
|
|
|
status = pIDAProcess->On401Authenticate(&auth_data_struct);
|
|
|
|
if(status == NOERROR)
|
|
{
|
|
assoc_obj = XP_NEW(struct address_auth_assoc);
|
|
|
|
if(!assoc_obj)
|
|
return NET_AUTH_FAILED_DISPLAY_DOCUMENT;
|
|
|
|
assoc_obj->auth = auth;
|
|
assoc_obj->address = XP_STRDUP(URL_s->address);
|
|
XP_ListAddObject(address_auth_list, assoc_obj);
|
|
|
|
XP_FREE(host);
|
|
return(NET_RETRY_WITH_AUTH);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
status = pIDAProcess->On200Authenticate(host, auth);
|
|
}
|
|
|
|
XP_FREE(host);
|
|
delete(auth);
|
|
|
|
if(status != NOERROR)
|
|
return(NET_AUTH_FAILED_DONT_DISPLAY);
|
|
else
|
|
return(NET_AUTH_SUCCEEDED);
|
|
}
|
|
|
|
|
|
/* ****************************************************************************
|
|
*
|
|
*/
|
|
extern "C" char *
|
|
WFE_BuildCompuserveAuthString(URL_Struct *URL_s)
|
|
{
|
|
XP_List * list_ptr;
|
|
struct address_auth_assoc *cur_assoc_ptr;
|
|
struct address_auth_assoc *assoc_obj = NULL;
|
|
static char *rv=NULL; /* malloc and free on successive calls */
|
|
|
|
IDAProcess *pIDAProcess = g_DA.Load();
|
|
|
|
if(pIDAProcess)
|
|
{
|
|
/* search for an existing association */
|
|
list_ptr = address_auth_list;
|
|
while((cur_assoc_ptr = (address_auth_assoc *)XP_ListNextObject(list_ptr)))
|
|
{
|
|
if(!XP_STRCMP(cur_assoc_ptr->address, URL_s->address))
|
|
assoc_obj = cur_assoc_ptr;
|
|
}
|
|
|
|
if(assoc_obj)
|
|
{
|
|
/* since we found it in the assoc list then
|
|
* we have gotten a 401 and are about to
|
|
* send another request. Send the
|
|
* header.
|
|
*/
|
|
return(assoc_obj->auth->m_pNewHeaders);
|
|
}
|
|
|
|
/* if we didn't find it in the assoc list then
|
|
* call the cheat routine to see if we need
|
|
* to send any headers
|
|
*/
|
|
|
|
if(rv)
|
|
{
|
|
XP_FREE(rv);
|
|
rv = NULL;
|
|
}
|
|
|
|
HRESULT status = ResultFromScode(E_FAIL);
|
|
char * host = NET_ParseURL(URL_s->address, GET_HOST_PART);
|
|
char * path = NET_ParseURL(URL_s->address, GET_PATH_PART | GET_SEARCH_PART);
|
|
char * method = GetMethod(URL_s);
|
|
|
|
if(host && path && method)
|
|
{
|
|
CDAPacket daPacket("");
|
|
|
|
status = pIDAProcess->Cheat(host, path, method, &daPacket);
|
|
|
|
rv = XP_STRDUP(daPacket.m_pNewHeaders);
|
|
}
|
|
|
|
if(host)
|
|
XP_FREE(host);
|
|
if(path)
|
|
XP_FREE(path);
|
|
if(method)
|
|
XP_FREE(method);
|
|
}
|
|
|
|
return(rv);
|
|
}
|