]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
Added compatibility with Tom Wu's libsrp's password files.
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Sun, 13 May 2001 10:05:15 +0000 (10:05 +0000)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Sun, 13 May 2001 10:05:15 +0000 (10:05 +0000)
21 files changed:
lib/Makefile.am
lib/auth_srp.c
lib/auth_srp_passwd.c
lib/auth_srp_passwd.h
lib/crypt.c
lib/crypt.h [new file with mode: 0644]
lib/crypt_bcrypt.c
lib/crypt_bcrypt.h
lib/crypt_srpsha1.c
lib/crypt_srpsha1.h
lib/gnutls.h
lib/gnutls_srp.c
lib/gnutls_srp.h
src/Makefile.am
src/README.crypt [new file with mode: 0644]
src/cli.c
src/crypt.c
src/crypt.gaa
src/gaa.h
src/gaaout.c
src/serv.c

index f07f40a1ccb1bbde9556add8684a53b172b11b1c..3924e0d1f97fcd88892ee25db15ea68e308f79a3 100644 (file)
@@ -6,7 +6,8 @@ EXTRA_DIST = debug.h gnutls_compress.h defines.h gnutls_plaintext.h \
        gnutls_compress_int.h gnutls_session.h gnutls_priority.h gnutls_auth.h \
        auth_anon.h auth_dhe_dss.h gnutls_extensions.h ext_srp.h \
        gnutls_auth_int.h crypt_bcrypt.h gnutls_random.h crypt_srpsha1.h \
-       cert_b64.h gnutls_srp.h auth_srp.h auth_srp_passwd.h gnutls_v2_compat.h
+       cert_b64.h gnutls_srp.h auth_srp.h auth_srp_passwd.h gnutls_v2_compat.h \
+       crypt.h
 lib_LTLIBRARIES = libgnutls.la
 libgnutls_la_SOURCES = gnutls.c gnutls_compress.c debug.c gnutls_plaintext.c \
        gnutls_cipher.c gnutls_buffers.c gnutls_handshake.c gnutls_num.c \
index a150e76cfc784355957dd72782bb10fa2269465d..5c5dff227b0c92c3896a5f143ed658cb14aa3f68 100644 (file)
@@ -71,16 +71,19 @@ int gen_srp_server_kx(GNUTLS_KEY key, opaque ** data)
        uint8 *data_g;
        uint8 pwd_algo;
        GNUTLS_SRP_PWD_ENTRY *pwd_entry;
+       int err;
 
        if (key->username == NULL) {
                return GNUTLS_E_INSUFICIENT_CRED;
        }
 
-       pwd_entry = _gnutls_srp_pwd_read_entry( key, key->username);
+       pwd_entry = _gnutls_srp_pwd_read_entry( key, key->username, &err);
 
        if (pwd_entry == NULL) {
-               pwd_entry = _gnutls_randomize_pwd_entry();
-               /* return GNUTLS_E_PWD_ERROR; */
+               if (err==0)
+                       pwd_entry = _gnutls_randomize_pwd_entry();
+               else 
+                       return GNUTLS_E_PWD_ERROR;
        }
 
        pwd_algo = (uint8) pwd_entry->algorithm;
@@ -319,12 +322,12 @@ int proc_srp_server_kx(GNUTLS_KEY key, opaque * data, int data_size)
        /* generate x = SHA(s | SHA(U | ":" | p))
         * (or the equivalent using bcrypt)
         */
-       hd = _gnutls_calc_srp_x( username, password, data_s, n_s, pwd_algo);
+       hd = _gnutls_calc_srp_x( username, password, data_s, n_s, pwd_algo, &_n_g);
        if (hd==NULL) {
                gnutls_assert();
                return GNUTLS_E_HASH_FAILED;
        }
