Subversion Repositories MLServ

Rev

Rev 6 | Rev 8 | 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 7 2024-09-25 00:56:55Z 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
 
7 nishi 14
const char* cm_crypt_methods[] = {"DES",    "MD5", "Blowfish", "", "", "SHA-256", "SHA-512",
15
#ifdef __NetBSD__
16
				  "Argon2",
17
#endif
18
				  NULL};
5 nishi 19
 
20
char* cm_crypt_spec(int num, const char* string, const char* salt) {
21
	char* r = NULL;
22
	if(num == C_DES) {
23
		r = crypt(string, salt);
24
	} else if(num == C_MD5 || num == C_SHA256 || num == C_SHA512) {
7 nishi 25
		char* buffer = malloc(3 + strlen(salt) + 1 + 1);
26
		buffer[3 + strlen(salt) + 1] = 0;
27
		sprintf(buffer, "$%d$%s$", num, salt);
5 nishi 28
 
29
		r = crypt(string, buffer);
30
 
31
		free(buffer);
32
	} else if(num == C_BLOWFISH) {
7 nishi 33
		char* buffer = malloc(4 + 3 + strlen(salt) + 1 + 1);
34
		buffer[4 + 3 + strlen(salt) + 1] = 0;
35
		sprintf(buffer, "$%da$08$%s$", num, salt);
5 nishi 36
 
37
		r = crypt(string, buffer);
38
 
39
		free(buffer);
7 nishi 40
	} else if(num == C_ARGON2) {
41
		if(strlen(salt) != 16) return NULL;
42
		char* buffer = malloc(1 + 8 + 1 + 4 + 1 + 16 + 1 + 1 + 7);
43
		buffer[1 + 8 + 1 + 4 + 1 + 16 + 1 + 7] = 0;
44
		sprintf(buffer, "$argon2id$v=19$m=4096$%s$", salt);
45
 
46
		r = crypt(string, buffer);
47
 
48
		free(buffer);
5 nishi 49
	}
50
	if(r == NULL || strcmp(r, "*0") == 0 || strcmp(r, ":") == 0) r = NULL;
51
	return r;
52
}
53
 
54
int cm_crypt_try(int num) {
55
	printf("Trying %s... ", cm_crypt_methods[num]);
56
	fflush(stdout);
57
 
58
	if(cm_crypt_spec(num, "random", "randomrandomrandomrandom") != NULL) {
59
		printf("works\n");
60
		return 1;
61
	}
7 nishi 62
 
63
#ifdef __NetBSD__
64
	if(cm_crypt_spec(num, "random", "abcdabcdabcdabcd") != NULL) {
65
		printf("works\n");
66
		return 1;
67
	}
68
#endif
69
 
70
	printf("does not work\n");
71
 
72
	return 0;
5 nishi 73
}
74
 
75
int cm_chosen_crypt;
76
 
77
int cm_crypt_init(void) {
78
	int i;
79
	int last = -1;
80
	for(i = C_START + 1; i < C_END; i++) {
81
		if(strlen(cm_crypt_methods[i]) != 0) {
82
			if(cm_crypt_try(i)) {
83
				last = i;
84
			}
85
		}
86
	}
87
	cm_chosen_crypt = last;
88
	return last;
89
}
90
 
91
char* cm_crypt(const char* string) {
92
	char salt[65];
93
	salt[64] = 0;
94
	int i;
95
	FILE* f = fopen("/dev/urandom", "rb");
96
	unsigned char c;
97
	const char usable[] = "0123456789abcdefghijklmnopqrstuvwxyz";
98
	for(i = 0; i < 64; i++) {
99
		fread(&c, 1, 1, f);
100
		salt[i] = c % strlen(usable);
101
	}
102
	fclose(f);
103
	return cm_crypt_spec(cm_chosen_crypt, string, salt);
104
}