Re: cryptmodule.c

Andy Bensky (ab@infoseek.com)
Mon, 16 May 1994 14:00:02 -0700

I was going to send this in when I sent in the lockfile module, but I
forgot. This is a version of cryptmodule I wrote a few weeks ago
that allows for a salt to be passed in to crypt, or it will generate
one on the fly using a random number seeded by the current time, if
you do not supply a seed.

I called the function in cryptmodule that does the work Encrypt, but that
is easy enough to change. I have tested this code on both Solaris and
SunOS 4.1.3

- andy

/*
@(#)cryptmodule.c 1.3 04 May 1994
*/
/* Hooks to call the Unix crypt to implement DES encryption on a string.
*/

#ifdef SOLARIS
#include <crypt.h>
#else
extern char *crypt();
#endif
#include <time.h>
#include "allobjects.h"

/* Error conditions that can be raised */

object *SaltWrongLength;

/* Headers for functions accessible from Python as module methods */
static object *Encrypt( object *self, object *args );

static struct methodlist crypt_methods[] = {
{"Encrypt", Encrypt},
{NULL, NULL}
};

/*
* Name: initcrypt
* Description:
* Initialzation function that Python will use to establish callbacks to
* the methods of this module.
*
* Returns:
* void -
*
* Notes:
*/
void initcrypt()
{
object *m, *d;

m = initmodule("crypt", crypt_methods);
d = getmoduledict(m);
SaltWrongLength = newstringobject("Salt must be 2 characters");
dictinsert(d,"SaltWrongLength", SaltWrongLength);
}

/* From local_passwd.c (C) Regents of Univ. of California blah blah */
static unsigned char itoa64[] = /* 0 ... 63 => ascii - 64 */
"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";

to64(s, v, n)
register char *s;
register long v;
register int n;
{
while (--n >= 0)
{
*s++ = itoa64[v&0x3f];
v >>= 6;
}
}

/*
* Name: Encrypt
* Description:
* Python inerface to the system's DES crypt function (see crypt(3c))
* Arguments passed in from Python are the string to be encrypted and an
* optional 2 character string to be used as a salt for encryption.
* If a salt is not provided one will be generated randomly.
*
* Returns:
* - a string object containing the encrypted string
*
* Notes:
*/
static object *Encrypt( object *self, object *args )
{
char *string;
char *encrypted_string;
char *salt = 0;
char new_salt[3];
int saltlen;
object *encrypted_string_object = 0;

if (args && getargs(args, "(ss#)", &string, &salt, &saltlen))
{
if ( saltlen > 2 )
{
err_setstr(SaltWrongLength, "Salt provided is too long");
salt = 0;
}
else if ( saltlen < 2 )
{
err_setstr(SaltWrongLength, "Salt provided is too short");
salt = 0;
}
}
else if ( args && getargs(args, "s", &string) )
{
/* seed the random number generator with the current time */
(void)srand((int)time((time_t *)NULL));
to64(&new_salt[0], rand(), 2);
new_salt[2] = '\0';
salt = new_salt;
}
else
{
err_setstr(TypeError, "Usage: Encrypt(string, [salt(2 characters)])");
}
if ( salt )
{
encrypted_string = crypt(string, salt);
encrypted_string_object = newstringobject(encrypted_string);
}

return(encrypted_string_object);
}