Prev | 1  2  3  4  5  6  7  8  9  10  11  ... Next
Jobs: Customer Support Engineers Draft Hidden Sticky
Read | jobs, organizations, people | Thursday, March 04, 2010 7:23 PM | Post Comment | 20 Clicks

We’ve got openings for customer support engineers! We pride ourselves with excellent customer support located right here in New York City near Grand Central. Work closely with developers in a true software company taking phone calls and helping fortune 100 customers resolve complicated enterprise software issues. Send me a resume to dblock at dblock org if you’re awesome. No recruiters, I mean it.

WAFFLE: Windows Authentication Functional Framework (LE) Draft Hidden Sticky
Read | waffle, java, .net, active directory, win32 | Monday, March 01, 2010 2:28 PM | Post Comment | 47 Clicks

I am pleased to announce the open-sourcing of WAFFLE.

http://waffle.codeplex.com

WAFFLE stands for Windows Authentication Functional Framework (Light Edition). WAFFLE is a .NET library with a COM interface and a Java bridge that provides a working implementation of server-side Windows authentication, including Forms, Negotiate, NTLM and other SPNEGOs.

The long story:

We had a pickle. Our enterprise application, written in Java, needed Windows Forms authentication. We had no idea how to do this. After logon we wanted to get the logged on user's SID, a fully qualified name and domain groups, including nested ones to match an account in our database. Then we wanted to allow users to switch the application from Forms authentication to Windows authentication with single sign-on. Hard to believe, but we couldn't find anything that did what we wanted! So we wrote WAFFLE. Today we use JAAS and Tomcat and WAFFLE as a back-end, allowing our users to do all of forms logon, Windows NTLM, Negotiate and Kerberos (SPNEGO) authentication. WAFFLE is written in .NET and we use a Jacob Java bridge for interop. In some near future we’ll add the Java code that does Negotiate and NTLM in a Tomcat valve, it’s pretty straightforward.

If nothing else, this code serves as a clean and working example for everything related to LogonUser, InitializeSecurityContext and AcceptSecurityContext APIs.

JNA: Advapi32, Netapi32 and Secur32 Draft Hidden Sticky
Read | jna, java | Monday, February 22, 2010 7:00 PM | Post Comment | 24 Clicks
I made a code commit to JNA today. Yes, I am committing Java code to an LGPL project on java.net. Please don't hate me. I don't want to be dodging stones, so I'll be sticking to crowded spaces and plan to take the 6 train down from Grand Central today.
Win32 PInvoke with JNA Draft Hidden Sticky
Read | jna, java, win32 | Thursday, February 18, 2010 10:20 PM | 2 Comments | Post Comment | 82 Clicks

One of the main reasons I never liked JAVA is because of it's cross-platform philosophy. The idea is that everything needs to be so generic and portable, that you can’t get anything actually done. Running applications in the real world means integrating with the operating system. In my own experience I needed to get the username of the user logged into Windows, so I’ve generated everything from JNI monstrosities, C# libraries with COM wrappers invoked via Jacob to making remote service calls from CXF to WCF. Can someone please provide a solution that doesn’t make me feel retarded debugging SOAP messages for a local call to GetUserNameW?!

Thank you. The answer is called JNA.

Wrapping a Win32 function is a trivial exercise for any C/C++ developer who dealt with Win32. GetUserNameW takes a wchar_t buffer and a pointer to a length. In JNA this looks like this.

  1. import com.sun.jna.*;
  2. import com.sun.jna.ptr.IntByReference;
  3.  
  4. public interface IAdvapi32 extends com.sun.jna.examples.win32.W32API {
  5.     IAdvapi32 INSTANCE = (IAdvapi32) Native.loadLibrary("Advapi32", IAdvapi32.class);
  6.     
  7.     public boolean GetUserNameW(char[] buffer, IntByReference len);
  8. }

In order not to feel too much like a Win32 developer, we ought to wrap this thing with a usable method. GetUserName returns a boolean for success or failure and can give us an additional error when the buffer isn’t sufficiently large.

  1. public abstract class Advapi32 {
  2.  
  3.     public static final int ERROR_INSUFFICIENT_BUFFER = 122;
  4.  
  5.     public static String getUserName() {
  6.         char[] buffer = new char[128];
  7.         IntByReference len = new IntByReference(buffer.length);
  8.         boolean result = IAdvapi32.INSTANCE.GetUserNameW(buffer, len);
  9.         
  10.         if (! result) {
  11.             
  12.             int rc = Kernel32.INSTANCE.GetLastError();
  13.  
  14.             switch(rc) {
  15.             case ERROR_INSUFFICIENT_BUFFER:
  16.                 buffer = new char[len.getValue()];
  17.                 break;
  18.             default:
  19.                 throw new LastErrorException(Native.getLastError());
  20.             }
  21.             
  22.             result = IAdvapi32.INSTANCE.GetUserNameW(buffer, len);
  23.         }
  24.         
  25.         if (! result) {
  26.             throw new LastErrorException(Native.getLastError());
  27.         }
  28.         
  29.         return Native.toString(buffer);
  30.     }
  31. }

