Solved

initialize and script activex control marked as unsafe

Posted on 2003-10-27
11
1,359 Views
Last Modified: 2013-11-18
Hi I have aproblem in signing the active component using registry entry method.

Here is the code

#include "stdafx.h"
#include "resource.h"
#include <initguid.h>
#include "SysInfo.h"
#include "helpers.h"
#include "ObjSafe.H"
#include <string>
//#include <ole2.h>
//#include <windows.h>


#include "SysInfo_i.c"
#include "SysData.h"


CComModule _Module;

BEGIN_OBJECT_MAP(ObjectMap)
OBJECT_ENTRY(CLSID_SysData, CSysData)
END_OBJECT_MAP()

/////////////////////////////////////////////////////////////////////////////
// DLL Entry Point

extern "C"
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
{
    if (dwReason == DLL_PROCESS_ATTACH)
    {
        _Module.Init(ObjectMap, hInstance, &LIBID_SYSINFOLib);
        DisableThreadLibraryCalls(hInstance);
    }
    else if (dwReason == DLL_PROCESS_DETACH)
        _Module.Term();
    return TRUE;    // ok
}

/////////////////////////////////////////////////////////////////////////////
// Used to determine whether the DLL can be unloaded by OLE

STDAPI DllCanUnloadNow(void)
{
    return (_Module.GetLockCount()==0) ? S_OK : S_FALSE;
}

/////////////////////////////////////////////////////////////////////////////
// Returns a class factory to create an object of the requested type

STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
{
    return _Module.GetClassObject(rclsid, riid, ppv);
}

/////////////////////////////////////////////////////////////////////////////
// DllRegisterServer - Adds entries to the system registry

STDAPI DllRegisterServer(void)
{
   
      UUID result;
      
      
      LPOLESTR lpsz=(LPOLESTR)("{49232000-16E4-426C-A231-62846947304B}");

         CLSIDFromString(lpsz, &result);



      HRESULT hr = CreateComponentCategory(CATID_SafeForScripting,
         L"Controls that are safely scriptable");

      if (SUCCEEDED(hr))
         // Only register if category exists.
         RegisterCLSIDInCategory(result, CATID_SafeForScripting);
         // Don't care if this call fails.

      // Mark as safe for data initialization.
      hr = CreateComponentCategory(CATID_SafeForInitializing,
         L"Controls safely initializable from persistent data");

      if (SUCCEEDED(hr))
         // Only register if category exists.
         RegisterCLSIDInCategory(result, CATID_SafeForInitializing);
         // Don't care if this call fails.

    return _Module.RegisterServer(TRUE);

      


      
}

/////////////////////////////////////////////////////////////////////////////
// DllUnregisterServer - Removes entries from the system registry

STDAPI DllUnregisterServer(void)
{
    return _Module.UnregisterServer(TRUE);
}


///////

//helpers.cpp

#include "stdafx.h"

#include "helpers.h"

/////////////////////////////////////////////////////////////////////////////
// CreateComponentCategory - Ensures component category exists in registry
// (Copied from ActiveX SDK docs)

HRESULT CreateComponentCategory(CATID catid, WCHAR* catDescription)
{

    ICatRegister* pcr = NULL ;      // interface pointer
    HRESULT hr = S_OK ;

    hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr,
                  NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pcr);
      if (FAILED(hr))
            return hr;

    // Make sure the HKCR\Component Categories\{..catid...}
    // key is registered
    CATEGORYINFO catinfo;
    catinfo.catid = catid;
    catinfo.lcid = 0x0409 ; // english

      // Make sure the provided description is not too long.
      // Only copy the first 127 characters if it is
      int len = wcslen(catDescription);
      if (len>127)
            len = 127;
    wcsncpy(catinfo.szDescription, catDescription, len);
      // Make sure the description is null terminated
      catinfo.szDescription[len] = '\0';

    hr = pcr->RegisterCategories(1, &catinfo);
      pcr->Release();

      return hr;
}



/////////////////////////////////////////////////////////////////////////////
// RegisterCLSIDInCategory - Registers class clsid as implementing category catid
// (Copied from ActiveX SDK docs)

HRESULT RegisterCLSIDInCategory(REFCLSID clsid, CATID catid)
{
// Register your component categories information.
    ICatRegister* pcr = NULL ;
    HRESULT hr = S_OK ;
    hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr,
                  NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pcr);
    if (SUCCEEDED(hr))
    {
       // Register this category as being "implemented" by
       // the class.
       CATID rgcatid[1] ;
       rgcatid[0] = catid;
       hr = pcr->RegisterClassImplCategories(clsid, 1, rgcatid);
    }

    if (pcr != NULL)
        pcr->Release();
 
      return hr;
}

