1 #include <openssl/sha.h>
7 int ReadBytes(char *str, unsigned char *buffer, size_t buffer_length) {
9 if (strlen(str) != buffer_length * 2)
11 for (i = 0; i < buffer_length; i++) {
12 sscanf(str + i*2, "%2x", &val);
13 buffer[i] = (unsigned char) val;
18 unsigned char *HashPass(const char *pass, unsigned char salt[SALT_LENGTH]) {
19 unsigned char *buffer, *result;
20 size_t pass_length = strlen(pass);
21 size_t buffer_length = pass_length + SALT_LENGTH;
22 buffer = malloc(buffer_length * sizeof(unsigned char));
26 memcpy(buffer, pass, pass_length);
27 memcpy(buffer + pass_length, salt, SALT_LENGTH);
28 result = SHA1(buffer, buffer_length, NULL);
34 int WriteUserPass(FILE *fp, const char *user, const char *pass) {
35 unsigned char salt[SALT_LENGTH], *sha1;
38 FILE *fpr = fopen("/dev/urandom", "r");
41 fread(salt, sizeof(unsigned char), SALT_LENGTH, fpr);
47 sha1 = HashPass(pass, salt);
51 fprintf(fp, "%s:", user);
52 for (i = 0; i < SALT_LENGTH; i++) {
53 fprintf(fp, "%02x", salt[i]);
56 for (i = 0; i < 20; i++) {
57 fprintf(fp, "%02x", sha1[i]);
64 int CheckUserPass(const char *passfile, const char *cuser, const char *cpass) {
65 FILE *fp = fopen(passfile, "r");
71 while (fgets(buffer, BUFSIZ, fp)) {
72 char *user, *salt, *hash, *ptr;
75 ptr = strchr(buffer, ':');
79 ptr = strchr(ptr, '$');
83 ptr = strchr(ptr, '\n');
87 if (strlen(hash) != 20 * 2) {
88 printf("Invalid SHA-1 hash: %s\n", hash);
90 } else if (strlen(salt) != SALT_LENGTH * 2) {
91 printf("Invalid salt length: %s\n", salt);
93 } else if (strcmp(user, cuser)) {
97 unsigned char saltbytes[SALT_LENGTH], hashbytes[20];
98 ReadBytes(salt, saltbytes, SALT_LENGTH);
99 ReadBytes(hash, hashbytes, 20);
100 if (!memcmp(HashPass(cpass, saltbytes), hashbytes, 20)) {
101 printf("Matched with user: %s\n", cuser);
114 int main(int argc, char *argv[]) {
116 printf("Usage: %s user pass fname\n", argv[0]);
120 FILE *fp = fopen(argv[3], "w");
122 if (!WriteUserPass(fp, argv[1], argv[2])) {
123 fprintf(stderr, "Failed to hash: %s:%s\n", argv[1], argv[2]);
128 CheckUserPass(argv[3], argv[1], argv[2]);