unixcrypt.pas 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. {$IFNDEF FPC_DOTTEDUNITS}
  2. unit unixcrypt;
  3. {$ENDIF FPC_DOTTEDUNITS}
  4. {$mode objfpc}
  5. {$linklib crypt}
  6. {$H+}
  7. interface
  8. {$IFDEF FPC_DOTTEDUNITS}
  9. uses
  10. System.CTypes;
  11. {$ELSE FPC_DOTTEDUNITS}
  12. uses
  13. ctypes;
  14. {$ENDIF FPC_DOTTEDUNITS}
  15. function crypt(const key: PAnsiChar; const salt: PAnsiChar): PAnsiChar; cdecl; external;
  16. // salt helper functions
  17. function gen_des_salt: RawByteString;
  18. function gen_md5_salt: RawByteString;
  19. // crypt helper functions
  20. function crypt_password(const key: RawByteString; const UseMD5: boolean): RawByteString;
  21. function validate_password(const key: RawByteString; const hash: RawByteString): boolean;
  22. implementation
  23. const
  24. salt_chars: array[0..63] of AnsiChar = (
  25. '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',
  26. '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',
  27. '0','1','2','3','4','5','6','7','8','9','.','/');
  28. function gen_des_salt: RawByteString;
  29. begin
  30. Result := salt_chars[Random(64)] + salt_chars[Random(64)];
  31. end;
  32. function gen_md5_salt: RawByteString;
  33. var
  34. i: integer;
  35. begin
  36. Result := '$1$';
  37. for i := 0 to 7 do
  38. Result := Result + salt_chars[Random(64)];
  39. end;
  40. function crypt_password(const key: RawByteString; const UseMD5: boolean): RawByteString;
  41. begin
  42. if UseMD5 then
  43. Result := crypt(PAnsiChar(key), PAnsiChar(gen_md5_salt)) else
  44. Result := crypt(PAnsiChar(key), PAnsiChar(gen_des_salt));
  45. end;
  46. function validate_password(const key: RawByteString; const hash: RawByteString): boolean;
  47. begin
  48. Result :=
  49. // MD5 compare
  50. ((Length(hash) = 34) and (hash[1] = '$') and (hash[2] = '1') and (hash[3] = '$') and (hash[12] = '$') and (crypt(PAnsiChar(key), PAnsiChar(copy(hash, 1, 11))) = hash)) or
  51. // DES compare
  52. ((Length(hash) = 13) and (crypt(PAnsiChar(key), PAnsiChar(copy(hash, 1, 2))) = hash));
  53. end;
  54. end.