Sunday, April 20, 2014

Migrated my Linode to take advantage of double RAM and SSDs

$ sudo pacman -Syu has never been so fast ;-)

Linode recently announced a revamp of their infrastructure providing, among other things, SSD storage and double RAM. I am on their lowest priced plan, which means 2GB memory and 48 GB storage on 2 cores on a Intel Xeon E5-2680 v2 @ 2.80GHz sets me back just $20/month.

While going down to two cores from the previous upgrade to eight may not sound impressive, my early impressions are that there is indeed much less contention as Linode claims. Besides, the extra 1 GB of memory is very likely much more crucial to my modest needs than the spare cores none of which got fully utilized.

I had to switch to a 64-bit kernel for the migration, but I left everything else in 32-bit, mostly because I am impatient like that. They ask you to allow about 36 minutes for the process, but, in my case the whole thing from clicking migrate to full reboot was about 10 minutes and 32 seconds.

I have been a very happy customer for almost seven years now. Yes, I also use DigitalOcean and RamNode, but I am really fond of my Linode.

While Linode is offering new sweet goodies, you can get a very decent VPS from RamNode for less than $70/year by using the discount code RN25OFF.

DigitalOcean offers some incredibly helpful, developer centric options.

If you are looking for a VPS solution where you are in complete control, you could a lot worse than these favorites.

PS: Those are all affiliate links. Here are the links without affiliate codes: DigitalOcean, Linode, and RamNode.

Wednesday, April 16, 2014

Is a strong caution about Heartbleed worth the disruption to distributions with a declared dependency on Crypt::SSLeay?

As I noted previously, distributions with a declared dependency on Crypt::SSLeay may not really need Crypt::SSLeay.

Heartbleed is a serious bug in OpenSSL that allows one side of a "secure" connection to read the memory of the process running on the other side of the connection. While the initial attention focused on clients being able to read confidential data from server processes, clients are also vulnerable.

In a nutshell, you might think your little robot is taking too long fetching stock quotes from remote, but it might just be sucking your memory in 64Kb blocks at a time (yes, there are some details I am glossing over). Host verification may not help you feel secure because, among other reasons, 1) Someone might actually have obtained the certificate for the server via previous attacks on that and might have tricked you into connecting to their server; 2) The server might have been taken over by a hostile party; and 3) The remote might have been legitimately using a self-signed certificate in the past, and you have disabled host verification.

Which means connecting to a remote with a vulnerable client is not safe.

I recently added a test to Crypt::SSLeay 0.65_13 to check for the version of the OpenSSL library it uses which required adding a litte XS to SSLeay.xs. This test fails if the OpenSSL library in use is a version that was revealed to be vulnerable to the Heartbleed bug.

As of 0.65_12, the only failures were coming from machines where IO::Socket::INET was automatically overridden by IO::Socket::IP.

For 0.65_13 version, the current failure rate on CPANTesters is about 75%.

If I leave this test in for the next release, systems with a vulnerable OpenSSL will not be able to automatically update. They will have to force install Crypt::SSLeay.

Now, they may not really need Crypt::SSLeay. LWP might be using IO::Socket::SSL under the covers, but either way, they are depending on OpenSSL to provide a secure communications channel. So, moving to a version of OpenSSL that is not vulnerable would be useful even if Crypt::SSLeay is a superfluous dependency.

Is it worth causing this kind of disruption by having make test for Crypt::SSLeay fail if it was built against a vulnerable OpenSSL?

Does your code really depend on Crypt::SSLeay?

I added the following section to the development version of Crypt::SSLeay:

Starting with version 6.02 of LWP, https support was unbundled into LWP::Protocol::https. This module specifies as one of its prerequisites IO::Socket::SSL which is automatically used by LWP::UserAgent unless this preference is overridden separately. IO::Socket::SSL is a more complete implementation, and, crucially, it allows hostname verification. Crypt::SSLeay does not support this. At this point, Crypt::SSLeay is maintained to support existing software that already depends on it.

However, it is possible that your software does not really depend on Crypt::SSLeay, only on the ability of LWP::UserAgent class to communicate with sites over SSL/TLS.

If are using version LWP 6.02 or later, and therefore have installed LWP::Protocol::https and its dependencies, and do not explicitly use Net::SSL before loading LWP::UserAgent, or override the default socket class, you are probably using IO::Socket::SSL and do not really need Crypt::SSLeay

