+++ /dev/null
-#include <openssl/sha.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#define SALT_LENGTH 20
-
-int ReadBytes(char *str, unsigned char *buffer, size_t buffer_length) {
- unsigned i, val;
- if (strlen(str) != buffer_length * 2)
- return 0;
- for (i = 0; i < buffer_length; i++) {
- sscanf(str + i*2, "%2x", &val);
- buffer[i] = (unsigned char) val;
- }
- return 1;
-}
-
-unsigned char *HashPass(const char *pass, unsigned char salt[SALT_LENGTH]) {
- unsigned char *buffer, *result;
- size_t pass_length = strlen(pass);
- size_t buffer_length = pass_length + SALT_LENGTH;
- buffer = malloc(buffer_length * sizeof(unsigned char));
- if (!buffer)
- return NULL;
-
- memcpy(buffer, pass, pass_length);
- memcpy(buffer + pass_length, salt, SALT_LENGTH);
- result = SHA1(buffer, buffer_length, NULL);
- free(buffer);
-
- return result;
-}
-
-int WriteUserPass(FILE *fp, const char *user, const char *pass) {
- unsigned char salt[SALT_LENGTH], *sha1;
- size_t i;
-
- FILE *fpr = fopen("/dev/urandom", "r");
- if (!fpr)
- return 0;
- fread(salt, sizeof(unsigned char), SALT_LENGTH, fpr);
- fclose(fpr);
-
- if (!fp)
- return 0;
-
- sha1 = HashPass(pass, salt);
- if (!sha1)
- return 0;
-
- fprintf(fp, "%s:", user);
- for (i = 0; i < SALT_LENGTH; i++) {
- fprintf(fp, "%02x", salt[i]);
- }
- fprintf(fp, "$");
- for (i = 0; i < 20; i++) {
- fprintf(fp, "%02x", sha1[i]);
- }
- fprintf(fp, "\n");
-
- return 1;
-}
-
-int CheckUserPass(const char *passfile, const char *cuser, const char *cpass) {
- FILE *fp = fopen(passfile, "r");
- char buffer[BUFSIZ];
- int ret = 0;
- if (!fp)
- return 0;
-
- while (fgets(buffer, BUFSIZ, fp)) {
- char *user, *salt, *hash, *ptr;
-
- user = buffer;
- ptr = strchr(buffer, ':');
- if (ptr) {
- *ptr++ = 0;
- salt = ptr;
- ptr = strchr(ptr, '$');
- if (ptr) {
- *ptr++ = 0;
- hash = ptr;
- ptr = strchr(ptr, '\n');
- if (ptr)
- *ptr = 0;
-
- if (strlen(hash) != 20 * 2) {
- printf("Invalid SHA-1 hash: %s\n", hash);
- continue;
- } else if (strlen(salt) != SALT_LENGTH * 2) {
- printf("Invalid salt length: %s\n", salt);
- continue;
- } else if (strcmp(user, cuser)) {
- continue;
- }
-
- unsigned char saltbytes[SALT_LENGTH], hashbytes[20];
- ReadBytes(salt, saltbytes, SALT_LENGTH);
- ReadBytes(hash, hashbytes, 20);
- if (!memcmp(HashPass(cpass, saltbytes), hashbytes, 20)) {
- printf("Matched with user: %s\n", cuser);
- ret = 1;
- break;
- }
-
- }
- }
- }
-
- fclose(fp);
- return ret;
-}
-
-int main(int argc, char *argv[]) {
- if (argc != 4) {
- printf("Usage: %s user pass fname\n", argv[0]);
- return 1;
- }
-
- FILE *fp = fopen(argv[3], "w");
-
- if (!WriteUserPass(fp, argv[1], argv[2])) {
- fprintf(stderr, "Failed to hash: %s:%s\n", argv[1], argv[2]);
- return 1;
- }
- fclose(fp);
-
- CheckUserPass(argv[3], argv[1], argv[2]);
- return 0;
-}