Greatings to you all,

Since there was much more interest in the password encryption
.DLL than I tought there would be, and since I got some good
suggestions from many of you, I decided to put some sort of order
in all that.

I plan to cover, briefly, the following subjects:
    1) Why did I want to know how Interbase passwords were
       encrypted.
    2) What I found out.
    3) Why the C UNIX crypt routine is required and why I don't
       plan to translate it in Pascal/Delphi.
    4) How you can use crypt (from Delphi).
    5) What must be done if you are to manage users with a login
       other than SYSDBA.
    6) Why I don't like the fact that it's in a .DLL and how to
       make that more secure.
    7) Why wasn't I so brief after all...


-----------------------------------------------------------------
1) Why did I want to know how Interbase passwords were encrypted.

This is the original message I sent:
------------------------------------
OK, I searched enough.  I didn't find anywhere the way to change
a user's password for his Interbase login.  (That is with the
exception of the "Server manager".  I know I can change it there
provided I have the proper rights.)

I managed to create users by connecting myself to the ISC4.GDB
database and inserting records in the users table.  However, I
can only assign them an encrypted password I already know.  I
can't create new passwords.

I see only 3 solutions (not counting total abandonment).  1)
Somehow the DLL that encrypts passwords can be loaded and
accessed if there is such a DLL available.  2) The encryption
method is known and code can be written for it (or is already
available). 3) There is an undocumented feature (or buried deep
feature) which can do it.

As a final resort I suppose that it may be possible to activate
the "Server manager" from within an application and to feed it
the appropriate key sequences to do what I want, but that seems
to be such a clumsy way to do it...

Is there a solution.  Could the interbase people implement the
"CREATE USER", "ALTER USER" and "DROP USER" command.  They
should, it would make it a better product.

Hope that there is a viable solution.
-------------------------------------

As I found out, the third solution is the one for me.  At least
for now.

There was also some other need which wasn't stated here.  We
needed to create users within the application so we can build a
rather elaborate number of validation triggers.  Many rely on
knowing who the user is.  We couldn't just use the available
granting mecanism available in the Interbase.  (We use it, but we
have to go even into more details).


-----------------------------------------------------------------
2) What I found out.

I received messages suggesting that I use GSEC, unfortunately I
hadn't stated that it had to work with Delphi 1.x because our
application has to run under Windows 3.1 (sic).

I received suggestions that I should use someone's well done tool
but the creation of users had to be invisible to the user.

In the neantime I had tried my copy of the UNIX crypt with all
the salts possible (BTW, I found a weird delphi bug when you load
and unload a .DLL thousands of times within the same routine.)
Anyway, none worked, but I needed the routine for my own security
interface anyway.


-----------------------------------------------------------------
3) Why the C UNIX crypt routine is required and why I don't
   plan to translate it in Pascal/Delphi.

And then, I received a mail from Jeremy R. Bettis who found out,
I beleive in a UNIX Interbase sample program, that there was some
encryption being done with the UNIX crypt routine using the salt
value "9z".  But he said that it didn't produce the encrypted
password found in the Interbase USERS table.  I mailed back
suggesting that maybe there was overcrypting, tried it a short
while later, and it worked.  The result was striped of the
heading "9z" and crypted again with "9z" as the key.  That final
result, striped of the heading "9z" is the Interbase crypted
password.