//helpers.h

#include "comcat.h"

HRESULT CreateComponentCategory(CATID catid, WCHAR* catDescription);
HRESULT RegisterCLSIDInCategory(REFCLSID clsid, CATID catid);

I am using the the article publishe in msdn site

The url is

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnaxctrl/html/msdn_signmark.asp

But I could not made it to work with out browser security setting. I understand I donot have to make browser setting (initialize and script activex control marked as unsafe) to run the active x component. Can anybody pl help me.

Thanks
Abinash

0
Comment
Question by:aparida123
11 Comments
 
LVL 9

Expert Comment

by:_ys_
Comment Utility
My thought is that this could be failing
>> LPOLESTR lpsz=(LPOLESTR)("{49232000-16E4-426C-A231-62846947304B}");
>> CLSIDFromString(lpsz, &result);

Just use the CLSID you already have, rather than synthesising your own
RegisterCLSIDInCategory(CLSID_SysData, CATID_SafeForScripting);

>> // Don't care if this call fails
You obviously do, and it's causing grief.

Always check the HRESULTs returned. When something fails they make a good starting point for diagnosis

Note that marking it as safe this way, does not include the initial download. That's still unsafe.
0
 

Author Comment

by:aparida123
Comment Utility
Sorry I could not get you, U mean to say aftre applying registry setting in this code, still I have to do the browser setting for the initialize and script activex control marked as unsafe to run the dll from IE?
0
 

Author Comment

by:aparida123
Comment Utility
it does not work , to run the dll I have to make the browser setting. Also I tried with

IObjectSafetyImpl'

But it is giving me compiler error

error C2504: 'IObjectSafetyImpl' : base class undefined

My Code is

// SysData.h : Declaration of the CSysData

#ifndef __SYSDATA_H_
#define __SYSDATA_H_

#include "resource.h"       // main symbols
//#include "BrowserInfo.h"
//#include <Atlbase.h>

/////////////////////////////////////////////////////////////////////////////
// CSysData
class ATL_NO_VTABLE CSysData :
      public IObjectSafetyImpl<CSysData, INTERFACESAFE_FOR_UNTRUSTED_CALLER |INTERFACESAFE_FOR_UNTRUSTED_DATA >,
      public CComObjectRootEx<CComSingleThreadModel>,
      public CComCoClass<CSysData, &CLSID_SysData>,
      public IDispatchImpl<ISysData, &IID_ISysData, &LIBID_SYSINFOLib>
      

