home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / winfe / authdll.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  11.8 KB  |  553 lines

  1. /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2.  *
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  *
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  *
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18. /* ****************************************************************************
  19.  *
  20.  */
  21. #include "stdafx.h"
  22. #include <windows.h>
  23. #include <ole2.h>
  24. #include "DAIntf.h"
  25. #include "xp.h"
  26.  
  27. #include <initguid.h>
  28. #include "DAIntf.h"
  29.  
  30.  
  31. /* ****************************************************************************
  32.  *
  33.  */
  34. class    CDALoader
  35. {
  36.     IDAProcess *m_pIDAProcess;
  37.  
  38. public:
  39.     
  40.     CDALoader(void);
  41.     ~CDALoader(void);
  42.  
  43.     IDAProcess *Load(void);
  44.  
  45.     IDAProcess *Interface(void) { return m_pIDAProcess; }
  46. };
  47.  
  48.  
  49. /* ****************************************************************************
  50.  *
  51.  */
  52. CDALoader::CDALoader(void)
  53.     :    m_pIDAProcess(NULL)
  54. {
  55. }
  56.  
  57.  
  58. /* ****************************************************************************
  59.  *
  60.  */
  61. CDALoader::~CDALoader(void)
  62. {
  63.     if    (m_pIDAProcess)
  64.     {
  65.         m_pIDAProcess->Release();
  66.  
  67.         CoUninitialize();
  68.     }
  69. }
  70.  
  71.  
  72. /* ****************************************************************************
  73.  *
  74.  */
  75. IDAProcess *    CDALoader::Load(void)
  76. {
  77.     static tried_once = FALSE;
  78.                
  79.  
  80.     if    (m_pIDAProcess)
  81.     {
  82.         return    m_pIDAProcess;
  83.     }
  84.                
  85.     if(tried_once)
  86.         return NULL;
  87.     else
  88.         tried_once = TRUE;
  89.  
  90.     if    (SUCCEEDED(CoInitialize(NULL)))
  91.     {
  92.         if    (SUCCEEDED(CoCreateInstance(CLSID_DA,
  93.                                         NULL,
  94.                                         CLSCTX_INPROC_SERVER,
  95.                                         IID_IDAProcess,
  96.                                         (LPVOID *)&m_pIDAProcess)))
  97.         {
  98.             return    m_pIDAProcess;
  99.         }
  100.  
  101.         CoUninitialize();
  102.     }
  103.  
  104.     return    NULL;
  105. }
  106.  
  107.  
  108. /* ****************************************************************************
  109.  *
  110.  */
  111. PRIVATE XP_List *     address_auth_list = 0;
  112. static    CDALoader    g_DA;
  113.  
  114. /* ****************************************************************************
  115.  *
  116.  */
  117. class    CDAPacket    :    public    IDAPacket
  118. {
  119.     LONG    m_cRef;
  120.     char *  m_pPassedInHeader;
  121.  
  122. public:
  123.     CDAPacket(char *pHeader);
  124.     ~CDAPacket(void);
  125.  
  126.     char *    m_pNewHeaders;
  127.  
  128.     // IUnknown methods.
  129.     STDMETHOD_(ULONG, AddRef)(THIS);
  130.     STDMETHOD_(ULONG, Release)(THIS);
  131.     STDMETHOD(QueryInterface)(THIS_
  132.                               REFIID riid,
  133.                               LPVOID *ppvObject);
  134.  
  135.     // IDAPacket methods.
  136.     STDMETHOD(AddNameValue)(THIS_
  137.                             const TCHAR *pszName, 
  138.                             const TCHAR *pszValue);
  139.  
  140.     STDMETHOD(FindValue)(THIS_ 
  141.                          const TCHAR *pszName,
  142.                          const TCHAR *pszSubName,
  143.                          TCHAR *      pszValue,
  144.                          DWORD        cbValue)          const;
  145.  
  146.     STDMETHOD(ReplaceNameValue)(THIS_
  147.                                 const TCHAR *pszName, 
  148.                                 const TCHAR *pszValue);
  149. };
  150.  
  151. /* ****************************************************************************
  152.  *
  153.  */
  154. struct address_auth_assoc {
  155.     char *address;
  156.     CDAPacket *auth;
  157. };
  158.  
  159.  
  160. /* ****************************************************************************
  161.  *
  162.  */
  163. CDAPacket::CDAPacket(char *pPassedInHeader)
  164.     :    m_cRef(1),
  165.         m_pNewHeaders(NULL)
  166. {
  167.     m_pPassedInHeader = pPassedInHeader;
  168. }
  169.  
  170.  
  171. /* ****************************************************************************
  172.  *
  173.  */
  174. CDAPacket::~CDAPacket(void)
  175. {
  176.     if(m_pNewHeaders)
  177.         XP_FREE(m_pNewHeaders);
  178. }
  179.  
  180.  
  181. /* ****************************************************************************
  182.  *
  183.  */
  184. STDMETHODIMP_(ULONG)    CDAPacket::AddRef(void)
  185. {
  186. #ifdef WIN32
  187.     return    InterlockedIncrement(&m_cRef);
  188. #else
  189.     return    ++m_cRef;
  190. #endif
  191. }
  192.  
  193.  
  194. /* ****************************************************************************
  195.  *
  196.  */
  197. STDMETHODIMP_(ULONG)    CDAPacket::Release(void)
  198. {
  199. #ifdef WIN32
  200.     return    InterlockedDecrement(&m_cRef);
  201. #else
  202.     return    --m_cRef;
  203. #endif
  204. }
  205.  
  206.  
  207. /* ****************************************************************************
  208.  *
  209.  */
  210. STDMETHODIMP    CDAPacket::QueryInterface
  211. (
  212.     REFIID         riid,
  213.     LPVOID *    ppvObject
  214. )
  215. {
  216.     if    (!ppvObject)
  217.     {
  218.         return    ResultFromScode(E_INVALIDARG);
  219.     }
  220.  
  221.     *ppvObject = NULL;
  222.  
  223.     if    (riid == IID_IDAPacket)
  224.     {
  225.         *ppvObject = (IDAPacket *)this;
  226.     }    else    if    (riid == IID_IUnknown)
  227.     {
  228.         *ppvObject = (IUnknown *)this;
  229.     }
  230.     else
  231.     {
  232.         return    ResultFromScode(E_NOINTERFACE);
  233.     }
  234.  
  235.     AddRef();
  236.  
  237.     return    NOERROR;
  238. }
  239.  
  240.  
  241. /* ****************************************************************************
  242.  *
  243.  */
  244. STDMETHODIMP    CDAPacket::AddNameValue
  245. (
  246.     const TCHAR *pszName, 
  247.     const TCHAR *pszValue
  248. )
  249. {
  250.     if    (!pszName || !pszValue)
  251.     {
  252.         return    ResultFromScode(E_FAIL);
  253.     }
  254.  
  255.     if(m_pNewHeaders)
  256.       {
  257.           char * tmp = m_pNewHeaders;
  258.           m_pNewHeaders = PR_smprintf("%s%s: %s"CRLF, 
  259.                                         tmp ? tmp : "",
  260.                                          pszName, 
  261.                                          pszValue);
  262.         XP_FREE(tmp);
  263.       }
  264.     else
  265.       {
  266.           m_pNewHeaders = PR_smprintf("%s: %s"CRLF, 
  267.                                          pszName, 
  268.                                          pszValue);
  269.       }
  270.  
  271.     return    NOERROR;
  272. }
  273.  
  274.  
  275. /* ****************************************************************************
  276.  *
  277.  */
  278. STDMETHODIMP    CDAPacket::FindValue
  279. (
  280.     const TCHAR *pszName,
  281.     const TCHAR *pszSubName,
  282.     TCHAR *      pszValue,
  283.     DWORD        cbValue
  284. )    const
  285. {
  286.     
  287.     #define WWW_AUTHENTICATE "WWW-Authenticate"
  288.  
  289.     if(strncasecomp(pszName, WWW_AUTHENTICATE, sizeof(WWW_AUTHENTICATE) - 1))
  290.         return ResultFromScode(E_FAIL);  /* not a valid name */
  291.  
  292.     if(pszSubName == NULL)
  293.       {
  294.         strncpy(pszValue, "Remote-Passphrase", CASTSIZE_T(cbValue));
  295.         pszValue[cbValue-1] = '\0';
  296.         return (NOERROR);
  297.       }
  298.  
  299.     char *token;
  300.  
  301.     while((token = strcasestr(m_pPassedInHeader, pszSubName)))
  302.       {
  303.           /* look for an immediate equal and then a quote
  304.          */
  305.         char *cp = token;
  306.         char *end_of_value;
  307.  
  308.         cp += XP_STRLEN(pszSubName);
  309.  
  310.         while(isspace(*cp)) cp++;
  311.  
  312.         if(*cp != '=')
  313.             continue;
  314.             
  315.         while(isspace(*cp)) cp++;
  316.  
  317.         if(*++cp != '"')
  318.             continue;
  319.  
  320.         end_of_value = strchr(++cp, '"');
  321.  
  322.         if(!end_of_value)
  323.           return ResultFromScode(E_FAIL);
  324.  
  325.         *end_of_value = '\0';
  326.  
  327.         if(end_of_value - cp > (ptrdiff_t)cbValue)
  328.           {
  329.               *end_of_value = '"';
  330.             return ResultFromScode(E_FAIL);
  331.           }
  332.  
  333.         XP_STRCPY(pszValue, cp);
  334.  
  335.         *end_of_value = '"';
  336.  
  337.         return (NOERROR);
  338.       }
  339.  
  340.     return ResultFromScode(E_FAIL);
  341. }
  342.  
  343.  
  344. /* ****************************************************************************
  345.  *
  346.  */
  347. STDMETHODIMP    CDAPacket::ReplaceNameValue
  348. (
  349.     const TCHAR *pszName, 
  350.     const TCHAR *pszValue
  351. )
  352. {
  353.     return ResultFromScode(E_NOTIMPL);
  354. }
  355.  
  356.  
  357. /* ****************************************************************************
  358.  *
  359.  */
  360. PRIVATE    char *GetMethod(URL_Struct *URL_s)
  361. {
  362.     if(URL_s->method == URL_POST_METHOD)
  363.         return    XP_STRDUP("POST");
  364.     else if(URL_s->method == URL_HEAD_METHOD)
  365.         return    XP_STRDUP("HEAD");
  366.     else 
  367.         return    XP_STRDUP("GET");
  368. }
  369.  
  370.  
  371. /* ****************************************************************************
  372.  *
  373.  */
  374. extern "C" int
  375. WFE_DoCompuserveAuthenticate(MWContext *context,
  376.                              URL_Struct *URL_s, 
  377.                              char *authenticate_header_value)
  378. {
  379.     struct address_auth_assoc * assoc_obj = 0;
  380.     struct address_auth_assoc * cur_assoc_ptr;
  381.     CDAPacket *auth;
  382.     XP_List *list_ptr;
  383.     char *host;
  384.     HRESULT    status;
  385.  
  386.     // Load the DA OLE server if it hasn't already been loaded.
  387.     IDAProcess *pIDAProcess = g_DA.Interface();
  388.  
  389.     if    (!pIDAProcess)
  390.     {
  391.         return NET_AUTH_FAILED_DISPLAY_DOCUMENT;
  392.     }
  393.  
  394.     if(!address_auth_list)
  395.       {
  396.         address_auth_list = XP_ListNew();
  397.         if(!address_auth_list)
  398.         return NET_AUTH_FAILED_DISPLAY_DOCUMENT;
  399.       }
  400.  
  401.     /* search for an existing association */
  402.     list_ptr = address_auth_list;
  403.     while((cur_assoc_ptr = (address_auth_assoc *)XP_ListNextObject(list_ptr)))
  404.       {
  405.           if(!XP_STRCMP(cur_assoc_ptr->address, URL_s->address))
  406.           {
  407.             assoc_obj = cur_assoc_ptr;
  408.               break;
  409.             }
  410.       }
  411.  
  412.     if(assoc_obj)
  413.       {
  414.           XP_ListRemoveObject(address_auth_list, assoc_obj);
  415.           delete assoc_obj->auth;
  416.         XP_FREE(assoc_obj->address);
  417.         XP_FREE(assoc_obj);          
  418.       }
  419.  
  420.     if(URL_s->server_status != 200
  421.         && URL_s->server_status != 401)
  422.         return(FALSE);
  423.  
  424.     
  425.     auth = new CDAPacket(authenticate_header_value);
  426.                                                  
  427.     auth->m_pNewHeaders = XP_STRDUP("Extension: Security/Remote-Passphrase"CRLF);
  428.  
  429.     host = NET_ParseURL(URL_s->address, GET_HOST_PART);
  430.  
  431.     if(URL_s->server_status == 401)    
  432.       {
  433.         struct SDAAuthData auth_data_struct;
  434.         char  username[256] = "";
  435.         char  password[256] = "";
  436.         char  realm[256] = "";
  437.         char * path = NET_ParseURL(URL_s->address, GET_PATH_PART | GET_SEARCH_PART);
  438.             
  439.         auth_data_struct.pIDAPacketIn    = auth;
  440.         auth_data_struct.pszHost         = host;
  441.         auth_data_struct.pszURI            = path;
  442.         auth_data_struct.pszMethod        = GetMethod(URL_s);
  443.         auth_data_struct.pIDAPacketOut    = auth;
  444.         auth_data_struct.bShowDialog     = 1;
  445.         auth_data_struct.hParent         = NULL;
  446.         auth_data_struct.pszUsername     = username;
  447.         auth_data_struct.wMaxUsername     = sizeof(username) - 1;
  448.         auth_data_struct.pszRealmname     = realm;
  449.         auth_data_struct.pszPassword     = password;
  450.         auth_data_struct.wMaxPassword     = sizeof(password) - 1;
  451.         auth_data_struct.pIDAPassword     = NULL;
  452.  
  453.         status = pIDAProcess->On401Authenticate(&auth_data_struct);
  454.  
  455.         if(status == NOERROR)
  456.           {
  457.             assoc_obj = XP_NEW(struct address_auth_assoc);
  458.  
  459.             if(!assoc_obj)
  460.                 return NET_AUTH_FAILED_DISPLAY_DOCUMENT;
  461.  
  462.             assoc_obj->auth = auth;
  463.             assoc_obj->address = XP_STRDUP(URL_s->address);
  464.             XP_ListAddObject(address_auth_list, assoc_obj);
  465.  
  466.             XP_FREE(host);
  467.             return(NET_RETRY_WITH_AUTH);
  468.           }
  469.       }    
  470.     else
  471.       {
  472.         status = pIDAProcess->On200Authenticate(host, auth); 
  473.       }
  474.                             
  475.     XP_FREE(host);
  476.     delete(auth);
  477.  
  478.     if(status != NOERROR)
  479.         return(NET_AUTH_FAILED_DONT_DISPLAY);
  480.     else
  481.         return(NET_AUTH_SUCCEEDED);
  482. }
  483.  
  484.  
  485. /* ****************************************************************************
  486.  *
  487.  */
  488. extern "C" char *
  489. WFE_BuildCompuserveAuthString(URL_Struct *URL_s)
  490. {
  491.     XP_List * list_ptr;
  492.     struct address_auth_assoc *cur_assoc_ptr;
  493.     struct address_auth_assoc *assoc_obj = NULL;
  494.     static char *rv=NULL;  /* malloc and free on successive calls */
  495.     
  496.     IDAProcess *pIDAProcess = g_DA.Load();
  497.  
  498.     if(pIDAProcess)
  499.     {
  500.         /* search for an existing association */
  501.         list_ptr = address_auth_list;
  502.         while((cur_assoc_ptr = (address_auth_assoc *)XP_ListNextObject(list_ptr)))
  503.           {
  504.             if(!XP_STRCMP(cur_assoc_ptr->address, URL_s->address))
  505.                 assoc_obj = cur_assoc_ptr;
  506.           }
  507.     
  508.         if(assoc_obj)
  509.           {
  510.             /* since we found it in the assoc list then
  511.              * we have gotten a 401 and are about to
  512.              * send another request.  Send the
  513.              * header.
  514.              */
  515.             return(assoc_obj->auth->m_pNewHeaders);
  516.           }
  517.         
  518.         /* if we didn't find it in the assoc list then
  519.          * call the cheat routine to see if we need
  520.          * to send any headers
  521.          */    
  522.     
  523.         if(rv)
  524.           {
  525.             XP_FREE(rv);
  526.             rv = NULL;
  527.           }
  528.     
  529.         HRESULT        status     = ResultFromScode(E_FAIL);
  530.         char *        host     = NET_ParseURL(URL_s->address, GET_HOST_PART);
  531.         char *        path    = NET_ParseURL(URL_s->address, GET_PATH_PART | GET_SEARCH_PART);
  532.         char *        method  = GetMethod(URL_s);
  533.  
  534.         if(host && path && method)
  535.         {
  536.             CDAPacket   daPacket("");   
  537.     
  538.             status = pIDAProcess->Cheat(host, path, method, &daPacket);
  539.     
  540.             rv = XP_STRDUP(daPacket.m_pNewHeaders);
  541.         }
  542.  
  543.         if(host)
  544.             XP_FREE(host);
  545.         if(path)
  546.             XP_FREE(path);
  547.         if(method)
  548.             XP_FREE(method);
  549.     }
  550.                     
  551.     return(rv);
  552. }
  553.