I have in my posession, from a while ago, the source of the real
worldwide UNIX crypt routine.  I have adapted it to work in a
Window environment as a .DLL (5K).  ORIGINALLY, I had written the
unixpass.dll in such a way that it REQUIRED the bc450rtl.dll
(Borland C++ 4.5 runtime libraries).  Fortunately, I FOUND OUT
HOW TO GET RID OF BC450RTL.DLL (so those of you who didn't like
to have to use it you can rest now, as I didn't like it either).
I also reduced the size of the unixpass.dll by removing the debug
information option flags and resetting other options.  It can be
called from C or Delphi (1.x and 2).  It was compiled with
Borland C++ 4.5.  I have included the .DLL for Windows (3.x .. NT
4.0) and the .C source too.

Now, if anyone of you bathers to check the C source, you'll
understand why I don't want to translate it in Delphi.  It uses
many features only found in C to go about it's task.
Furthermore, there would always be some doubt about it's
exactness (at least, I would have some doubts).

Finally, before you rush, hoping to discover your boss' password,
you should know that UNIX employs an encrypting mecanism where it
purposefully loses bits of information.  That way, it is
impossible to revert back to the original password.  Of course,
if your boss chosed his password supidly, you may be able to gess
it and try out your hunches with this.  But then, being of more
experience than you he probably chooses well...  Anyway, don't
get any ideas, the "9z" equivalent is published in the
/etc/passwd of UNIX systems too and they are as secure as they
have even been, but I don't want to start a security debate here.
(Of course, some systems now use /etc/shadow because they had
security problems with users seeing what the encrypted password
were).  If anyone of you is interested in making sure that the
Interbase passwords are choosen intelligently you should try to
get a hold of UNIX security tools, like Satan, and adapt whatever
portion applies to your environment.


-----------------------------------------------------------------
4) How you can use crypt (from Delphi).

To encrypt a password is rather simple.  You just call the
routine that I named "Encrypt" thus:

    CryptedString := Encrypt(SaltString, PasswordString);

For our purpose though, we can call it like this:

    IntermediateString := COPY(Encrypt('9z', PasswordString), 3, 100);
    InterbasePassword  := COPY(Encrypt('9z', IntermediateString), 3, 100);

I know the "IntermediateString" isn't required, I just put it
there so the whole thing would be clearer.

Encrypt is actually a Delphi routine which loads the
unixpass.dll, calls the appropriate routine performing string
transformations to PCHAR and returns the crypted result.  BTW,
that result is always 13 characters, the first to being the salt
characters and the 11 others the crypted password.  (I know I put
100 on the COPY statement, but it's just to be on the safe side).

Encrypt loads the .DLL the 16 bits way.  That is, it won't work
with Delphi 2.0.  The change is rather simple to implement as I
have done so before, but I don't have an example right now.  So,
unixpass.dll does work with Delphi 2.0, you only have to adjust
the way the DLL is loaded.

I tought of putting a copy of Encrypt here, but since I plan to
send all the sources along with this document, you only have to
look it up in the UNIT1.PAS file.


-----------------------------------------------------------------
5) What must be done if you are to manage users with a login
   other than SYSDBA.

If you plan on creating users within a Delphi application, here
is what I have done to do so.

We are talking about the database ISC4.GDB (which can be about
anywhere on your local system or server) and the table USERS
within it.

I've created a different user just for our needs.  I have granted
to that user, from Windows ISQL, all the rights possible except
granting capabilities (as I didn't need it).  The rights are,
SELECT (which all users have on the USERS table), INSERT, DELETE
and UPDATE.

I created an aliases which refers to the ISC4.GDB database so I
can access it with Delphi database components.

I connect to the database using the special user as indicated
above.  I can then manipulate the USERS table as I would any
other table.  My only problem was that when I inserted users I
couldn't write an encrypted password in the database.  Now I can.


-----------------------------------------------------------------
6) Why I don't like the fact that it's in a .DLL and how to
   make that more secure.

Anyone can swipe a .DLL on you and plug his own version, which
ultimately calls yours.  He could then see what parameters you
are passing.  I've developed my owns means of preventing that,
and have included in the copy I sent you a crude way of doing the
same.  Unfortunately, I can't tell you what I've done myself as
it relies partly on secrecy.  But if I find a better way, I'll
let you know.

What I have implemented is a return value for the routine which
wouldn't be needed.  If the return value isn't what you expect,
you can deduce that the .DLL has been swipped.


-----------------------------------------------------------------
7) Why wasn't I so brief after all...

I lied?


In conclusion, I give thanks to all those that helped me,
specially Jeremy R. Bettis who found out about the "9z" and
without whose help none of this would have been possible.  I
would also like to salute my mother...  Oh! Shut up.

Grard Perreault
gperreau@igp.qc.ca
http://www.igp.qc.ca