{
public:
      CSysData()
      {
      }

DECLARE_REGISTRY_RESOURCEID(IDR_SYSDATA)

DECLARE_PROTECT_FINAL_CONSTRUCT()

BEGIN_COM_MAP(CSysData)
      COM_INTERFACE_ENTRY(IObjectSafety)
      COM_INTERFACE_ENTRY(ISysData)
      COM_INTERFACE_ENTRY(IDispatch)
      
END_COM_MAP()

// ISysData

STDMETHOD(GetInterfaceSafetyOptions)(REFIID riid,
                                  DWORD *pdwSupportedOptions,
                                  DWORD *pdwEnabledOptions)
{
ATLTRACE(_T("CObjectSafetyImpl::GetInterfaceSafetyOptions\n"));
if (!pdwSupportedOptions || !pdwEnabledOptions)
   return E_FAIL;
LPUNKNOWN pUnk;
if (_InternalQueryInterface (riid, (void**)&pUnk) == E_NOINTERFACE) {
   // Our object doesn't even support this interface.
   return E_NOINTERFACE;
}else{
   // Cleanup after ourselves.
   pUnk->Release();
   pUnk = NULL;
}
if (riid == IID_IDispatch) {
   // IDispatch is an interface used for scripting. If your
   // control supports other IDispatch or Dual interfaces, you
   // may decide to add them here as well. Client wants to know
   // if object is safe for scripting. Only indicate safe for
   // scripting when the interface is safe.
   *pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER;
   *pdwEnabledOptions = m_dwCurrentSafety &
                        INTERFACESAFE_FOR_UNTRUSTED_CALLER;
   return S_OK;
}else if ((riid == IID_IPersistStreamInit) ||
          (riid == IID_IPersistStorage)) {
   // IID_IPersistStreamInit and IID_IPersistStorage are
   // interfaces used for Initialization. If your control
   // supports other Persistence interfaces, you may decide to
   // add them here as well. Client wants to know if object is
   // safe for initializing. Only indicate safe for initializing
   // when the interface is safe.
   *pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_DATA;
   *pdwEnabledOptions = m_dwCurrentSafety &
                        INTERFACESAFE_FOR_UNTRUSTED_DATA;
   return S_OK;
}else{
   // We are saying that no other interfaces in this control are
   // safe for initializing or scripting.
   *pdwSupportedOptions = 0;
   *pdwEnabledOptions = 0;
   return E_FAIL;
}
}



STDMETHOD(SetInterfaceSafetyOptions)(REFIID riid,
                                  DWORD dwOptionSetMask,
                                  DWORD dwEnabledOptions)
{
ATLTRACE(_T("CObjectSafetyImpl::SetInterfaceSafetyOptions\n"));
if (!dwOptionSetMask && !dwEnabledOptions) return E_FAIL;
LPUNKNOWN pUnk;
if (_InternalQueryInterface (riid, (void**)&pUnk) == E_NOINTERFACE) {
   // Our object doesn't even support this interface.
   return E_NOINTERFACE;
}else{
   // Cleanup after ourselves.
   pUnk->Release();
   pUnk = NULL;
}
// Store our current safety level to return in
// GetInterfaceSafetyOptions
m_dwCurrentSafety |= dwEnabledOptions & dwOptionSetMask;
if ((riid == IID_IDispatch) &&
    (m_dwCurrentSafety & INTERFACESAFE_FOR_UNTRUSTED_CALLER)) {
   // Client wants us to disable any functionality that would
   // make the control unsafe for scripting. The same applies to
   // any other IDispatch or Dual interfaces your control may
   // support. Because our control is safe for scripting by
   // default we just return S_OK.
   return S_OK;
}else if (((riid == IID_IPersistStreamInit) ||
           (riid == IID_IPersistStorage)) &&
          (m_dwCurrentSafety & INTERFACESAFE_FOR_UNTRUSTED_DATA)) {
   // Client wants us to make the control safe for initializing
   // from persistent data. For these interfaces, this control
   // is safe so we return S_OK. For Any interfaces that are not
   // safe, we would return E_FAIL.
   return S_OK;
}else{
   // This control doesn't allow Initialization or Scripting
   // from any other interfaces so return E_FAIL.
   return E_FAIL;
}
}




public:
      STDMETHOD(GetData)(/*[out]*/ BSTR* ReturnVal);
};

#endif //__SYSDATA_H_
0
 
LVL 9

Expert Comment

by:_ys_
Comment Utility
>> still I have to do the browser setting ...
Nope.

When the user first connect to the page, the control wil have to be downloaded and installed on the local system. This part will still prompt the user - but once only. After downloaded and installed they'll not see any more messages, reagrdless of the browser settings.

Unless you're willing to digitally sign your control, this cannot be avoided - without reverting to altering the browser settings.
0
 

Author Comment

by:aparida123
Comment Utility
I solved the error in IObjectSafetyImpl and no I ma trying with it.
You mean to say my browser setting for the initialize and script activex control marked as unsafe should always be kept as enable for the first time even if I implement the registry methor or IObjectSafetyImpl interface?
0
Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 

Author Comment

by:aparida123
Comment Utility
I am signing the control, But I donot want user to change their default setting for the IE to run the Activex dll.
0
 
LVL 9

Expert Comment

by:_ys_
Comment Utility
The default 'medium' setting will allow what you want top do - it will still prompt the user to accept the download though (but this is once only - the initial download).

After download and installation, all things will work as expected.
0
 

Author Comment

by:aparida123
Comment Utility
I think I solved the problem by implemeting IObjectsafety.
0
 
LVL 9

Expert Comment

by:_ys_
Comment Utility
It's generally either registry entry or IObjectSafety method. Never seen a situation where one succeeds whilst the other fails.
0
 
LVL 9

Expert Comment

by:tinchos
Comment Utility
No comment has been added lately, so it's time to clean up this question.
I will leave the following recommendation for this question in the Cleanup topic area:

PAQ with points refunded

Please leave any comments here within the next four days.
PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!

Tinchos
EE Cleanup Volunteer
0
 

Accepted Solution

by:
ee_ai_construct earned 0 total points
Comment Utility
PAQed, with points refunded (500)

ee_ai_construct
Community Support Moderator
0

Featured Post

Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

Join & Write a Comment

  Included as part of the C++ Standard Template Library (STL) is a collection of generic containers. Each of these containers serves a different purpose and has different pros and cons. It is often difficult to decide which container to use and …
Many modern programming languages support the concept of a property -- a class member that combines characteristics of both a data member and a method.  These are sometimes called "smart fields" because you can add logic that is applied automaticall…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

9 Experts available now in Live!

Get 1:1 Help Now