summaryrefslogtreecommitdiffstats
path: root/src/gss_auth.c
diff options
context:
space:
mode:
authorSimo Sorce <simo@redhat.com>2014-05-15 13:59:09 +0200
committerSimo Sorce <simo@redhat.com>2014-08-07 12:44:46 -0400
commit606a92c567e11565215d80e7e1424092c8eb0bde (patch)
treea3dcbe7e904ddef0fff745f576071f061d7b8f51 /src/gss_auth.c
parent9900ca295bb598eede3222a60ce5b9b1cf68166e (diff)
downloadgss-ntlmssp-606a92c567e11565215d80e7e1424092c8eb0bde.tar.gz
gss-ntlmssp-606a92c567e11565215d80e7e1424092c8eb0bde.tar.xz
gss-ntlmssp-606a92c567e11565215d80e7e1424092c8eb0bde.zip
Add support to perform external operations
This allows the code to know it has to use an external mechanism, such as winbind, to handle authentication. Based on work from David Woodhouse <David.Woodhouse@intel.com>
Diffstat (limited to 'src/gss_auth.c')
-rw-r--r--src/gss_auth.c104
1 files changed, 104 insertions, 0 deletions
diff --git a/src/gss_auth.c b/src/gss_auth.c
new file mode 100644
index 0000000..710099f
--- /dev/null
+++ b/src/gss_auth.c
@@ -0,0 +1,104 @@
+/* Copyright (C) 2014 GSS-NTLMSSP contributors, see COPYING for License */
+
+#include <errno.h>
+#include "gss_ntlmssp.h"
+
+uint32_t gssntlm_srv_auth(uint32_t *minor,
+ struct gssntlm_ctx *ctx,
+ struct gssntlm_cred *cred,
+ struct ntlm_buffer *nt_chal_resp,
+ struct ntlm_buffer *lm_chal_resp,
+ struct ntlm_key *key_exchange_key)
+{
+ struct ntlm_key ntlmv2_key = { .length = 16 };
+ struct ntlm_buffer nt_proof = { 0 };
+ uint32_t retmaj, retmin;
+ const char *domstr;
+ int retries;
+
+ if (key_exchange_key->length != 16) {
+ *minor = EINVAL;
+ return GSS_S_FAILURE;
+ }
+
+ switch (cred->type) {
+
+ case GSSNTLM_CRED_USER:
+ for (retries = 2; retries > 0; retries--) {
+
+ if (retries == 2) {
+ domstr = cred->cred.user.user.data.user.domain;
+ } else {
+ domstr = NULL;
+ }
+
+ /* NTLMv2 Key */
+ retmin = NTOWFv2(ctx->ntlm, &cred->cred.user.nt_hash,
+ cred->cred.user.user.data.user.name,
+ domstr, &ntlmv2_key);
+ if (retmin) {
+ retmaj = GSS_S_FAILURE;
+ goto done;
+ }
+
+ /* NTLMv2 Response */
+ retmin = ntlmv2_verify_nt_response(nt_chal_resp,
+ &ntlmv2_key,
+ ctx->server_chal);
+ if (retmin == 0) {
+ break;
+ } else {
+ if (ctx->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) {
+ /* LMv2 Response */
+ retmin = ntlmv2_verify_lm_response(lm_chal_resp,
+ &ntlmv2_key,
+ ctx->server_chal);
+ if (retmin == 0) {
+ break;
+ }
+ }
+ }
+ if (retmin && retries < 2) {
+ retmaj = GSS_S_FAILURE;
+ goto done;
+ }
+ }
+ /* The NT proof is the first 16 bytes */
+ nt_proof.data = nt_chal_resp->data;
+ nt_proof.length = 16;
+
+ /* The Session Base Key */
+ /* In NTLMv2 the Key Exchange Key is the Session Base Key */
+ retmin = ntlmv2_session_base_key(&ntlmv2_key, &nt_proof,
+ key_exchange_key);
+ if (retmin) {
+ retmaj = GSS_S_FAILURE;
+ goto done;
+ }
+ break;
+
+ case GSSNTLM_CRED_EXTERNAL:
+ retmin = external_srv_auth(cred->cred.external.user.data.user.name,
+ cred->cred.external.user.data.user.domain,
+ ctx->workstation, ctx->server_chal,
+ nt_chal_resp, lm_chal_resp,
+ key_exchange_key);
+ if (retmin) {
+ retmaj = GSS_S_FAILURE;
+ goto done;
+ }
+ break;
+
+ default:
+ retmin = EINVAL;
+ retmaj = GSS_S_FAILURE;
+ goto done;
+ }
+
+ retmaj = GSS_S_COMPLETE;
+ retmin = 0;
+
+done:
+ *minor = retmin;
+ return retmaj;
+}