-       _n_g = 20;
+
        if (gcry_mpi_scan(&key->x, GCRYMPI_FMT_USG, hd, &_n_g) != 0) {
                gnutls_assert();
                return GNUTLS_E_MPI_SCAN_FAILED;
index 119cde8b49e31698f0a4ed22d8add022d8b01a09..56e60542333e248b44124703e932b721e89c1288 100644 (file)
  * string(username):base64(v):base64(salt):int(index)
  */
 static int pwd_put_values( GNUTLS_SRP_PWD_ENTRY *entry, char *str, int str_size) {
-char * p;
+char * p, *p2;
 int len;
 opaque *verifier;
 int verifier_size;
-int index;
+int indx;
 
-       entry->algorithm = SRPSHA1_CRYPT;
-       
        p = rindex( str, ':'); /* we have index */
        if (p==NULL) {
                gnutls_assert();
@@ -53,8 +51,8 @@ int index;
        p++;
 
        len = strlen(p);
-       index = atoi(p);
-       if (index==0) {
+       indx = atoi(p);
+       if (indx==0) {
                gnutls_assert();
                return GNUTLS_E_PARSING_ERROR;
        }
@@ -86,7 +84,21 @@ int index;
        
        *p='\0';
        p++;
-       
+
+       if ( (p2 = index(p, '$')) == NULL) {
+               entry->algorithm = SRPSHA1_CRYPT;
+       } else {
+               p++;
+               entry->algorithm = atoi(p);
+               p2 = index(p, '$'); /* find the last $ */
+               if (p2==NULL) {
+                       gnutls_assert();
+                       gnutls_free(entry->salt);
+                       return GNUTLS_E_PARSING_ERROR;
+               }
+               p = p2+1;
+       }
+
        len = strlen(p);
        verifier_size = _gnutls_sbase64_decode( p, len, &verifier);
        if (verifier_size <= 0) {
@@ -107,7 +119,7 @@ int index;
 
        entry->username = strdup(str);
 
-       return index;
+       return indx;
 }
 
 
@@ -203,7 +215,7 @@ static int pwd_read_conf( SRP_SERVER_CREDENTIALS* cred, GNUTLS_SRP_PWD_ENTRY* en
            while( (line[i]!=':') && (line[i]!='\0') && (i < sizeof(line)) ) {
                    i++;
            }
-           if (strncmp( indexstr, line, i) == 0) {
+           if (strncmp( indexstr, line, strlen(indexstr)) == 0) {
                        if ((index = pwd_put_values2( entry, line, strlen(line))) >= 0)
                                return 0;
                        else {
@@ -216,7 +228,7 @@ static int pwd_read_conf( SRP_SERVER_CREDENTIALS* cred, GNUTLS_SRP_PWD_ENTRY* en
 }
 
 
-GNUTLS_SRP_PWD_ENTRY *_gnutls_srp_pwd_read_entry( GNUTLS_KEY key, char* username) {
+GNUTLS_SRP_PWD_ENTRY *_gnutls_srp_pwd_read_entry( GNUTLS_KEY key, char* username, int *err) {
        SRP_SERVER_CREDENTIALS* cred;
        FILE * fd;
        char line[5*1024];
@@ -224,8 +236,11 @@ GNUTLS_SRP_PWD_ENTRY *_gnutls_srp_pwd_read_entry( GNUTLS_KEY key, char* username
        GNUTLS_SRP_PWD_ENTRY * entry = gnutls_malloc(sizeof(GNUTLS_SRP_PWD_ENTRY));
        int index;
 
+       *err = 0; /* normal exit */
+       
        cred = _gnutls_get_kx_cred( key, GNUTLS_KX_SRP, NULL);
        if (cred==NULL) {
+               *err = 1;
                gnutls_assert();
                gnutls_free(entry);
                return NULL;
@@ -233,18 +248,19 @@ GNUTLS_SRP_PWD_ENTRY *_gnutls_srp_pwd_read_entry( GNUTLS_KEY key, char* username
 
        fd = fopen( cred->password_file, "r");
        if (fd==NULL) {
+               *err = 1; /* failed due to critical error */
                gnutls_assert();
                gnutls_free(entry);
                return NULL;
        }
 
        while( fgets( line, sizeof(line), fd) != NULL) {
-    /* move to first ':' */
+           /* move to first ':' */
            i=0;
            while( (line[i]!=':') && (line[i]!='\0') && (i < sizeof(line)) ) {
                    i++;
            }
-           if (strncmp( username, line, i) == 0) {
+           if (strncmp( username, line, strlen(username)) == 0) {
                        if ((index = pwd_put_values( entry, line, strlen(line))) >= 0)
                                if (pwd_read_conf( cred, entry, index)==0) {
                                        return entry;
@@ -262,7 +278,7 @@ GNUTLS_SRP_PWD_ENTRY *_gnutls_srp_pwd_read_entry( GNUTLS_KEY key, char* username
        
 }
 #define RNDUSER "rnd"
-#define RND_SALT_SIZE 16
+#define RND_SALT_SIZE 17
 GNUTLS_SRP_PWD_ENTRY* _gnutls_randomize_pwd_entry() {
        GNUTLS_SRP_PWD_ENTRY * pwd_entry = gnutls_malloc(sizeof(GNUTLS_SRP_PWD_ENTRY));
        size_t n = sizeof diffie_hellman_group1_prime;
index e686cb57cbcdfef0077c648bd36118ba43745834..77e0c0cd1becef9df8ba0a1a21bacc85a31977a3 100644 (file)
@@ -11,6 +11,6 @@ typedef struct {
 } GNUTLS_SRP_PWD_ENTRY;
 
 /* this is localy alocated. It should be freed using the provided function */
-GNUTLS_SRP_PWD_ENTRY *_gnutls_srp_pwd_read_entry( GNUTLS_KEY key, char* username);
+GNUTLS_SRP_PWD_ENTRY *_gnutls_srp_pwd_read_entry( GNUTLS_KEY key, char* username, int* err);
 void _gnutls_srp_clear_pwd_entry( GNUTLS_SRP_PWD_ENTRY * entry);
 GNUTLS_SRP_PWD_ENTRY* _gnutls_randomize_pwd_entry();
index c14b0c54c9d4777c5b109ef8c5479914f33cee78..e6e9776d12ed9221a2e2798eff3d8ddf7e7d9bb5 100644 (file)
 #include "crypt_srpsha1.h"
 #include "gnutls_random.h"
 
-char * gnutls_crypt(const char* username, const char *passwd, crypt_algo algo, int salt) {
+char * gnutls_crypt(const char* username, const char *passwd, crypt_algo algo, int salt, MPI g, MPI n) {
        
        switch(algo) {
        case BLOWFISH_CRYPT: /* bcrypt */
                /* salt in bcrypt is actually the cost */
-               return crypt_bcrypt_wrapper(passwd, salt);
+               return crypt_bcrypt_wrapper(passwd, salt, g, n);
        case SRPSHA1_CRYPT: /* bcrypt */
                /* salt in bcrypt is the salt size */
-               return crypt_srpsha1_wrapper(username, passwd, salt);
+               return crypt_srpsha1_wrapper(username, passwd, salt, g, n);
        }
        return NULL;
 }
 
-int gnutls_crypt_vrfy(const char* username, const char *passwd, char* salt) {
+int gnutls_crypt_vrfy(const char* username, const char *passwd, char* salt, MPI g, MPI n) {
        char* cr;
-       
+
        switch(salt[0]) {
        case '$':
                switch(salt[1]) {
                case '2':
-                       cr = crypt_bcrypt(passwd, salt);
-                       if (strncmp(cr, salt, strlen(cr))==0) return 0;
-                       break;
-               case '4':
-                       cr = crypt_srpsha1(username, passwd, salt);
+                       cr = crypt_bcrypt(passwd, salt, g, n);
                        if (strncmp(cr, salt, strlen(cr))==0) return 0;
                        break;
                }
+       default:
+               cr = crypt_srpsha1(username, passwd, salt, g, n);
+               if (strncmp(cr, salt, strlen(cr))==0) return 0;
+               break;
        }
        return 1;
 }
diff --git a/lib/crypt.h b/lib/crypt.h
new file mode 100644 (file)
index 0000000..205ec72
--- /dev/null
@@ -0,0 +1,4 @@
+/* crypt functions */
+
+char * gnutls_crypt(const char* username, const char *passwd, crypt_algo algo, int salt, MPI g, MPI n);
+int gnutls_crypt_vrfy(const char* username, const char *passwd, char* salt, MPI g, MPI n);
index c635c6296ff9601aadb012b5e4b50c3b181ca196..aade53b2a9c1d0d773bfb623913ba3a08f9cbe47 100644 (file)
@@ -74,12 +74,12 @@ static void _blf_encrypt(blf_ctx * c, uint8 * x)
 
        x[0] = (Xl >> 24) & 0xff;
        x[1] = (Xl >> 16) & 0xff;
-       x[2] = (Xl >>  8) & 0xff;
-       x[3] = (Xl      ) & 0xff;
+       x[2] = (Xl >> 8) & 0xff;
+       x[3] = (Xl) & 0xff;
        x[4] = (Xr >> 24) & 0xff;
        x[5] = (Xr >> 16) & 0xff;
-       x[6] = (Xr >>  8) & 0xff;
-       x[7] = (Xr      ) & 0xff;
+       x[6] = (Xr >> 8) & 0xff;
+       x[7] = (Xr) & 0xff;
 }
 
 /* x should be a 64 bit integer */
@@ -118,8 +118,7 @@ static short initialize_blowfish(blf_ctx * c)
 {
        short i;
 
-       uint32 ks0[] =
-       {
+       uint32 ks0[] = {
                0xd1310ba6UL, 0x98dfb5acUL, 0x2ffd72dbUL, 0xd01adfb7UL,
                0xb8e1afedUL, 0x6a267e96UL,
                0xba7c9045UL, 0xf12c7f99UL, 0x24a19947UL, 0xb3916cf7UL,
@@ -207,8 +206,7 @@ static short initialize_blowfish(blf_ctx * c)
                0x53b02d5dUL, 0xa99f8fa1UL, 0x08ba4799UL, 0x6e85076aUL
        };
 
-       uint32 ks1[] =
-       {
+       uint32 ks1[] = {
                0x4b7a70e9UL, 0xb5b32944UL, 0xdb75092eUL, 0xc4192623UL,
                0xad6ea6b0UL, 0x49a7df7dUL,
                0x9cee60b8UL, 0x8fedb266UL, 0xecaa8c71UL, 0x699a17ffUL,
@@ -296,8 +294,7 @@ static short initialize_blowfish(blf_ctx * c)
                0x153e21e7UL, 0x8fb03d4aUL, 0xe6e39f2bUL, 0xdb83adf7UL
        };
 
-       uint32 ks2[] =
-       {
+       uint32 ks2[] = {
                0xe93d5a68UL, 0x948140f7UL, 0xf64c261cUL, 0x94692934UL,
                0x411520f7UL, 0x7602d4f7UL,
                0xbcf46b2eUL, 0xd4a20068UL, 0xd4082471UL, 0x3320f46aUL,
@@ -385,8 +382,7 @@ static short initialize_blowfish(blf_ctx * c)
                0xd79a3234UL, 0x92638212UL, 0x670efa8eUL, 0x406000e0UL
        };
 
-       uint32 ks3[] =
-       {
+       uint32 ks3[] = {
                0x3a39ce37UL, 0xd3faf5cfUL, 0xabc27737UL, 0x5ac52d1bUL,
                0x5cb0679eUL, 0x4fa33742UL,
                0xd3822740UL, 0x99bc9bbeUL, 0xd5118e9dUL, 0xbf0f7315UL,
@@ -475,8 +471,7 @@ static short initialize_blowfish(blf_ctx * c)
        };
 
 
-       uint32 pi[] =
-       {
+       uint32 pi[] = {
                0x243f6a88UL, 0x85a308d3UL, 0x13198a2eUL, 0x03707344UL,
                0xa4093822UL, 0x299f31d0UL,
                0x082efa98UL, 0xec4e6c89UL, 0x452821e6UL, 0x38d01377UL,
@@ -501,23 +496,24 @@ static short initialize_blowfish(blf_ctx * c)
        return 0;
 }
 
-static short _blf_ExpandKey(blf_ctx * c, const uint8 * key, short keybytes, const uint8* bsalt)
+static short _blf_ExpandKey(blf_ctx * c, const uint8 * key, short keybytes,
+                           const uint8 * bsalt)
 {
        short i, j;
        int k;
        uint32 data, temp[2];
        uint32 wsalt[4];
 
-       if (bsalt!=NULL) {
+       if (bsalt != NULL) {
                wsalt[0] = 0x00000000;
                wsalt[1] = 0x00000000;
                wsalt[2] = 0x00000000;
                wsalt[3] = 0x00000000;
-               for (i=0;i<4;i++) {
+               for (i = 0; i < 4; i++) {
                        wsalt[0] = (wsalt[0] << 8) | bsalt[i];
-                       wsalt[1] = (wsalt[1] << 8) | bsalt[i+4];
-                       wsalt[2] = (wsalt[2] << 8) | bsalt[i+8];
-                       wsalt[3] = (wsalt[3] << 8) | bsalt[i+12];
+                       wsalt[1] = (wsalt[1] << 8) | bsalt[i + 4];
+                       wsalt[2] = (wsalt[2] << 8) | bsalt[i + 8];
+                       wsalt[3] = (wsalt[3] << 8) | bsalt[i + 12];
                }
        }
 
@@ -527,16 +523,16 @@ static short _blf_ExpandKey(blf_ctx * c, const uint8 * key, short keybytes, cons
        /* Step 1: XOR the Pbox with the key */
        for (i = 0; i < BF_N + 2; i++) {
                data = 0x00000000;
-               data = (data << 8) | key[(j)   % keybytes];
-               data = (data << 8) | key[(j+1) % keybytes];
-               data = (data << 8) | key[(j+2) % keybytes];
-               data = (data << 8) | key[(j+3) % keybytes];
+               data = (data << 8) | key[(j) % keybytes];
+               data = (data << 8) | key[(j + 1) % keybytes];
+               data = (data << 8) | key[(j + 2) % keybytes];
+               data = (data << 8) | key[(j + 3) % keybytes];
 
                c->P[i] ^= data;
                j = (j + 4) % keybytes;
        }
 
-       k = 2; /* This should be 0 ??? */
+       k = 2;                  /* This should be 0 ??? */
        /* Step 2: Use the salt on Pbox */
        for (i = 0; i < BF_N + 2; i += 2) {
                if (bsalt != NULL) {
@@ -568,8 +564,8 @@ static short _blf_ExpandKey(blf_ctx * c, const uint8 * key, short keybytes, cons
 
 
 
-static blf_ctx *
_blf_init( uint8 *salt, const char *key, int key_len, int cost)
+static blf_ctx *_blf_init(uint8 * salt, const char *key, int key_len,
                        int cost)
 {
        blf_ctx *state = malloc(sizeof(blf_ctx));
        uint32 i, rcost;
@@ -586,16 +582,15 @@ static blf_ctx *
        return state;
 }
 
-static void _blf_deinit(blf_ctx *ctx)
+static void _blf_deinit(blf_ctx * ctx)
 {
        free(ctx);
 }
 static const char magic[] = "$2$";
 
-char *
- crypt_bcrypt(const char *passwd, const char *salt)
+char *crypt_bcrypt(const char *passwd, const char *salt, MPI g, MPI n)
 {
-       unsigned char *sp, *tsp;
+       unsigned char *sp;
        blf_ctx *ctx;
        unsigned char text[24] = "OrpheanBeholderScryDoubt";
        uint8 *csalt;
@@ -604,7 +599,7 @@ char *
        int i, salt_size = strlen(salt);
        unsigned char *local_salt, *v;
        int passwd_len, vsize;
-       opaque *tmp, *g, *n;
+       opaque *tmp;
 
        passwd_len = strlen(passwd) + 1;        /* we want the null also */
        if (passwd_len > 56)
@@ -612,105 +607,110 @@ char *
 
        local_salt = malloc(salt_size + 1);
        strcpy((char *) local_salt, salt);
-       sp = local_salt;
-
-       /* If it starts with the magic string, then skip that */
-       if (!strncmp((char *) sp, magic, strlen(magic)))
-               sp += strlen(magic);
 
-       tsp = sp;
-       while((*tsp)!='$') tsp++;
-       *tsp = '\0';            /* put a null after the end of salt */
+       sp = index( local_salt, ':'); /* move to salt - after verifier */
+       if (sp==NULL) {
+               gnutls_assert();
+               return NULL;
+       }
+       sp++;
 
-       _gnutls_base64_decode( sp, strlen(sp), &csalt);
+       _gnutls_sbase64_decode(sp, strlen(sp), &csalt);
 
        cost = (uint8) csalt[0];
-       ctx = _blf_init( &csalt[1], passwd, passwd_len, cost);
+       ctx = _blf_init(&csalt[1], passwd, passwd_len, cost);
        gnutls_free(csalt);
-       
+
        for (i = 0; i < 64; i++) {
                _blf_encrypt(ctx, (uint8 *) text);
-               _blf_encrypt(ctx, (uint8 *) &text[8]);
-               _blf_encrypt(ctx, (uint8 *) &text[16]);
+               _blf_encrypt(ctx, (uint8 *) & text[8]);
+               _blf_encrypt(ctx, (uint8 *) & text[16]);
        }
 
        /* v = g^x mod n */
-       vsize = _gnutls_srp_gx(text, 8*3, &v, &g, &n);
-       if (vsize==-1 || v==NULL) {
+       vsize = _gnutls_srp_gx(text, 8 * 3, &v, g, n);
+       if (vsize == -1 || v == NULL) {
                gnutls_assert();
                return NULL;
        }
-       
-       _gnutls_base64_encode(v, vsize, &rtext);
+
+       _gnutls_sbase64_encode(v, vsize, &rtext);
        gnutls_free(v);
 
-       tmp = gnutls_malloc( strlen(magic)+3+strlen(sp)+1+strlen(rtext)+strlen(g)+2+strlen(n)+1);
+       tmp =
+           gnutls_malloc(strlen(magic) + 3 + strlen(sp) + 1 +
+                         strlen(rtext) + 1);
 
-       sprintf( tmp, "%s%.2u$%s$%s$%s$%s", magic, (unsigned int) cost, sp, rtext, g, n);
-       gnutls_free(g);
-       gnutls_free(n);
+       sprintf(tmp, "%s%s:%s", magic, rtext, sp);
 
        gnutls_free(local_salt);
        gnutls_free(rtext);
-       
+
        _blf_deinit(ctx);
        return tmp;
 }
 
-char *crypt_bcrypt_wrapper(const char *pass_new, int cost)
+/* cost is stored as the first byte in salt (thus < 255) which is fine! */
+char *crypt_bcrypt_wrapper(const char *pass_new, int cost, MPI g, MPI n)
 {
-       unsigned char *result;
-       char* tcp;
-       unsigned char* rand;
-       char *e = NULL;
-          int result_size;
-          
-       rand = _gnutls_get_random( 17, GNUTLS_WEAK_RANDOM);
-       /* cost should be <32 and >6 */
-       if (cost >=32) cost=31;
-       if (cost < 1) cost = 1;
-
-          rand[0] = (uint8) cost;
-          result_size = _gnutls_base64_encode( rand, 17, &result);
-          if (result_size < 0) {
-               gnutls_assert();
-               return NULL;
-          }
-
-          tcp = gnutls_calloc( 1, strlen(magic)+ 3 + result_size +1+1);
-       sprintf(tcp, "%s$%s$", magic, result);
-
-          gnutls_free(result);
-
-          _gnutls_free_rand(rand);
-          
-       e = crypt_bcrypt(pass_new, (const char *) tcp);
-          gnutls_free(tcp);
-                  
-       return e;
+       unsigned char *result;
+       char *tcp;
+       unsigned char *rand;
+       char *e = NULL;
+       int result_size;
+
+       rand = _gnutls_get_random(17, GNUTLS_WEAK_RANDOM);
+       /* cost should be <32 and >6 */
+       if (cost >= 32)
+               cost = 31;
+       if (cost < 1)
+               cost = 1;
+
+       rand[0] = (uint8) cost;
+       result_size = _gnutls_sbase64_encode(rand, 17, &result);
+       if (result_size < 0) {
+               gnutls_assert();
+               return NULL;
+       }
+
+       tcp = gnutls_calloc(1, 1 + result_size + 1);
+       sprintf(tcp, ":%s", result);
+
+       gnutls_free(result);
+
+       _gnutls_free_rand(rand);
+
+       e = crypt_bcrypt(pass_new, (const char *) tcp, g, n);
+       gnutls_free(tcp);
+
+       return e;
 }
 
-void *
- _gnutls_calc_srp_bcrypt( char *passwd, opaque *salt, int salt_size)
+void *_gnutls_calc_srp_bcrypt(char *passwd, opaque * salt, int salt_size, int* size)
 {
        blf_ctx *ctx;
        opaque text[24] = "OrpheanBeholderScryDoubt";
        int passwd_len, i;
        opaque *tmp;
 
+       *size = sizeof(text);
+       
+       /* we need 16 + cost */
+       if (salt_size < 17) return NULL;
+       
        passwd_len = strlen(passwd) + 1;        /* we want the null also */
        if (passwd_len > 56)
                passwd_len = 56;
 
-       ctx = _blf_init( &salt[1], passwd, passwd_len, salt[0]);
+       ctx = _blf_init(&salt[1], passwd, passwd_len, (uint32)salt[0]);
 
        tmp = malloc(sizeof(text));
-       memcpy( tmp, text, sizeof(text));
-               
+       memcpy(tmp, text, sizeof(text));
+
        for (i = 0; i < 64; i++) {
                _blf_encrypt(ctx, (uint8 *) tmp);
-               _blf_encrypt(ctx, (uint8 *) &tmp[8]);
-               _blf_encrypt(ctx, (uint8 *) &tmp[16]);
+               _blf_encrypt(ctx, (uint8 *) & tmp[8]);
+               _blf_encrypt(ctx, (uint8 *) & tmp[16]);
        }
 
        _blf_deinit(ctx);
index aedb3c6aa29bf16ca601300c27498ca7a167f081..98f04c575f4d33c5a08e55e165385fb591a23684 100644 (file)
@@ -1,3 +1,3 @@
-char * crypt_bcrypt (const char *passwd, const char *salt);
-char *crypt_bcrypt_wrapper(const char *pass_new, int cost);
-void * _gnutls_calc_srp_bcrypt( char *passwd, opaque *salt, int salt_size);
+char * crypt_bcrypt (const char *passwd, const char *salt, MPI g, MPI n);
+char *crypt_bcrypt_wrapper(const char *pass_new, int cost, MPI g, MPI n);
+void * _gnutls_calc_srp_bcrypt( char *passwd, opaque *salt, int salt_size, int* size);
index 5c1397eab55cd2035cc7f41b6329d5b2b063bd64..c7ab337f666d240c494b49108cc0675ee4d7bfb0 100644 (file)
 
 /*     x = SHA(<salt> | SHA(<username> | ":" | <raw password>)) */
 
-static const char magic[] = "$0$";
+static const char magic[] = "";
 
-char *
crypt_srpsha1(const char* username, const char *passwd, const char *salt)
+char *crypt_srpsha1(const char *username, const char *passwd,
                  const char *salt, MPI g, MPI n)
 {
-       unsigned char *sp, *tsp, *r1;
+       unsigned char *sp, *r1;
        int salt_size = strlen(salt);
        unsigned char *local_salt, *v;
        int passwd_len;
        GNUTLS_MAC_HANDLE h1;
        int vsize, hash_len = gnutls_hash_get_algo_len(GNUTLS_MAC_SHA);
-       opaque *tmp, *g, *n;
-       uint8 *rtext, * csalt;
-                       
+       opaque *tmp;
+       uint8 *rtext, *csalt;
+       int rsalt_size;
+
        passwd_len = strlen(passwd);    /* we do not want the null */
 
        h1 = gnutls_hash_init(GNUTLS_MAC_SHA);
-       gnutls_hash(h1, (char*)username, strlen(username));
+       gnutls_hash(h1, (char *) username, strlen(username));
        gnutls_hash(h1, ":", 1);
-       gnutls_hash(h1, (char*)passwd, passwd_len);
+       gnutls_hash(h1, (char *) passwd, passwd_len);
        r1 = gnutls_hash_deinit(h1);
 
+       
        local_salt = malloc(salt_size + 1);
        strcpy((char *) local_salt, salt);
-       sp = local_salt;
 
-       /* If it starts with the magic string, then skip that */
-       if (!strncmp((char *) sp, magic, strlen(magic)))
-               sp += strlen(magic);
+       sp = index( local_salt, ':'); /* move to salt - after verifier */
+       if (sp==NULL) {
+               gnutls_assert();
+               return NULL;
+       }
+       sp++;
 
-       tsp = sp;
-       while((*tsp)!='$') tsp++;
-       *tsp = '\0';            /* put a null after the end of salt */
+       rsalt_size = _gnutls_sbase64_decode(sp, strlen(sp), &csalt);
 
-       _gnutls_base64_decode( sp, strlen(sp), &csalt);
-       
        h1 = gnutls_hash_init(GNUTLS_MAC_SHA);
-       gnutls_hash(h1, csalt, 16);
+       gnutls_hash(h1, csalt, rsalt_size);
        gnutls_free(csalt);
-       
+
        gnutls_hash(h1, r1, hash_len);
-       
+
        gnutls_free(r1);
        r1 = gnutls_hash_deinit(h1);
-       
+
        /* v = g^x mod n */
-       vsize = _gnutls_srp_gx(r1, hash_len, &v, &g, &n);
+       vsize = _gnutls_srp_gx(r1, hash_len, &v, g, n);
        gnutls_free(r1);
-       if (vsize==-1 || v==NULL) {
+       if (vsize == -1 || v == NULL) {
                gnutls_assert();
                return NULL;
        }
 
-       _gnutls_base64_encode(v, vsize, &rtext);
+       _gnutls_sbase64_encode(v, vsize, &rtext);
        gnutls_free(v);
 
-       tmp = gnutls_malloc( strlen(sp)+strlen(rtext)+strlen(magic)+strlen(g)+2+strlen(n)+1+1 );
-       
-       sprintf( tmp, "%s%s$%s$%s$%s", magic, sp, rtext,g ,n);
-       gnutls_free(g);
-       gnutls_free(n);
+       tmp =
+           gnutls_malloc(strlen(sp) + strlen(rtext) + strlen(magic) + 1 +
+                         1);
+
+       sprintf(tmp, "%s%s:%s", magic, rtext, sp);
 
        gnutls_free(rtext);
        gnutls_free(local_salt);
 
        return tmp;
 }
+
 /* salt here is the salt size */
-char *crypt_srpsha1_wrapper(const char* username, const char *pass_new, int salt)
+char *crypt_srpsha1_wrapper(const char *username, const char *pass_new,
+                           int salt, MPI g, MPI n)
 {
-       unsigned char *result;
-       char *tcp;
-       unsigned char* rand;
-       char *e = NULL;
-          int result_size;
-          
-          if (salt > 50 || salt <= 0) return NULL; /* wow that's pretty long salt */
-          
-       rand = _gnutls_get_random( salt, GNUTLS_WEAK_RANDOM);
-
-       result_size = _gnutls_base64_encode( rand, salt, &result);
-          if (result_size < 0) {
-               gnutls_assert();
-               return NULL;
-          }
-          
-          tcp = gnutls_calloc( 1, result_size + strlen(magic)+1 +1 );
-          sprintf(tcp, "%s%s$", magic, result);
-
-          gnutls_free(result);
-          _gnutls_free_rand(rand);
-       /* no longer need cleartext */
-
-       e = crypt_srpsha1(username, pass_new, (const char *) tcp);
-          gnutls_free(tcp);
-          
-       return e;
+       unsigned char *result;
+       char *tcp;
+       unsigned char *rand;
+       char *e = NULL;
+       int result_size;
+
+       if (salt > 50 || salt <= 0)
+               return NULL;    /* wow that's pretty long salt */
+
+       rand = _gnutls_get_random(salt, GNUTLS_WEAK_RANDOM);
+
+       result_size = _gnutls_sbase64_encode(rand, salt, &result);
+       if (result_size < 0) {
+               gnutls_assert();
+               return NULL;
+       }
+
+       tcp = gnutls_calloc(1, 1+ result_size + 1);
+       sprintf(tcp, ":%s", result);
+
+       gnutls_free(result);
+       _gnutls_free_rand(rand);
+       /* no longer need cleartext */
+
+       e = crypt_srpsha1(username, pass_new, (const char *) tcp, g, n);
+       gnutls_free(tcp);
+
+       return e;
 }
index 36005ec3e05f3443cddc56e14c7663dc199f6188..bf0d55ebbe6dabaa2105a0add49396846b35eb77 100644 (file)
@@ -1,2 +1,2 @@
-char * crypt_srpsha1(const char* username, const char *passwd, const char *salt);
-char *crypt_srpsha1_wrapper(const char* username, const char *pass_new, int salt);
+char * crypt_srpsha1(const char* username, const char *passwd, const char *salt, MPI g, MPI n);
+char *crypt_srpsha1_wrapper(const char* username, const char *pass_new, int salt, MPI g, MPI n);
index b40301c0683e6deb712cef99c55bb89ea9409ece..73f330a2fa94696d4256a7c42ccd46789be395ff 100644 (file)
@@ -94,13 +94,6 @@ int gnutls_set_db_name( GNUTLS_STATE state, char* filename);
 int gnutls_clean_db( GNUTLS_STATE state);
 
 
-/* crypt functions */
-enum crypt_algo { SRPSHA1_CRYPT, BLOWFISH_CRYPT=2 };
-typedef enum crypt_algo crypt_algo;
-
-char * gnutls_crypt(const char* username, const char *passwd, crypt_algo algo, int salt);
-int gnutls_crypt_vrfy(const char* username, const char *passwd, char* salt);
-
 /* Functions for setting/clearing credentials */
 int gnutls_clear_creds( GNUTLS_STATE state);
 /* cred is a structure defined by the kx algorithm */
index c0a87b2aa143c1488c4f2b0cb5bcc7779443118d..70b9550384c3df72f54f1a2f70a05fc7280ce788 100644 (file)
@@ -53,11 +53,11 @@ const uint8 diffie_hellman_group1_prime[130] = { 0x04, 0x00,
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
 };
 
-int _gnutls_srp_gx(opaque *text, int textsize, opaque** result, opaque** ret_g, opaque** ret_n) {
+int _gnutls_srp_gn( opaque** ret_g, opaque** ret_n) {
 
-       MPI g, prime, x, e;
+       MPI g, prime;
        size_t n = sizeof diffie_hellman_group1_prime;
-       int result_size, siz;
+       int siz;
        char* tmp;
 
        if (gcry_mpi_scan(&prime, GCRYMPI_FMT_USG,
@@ -65,27 +65,9 @@ int _gnutls_srp_gx(opaque *text, int textsize, opaque** result, opaque** ret_g,
                gnutls_assert();
                return GNUTLS_E_MPI_SCAN_FAILED;
        }
-       if (gcry_mpi_scan(&x, GCRYMPI_FMT_USG,
-                         text, &textsize)) {
-               gnutls_assert();
-               gcry_mpi_release(prime);
-               return GNUTLS_E_MPI_SCAN_FAILED;
-       }
 
        g = gcry_mpi_set_ui(NULL, SRP_G);
 
-       e = gcry_mpi_alloc_like(prime);
-
-       /* e = g^x mod prime (n) */
-       gcry_mpi_powm(e, g, x, prime);
-       gcry_mpi_release(x);
-
-       
-       gcry_mpi_print(GCRYMPI_FMT_USG, NULL, &result_size, e);
-       if (result!=NULL) {
-               *result = gnutls_malloc(result_size);
-               gcry_mpi_print(GCRYMPI_FMT_USG, *result, &result_size, e);      
-       }
 
        siz = 0;
        gcry_mpi_print(GCRYMPI_FMT_USG, NULL, &siz, g);
@@ -93,7 +75,7 @@ int _gnutls_srp_gx(opaque *text, int textsize, opaque** result, opaque** ret_g,
                tmp = gnutls_malloc(siz);
                gcry_mpi_print(GCRYMPI_FMT_USG, tmp, &siz, g);
 
-               if (_gnutls_base64_encode( tmp, siz, ret_g) < 0)  {
+               if (_gnutls_sbase64_encode( tmp, siz, ret_g) < 0)  {
                        gnutls_free(tmp);
                        return GNUTLS_E_UNKNOWN_ERROR;
                }
@@ -105,7 +87,7 @@ int _gnutls_srp_gx(opaque *text, int textsize, opaque** result, opaque** ret_g,
        if (ret_n!=NULL) {
                tmp = gnutls_malloc(siz);
                gcry_mpi_print(GCRYMPI_FMT_USG, tmp, &siz, prime);
-               if (_gnutls_base64_encode( tmp, siz, ret_n) < 0) {
+               if (_gnutls_sbase64_encode( tmp, siz, ret_n) < 0) {
                        gnutls_free(tmp);
                        return GNUTLS_E_UNKNOWN_ERROR;
                }
@@ -113,10 +95,40 @@ int _gnutls_srp_gx(opaque *text, int textsize, opaque** result, opaque** ret_g,
                gnutls_free(tmp);
        }
        
-       gcry_mpi_release(e);
        gcry_mpi_release(g);
        gcry_mpi_release(prime);
 
+       return 0;
+
+}
+
+
+int _gnutls_srp_gx(opaque *text, int textsize, opaque** result, MPI g, MPI prime) {
+
+       MPI x, e;
+       int result_size;
+
+       if (gcry_mpi_scan(&x, GCRYMPI_FMT_USG,
+                         text, &textsize)) {
+               gnutls_assert();
+               return GNUTLS_E_MPI_SCAN_FAILED;
+       }
+
+       e = gcry_mpi_alloc_like(prime);
+
+       /* e = g^x mod prime (n) */
+       gcry_mpi_powm(e, g, x, prime);
+       gcry_mpi_release(x);
+
+       
+       gcry_mpi_print(GCRYMPI_FMT_USG, NULL, &result_size, e);
+       if (result!=NULL) {
+               *result = gnutls_malloc(result_size);
+               gcry_mpi_print(GCRYMPI_FMT_USG, *result, &result_size, e);      
+       }
+
+       gcry_mpi_release(e);
+
        return result_size;
 
 }
@@ -226,10 +238,12 @@ int bits;
 /* generate x = SHA(s | SHA(U | ":" | p))
  * The output is exactly 20 bytes
  */
-void* _gnutls_calc_srp_sha( char* username, char* password, opaque* salt, int salt_size) {
+void* _gnutls_calc_srp_sha( char* username, char* password, opaque* salt, int salt_size, int* size) {
 GNUTLS_MAC_HANDLE td;
 opaque* res;
 
+       *size = 20;
+       
        td = gnutls_hash_init(GNUTLS_MAC_SHA);
        gnutls_hash(td, username, strlen(username));
        gnutls_hash(td, ":", 1);
@@ -244,13 +258,13 @@ opaque* res;
        return gnutls_hash_deinit(td);
 }
 
-void* _gnutls_calc_srp_x( char* username, char* password, opaque* salt, int salt_size, uint8 crypt_algo) {
+void* _gnutls_calc_srp_x( char* username, char* password, opaque* salt, int salt_size, uint8 crypt_algo, int* size) {
        
        switch(crypt_algo) {
                case SRPSHA1_CRYPT:
-                       return _gnutls_calc_srp_sha( username, password, salt, salt_size);
+                       return _gnutls_calc_srp_sha( username, password, salt, salt_size, size);
                case BLOWFISH_CRYPT:
-                       return _gnutls_calc_srp_bcrypt( password, salt, salt_size);
+                       return _gnutls_calc_srp_bcrypt( password, salt, salt_size, size);
        }
        return NULL;    
 }
index 67fffba031d314627c199e9c0b7371067dc63bde..d7ed82d179664193a7cff210d07c8005923a5794 100644 (file)
@@ -1,10 +1,11 @@
-int _gnutls_srp_gx(opaque *text, int textsize, opaque** result, opaque** ret_g, opaque** ret_n);
+int _gnutls_srp_gx(opaque *text, int textsize, opaque** result, MPI g, MPI prime);
 MPI _gnutls_calc_srp_B(MPI * ret_b, MPI g, MPI n, MPI v);
 MPI _gnutls_calc_srp_u( MPI B);
 MPI _gnutls_calc_srp_S1(MPI A, MPI b, MPI u, MPI v, MPI n);
 MPI _gnutls_calc_srp_A(MPI *a, MPI g, MPI n);
 MPI _gnutls_calc_srp_S2(MPI B, MPI g, MPI x, MPI a, MPI u, MPI n);
-void* _gnutls_calc_srp_x( char* username, char* password, opaque* salt, int salt_size, uint8 crypt_algo);
+void* _gnutls_calc_srp_x( char* username, char* password, opaque* salt, int salt_size, uint8 crypt_algo, int* size);
+int _gnutls_srp_gn( opaque** ret_g, opaque** ret_n);
 
 /* our prime */
 extern const uint8 diffie_hellman_group1_prime[130];
index ef363b40608f0e74163ac172481ba421150b0b24..5b090ecbc684d7828f35a1bbb41d72366b2de4e4 100644 (file)
@@ -1,4 +1,5 @@
-EXTRA_DIST = port.h crypt.gaa gaa.h
+EXTRA_DIST = port.h crypt.gaa gaa.h README.crypt
+INCLUDES = -I../lib
 noinst_PROGRAMS = serv cli crypt
 serv_SOURCES = serv.c
 serv_LDADD = ../lib/libgnutls.la $(GCRYPT_LIBS)
diff --git a/src/README.crypt b/src/README.crypt
new file mode 100644 (file)
index 0000000..33ea36a
--- /dev/null
@@ -0,0 +1,28 @@
+crypt is a very simple program that emulates the programs in the libsrp 
+found in http://srp.stanford.edu.
+
+It is intended for use in places where you don't expect srp
+authentication to be the performed to system users. If this
+is the case use libsrp and the pam modules provided.
+
+
+Libsrp uses two files. One called 'tpasswd' which holds usernames and
+verifiers, and 'tpasswd.conf' which holds generators and primes.
+
+How to use crypt:
+
+Run: crypt --create_conf /etc/tpasswd.conf
+
+* This will create tpasswd.conf which holds the g and n values for
+SRP protocol (generator and a large prime).
+
+Run: crypt --passwd /etc/tpasswd --passwd_conf /etc/tpasswd.conf -u test
+
+* This will create /etc/tpasswd and will add user 'test' (you will also
+be prompted for a password).
+
+Run: crypt --passwd /etc/tpasswd --passwd_conf /etc/tpasswd.conf --verify -u test
+
+* You will be promted for a password, and if this password matches the one
+in /etc/tpasswd you will get an ok.
+
index 81e314c3e51df3d2d473d3050bb3131b02322706..c10b1b58e3e41609c22a91ceb3b81b60e489baab 100644 (file)
--- a/src/cli.c
+++ b/src/cli.c
@@ -60,8 +60,8 @@ int main()
        char *tmp;
        SRP_CLIENT_CREDENTIALS cred;
        
-       cred.username = "test";
-       cred.password = "test";
+       cred.username = "test2";
+       cred.password = "test2";
        
 //     signal(SIGPIPE, SIG_IGN);
 
index 7768f5229b4150059de006a32dc4b1cc563637f4..ec91803fb6780da6a18cb271b93af9153cdcc039 100644 (file)
 #include <string.h>
 #include <stdlib.h>
 #include <unistd.h>
-#include "../lib/gnutls.h"
+#include "../lib/defines.h"
+#include "../lib/gnutls_int.h"
+#include "../lib/gnutls_srp.h"
+#include "../lib/crypt.h"
+#include "../lib/cert_b64.h"
 #include "gaa.h"
+#include <pwd.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+int crypt_int(char *username, char *passwd, int crypt, int salt,
+             char *tpasswd_conf, char *tpasswd);
+static int read_conf_values(MPI * g, MPI * n, char *str, int str_size);
+
+int generate_create_conf(char *file)
+{
+       FILE *fd;
+       char line[5 * 1024];
+       int index = 1;
+       unsigned char *g, *n;
+
+       fd = fopen(file, "w");
+       if (fd == NULL) {
+               fprintf(stderr, "Cannot open file '%s'\n", file);
+               return -1;
+       }
 
-int verify_passwd(char *file, char* username, char* passwd) {
-       FILE* fd;
-       char line[513];
+       _gnutls_srp_gn(&g, &n);
+       sprintf(line, "%d:%s:%s\n", index, n, g);
+
+       fwrite(line, 1, strlen(line), fd);
+
+       fclose(fd);
+       return 0;
+
+}
+
+
+int verify_passwd(char *conffile, char *file, char *username, char *passwd)
+{
+       FILE *fd;
+       char line[5 * 1024];
        int i;
-       
-       fd = fopen( file, "r");
-       if (fd==NULL) {
+       MPI g, n;
+       int index;
+       char *p;
+
+       fd = fopen(conffile, "r");
+       if (fd == NULL) {
+               fprintf(stderr, "Cannot find %s\n", conffile);
+               return -1;
+       }
+
+       p = fgets(line, sizeof(line) - 1, fd);
+
+       if (p == NULL) {
+               fprintf(stderr, "Cannot find entry in %s\n", conffile);
+               return -1;
+       }
+       line[sizeof(line) - 1] = 0;
+
+       fclose(fd);
+       if ((index = read_conf_values(&g, &n, line, strlen(line))) < 0) {
+               fprintf(stderr, "Cannot parse conf file '%s'\n", conffile);
+               return -1;
+       }
+
+       fd = fopen(file, "r");
+       if (fd == NULL) {
                fprintf(stderr, "Cannot open file '%s'\n", file);
                return -1;
        }
 
-       while( fgets( line, sizeof(line), fd) != NULL) {
+       while (fgets(line, sizeof(line), fd) != NULL) {
                /* move to first ':' */
-               i=0;
-               while( (line[i]!=':') && (line[i]!='\0') && (i < sizeof(line)) ) {
+               i = 0;
+               while ((line[i] != ':') && (line[i] != '\0')
+                      && (i < sizeof(line))) {
                        i++;
                }
-               if (strncmp( username, line, i) == 0) {
-                               if (gnutls_crypt_vrfy( username, passwd, &line[++i]) == 0) {
-                                       fprintf(stderr, "Password verified\n");
-                               } else {
-                                       fprintf(stderr, "Password does NOT match\n");
-                               }
-                               return 0;
+               if (strncmp(username, line, strlen(username)) == 0) {
+                       if (gnutls_crypt_vrfy
+                           (username, passwd, &line[++i], g, n) == 0) {
+                               fprintf(stderr, "Password verified\n");
+                       } else {
+                               fprintf(stderr,
+                                       "Password does NOT match\n");
+                       }
+                       return 0;
                }
        }
 
        fclose(fd);
        return -1;
-       
+
 }
 
-int main(int argc, char** argv) {
-gaainfo info;
-char* passwd;
-char* cr=NULL;
-int crypt, salt;
-
-       if ( gaa(argc, argv, &info) != -1) {
-               fprintf(stderr, "Error in the arguments.\n");
-               return -1;
-    }
-    
-    salt = info.salt;
-    
-    if(info.crypt==NULL) {
-       crypt = SRPSHA1_CRYPT;
-       salt = 16;
-    } else {
-       if (strcasecmp( info.crypt, "bcrypt")==0) {
-               crypt = BLOWFISH_CRYPT;
-               if (salt==0) salt = 6; /* cost is 6 */
-       }
-       else if (strcasecmp( info.crypt, "srpsha")==0) {
-               crypt = SRPSHA1_CRYPT;
-               if (salt==0) salt = 16; /* 16 bytes salt */
-       }
-       else {
-               fprintf(stderr, "Unknown algorithm\n");
-               return -1;
-       }
-    }          
-
-    passwd = getpass("Enter password: ");
-        
-    if (info.passwd != NULL) {
-       verify_passwd( info.passwd, info.username, passwd);
-       return 0;
-    }
-
-
-    cr = gnutls_crypt( info.username, passwd, crypt, salt);
-    if (cr==NULL) {
-       fprintf(stderr, "Cannot gnutls_crypt()...\n");
-       return -1;
-    }
-    
-    printf("%s:%s\n", info.username, cr);
-    free(cr);
+#define KPASSWD "/etc/tpasswd"
+#define KPASSWD_CONF "/etc/tpasswd.conf"
+
+int main(int argc, char **argv)
+{
+       gaainfo info;
+       char *passwd;
+       int crypt, salt;
+       struct passwd *pwd;
+
+       if (gaa(argc, argv, &info) != -1) {
+               fprintf(stderr, "Error in the arguments.\n");
+               return -1;
+       }
+
+       salt = info.salt;
+
+       if (info.create_conf != NULL) {
+               return generate_create_conf(info.create_conf);
+       }
+
+       if (info.passwd == NULL)
+               info.passwd = KPASSWD;
+       if (info.passwd_conf == NULL)
+               info.passwd_conf = KPASSWD_CONF;
+
+       if (info.username == NULL) {
+               pwd = getpwuid(getuid());
+
+               if (pwd == NULL) {
+                       fprintf(stderr, "No such user\n");
+                       return -1;
+               }
+
+               info.username = pwd->pw_name;
+       }
+
+       if (info.crypt == NULL) {
+               crypt = SRPSHA1_CRYPT;
+               salt = 16;
+       } else {
+               if (strcasecmp(info.crypt, "bcrypt") == 0) {
+                       crypt = BLOWFISH_CRYPT;
+                       if (salt == 0)
+                               salt = 6;       /* cost is 6 */
+               } else if (strcasecmp(info.crypt, "srpsha") == 0) {
+                       crypt = SRPSHA1_CRYPT;
+                       if (salt == 0)
+                               salt = 10;      /* 10 bytes salt */
+               } else {
+                       fprintf(stderr, "Unknown algorithm\n");
+                       return -1;
+               }
+       }
+
+       passwd = getpass("Enter password: ");
+
+/* not ready yet */
+       if (info.verify != 0) {
+               return verify_passwd(info.passwd_conf, info.passwd,
+                                    info.username, passwd);
+       }
+
+
+       return crypt_int(info.username, passwd, crypt, salt,
+                        info.passwd_conf, info.passwd);
+
+}
+
+int crypt_int(char *username, char *passwd, int crypt, int salt,
+             char *tpasswd_conf, char *tpasswd)
+{
+       FILE *fd;
+       char *cr;
+       MPI g, n;
+       char line[5 * 1024];
+       char *p;
+       int index;
+
+       fd = fopen(tpasswd_conf, "r");
+       if (fd == NULL) {
+               fprintf(stderr, "Cannot find %s\n", tpasswd_conf);
+               return -1;
+       }
+
+       p = fgets(line, sizeof(line) - 1, fd);
+
+       if (p == NULL) {
+               fprintf(stderr, "Cannot find entry in %s\n", tpasswd_conf);
+               return -1;
+       }
+       line[sizeof(line) - 1] = 0;
+
+       fclose(fd);
+       if ((index = read_conf_values(&g, &n, line, strlen(line))) < 0) {
+               fprintf(stderr, "Cannot parse conf file '%s'\n",
+                       tpasswd_conf);
+               return -1;
+       }
+
+       cr = gnutls_crypt(username, passwd, crypt, salt, g, n);
+       if (cr == NULL) {
+               fprintf(stderr, "Cannot gnutls_crypt()...\n");
+               return -1;
+       } else {
+
+               fd = fopen(tpasswd, "a");
+               if (fd == NULL) {
+                       fprintf(stderr, "Cannot open '%s' for append\n",
+                               tpasswd);
+                       return -1;
+               }
+               fprintf(fd, "%s:%s:%u\n", username, cr, index);
+               fclose(fd);
+               free(cr);
+       }
+
+
        return 0;
+}
+
+
+
+/* this function parses tpasswd.conf file. Format is:
+ * int(index):base64(n):int(g)
+ */
+static int read_conf_values(MPI * g, MPI * n, char *str, int str_size)
+{
+       char *p;
+       int len;
+       opaque *tmp;
+       int tmp_size;
+       int index;
 
+       index = atoi(str);
 
-}
\ No newline at end of file
+       p = rindex(str, ':');   /* we have g */
+       if (p == NULL) {
+               return -1;
+       }
+
+       *p = '\0';
+       p++;
+
+       /* read the generator */
+       len = strlen(p);
+       tmp_size = _gnutls_sbase64_decode(p, len, &tmp);
+
+       if (tmp_size < 0) {
+               gnutls_free(tmp);
+               return -1;
+       }
+       if (gcry_mpi_scan(g, GCRYMPI_FMT_USG, tmp, &tmp_size)) {
+               gnutls_free(tmp);
+               return -1;
+       }
+
+       gnutls_free(tmp);
+
+
+       /* now go for n - modulo */
+       p = rindex(str, ':');   /* we have n */
+       if (p == NULL) {
+               return -1;
+       }
+
+       *p = '\0';
+       p++;
+
+       len = strlen(p);
+       tmp_size = _gnutls_sbase64_decode(p, len, &tmp);
+
+       if (tmp_size < 0) {
+               gnutls_free(tmp);
+               return -1;
+       }
+       if (gcry_mpi_scan(n, GCRYMPI_FMT_USG, tmp, &tmp_size)) {
+               gnutls_free(tmp);
+               return -1;
+       }
+
+       gnutls_free(tmp);
+
+       return index;
+}
index e37a1552bf1826270f2c1b4bcc4e38819964295f..3ab1ed5d77a986afc049eed5dc8889e3c584bdc5 100644 (file)
@@ -1,10 +1,11 @@
-helpnode "Crypt help\nUsage : crypt [-u user] [-p password file]"
+helpnode "Crypt help\nUsage : crypt [options]"
 
 #char *username;
 option (u,username) STR "username" { $username = $1 } "specify username."
 
 #char *passwd;
-option (p, passwd) STR "passwd" { $passwd = $1 } "specify a password file."
+option (p, passwd) STR "FILE" { $passwd = $1 } "specify a password file."
+
 
 #char *crypt;
 option (c, crypt) STR "crypt" { $crypt = $1 } "specify crypt algorithm (bcrypt/srpsha)."
@@ -12,8 +13,17 @@ option (c, crypt) STR "crypt" { $crypt = $1 } "specify crypt algorithm (bcrypt/s
 #int salt;
 option (s, salt) INT "salt" { $salt = $1 } "specify salt/cost size for crypt algorithm."
 
+#int verify;
+option (verify) { $verify = 1 } "just verify password."
+
+#char *passwd_conf;
+option ( passwd_conf) STR "FILE" { $passwd_conf = $1 } "specify a password conf file."
+
+#char *create_conf;
+option ( create_conf) STR "FILE" { $create_conf = $1 } "Generate a tpasswd.conf file."
+
 option (h, help) { gaa_help(); exit(0); } "shows this help text"
 
-init { $username=NULL; $passwd=NULL; $crypt=NULL; $salt=0; }
+init { $username=NULL; $passwd=NULL; $crypt=NULL; $salt=0;
+       $create_conf=NULL; $passwd_conf=NULL; $verify = 0; }
 
-OBLIGAT u
index bd74448d51c79b207512e579832aa840f0e01d02..4c4e87191964981995288066cf93379f8dd51c9a 100644 (file)
--- a/src/gaa.h
+++ b/src/gaa.h
@@ -8,9 +8,15 @@ typedef struct _gaainfo gaainfo;
 
 struct _gaainfo
 {
-#line 12 "crypt.gaa"
+#line 22 "crypt.gaa"
+       char *create_conf;
+#line 19 "crypt.gaa"
+       char *passwd_conf;
+#line 16 "crypt.gaa"
+       int verify;
+#line 13 "crypt.gaa"
        int salt;
-#line 9 "crypt.gaa"
+#line 10 "crypt.gaa"
        char *crypt;
 #line 6 "crypt.gaa"
        char *passwd;
index c6a764b7da1da5451d47815adafc3e0faf65b429..b4312b50bd3a0621a94ca79f23aba3af8ec5fb9f 100644 (file)
@@ -102,11 +102,14 @@ void __gaa_helpsingle(char short_name, char *name,
 
 void gaa_help()
 {
-       printf("Crypt help\nUsage : crypt [-u user] [-p password file]""\n");
+       printf("Crypt help\nUsage : crypt [options]""\n");
        __gaa_helpsingle('u', "username", """username"" ", "specify username.");
-       __gaa_helpsingle('p', "passwd", """passwd"" ", "specify a password file.");
+       __gaa_helpsingle('p', "passwd", """FILE"" ", "specify a password file.");
        __gaa_helpsingle('c', "crypt", """crypt"" ", "specify crypt algorithm (bcrypt/srpsha).");
        __gaa_helpsingle('s', "salt", """salt"" ", "specify salt/cost size for crypt algorithm.");
+       __gaa_helpsingle(0, "verify", "", "just verify password.");
+       __gaa_helpsingle(0, "passwd_conf", """FILE"" ", "specify a password conf file.");
+       __gaa_helpsingle(0, "create_conf", """FILE"" ", "Generate a tpasswd.conf file.");
        __gaa_helpsingle('h', "help", "", "shows this help text");
 
 #line 100 "gaa.skel"
@@ -122,9 +125,15 @@ typedef struct _gaainfo gaainfo;
 
 struct _gaainfo
 {
-#line 12 "crypt.gaa"
+#line 22 "crypt.gaa"
+       char *create_conf;
+#line 19 "crypt.gaa"
+       char *passwd_conf;
+#line 16 "crypt.gaa"
+       int verify;
+#line 13 "crypt.gaa"
        int salt;
-#line 9 "crypt.gaa"
+#line 10 "crypt.gaa"
        char *crypt;
 #line 6 "crypt.gaa"
        char *passwd;
@@ -184,12 +193,15 @@ int gaa_error = 0;
 #define GAA_MULTIPLE_OPTION     3
 
 #define GAA_REST                0
-#define GAA_NB_OPTION           5
+#define GAA_NB_OPTION           8
 #define GAAOPTID_help  1
-#define GAAOPTID_salt  2
-#define GAAOPTID_crypt 3
-#define GAAOPTID_passwd        4
-#define GAAOPTID_username      5
+#define GAAOPTID_create_conf   2
+#define GAAOPTID_passwd_conf   3
+#define GAAOPTID_verify        4
+#define GAAOPTID_salt  5
+#define GAAOPTID_crypt 6
+#define GAAOPTID_passwd        7
+#define GAAOPTID_username      8
 
 #line 168 "gaa.skel"
 
@@ -372,6 +384,18 @@ float gaa_getfloat(char *arg)
 }
 /* option structures */
 
+struct GAAOPTION_create_conf 
+{
+       char* arg1;
+       int size1;
+};
+
+struct GAAOPTION_passwd_conf 
+{
+       char* arg1;
+       int size1;
+};
+
 struct GAAOPTION_salt 
 {
        int arg1;
@@ -425,6 +449,8 @@ int gaa_get_option_num(char *str, int status)
     switch(status)
         {
         case GAA_LETTER_OPTION:
+                       GAA_CHECK1STR("", GAAOPTID_create_conf);
+                       GAA_CHECK1STR("", GAAOPTID_passwd_conf);
                        GAA_CHECK1STR("s", GAAOPTID_salt);
                        GAA_CHECK1STR("c", GAAOPTID_crypt);
                        GAA_CHECK1STR("p", GAAOPTID_passwd);
@@ -432,11 +458,15 @@ int gaa_get_option_num(char *str, int status)
         case GAA_MULTIPLE_OPTION:
 #line 375 "gaa.skel"
                        GAA_CHECK1STR("h", GAAOPTID_help);
+                       GAA_CHECK1STR("", GAAOPTID_verify);
 
 #line 277 "gaa.skel"
         break;
         case GAA_WORD_OPTION:
                        GAA_CHECKSTR("help", GAAOPTID_help);
+                       GAA_CHECKSTR("create_conf", GAAOPTID_create_conf);
+                       GAA_CHECKSTR("passwd_conf", GAAOPTID_passwd_conf);
+                       GAA_CHECKSTR("verify", GAAOPTID_verify);
                        GAA_CHECKSTR("salt", GAAOPTID_salt);
                        GAA_CHECKSTR("crypt", GAAOPTID_crypt);
                        GAA_CHECKSTR("passwd", GAAOPTID_passwd);
@@ -453,6 +483,8 @@ int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
 {
     int OK = 0;
     int gaa_last_non_option;
+       struct GAAOPTION_create_conf GAATMP_create_conf;
+       struct GAAOPTION_passwd_conf GAATMP_passwd_conf;
        struct GAAOPTION_salt GAATMP_salt;
        struct GAAOPTION_crypt GAATMP_crypt;
        struct GAAOPTION_passwd GAATMP_passwd;
@@ -479,9 +511,36 @@ int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
     {
        case GAAOPTID_help:
        OK = 0;
-#line 15 "crypt.gaa"
+#line 25 "crypt.gaa"
 { gaa_help(); exit(0); ;};
 
+               return GAA_OK;
+               break;
+       case GAAOPTID_create_conf:
+       OK = 0;
+               GAA_TESTMOREARGS;
+               GAA_FILL(GAATMP_create_conf.arg1, gaa_getstr, GAATMP_create_conf.size1);
+               gaa_index++;
+#line 23 "crypt.gaa"
+{ gaaval->create_conf = GAATMP_create_conf.arg1 ;};
+
+               return GAA_OK;
+               break;
+       case GAAOPTID_passwd_conf:
+       OK = 0;
+               GAA_TESTMOREARGS;
+               GAA_FILL(GAATMP_passwd_conf.arg1, gaa_getstr, GAATMP_passwd_conf.size1);
+               gaa_index++;
+#line 20 "crypt.gaa"
+{ gaaval->passwd_conf = GAATMP_passwd_conf.arg1 ;};
+
+               return GAA_OK;
+               break;
+       case GAAOPTID_verify:
+       OK = 0;
+#line 17 "crypt.gaa"
+{ gaaval->verify = 1 ;};
+
                return GAA_OK;
                break;
        case GAAOPTID_salt:
@@ -489,7 +548,7 @@ int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
                GAA_TESTMOREARGS;
                GAA_FILL(GAATMP_salt.arg1, gaa_getint, GAATMP_salt.size1);
                gaa_index++;
-#line 13 "crypt.gaa"
+#line 14 "crypt.gaa"
 { gaaval->salt = GAATMP_salt.arg1 ;};
 
                return GAA_OK;
@@ -499,7 +558,7 @@ int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
                GAA_TESTMOREARGS;
                GAA_FILL(GAATMP_crypt.arg1, gaa_getstr, GAATMP_crypt.size1);
                gaa_index++;
-#line 10 "crypt.gaa"
+#line 11 "crypt.gaa"
 { gaaval->crypt = GAATMP_crypt.arg1 ;};
 
                return GAA_OK;
@@ -534,7 +593,7 @@ int gaa_try(int gaa_num, int gaa_index, gaainfo *gaaval, char *opt_list)
 int gaa(int argc, char **argv, gaainfo *gaaval)
 {
     int tmp1, tmp2;
-    int i, j, k;
+    int i, j;
     char *opt_list;
 
     GAAargv = argv;
@@ -547,8 +606,9 @@ int gaa(int argc, char **argv, gaainfo *gaaval)
     if(inited == 0)
     {
 
-#line 17 "crypt.gaa"
-{ gaaval->username=NULL; gaaval->passwd=NULL; gaaval->crypt=NULL; gaaval->salt=0; ;};
+#line 27 "crypt.gaa"
+{ gaaval->username=NULL; gaaval->passwd=NULL; gaaval->crypt=NULL; gaaval->salt=0;
+       gaaval->create_conf=NULL; gaaval->passwd_conf=NULL; gaaval->verify = 0; ;};
 
     }
     inited = 1;
@@ -620,7 +680,6 @@ int gaa(int argc, char **argv, gaainfo *gaaval)
     }
 if(gaa_processing_file == 0)
 {
-       GAA_OBLIGAT("u");
 
 #line 507 "gaa.skel"
 #ifdef GAA_REST_EXISTS
index 0d4bef9285a7b1bf9a26198228eb47b987f8a3d7..4acef2a784068591fb55d9c14490cfd63c649797 100644 (file)
@@ -48,8 +48,8 @@ int main()
     
     /* this is a password file (created with the included crypt utility) 
      */
-    cred.password_file="/etc/tpasswd";
-    cred.password_conf_file="/etc/tpasswd.conf";
+    cred.password_file="tpasswd";
+    cred.password_conf_file="tpasswd.conf";
     
     listen_sd = socket(AF_INET, SOCK_STREAM, 0);
     ERR(listen_sd, "socket");