If you have both Crypt::SSLeay and IO::Socket::SSL installed, and would like to force LWP::UserAgent to use Crypt::SSLeay, you can use:

use Net::HTTPS;
$Net::HTTPS::SSL_SOCKET_CLASS = 'Net::SSL';
use LWP::UserAgent;

or

local $ENV{PERL_NET_HTTPS_SSL_SOCKET_CLASS} = 'Net::SSL';
use LWP::UserAgent;

or

use Net::SSL;
use LWP::UserAgent;

For example, metacpan tells me Finance::Quote has a declared dependency on Crypt::SSLeay. But, when I look at the source, I see:

my $ua;
 
  if ($USE_EXPERIMENTAL_UA) {
    $ua = Finance::Quote::UserAgent->new;
  } else {
    $ua = LWP::UserAgent->new;
  }

The other dependencies it declares are:

 "LWP::UserAgent" => 0,
    "Mozilla::CA" => 0,

That means, installing this module would pull in the latest LWP. Given that Crypt::SSLeay depends on LWP::Protocol::https, and that pulls in IO::Socket::SSL.

Since Finance::Quote does not seem to explicitly override the choice of plumbing, unless a user of the module set the environment variable PERL_NET_HTTPS_SSL_SOCKET_CLASS to Net::SSL.

See what I mean?

In conclusion, it is entirely possible that your code has been running without actually using Crypt::SSLeay for the past few years. Given the advantages of IO::Socket::SSL over Crypt::SSLeay, it is probably a good idea to ask yourself whether you really need to declare a dependency on Crypt::SSLeay.

Maybe all you need is a dependency on LWP::Protocol::https.

The updates I make to Crypt::SSLeay are mostly limited to build processes etc. They are not very frequent. The places that really depend on Crypt::SSLeay tend to have in place much older ecosystems. It is hard to diagnose problems in those environments if I break something. On the other hand, in more modern environments, your code that uses LWP::UserAgent to communicate over HTTPS is probably not touching anything within Crypt::SSLeay.

So, maybe it's time to remove that declared dependency in your Makefile.PL.

Monday, April 14, 2014

Why does Crypt::SSLeay fail to build under Strawberry Perl?

After a comment on my blog attracted my attention to some interesting failures when trying to build Crypt::SSLeay with Strawberry Perl, I was perplexed.

I don't really use Strawberry. I have always used either ActivePerl, or built my own perl, depending on my taste for experimentation. So, I went over to Strawberry Perl's web site, and downloaded their latest portable 64-bit distribution, unzipped, and tried to install Crypt::SSLeay.

And, I got a similar failure at link stage:

dlltool --def SSLeay.def --output-exp dll.exp
g++.exe -o blib\arch\auto\Crypt\SSLeay\SSLeay.dll -Wl,
    --base-file -Wl,dll.base -
mdll -s -L"C:\…\strawberry\perl\lib\CORE"
    -L"C:\…\strawberry\c\lib" SSLeay.o
    C:\…\strawberry\perl\lib\CORE\libperl518.a
    C:\…\strawberry\c\lib\libssl32.a
    C:\…\strawberry\c\lib\libssleay32.a
    C:\…\strawberry\c\lib\libz.a 
    C:\…\strawberry\c\x86_64-w64-mingw32\lib\libmoldname.a
    C:\…\strawberry\c\x86_64-w64-mingw32\lib\libkernel32.a
    C:\…\strawberry\c\x86_64-w64-mingw32\lib\libuser32.a
    C:\…\strawberry\c\x86_64-w64-mingw32\lib\libgdi32.a
    C:\…\strawberry\c\x86_64-w64-mingw32\lib\libwinspool.a
    C:\…\strawberry\c\x86_64-w64-mingw32\lib\libcomdlg32.a
    C:\…\strawberry\c\x86_64-w64-mingw32\lib\libadvapi32.a
    C:\…\strawberry\c\x86_64-w64-mingw32\lib\libshell32.a
    C:\…\strawberry\c\x86_64-w64-mingw32\lib\libole32.a
    C:\…\strawberry\c\x86_64-w64-mingw32\lib\liboleaut32.a
    C:\…\strawberry\c\x86_64-w64-mingw32\lib\libnetapi32.a
    C:\…\strawberry\c\x86_64-w64-mingw32\lib\libuuid.a
    C:\…\strawberry\c\x86_64-w64-mingw32\lib\libws2_32.a
    C:\…\strawberry\c\x86_64-w64-mingw32\lib\libmpr.a
    C:\…\strawberry\c\x86_64-w64-mingw32\lib\libwinmm.a
    C:\…\strawberry\c\x86_64-w64-mingw32\lib\libversion.a
    C:\…\strawberry\c\x86_64-w64-mingw32\lib\libodbc32.a
    C:\…\strawberry\c\x86_64-w64-mingw32\lib\libodbccp32.a 
    C:\…\strawberry\c\x86_64-w64-mingw32\lib\libcomctl32.a
    dll.exp
