Skip to content

Commit

Permalink
CP-50518: Add stub for crypt_r to ocaml/auth
Browse files Browse the repository at this point in the history
This change adds a binding stub for the crypt_r ("re-entrant crypt") function.

The introduced external function is of type:

  crypt_r : key:string -> salt:string -> string option

The arguments are labelled to avoid mixup.

In the case of failure, None is returned (no explicit error). Otherwise, the
result is Some h, where h is the string containing the computed hash.

The usage pattern that most are familiar with is:

  h  = crypt_r(k, s)
  h' = crypt_r(k', s)
  equal = h == h'

However, the following is also a valid way of expressing the same, and doesn't
require extracting the salt (which is embedded in the resultant hash string):

  h  = crypt_r(k, s)
  h' = crypt_r(k', h)
  equal = h == h'

There is potential for more error handling, but the largest potential for error
is in supplying well formed inputs. Different implementations support different
errnos, which complicates how accurate any attempt at error reporting would be.

The difficulty with over-specifying the requirements of this function at the
API level is that different implementations may have different behaviour. To
this end, any unit testis exercising this binding will need to explicitly test
invariants we expect our specific implementation to have. The precise
implementation of the function installed on the host is up to the shared
library we link against (which, in practice, I've found to differ in behaviour
from what is installed on my host Linux machine).

Signed-off-by: Colin James <[email protected]>
  • Loading branch information
contificate committed Aug 6, 2024
1 parent 2097a16 commit 64a15de
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 0 deletions.
3 changes: 3 additions & 0 deletions ocaml/auth/pam.ml
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,6 @@
external authenticate : string -> string -> unit = "stub_XA_mh_authorize"

external change_password : string -> string -> unit = "stub_XA_mh_chpasswd"

external crypt_r : key:string -> salt:string -> string option
= "stub_XA_crypt_r"
19 changes: 19 additions & 0 deletions ocaml/auth/xa_auth_stubs.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,25 @@ void __attribute__((constructor)) stub_XA_workaround(void)
crypt_r("", "$6$", &data);
}

/* key:string -> salt:string -> string option */
CAMLprim value stub_XA_crypt_r(value key, value salt) {
CAMLparam2(key, salt);
CAMLlocal1(result);

struct crypt_data cd = {0};

caml_enter_blocking_section();
const char* const hashed =
crypt_r(String_val(key), String_val(salt), &cd);
caml_leave_blocking_section();

if (!hashed || *hashed == '*')
CAMLreturn(Val_none);

result = caml_copy_string(hashed);
CAMLreturn(caml_alloc_some(result));
}

/*
* Local variables:
* mode: C
Expand Down

0 comments on commit 64a15de

Please sign in to comment.