summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2007-03-21 19:15:14 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 12:18:48 -0500
commit42238c78bb8820a21cfb08fc29a5109ee1a62bab (patch)
tree7b794df2ecfb47779e70b30e24f288e2eca53bdf
parent56c777882f0e9fc64e69290db8f6db5fe90225fd (diff)
downloadsamba-42238c78bb8820a21cfb08fc29a5109ee1a62bab.tar.gz
samba-42238c78bb8820a21cfb08fc29a5109ee1a62bab.tar.bz2
samba-42238c78bb8820a21cfb08fc29a5109ee1a62bab.zip
r21917: Start to do the gss versions of sign+seal.
Jeremy. (This used to be commit a226645353a40047b72de1b96c3a7676a2bf1034)
-rw-r--r--source3/include/client.h4
-rw-r--r--source3/include/includes.h4
-rw-r--r--source3/libsmb/smb_seal.c97
-rw-r--r--source3/smbd/seal.c8
4 files changed, 85 insertions, 28 deletions
diff --git a/source3/include/client.h b/source3/include/client.h
index 0f268834c6..a81c19bc55 100644
--- a/source3/include/client.h
+++ b/source3/include/client.h
@@ -79,14 +79,14 @@ struct rpc_pipe_client {
};
/* Transport encryption state. */
-enum smb_trans_enc_type { SMB_TRANS_ENC_NTLM, SMB_TRANS_ENC_KRB5 };
+enum smb_trans_enc_type { SMB_TRANS_ENC_NTLM, SMB_TRANS_ENC_GSS };
struct smb_trans_enc_state {
enum smb_trans_enc_type smb_enc_type;
BOOL enc_on;
union {
NTLMSSP_STATE *ntlmssp_state;
-#if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5)
+#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5)
gss_ctx_id_t context_handle;
#endif
};
diff --git a/source3/include/includes.h b/source3/include/includes.h
index b591d7d807..c51da335a2 100644
--- a/source3/include/includes.h
+++ b/source3/include/includes.h
@@ -1187,10 +1187,10 @@ krb5_error_code smb_krb5_mk_error(krb5_context context,
krb5_data *reply);
/* Call for SMB transport encryption. */
-#if defined(HAVE_GSSAPI_SUPPORT)
+#if defined(HAVE_GSSAPI)
NTSTATUS common_gss_decrypt_buffer(gss_ctx_id_t context_handle, char *buf);
#endif
-#if defined(HAVE_GSSAPI_SUPPORT)
+#if defined(HAVE_GSSAPI)
NTSTATUS common_gss_encrypt_buffer(gss_ctx_id_t context_handle, char *buf, char **buf_out);
#endif
diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c
index 9ea3a10350..f16c1402a2 100644
--- a/source3/libsmb/smb_seal.c
+++ b/source3/libsmb/smb_seal.c
@@ -124,7 +124,7 @@ NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf, cha
gss-api decrypt an incoming buffer.
******************************************************************************/
-#if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5)
+#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5)
NTSTATUS common_gss_decrypt_buffer(gss_ctx_id_t context_handle, char *buf)
{
return NT_STATUS_NOT_SUPPORTED;
@@ -136,10 +136,65 @@ NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf, cha
gss-api encrypt an outgoing buffer. Return the alloced encrypted pointer in buf_out.
******************************************************************************/
-#if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5)
- NTSTATUS common_gss_encrypt_buffer(gss_ctx_id_t context_handle, char *buf, char **buf_out)
+#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5)
+ NTSTATUS common_gss_encrypt_buffer(gss_ctx_id_t context_handle, char *buf, char **ppbuf_out)
{
- return NT_STATUS_NOT_SUPPORTED;
+ OM_uint32 ret = 0;
+ OM_uint32 minor = 0;
+ int flags_got = 0;
+ gss_buffer_desc in_buf, out_buf;
+ size_t buf_len = smb_len(buf) + 4; /* Don't forget the 4 length bytes. */
+
+ *ppbuf_out = NULL;
+
+ if (buf_len < 8) {
+ return NT_STATUS_BUFFER_TOO_SMALL;
+ }
+
+ in_buf.value = buf + 8;
+ in_buf.length = buf_len - 8;
+
+ ret = gss_wrap(&minor,
+ context_handle,
+ True, /* we want sign+seal. */
+ GSS_C_QOP_DEFAULT,
+ &in_buf,
+ &flags_got, /* did we get sign+seal ? */
+ &out_buf);
+
+ if (ret != GSS_S_COMPLETE) {
+ /* Um - no mapping for gss-errs to NTSTATUS yet. */
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ if (!flags_got) {
+ /* Sign+seal not supported. */
+ gss_release_buffer(&minor, &out_buf);
+ return NT_STATUS_NOT_SUPPORTED;
+ }
+
+ /* Ya see - this is why I *hate* gss-api. I don't
+ * want to have to malloc another buffer of the
+ * same size + 8 bytes just to get a continuous
+ * header + buffer, but gss won't let me pass in
+ * a pre-allocated buffer. Bastards (and you know
+ * who you are....). I might fix this by
+ * going to "encrypt_and_send" passing in a file
+ * descriptor and doing scatter-gather write with
+ * TCP cork on Linux. But I shouldn't have to
+ * bother :-*(. JRA.
+ */
+
+ *ppbuf_out = SMB_MALLOC(out_buf.length + 8); /* We know this can't wrap. */
+ if (!*ppbuf_out) {
+ gss_release_buffer(&minor, &out_buf);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ smb_setlen(*ppbuf_out, out_buf.length + 8);
+ memcpy(*ppbuf_out+8, out_buf.value, out_buf.length);
+ gss_release_buffer(&minor, &out_buf);
+ return NT_STATUS_OK;
}
#endif
@@ -162,14 +217,15 @@ NTSTATUS common_encrypt_buffer(struct smb_trans_enc_state *es, char *buffer, cha
return NT_STATUS_OK;
}
- if (es->smb_enc_type == SMB_TRANS_ENC_NTLM) {
- return common_ntlm_encrypt_buffer(es->ntlmssp_state, buffer, buf_out);
- } else {
-#if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5)
- return common_gss_encrypt_buffer(es->context_handle, buffer, buf_out);
-#else
- return NT_STATUS_NOT_SUPPORTED;
+ switch (es->smb_enc_type) {
+ case SMB_TRANS_ENC_NTLM:
+ return common_ntlm_encrypt_buffer(es->ntlmssp_state, buffer, buf_out);
+#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5)
+ case SMB_TRANS_ENC_GSS:
+ return common_gss_encrypt_buffer(es->context_handle, buffer, buf_out);
#endif
+ default:
+ return NT_STATUS_NOT_SUPPORTED;
}
}
@@ -191,14 +247,15 @@ NTSTATUS common_decrypt_buffer(struct smb_trans_enc_state *es, char *buf)
return NT_STATUS_OK;
}
- if (es->smb_enc_type == SMB_TRANS_ENC_NTLM) {
- return common_ntlm_decrypt_buffer(es->ntlmssp_state, buf);
- } else {
-#if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5)
- return common_gss_decrypt_buffer(es->context_handle, buf);
-#else
- return NT_STATUS_NOT_SUPPORTED;
+ switch (es->smb_enc_type) {
+ case SMB_TRANS_ENC_NTLM:
+ return common_ntlm_decrypt_buffer(es->ntlmssp_state, buf);
+#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5)
+ case SMB_TRANS_ENC_GSS:
+ return common_gss_decrypt_buffer(es->context_handle, buf);
#endif
+ default:
+ return NT_STATUS_NOT_SUPPORTED;
}
}
@@ -219,7 +276,7 @@ void common_free_encryption_state(struct smb_trans_enc_state **pp_es)
ntlmssp_end(&es->ntlmssp_state);
}
}
-#if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5)
+#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5)
if (es->smb_enc_type == SMB_TRANS_ENC_GSS) {
/* Free the gss context handle. */
}
@@ -251,7 +308,7 @@ void common_free_enc_buffer(struct smb_trans_enc_state *es, char *buf)
return;
}
-#if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5)
+#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5)
/* gss-api free buffer.... */
#endif
}
diff --git a/source3/smbd/seal.c b/source3/smbd/seal.c
index 64965d4272..9fa35601f8 100644
--- a/source3/smbd/seal.c
+++ b/source3/smbd/seal.c
@@ -180,8 +180,8 @@ NTSTATUS srv_encrypt_buffer(char *buffer, char **buf_out)
Until success we do everything on the partial enc ctx.
******************************************************************************/
-#if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5)
-static NTSTATUS srv_enc_spnego_gss_negotiate(char **ppdata, size_t *p_data_size, DATA_BLOB secblob)
+#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5)
+static NTSTATUS srv_enc_spnego_gss_negotiate(unsigned char **ppdata, size_t *p_data_size, DATA_BLOB secblob)
{
return NT_STATUS_NOT_SUPPORTED;
}
@@ -246,8 +246,8 @@ static NTSTATUS srv_enc_spnego_negotiate(unsigned char **ppdata, size_t *p_data_
srv_free_encryption_context(&partial_srv_trans_enc_ctx);
-#if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5)
- if (got_kerberos_mechanism && lp_use_kerberos_keytab()) ) {
+#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5)
+ if (got_kerberos_mechanism && lp_use_kerberos_keytab() ) {
status = srv_enc_spnego_gss_negotiate(ppdata, p_data_size, secblob);
} else
#endif