Rev 5 | Rev 7 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed
/* $Id: crypt.c 6 2024-09-25 00:20:21Z nishi $ */
#include "cm_crypt.h"
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef __linux__
#include <crypt.h>
#endif
const char* cm_crypt_methods[] = {"DES", "MD5", "Blowfish", "", "", "SHA-256", "SHA-512"};
char* cm_crypt_spec(int num, const char* string, const char* salt) {
char* r = NULL;
if(num == C_DES) {
r = crypt(string, salt);
} else if(num == C_MD5 || num == C_SHA256 || num == C_SHA512) {
char* buffer = malloc(3 + strlen(salt) + 1);
buffer[3 + strlen(salt)] = 0;
sprintf(buffer, "$%d$%s", num, salt);
r = crypt(string, buffer);
free(buffer);
} else if(num == C_BLOWFISH) {
char* buffer = malloc(4 + 3 + strlen(salt) + 1);
buffer[4 + 3 + strlen(salt)] = 0;
sprintf(buffer, "$%da$08$%s", num, salt);
r = crypt(string, buffer);
free(buffer);
}
if(r == NULL || strcmp(r, "*0") == 0 || strcmp(r, ":") == 0) r = NULL;
return r;
}
int cm_crypt_try(int num) {
printf("Trying %s... ", cm_crypt_methods[num]);
fflush(stdout);
if(cm_crypt_spec(num, "random", "randomrandomrandomrandom") != NULL) {
printf("works\n");
return 1;
} else {
printf("does not work\n");
return 0;
}
}
int cm_chosen_crypt;
int cm_crypt_init(void) {
int i;
int last = -1;
for(i = C_START + 1; i < C_END; i++) {
if(strlen(cm_crypt_methods[i]) != 0) {
if(cm_crypt_try(i)) {
last = i;
}
}
}
cm_chosen_crypt = last;
return last;
}
char* cm_crypt(const char* string) {
char salt[65];
salt[64] = 0;
int i;
FILE* f = fopen("/dev/urandom", "rb");
unsigned char c;
const char usable[] = "0123456789abcdefghijklmnopqrstuvwxyz";
for(i = 0; i < 64; i++) {
fread(&c, 1, 1, f);
salt[i] = c % strlen(usable);
}
fclose(f);
return cm_crypt_spec(cm_chosen_crypt, string, salt);
}