unixcrypt.pas 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. unit unixcrypt;
  2. {$mode objfpc}
  3. {$linklib crypt}
  4. {$H+}
  5. interface
  6. uses
  7. ctypes;
  8. function crypt(const key: pchar; const salt: pchar): pchar; cdecl; external;
  9. // salt helper functions
  10. function gen_des_salt: string;
  11. function gen_md5_salt: string;
  12. // crypt helper functions
  13. function crypt_password(const key: string; const UseMD5: boolean): string;
  14. function validate_password(const key: string; const hash: string): boolean;
  15. implementation
  16. const
  17. salt_chars: array[0..63] of char = (
  18. 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
  19. 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
  20. '0','1','2','3','4','5','6','7','8','9','.','/');
  21. function gen_des_salt: string;
  22. begin
  23. Result := salt_chars[Random(64)] + salt_chars[Random(64)];
  24. end;
  25. function gen_md5_salt: string;
  26. var
  27. i: integer;
  28. begin
  29. Result := '$1$';
  30. for i := 0 to 7 do
  31. Result := Result + salt_chars[Random(64)];
  32. end;
  33. function crypt_password(const key: string; const UseMD5: boolean): string;
  34. begin
  35. if UseMD5 then
  36. Result := crypt(pchar(key), pchar(gen_md5_salt)) else
  37. Result := crypt(pchar(key), pchar(gen_des_salt));
  38. end;
  39. function validate_password(const key: string; const hash: string): boolean;
  40. begin
  41. Result :=
  42. // MD5 compare
  43. ((Length(hash) = 34) and (hash[1] = '$') and (hash[2] = '1') and (hash[3] = '$') and (hash[12] = '$') and (crypt(pchar(key), pchar(copy(hash, 1, 11))) = hash)) or
  44. // DES compare
  45. ((Length(hash) = 13) and (crypt(pchar(key), pchar(copy(hash, 1, 2))) = hash));
  46. end;
  47. end.