Subversion Repositories MLServ

Rev

Rev 5 | Rev 7 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
5 nishi 1
/* $Id: crypt.c 6 2024-09-25 00:20:21Z nishi $ */
2
 
3
#include "cm_crypt.h"
4
 
5
#include <unistd.h>
6
#include <stdio.h>
7
#include <stdlib.h>
8
#include <string.h>
9
 
6 nishi 10
#ifdef __linux__
11
#include <crypt.h>
12
#endif
13
 
5 nishi 14
const char* cm_crypt_methods[] = {"DES", "MD5", "Blowfish", "", "", "SHA-256", "SHA-512"};
15
 
16
char* cm_crypt_spec(int num, const char* string, const char* salt) {
17
	char* r = NULL;
18
	if(num == C_DES) {
19
		r = crypt(string, salt);
20
	} else if(num == C_MD5 || num == C_SHA256 || num == C_SHA512) {
21
		char* buffer = malloc(3 + strlen(salt) + 1);
22
		buffer[3 + strlen(salt)] = 0;
23
		sprintf(buffer, "$%d$%s", num, salt);
24
 
25
		r = crypt(string, buffer);
26
 
27
		free(buffer);
28
	} else if(num == C_BLOWFISH) {
29
		char* buffer = malloc(4 + 3 + strlen(salt) + 1);
30
		buffer[4 + 3 + strlen(salt)] = 0;
31
		sprintf(buffer, "$%da$08$%s", num, salt);
32
 
33
		r = crypt(string, buffer);
34
 
35
		free(buffer);
36
	}
37
	if(r == NULL || strcmp(r, "*0") == 0 || strcmp(r, ":") == 0) r = NULL;
38
	return r;
39
}
40
 
41
int cm_crypt_try(int num) {
42
	printf("Trying %s... ", cm_crypt_methods[num]);
43
	fflush(stdout);
44
 
45
	if(cm_crypt_spec(num, "random", "randomrandomrandomrandom") != NULL) {
46
		printf("works\n");
47
		return 1;
48
	} else {
49
		printf("does not work\n");
50
		return 0;
51
	}
52
}
53
 
54
int cm_chosen_crypt;
55
 
56
int cm_crypt_init(void) {
57
	int i;
58
	int last = -1;
59
	for(i = C_START + 1; i < C_END; i++) {
60
		if(strlen(cm_crypt_methods[i]) != 0) {
61
			if(cm_crypt_try(i)) {
62
				last = i;
63
			}
64
		}
65
	}
66
	cm_chosen_crypt = last;
67
	return last;
68
}
69
 
70
char* cm_crypt(const char* string) {
71
	char salt[65];
72
	salt[64] = 0;
73
	int i;
74
	FILE* f = fopen("/dev/urandom", "rb");
75
	unsigned char c;
76
	const char usable[] = "0123456789abcdefghijklmnopqrstuvwxyz";
77
	for(i = 0; i < 64; i++) {
78
		fread(&c, 1, 1, f);
79
		salt[i] = c % strlen(usable);
80
	}
81
	fclose(f);
82
	return cm_crypt_spec(cm_chosen_crypt, string, salt);
83
}