Note how JNA implements those nice methods that convert char[] buffers to String. That’s service!

Cabinet.dll: what's a proper way to handle fdintCABINET_INFO in a split cab Draft Hidden Sticky
Read | win32 | Thursday, February 11, 2010 10:57 AM | Post Comment | 70 Clicks

I’ve been tracking a bug in CabLib, used in dotNetInstaller recently. CabLib is a complete C# and C++ wrapper for Cabinet.dll and its goal is to make it easier to CAB files. Anyone who used Cabinet.dll’s interface directly will quickly discover that it follows the usual Microsoft Win32 mantra: if a developer can do something himself with the existing API, don’t include that functionality in the platform SDK. This produces a well thought-through Cabinet SDK, provided that your user has a major in computer science and a PhD in cognitive psychology.

One of the more interesting aspects of CABs is so-called split CABs. This is just a chain of CAB files, useful if you need to put CABs on a set of floppy drives or embed as a Win32 resource, as dotNetInstaller does (resource size is limited). The Cabinet.dll interface is based on callbacks: you call FDICopy and it calls you back (fdintCABINET_INFO) whenever it encounters a file that is split over several CABs, telling you which next CAB to process. Logically, you would want to process that next CAB, except that here you need to wait for FDICopy to return to do it. This means you need to remember what the next CAB name is, so that you can call FDICopy on it. The algorithm around FDICopy looks like this.

  1. while (TRUE)
  2. {
  3.     if (! FdiCopy(context, cabFile, cabFolder, 0, FDICallback, 0, pParam))
  4.         break;
  5.  
  6.     if (! nextCab.Len())
  7.         break;
  8.     
  9.     cabFile = nextCab;
  10. }