SSLeay.o:SSLeay.c:(.text+0x403):
 undefined reference to `X509_get_issuer_name'
SSLeay.o:SSLeay.c:(.text+0x410):
 undefined reference to `X509_NAME_oneline'
SSLeay.o:SSLeay.c:(.text+0x42f):
 undefined reference to `CRYPTO_free'
SSLeay.o:SSLeay.c:(.text+0x573):
 undefined reference to `X509_get_subject_name'
SSLeay.o:SSLeay.c:(.text+0x580):
 undefined reference to `X509_NAME_oneline'
SSLeay.o:SSLeay.c:(.text+0x59f):
 undefined reference to `CRYPTO_free'
SSLeay.o:SSLeay.c:(.text+0x6d7):
 undefined reference to `X509_free'
SSLeay.o:SSLeay.c:(.text+0x2756):
 undefined reference to `d2i_PKCS12_fp'
SSLeay.o:SSLeay.c:(.text+0x2798):
 undefined reference to `PKCS12_parse'
SSLeay.o:SSLeay.c:(.text+0x27be)
: undefined reference to `EVP_PKEY_free'
SSLeay.o:SSLeay.c:(.text+0x27e0):
 undefined reference to `X509_free'
SSLeay.o:SSLeay.c:(.text+0x27e8):
 undefined reference to `PKCS12_free'
SSLeay.o:SSLeay.c:(.text+0x314e):
 undefined reference to `RAND_load_file'
SSLeay.o:SSLeay.c:(.text+0x3211):
 undefined reference to `OPENSSL_add_all_algorithms_noconf'
SSLeay.o:SSLeay.c:(.text+0x321b):
 undefined reference to `ERR_load_crypto_strings'
SSLeay.o:SSLeay.c:(.text+0x3270):
 undefined reference to `RAND_seed'
SSLeay.o:SSLeay.c:(.text+0x3316):
 undefined reference to `ERR_get_error'
SSLeay.o:SSLeay.c:(.text+0x3397):
 undefined reference to `ERR_get_error'
