Wednesday, April 27, 2005

When URL moniker meets security problems

URL moniker is a very useful. For example, URLDownloadToFile allows you to download files using IE. While it's easy to write code to do that job yourself, the users may be appreciated if they do not have to config it for their proxy.

Three months ago I met some problems with URLDownloadToFile when dealing with https url. If IE is used, it will pop up an error saying the certificate is not trusted, obviously the owner of the site does not want to spend money to get their certificate signed. URLDownloadToFile will simply fail in this case, it won't show you the dialog as IE does.

To see the dialog, we need to implement a callback object and pass it to URLDownloadToFile. MSDN simply said the callback should implement BindStatusCallback, but here, we need IHttpSecurity as well. And most important method is GetWindow() method. URLDownloadToFile need this to report error.

class Callback : public IBindStatusCallback, IHttpSecurity

STDMETHOD(GetWindow)(REFGUID rguidReason, HWND *phwnd)
if (NULL != phwnd_)
(*phwnd) = (*phwnd_);
(*phwnd) = GetDesktopWindow();
return S_OK;


CPPUNIT: constructor/destructor VS setUp/tearDown

In C++, we used to use constructor and destructor to manage resources.
In XUNIT, setUp() and tearDown() are favored instead. One of the reasons
is that some langurages like Java have only undetermined garbage collector,
while we need a "determined" way to clean up the state after each test.

But in C++, we can use stack. As mentioned in
Herb Sutter's OOPSLA keynote, this approach has its own
advantage. So when writing tests with CPPUNIT, I still prefer constructor/destructor over setUp/tearDown, and it works.

There is a disadvantage, althrough it should be a implementation issue
of CPPUNIT: TestFixtures' Constructor will be called before main() to register
themself. So if your constructor fails, the whole program won't run at all.
In this case, you have to call setUp().

Wednesday, April 13, 2005

resize web browser control

I have a dialog based MFC application using Microsoft web browser control(IWebBrowser2). From the first version, I disabled the maximize box and used non-resizable border to avoid the painful layout of GUI elements. Now I want to make it resizable, so I edited the properties in resources: now the dialog itself is resizable, but the Active X control doesn't.

I truned to google and hope it can be sovled in 5 minutes, but the search is
not very successful. After about an hour I solved the problem myself, even though it is very simple, I decided to write it down so that another poor man can get helped.

The solution is to use the OnSize() Event to size our control:

BEGIN_MESSAGE_MAP(CWebBrwoserDlg, CDialog)

void CWebBrwoserDlg::OnSize(UINT nType, int cx, int cy)
CDialog::OnSize(nType, cx, cy);//Call parent's OnSize first

if (m_browser.GetSafeHwnd() != NULL))//Make sure the windows is created.
m_browser.MoveWindow(0, 0, cx, cy);//resize browser control

Wednesday, April 06, 2005

Faked port 25 from symantec antivirus software

Symantec antivirus software gives me lots of trouble recently. To check if an email contains virus, it somehow creates a fake port 25 to intercept the traffic. So if you have Symentec antivirus software installed on your desktop, whenever you telnet or call connect() to a port 25, it will always succeed regardless the state of the remote host, even if the host is down.

So port scan using tcp connect will give lots of false positives unless you stop symentec antivirus service. To avoid that you have to bypass compromised tcp/ip stack. For example, synscan with pcap can give you better result, since there is no actual SYN/ACK back from the faked port.

Bug in Netscape Internet Service software

I spent almost a day on a "bug" appeared in my program, which is a very simple portscanner using non-blocking tcp connect. I closed all the sockets after they are used, but boundchecker still complains about "Outstanding Allocations", and the call path is "My Program->ws2_32.dll->sliplsp.dll". Actually I should pay more attention to sliplsp.dll, but at that moment, ws2_32.dll convinced me that the bug is in my program.

I opened windows task manager and noticed that the handle count keeps increasing. To see the details about the handle I launched Process Explorer, and found out there are lots of file handles named "\Device\WS2IFSL\NifsSct". What the hell is that?

Even google can not help, there is no useful discussion of NifsSct at all.

My program is quiet simple, but to be 100% sure, I started to use simple code to test, and found something interesting:
1. After socket() succeed, a new handle called "\Device\Afd\Endpoint" will be created.
2. After connect() succeed, a new handle called "\Device\Tcp" will be created.
3. After closesocket(), all of them will be closed.

But the problem is, "\Device\WS2IFSL\NifsSct" will be created along with the other two, and I have no idea what they are. Finally I had to give up after several hours of pointless efforts.

Then another day came. I want to solve another myth I saw: after reading tons of good words about Ruby on Rails, I want to give it a try myself, but the installation of rails("gem install rails") always deadlock ruby.exe. I was very disappointed about ruby at that moment, since there are source code at hand, I decided to find the "bug" and fix it.

Then my eyes opened: the debugger shows ruby.exe loads "C:\Programs Files\Netscape Internet Service\sliplsp.dll". Hah? I turned back to boundcheck, and enabled the full path in the view, it is the same dll!

I have had some bad experience before with programs hooked up with standard network stack. So I uninstalled Netscape Internet Service, deleted its folder after reboot, then everything goes fine. There is no more leaking \Device\WS2IFSL\NifsSct and I finally get rails installed.

There are not too much users in the world use Netscape Internet Service. It explains why there are no discussion about it at all.