s3-librpc Supply target service and server to spnego_generic_init_client()
[metze/samba/wip.git] / source3 / librpc / crypto / cli_spnego.c
index 3e40d15569f90f710597d89a76883a0a065c9ae3..98251c776ecfa6af2b43c4e124d8bb3c94e0faea 100644 (file)
@@ -2,6 +2,7 @@
  *  SPNEGO Encapsulation
  *  Client functions
  *  Copyright (C) Simo Sorce 2010.
+ *  Copyright (C) Andrew Bartlett 2011.
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
 
 #include "includes.h"
 #include "../libcli/auth/spnego.h"
-#include "include/ntlmssp_wrap.h"
+#include "include/auth_generic.h"
 #include "librpc/gen_ndr/ntlmssp.h"
+#include "auth/ntlmssp/ntlmssp.h"
 #include "librpc/crypto/gse.h"
 #include "librpc/crypto/spnego.h"
+#include "auth/gensec/gensec.h"
 
 static NTSTATUS spnego_context_init(TALLOC_CTX *mem_ctx,
                                    bool do_sign, bool do_seal,
@@ -81,70 +84,92 @@ NTSTATUS spnego_gssapi_init_client(TALLOC_CTX *mem_ctx,
        return NT_STATUS_OK;
 }
 
-NTSTATUS spnego_ntlmssp_init_client(TALLOC_CTX *mem_ctx,
+NTSTATUS spnego_generic_init_client(TALLOC_CTX *mem_ctx,
+                                   const char *oid,
                                    bool do_sign, bool do_seal,
                                    bool is_dcerpc,
+                                   const char *server,
+                                   const char *target_service,
                                    const char *domain,
                                    const char *username,
                                    const char *password,
                                    struct spnego_context **spnego_ctx)
 {
        struct spnego_context *sp_ctx = NULL;
+       struct auth_generic_state *auth_generic_state;
        NTSTATUS status;
 
        status = spnego_context_init(mem_ctx, do_sign, do_seal, &sp_ctx);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
-       sp_ctx->mech = SPNEGO_NTLMSSP;
+       if (strcmp(oid, GENSEC_OID_NTLMSSP) == 0) {
+               sp_ctx->mech = SPNEGO_NTLMSSP;
+       } else {
+               return NT_STATUS_INVALID_PARAMETER;
+       }
 
-       status = auth_ntlmssp_client_start(sp_ctx,
-                                       lp_netbios_name(),
-                                       lp_workgroup(),
-                                       lp_client_ntlmv2_auth(),
-                                       &sp_ctx->mech_ctx.ntlmssp_state);
+       status = auth_generic_client_prepare(sp_ctx,
+                                       &auth_generic_state);
        if (!NT_STATUS_IS_OK(status)) {
                TALLOC_FREE(sp_ctx);
                return status;
        }
 
-       status = auth_ntlmssp_set_username(sp_ctx->mech_ctx.ntlmssp_state,
+       status = auth_generic_set_username(auth_generic_state,
                                           username);
        if (!NT_STATUS_IS_OK(status)) {
                TALLOC_FREE(sp_ctx);
                return status;
        }
 
-       status = auth_ntlmssp_set_domain(sp_ctx->mech_ctx.ntlmssp_state,
+       status = auth_generic_set_domain(auth_generic_state,
                                         domain);
        if (!NT_STATUS_IS_OK(status)) {
                TALLOC_FREE(sp_ctx);
                return status;
        }
 
-       status = auth_ntlmssp_set_password(sp_ctx->mech_ctx.ntlmssp_state,
+       status = auth_generic_set_password(auth_generic_state,
                                           password);
        if (!NT_STATUS_IS_OK(status)) {
                TALLOC_FREE(sp_ctx);
                return status;
        }
 
-       /*
-        * Turn off sign+seal to allow selected auth level to turn it back on.
-        */
-       auth_ntlmssp_and_flags(sp_ctx->mech_ctx.ntlmssp_state,
-                                               ~(NTLMSSP_NEGOTIATE_SIGN |
-                                                 NTLMSSP_NEGOTIATE_SEAL));
-
        if (do_sign) {
-               auth_ntlmssp_or_flags(sp_ctx->mech_ctx.ntlmssp_state,
-                                               NTLMSSP_NEGOTIATE_SIGN);
+               gensec_want_feature(auth_generic_state->gensec_security,
+                                         GENSEC_FEATURE_SIGN);
        } else if (do_seal) {
-               auth_ntlmssp_or_flags(sp_ctx->mech_ctx.ntlmssp_state,
-                                               NTLMSSP_NEGOTIATE_SEAL |
-                                               NTLMSSP_NEGOTIATE_SIGN);
+               gensec_want_feature(auth_generic_state->gensec_security,
+                                         GENSEC_FEATURE_SEAL);
+       }
+
+       if (is_dcerpc) {
+               gensec_want_feature(auth_generic_state->gensec_security,
+                                   GENSEC_FEATURE_DCE_STYLE);
+       }
+
+       status = gensec_set_target_service(auth_generic_state->gensec_security, target_service);
+       if (!NT_STATUS_IS_OK(status)) {
+               TALLOC_FREE(sp_ctx);
+               return status;
+       }
+
+       status = gensec_set_target_hostname(auth_generic_state->gensec_security, server);
+       if (!NT_STATUS_IS_OK(status)) {
+               TALLOC_FREE(sp_ctx);
+               return status;
        }
 
+       status = auth_generic_client_start(auth_generic_state, oid);
+       if (!NT_STATUS_IS_OK(status)) {
+               TALLOC_FREE(sp_ctx);
+               return status;
+       }
+
+       sp_ctx->mech_ctx.gensec_security = talloc_move(sp_ctx, &auth_generic_state->gensec_security);
+       TALLOC_FREE(auth_generic_state);
        *spnego_ctx = sp_ctx;
        return NT_STATUS_OK;
 }
@@ -155,7 +180,7 @@ NTSTATUS spnego_get_client_auth_token(TALLOC_CTX *mem_ctx,
                                      DATA_BLOB *spnego_out)
 {
        struct gse_context *gse_ctx;
-       struct auth_ntlmssp_state *ntlmssp_ctx;
+       struct gensec_security *gensec_security;
        struct spnego_data sp_in, sp_out;
        DATA_BLOB token_in = data_blob_null;
        DATA_BLOB token_out = data_blob_null;
@@ -216,9 +241,9 @@ NTSTATUS spnego_get_client_auth_token(TALLOC_CTX *mem_ctx,
 
        case SPNEGO_NTLMSSP:
 
-               ntlmssp_ctx = sp_ctx->mech_ctx.ntlmssp_state;
-               status = auth_ntlmssp_update(ntlmssp_ctx, mem_ctx,
-                                            token_in, &token_out);
+               gensec_security = sp_ctx->mech_ctx.gensec_security;
+               status = gensec_update(gensec_security, mem_ctx, NULL,
+                                      token_in, &token_out);
                if (NT_STATUS_EQUAL(status,
                                    NT_STATUS_MORE_PROCESSING_REQUIRED)) {
                        mech_wants_more = true;
@@ -320,7 +345,7 @@ NTSTATUS spnego_get_negotiated_mech(struct spnego_context *sp_ctx,
                *auth_context = sp_ctx->mech_ctx.gssapi_state;
                break;
        case SPNEGO_NTLMSSP:
-               *auth_context = sp_ctx->mech_ctx.ntlmssp_state;
+               *auth_context = sp_ctx->mech_ctx.gensec_security;
                break;
        default:
                return NT_STATUS_INTERNAL_ERROR;
@@ -334,14 +359,17 @@ DATA_BLOB spnego_get_session_key(TALLOC_CTX *mem_ctx,
                                 struct spnego_context *sp_ctx)
 {
        DATA_BLOB sk;
-
+       NTSTATUS status;
        switch (sp_ctx->mech) {
        case SPNEGO_KRB5:
                return gse_get_session_key(mem_ctx,
                                           sp_ctx->mech_ctx.gssapi_state);
        case SPNEGO_NTLMSSP:
-               return auth_ntlmssp_get_session_key(
-                       sp_ctx->mech_ctx.ntlmssp_state, mem_ctx);
+               status = gensec_session_key(sp_ctx->mech_ctx.gensec_security, mem_ctx, &sk);
+               if (!NT_STATUS_IS_OK(status)) {
+                       return data_blob_null;
+               }
+               return sk;
        default:
                DEBUG(0, ("Unsupported type in request!\n"));
                return data_blob_null;
@@ -359,12 +387,12 @@ NTSTATUS spnego_sign(TALLOC_CTX *mem_ctx,
                                sp_ctx->mech_ctx.gssapi_state,
                                data, signature);
        case SPNEGO_NTLMSSP:
-               return auth_ntlmssp_sign_packet(
-                                       sp_ctx->mech_ctx.ntlmssp_state,
-                                       mem_ctx,
-                                       data->data, data->length,
-                                       full_data->data, full_data->length,
-                                       signature);
+               return gensec_sign_packet(
+                       sp_ctx->mech_ctx.gensec_security,
+                       mem_ctx,
+                       data->data, data->length,
+                       full_data->data, full_data->length,
+                       signature);
        default:
                return NT_STATUS_INVALID_PARAMETER;
        }
@@ -381,11 +409,11 @@ NTSTATUS spnego_sigcheck(TALLOC_CTX *mem_ctx,
                                    sp_ctx->mech_ctx.gssapi_state,
                                    data, signature);
        case SPNEGO_NTLMSSP:
-               return auth_ntlmssp_check_packet(
-                                       sp_ctx->mech_ctx.ntlmssp_state,
-                                       data->data, data->length,
-                                       full_data->data, full_data->length,
-                                       signature);
+               return gensec_check_packet(
+                       sp_ctx->mech_ctx.gensec_security,
+                       data->data, data->length,
+                       full_data->data, full_data->length,
+                       signature);
        default:
                return NT_STATUS_INVALID_PARAMETER;
        }
@@ -402,12 +430,12 @@ NTSTATUS spnego_seal(TALLOC_CTX *mem_ctx,
                                sp_ctx->mech_ctx.gssapi_state,
                                data, signature);
        case SPNEGO_NTLMSSP:
-               return auth_ntlmssp_seal_packet(
-                                       sp_ctx->mech_ctx.ntlmssp_state,
-                                       mem_ctx,
-                                       data->data, data->length,
-                                       full_data->data, full_data->length,
-                                       signature);
+               return gensec_seal_packet(
+                       sp_ctx->mech_ctx.gensec_security,
+                       mem_ctx,
+                       data->data, data->length,
+                       full_data->data, full_data->length,
+                       signature);
        default:
                return NT_STATUS_INVALID_PARAMETER;
        }
@@ -424,11 +452,11 @@ NTSTATUS spnego_unseal(TALLOC_CTX *mem_ctx,
                                    sp_ctx->mech_ctx.gssapi_state,
                                    data, signature);
        case SPNEGO_NTLMSSP:
-               return auth_ntlmssp_unseal_packet(
-                                       sp_ctx->mech_ctx.ntlmssp_state,
-                                       data->data, data->length,
-                                       full_data->data, full_data->length,
-                                       signature);
+               return gensec_unseal_packet(
+                       sp_ctx->mech_ctx.gensec_security,
+                       data->data, data->length,
+                       full_data->data, full_data->length,
+                       signature);
        default:
                return NT_STATUS_INVALID_PARAMETER;
        }