SSLeay.o:SSLeay.c:(.text+0x33b0):
 undefined reference to `ERR_error_string'

*Sigh!*

So, the libraries we want to link to are there, but …

I mean, at this point, I am actually using Devel::CheckLib to check if compiling programs against the requested libraries succeeds, so I know the libraries are there. Why is linking failing?

I mean, look at this:

C:\…\strawberry\c\lib> strings libeay32.a 
   | perl -ne "print if /X509_NAME_oneline/"
X509_NAME_oneline
__imp_X509_NAME_oneline
X509_NAME_oneline
X509_NAME_oneline
__imp_X509_NAME_oneline

So, at least superficially, it looks like everything is there. Why the failures?

Also, it turns out the January 2014 release of Strawberry Perl (/w perl 5.18) comes with OpenSSL 1.0.1e. Is there a better excuse to build OpenSSL from scratch?

But, that would require putting together a whole MinGW environment.

Of course, don't use outdated versions of OpenSSL. But, the solution to the linking problem was much simpler. The candidate library list I am using was ssl crypto ssl32 ssleay32 libeay32 z. Well, using GCC, libeay32.a would be linked by specifying -leay32. If you use -llibeay32, the linker will look for liblibeay32.a.

Therefore, changing that list of libraries to ssl crypto ssl32 ssleay32 eay32 z works for Strawberry. It does, however, fail when I try it using Windows SDK 7.1 build environment. Therefore, the new list of candidate libraries is ssl crypto ssl32 ssleay32 eay32 libeay32 z. I'll push the change to CPAN and GitHub.

Thursday, April 10, 2014

Building OpenSSL 1.0.1g on 64-bit Windows Pro 8.1 with Windows SDK 7.1

This, actually, turned out to be surprisingly straightforward.

I admit, nothing is really straightforward when it comes to OpenSSL, but as such things go, this simply involved:

  1. Download the latest source distribution
  2. Open up a SDK command prompt
  3. Optionally, get zlib, build DLL
  4. Get nasm and build executable
  5. If you did ask for zlib, add directories to INCLUDE and LIB:

    C:\…\openssl-1.0.1g> set INCLUDE=%INCLUDE%;C:\…\zlib-1.2.8
    C:\…\openssl-1.0.1g> set LIB=%LIB%;C:\…\zlib-1.2.8
  6. Run C:\…\openssl-1.0.1g> perl Configure VC-WIN64A zlib-dynamic --openssldir=C:\opt\OpenSSL
  7. Run C:\…\openssl-1.0.1g> ms\do_win64a
  8. Run C:\…\openssl-1.0.1g> nmake -f ms\ntdll.mak
  9. Wait … well, at least on my machine ;-)
  10. cd to out32dll, and run ..\ms\test
  11. Make sure all tests pass:

  12. Install by doing:

    C:\…\openssl-1.0.1g\out32dll> cd ..
    C:\…\openssl-1.0.1g> nmake -f ms\ntdll.mak install

Now, if you want to compile and link against OpenSSL, you will need to make sure C:\opt\OpenSSL\include and C:\opt\OpenSSL\lib are added to the INCLUDE and LIB paths, respectively. To run code linked against this OpenSSL build, you will also need to make sure programs built against it can located the DLLs. I put the files from both in a common location, say, C:\opt\bin which is then added to my %PATH%.

I want that extra bit of protection for C:\opt\bin, so it is only writable by an admin user. So, fire up an admin command window, and do:

C:\…> xcopy C:\opt\OpenSSL\bin\* C:\opt\bin
 C:\opt\OpenSSL\bin\libeay32.dll
 C:\opt\OpenSSL\bin\openssl.exe
 C:\opt\OpenSSL\bin\ssleay32.dll
 3 File(s) copied

and

C:\…> xcopy \users\sinan\src\zlib-1.2.8\zlib1.dll c:\opt\bin

How can we test this actually worked?

Well, let's try building Crypt::SSLeay:

C:\…\src> git clone https://github.com/nanis/Crypt-SSLeay.git

C:\…\src> cd Crypt-SSLeay

C:\…\Crypt-SSLeay> perl Makefile.PL --libpath=C:\opt\OpenSSL\lib --incpath=C:\opt\OpenSSL\include --live-tests --no-verbose

C:\…\Crypt-SSLeay> nmake test

which should yield:

t/00-basic.t .... ok
t/01-connect.t .. ok
t/02-live.t ..... # Reading configuration from 'test.config' on MSWin32
# network_tests : 1
t/02-live.t ..... 5/? # [RT #73755] Cheat by disabling LWP::UserAgent host verification
t/02-live.t ..... ok
All tests successful.
Files=3, Tests=29,  6 wallclock secs ( 0.06 usr +  0.02 sys =  0.08 CPU)
Result: PASS

Now, do an nmake install. Then, switch to a new, non-SDK command window to make sure that things work outside of the development environment as well. Try running the following script:

use strict;
use warnings;
use Test::More;

# Make sure LWP uses Crypt::SSLeay, not IO::Socket::SSL
# IO::Socket::SSL is better, but this is testing Crypt::SSLeay
use Net::HTTPS;
$Net::HTTPS::SSL_SOCKET_CLASS = 'Net::SSL';

use HTTP::Request;
use LWP::UserAgent;

my $method = 'HEAD';
my $uri = 'https://example.com/';

my $ua = LWP::UserAgent->new(
    ssl_opts => { verify_hostname => 0 },
);

my $req = HTTP::Request->new;

$req->method($method);
$req->uri($uri);

my $test_name = "$method '$uri'";

my $res = $ua->request($req);

if ($res->is_success) {
    my $socket_class = $res->header('Client-SSL-Socket-Class');
    # Make sure *WE* succeded ;-)
    if ( isa_ok($socket_class, 'Net::SSL') ) {
        pass $test_name;
    }
    else {
        fail $test_name;
        diag "Request succeded but UA used '$socket_class'";
    }
}
else {
    fail $test_name;
    diag "HTTP status = ", $res->status_line ;
}

done_testing;

Which produces:

C:\…\Temp> perl check-example.pl
ok 1 - The class (or class-like) 'Net::SSL' isa 'Net::SSL'
ok 2 - HEAD 'https://example.com/'
1..2

Keep in mind that IO::Socket::SSL is the better module. If you have upgraded to LWP 6.xx and also installed LWP::Protocol::https, your LWP::UserAgent object is very likely using IO::Socket::SSL. Only force the use of Crypt::SSLeay if you have a specific need.

Tuesday, April 8, 2014

Building and Installing gVim on Windows 8.1 Pro

Vim (most often gVim, but I am fine in the terminal as well) is the only editor that I am really used to using. So, when I installed Windows 8.1 on my trusty old laptop, I immediately wanted to build a brand spanking new 64-bit version (yeah, and this thing can't deal with 2x2GB properly, but why not?) with all the latest patches. That means, building from source. When I had XP SP3 on this thing, I had set up nice little environments for building every little thing I liked to build from source. On this new OS which really, desperately wants to run on a phone, I did not know how things were going to work (I have heard that things were even worse with 8.0).

After a few false starts (such as trying to do this with Visual Studio 2013 Express Edition for Windows Desktop), I realized the right tool to use is the Windows SDK 7.1.

I installed TortoiseHG and cloned the source:

I realize, green just is not my color … I seriously miss the way you could customize the GUI in XP. But, I digress …

Vim comes with a makefile, Make_mvc.mak for Microsoft's compiler. I noticed the cl that came with SDK 7.1 supported an optimization option called /favor:INTEL64, so I added that to the OPTFLAG variable right around line 481 and entered:

C:\…\vim\src> nmake -f Make_mvc.mak OPTIMIZE=SPACE CPU=AMD64 NETBANS=no GETTEXT=no GUI=yes

And, within about 30 seconds, the executable was built.

What now?

The file INSTALLpc.txt has a lot of information, and tells you what you need to do next, in section 10, at the end of the file:

C:\…\vim\src> mkdir c:\opt\vim\vim74

C:\…\vim\src> copy *.exe c:\opt\vim\vim74
gvim.exe
install.exe
uninstal.exe
vimrun.exe
        4 file(s) copied.

C:\…\vim\src> copy GvimExt\gvimext.dll c:\opt\vim\vim74
        1 file(s) copied.

C:\…\vim\src> copy xxd\xxd.exe c:\opt\vim\vim74
        1 file(s) copied.

C:\…\vim\src> xcopy ..\runtime\* c:\opt\vim\vim74 /e

Then I changed my directory to c:\opt\vim\vim74, and typed install. You get a funky text based menu where you enter item numbers to select and toggle options. I think this is what they call old school, but then I grew up with it, but I admit it might be daunting at first:

Originally, I had made a mistake, and staged the vim74 directory in %temp%. I promptly realized I had made a mistake: I needed those files in a better place, not in my %temp%. I moved the vim74 directory to c:\opt\vim\vim74, and typed install again.

I really don't want those batch files. So, I typed the digit 1 and pressed enter. The program listed a bunch of directories in my %path% giving me the option to create batch files in one of those directories. The last option, in my case 12, was not to create any batch files, and that's the one I went with.

I am also trying to be a disciplined Vim user, so I disabled the mapping of CTRL-C, CTRL-V … etc in the default _vimrc to be created. Of course, I had saved my trusted _vimrc, and that's going in my %userprofile% directory.

Finally, I disabled the creation of various icons on the desktop:

Finally, type d, press Enter, and there you have your "Edit with Vim" context-menu entry.

Hope this helps!

PS: If you also want vim.exe for console use, do an nmake -f Make_mvc.mak … GUI=yes clean and then repeat the nmake command without GUI=yes. You can simply copy the resulting vim.exe alongside gvim.exe.

Link with the 64-bit libraries, Luke!

I had some trouble building perl 5.18.2 after upgrading to Windows 8.1 Pro.

While the test failures seemed to be confined to Module::Build and ExtUtils::ParseXS, the fact that the failed tests involved XS and dynamic libraries meant I could not simply ignore them.

As my first step towards solving the issue, I removed everything related to Visual Studio Express 2013 from my system. I also uninstalled all SDKs other than the Windows 7.1 SDK which does come with a 64-bit command line build environment.

My first attempt at rebuilding resulted in exactly the same test failures.

The failures persisted after installing the distribution, and trying to build the modules from the command line.

Something was so borken that I was getting LNK 2001 errors for even TerminateProcess … I had initially focused on the more interesting __security_cookie, but that was a red herring.

Looking over the bundled win32\Makefile, I realized the problem (and therefore also the solution) was staring me right in the face. The original win32\Makefile has:

CCHOME          = $(MSVCDIR)
CCINCDIR        = $(CCHOME)\include
CCLIBDIR        = $(CCHOME)\lib

The SDK command prompt does not set %MSVCDIR%, so I had set that to C:\Program Files\Microsoft SDKs\Windows\v7.1.

Well, there is that small matter of linking with the correct libraries, which happen to be in the lib\x64 under that!

After changing those to:

CCHOME          = C:\Program Files\Microsoft SDKs\Windows\v7.1
CCINCDIR        = $(CCHOME)\include
CCLIBDIR        = $(CCHOME)\lib\x64

nmake test went without a hitch.

Then, just to make sure, I downloaded ExtUtils::ParseXS, and did a perl Makefile.PL, nmake test, with the following results:

Microsoft (R) Program Maintenance Utility Version 10.00.30319.01
Copyright (C) Microsoft Corporation.  All rights reserved.

cp lib/ExtUtils/ParseXS/Utilities.pm blib\lib\ExtUtils\ParseXS\Utilities.pm
cp lib/ExtUtils/ParseXS/Eval.pm blib\lib\ExtUtils\ParseXS\Eval.pm
cp lib/ExtUtils/Typemaps/Type.pm blib\lib\ExtUtils\Typemaps\Type.pm
cp lib/ExtUtils/Typemaps/Cmd.pm blib\lib\ExtUtils\Typemaps\Cmd.pm
cp lib/ExtUtils/ParseXS.pod blib\lib\ExtUtils\ParseXS.pod
cp lib/ExtUtils/ParseXS.pm blib\lib\ExtUtils\ParseXS.pm
cp lib/ExtUtils/ParseXS/Constants.pm blib\lib\ExtUtils\ParseXS\Constants.pm
cp lib/ExtUtils/Typemaps/OutputMap.pm blib\lib\ExtUtils\Typemaps\OutputMap.pm
cp lib/ExtUtils/ParseXS/CountLines.pm blib\lib\ExtUtils\ParseXS\CountLines.pm
cp lib/ExtUtils/xsubpp blib\lib\ExtUtils\xsubpp
cp lib/ExtUtils/Typemaps/InputMap.pm blib\lib\ExtUtils\Typemaps\InputMap.pm
cp lib/ExtUtils/Typemaps.pm blib\lib\ExtUtils\Typemaps.pm
        C:\opt\perl-5.18.2\bin\perl.exe -MExtUtils::Command -e cp -- lib/ExtUtil
s/xsubpp blib\script\xsubpp
        pl2bat.bat blib\script\xsubpp
        C:\opt\perl-5.18.2\bin\perl.exe "-MExtUtils::Command::MM" "-e" "test_har
ness(0, 'blib\lib', 'blib\arch')" t/*.t
t/001-basic.t ............................ ok
t/002-more.t ............................. ok
t/003-usage.t ............................ ok
t/101-standard_typemap_locations.t ....... ok
t/102-trim_whitespace.t .................. ok
t/103-tidy_type.t ........................ ok
t/104-map_type.t ......................... ok
t/105-valid_proto_string.t ............... ok
t/106-process_typemaps.t ................. ok
t/108-map_type.t ......................... ok
t/109-standard_XS_defs.t ................. ok
t/110-assign_func_args.t ................. ok
t/111-analyze_preprocessor_statements.t .. ok
t/112-set_cond.t ......................... ok
t/113-check_cond_preproc_statements.t .... ok
t/114-blurt_death_Warn.t ................. ok
t/115-avoid-noise.t ...................... ok
t/501-t-compile.t ........................ ok
t/510-t-bare.t ........................... ok
t/511-t-whitespace.t ..................... ok
t/512-t-file.t ........................... ok
t/513-t-merge.t .......................... ok
t/514-t-embed.t .......................... ok
t/515-t-cmd.t ............................ ok
t/516-t-clone.t .......................... ok
t/517-t-targetable.t ..................... ok
t/600-t-compat.t ......................... ok
All tests successful.
Files=27, Tests=265, 10 wallclock secs ( 0.19 usr +  0.14 sys =  0.33 CPU)
Result: PASS

PS: FYI, I used CCTYPE = MSVC100 with this SDK.