… and the callback …

  1. INT_PTR FdiCallback(FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin)
  2. {
  3.     switch (fdint)
  4.     {
  5.         case fdintCABINET_INFO:
  6.         {
  7.             nextCab = pfdin->psz1;

There’s a bug here, one that was not obvious to track. The symptom is that you’re not getting all the files extracted, some CAB files are missed. The problem is that while you’re processing CAB1, for FILE1 you can get a callback that says to continue in CAB2. Then you can get a callback for FILE2 that says to continue in CAB3. You should be ignoring that second callback because you haven’t processed CAB2 yet.

I initially fixed it with a list, but CabLib author pointed out that this is an overkill. The final code looks like this.

  1. while (TRUE)
  2. {
  3.     nextCab.clear();
  4.  
  5.     if (! FdiCopy(context, cabFile, cabFolder, 0, FDICallback, 0, pParam))
  6.         break;
  7.  
  8.     if (! nextCab.Len())
  9.         break;
  10.     
  11.     cabFile = nextCab;
  12. }

  1. INT_PTR FdiCallback(FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin)
  2. {
  3.     switch (fdint)
  4.     {
  5.         case fdintCABINET_INFO:
  6.         {
  7.             if (nextCab.empty())
  8.                 nextCab = pfdin->psz1;

This was a huge time suck from my development time. If there’s one conclusion you want to take away from this, is that you should never design an interface like the one in Cabinet.dll.

MSIOpenPackage on Windows 7: behavior changed Draft Hidden Sticky
Read | testing, msi, win32 | Wednesday, February 10, 2010 6:47 PM | Post Comment | 77 Clicks

I was very happy upgrading to Windows 7. Virtually everything worked. All kinds of source code that I am writing compiles and runs without issues. It’s only a week later that I had to touch the AppSecInc. Community MSI extensions and discovered that most unit tests are failing. I talked about unit testing custom actions earlier. I finally got to the bottom of it.

On Windows 7 the behavior of MSIOpenPackage has changed. We use it to run unit tests by creating a database (MSICreateDatabase) and calling MSIOpenPackage to get a working handle. On Windows 7 code that worked earlier always returns 0x80070645: This action is only valid for products that are currently installed. This is one obscure error code! Why do I need an installed product to open an MSI package?

Microsoft.public.platformsdk.msi was helpful [thread]. For MsiOpenPackage to succeed you now have to have a Property table with a populated ProductCode value in the MSI file itself. MsiExt shim code now looks like this. The two Execute statements are new. This incidentally demonstrates what fields you need in the MSI summary to get a valid MSI.

  1. _database.Create(_filename);
  2.  
  3.     MsiDatabaseSummaryEntry summary_entries[] =
  4.     {
  5.         { PID_TITLE, VT_LPSTR, L"MSI Shim Database" },
  6.         { PID_SUBJECT, VT_LPSTR, L"MSI Shim Database" },
  7.         { PID_AUTHOR, VT_LPSTR, L"AppSecInc." },
  8.         { PID_TEMPLATE, VT_LPSTR, ";1033" },
  9.         { PID_REVNUMBER, VT_LPSTR, "{00869AA3-A32E-4398-89B2-5C5DC7328C7C}" },
  10.         { PID_PAGECOUNT, VT_I4, 100 },
  11.         { PID_WORDCOUNT, VT_I4, 100 },
  12.     };
  13.  
  14.     // A valid MSI must have a summary for MsiOpenPackage to succeed
  15.     _database.SetSummary(summary_entries, ARRAYSIZE(summary_entries));
  16.     
  17.     // Windows 7 requires a property table with a ProductCode value
  18.     _database.Execute(L"CREATE TABLE `Property` (`Property` CHAR(72) NOT NULL, `Value` CHAR(0) NOT NULL LOCALIZABLE PRIMARY KEY `Property`)");
  19.     _database.Execute(L"INSERT INTO `Property` (`Property`, `Value`) VALUES ('ProductCode', '{07F7FB1B-992E-4a2d-805C-C803C98CFC42}')");
  20.     
  21.     _database.Commit();
  22.     _database.Close();
  23.  
  24.     Open(_filename);

Hope this saves you hours of fruitless debugging.

Maybe Raymond can answer why this change in behavior in Windows 7?

Oracle 0-day: how complex systems allow simple attacks Draft Hidden Sticky
Read | security, databases | Wednesday, February 10, 2010 10:00 AM | Post Comment | 101 Clicks
imageSince I work in database security, I heard “Oracle 0-Day” about every 15 minutes in the past few days [read this for details]. I watched the David Litchfield’s Blackhat presentation with the Oracle 11G 0-day exploit (the video was pulled down from Blackhat’s site and is now back here). The vulnerability is business as usual, while the fact that it’s a zero-day must really be upsetting for Oracle – if you have an Oracle 11G, it would seem that there’s nothing you can do. Well, it’s not entirely true – we already distributed to our customers a knowledgebase update with fix scripts that revoke those evil privileges that prevent the vulnerability from being exploited. Applying it is another story because you might have applications that need those, but this is not the subject of my post.

When I was at Microsoft I worked on Microsoft Billing amongst other things. I heard “Secure Code Initiative” just about as many times as “Oracle 0-Day” in those years. We focused on making systems simpler and more secure by design. Once the usual suspects of buffer overrun types were removed by not using strcpy and friends, it’s simple software design that eventually would yield secure software. SQL server is a great example, there hasn’t been a single severe vulnerability since SQL 2005. Oracle should go through a serious transformation of its programming and architecture practices, and simplify the system by core design. I mean, seriously, DBMS_JVM_EXP_PERMS mixed with a whole stack of Java APIs, seriously? Removing this kind of crap might be painful, but will go a long way to help sell more Oracle databases – otherwise, mark my words, it’s only a matter of time till a new generation of software and programmers makes Oracle databases obsolete and replace those monsters by cheaper, leaner alternatives.

Now let me see what other 0-day vulnerabilities for Oracle I have written on this napkin laying on my desk …
Prev | 1  2  3  4  5  6  7  8  9  10  11  ... Next
 Highlights
Dblock.org
FoodCandy
Vestris SVN
VMWareTasks
dotNetInstaller
RemoteInstall
MSI Extensions
ResourceLib
Popular Posts
Waffle
Stuff
all posts
.net
active directory
agile
architecture
asp.net
blog
build
codeproject
databases
dos
dotnetinstaller
google
hardware
hibernate
java
jna
jobs
log4cxx
me me
msbuild
msi
organizations
outlook
people
remoteinstall
scheme
security
subversion
syndication
testing
ui
vestris
vmware
waffle
win32
wix
wmi
p | s | pop | pics | c | me | h
185838 clicks since 8/10/2008