svn commit: samba r21876 - in branches/SAMBA_3_0/source: include lib libsmb

jra at samba.org jra at samba.org
Mon Mar 19 20:39:59 GMT 2007


Author: jra
Date: 2007-03-19 20:39:58 +0000 (Mon, 19 Mar 2007)
New Revision: 21876

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=21876

Log:
Start adding in the seal implementation - prototype code
for the server side enc. (doesn't break anything).
I'll keep updating this until I've got NTLM seal working
on both client and server, then add in the gss level
seal.
Jeremy.

Modified:
   branches/SAMBA_3_0/source/include/client.h
   branches/SAMBA_3_0/source/lib/util_sock.c
   branches/SAMBA_3_0/source/libsmb/smb_seal.c


Changeset:
Modified: branches/SAMBA_3_0/source/include/client.h
===================================================================
--- branches/SAMBA_3_0/source/include/client.h	2007-03-19 17:45:13 UTC (rev 21875)
+++ branches/SAMBA_3_0/source/include/client.h	2007-03-19 20:39:58 UTC (rev 21876)
@@ -34,8 +34,7 @@
  * These definitions depend on smb.h
  */
 
-struct print_job_info
-{
+struct print_job_info {
 	uint16 id;
 	uint16 priority;
 	size_t size;
@@ -79,6 +78,19 @@
 	struct dcinfo *dc;
 };
 
+/* Transport encryption state. */
+enum smb_trans_enc_type { SMB_TRANS_ENC_NTLM, SMB_TRANS_ENC_KRB5 };
+
+struct smb_trans_enc_state {
+	enum smb_trans_enc_type smb_enc_type;
+	union {
+		NTLMSSP_STATE *ntlmssp_state;
+#if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5)
+		gss_ctx_id_t context_handle;
+#endif
+	};
+};
+
 struct cli_state {
 	int port;
 	int fd;
@@ -137,6 +149,8 @@
 
 	smb_sign_info sign_info;
 
+	struct smb_trans_enc_state *trans_enc_state; /* Setup if we're encrypting SMB's. */
+
 	/* the session key for this CLI, outside 
 	   any per-pipe authenticaion */
 	DATA_BLOB user_session_key;

Modified: branches/SAMBA_3_0/source/lib/util_sock.c
===================================================================
--- branches/SAMBA_3_0/source/lib/util_sock.c	2007-03-19 17:45:13 UTC (rev 21875)
+++ branches/SAMBA_3_0/source/lib/util_sock.c	2007-03-19 20:39:58 UTC (rev 21876)
@@ -770,29 +770,32 @@
 	size_t len;
 	size_t nwritten=0;
 	ssize_t ret;
+	char *buf_out;
 
 	/* Sign the outgoing packet if required. */
 	srv_calculate_sign_mac(buffer);
 
-	status = srv_encrypt_buffer(buffer);
+	status = srv_encrypt_buffer(buffer, &buf_out);
 	if (!NT_STATUS_IS_OK(status)) {
 		DEBUG(0, ("send_smb: SMB encryption failed on outgoing packet! Error %s\n",
 			nt_errstr(status) ));
 		return False;
 	}
 
-	len = smb_len(buffer) + 4;
+	len = smb_len(buf_out) + 4;
 
 	while (nwritten < len) {
-		ret = write_data(fd,buffer+nwritten,len - nwritten);
+		ret = write_data(fd,buf_out+nwritten,len - nwritten);
 		if (ret <= 0) {
 			DEBUG(0,("Error writing %d bytes to client. %d. (%s)\n",
 				(int)len,(int)ret, strerror(errno) ));
+			srv_free_buffer(buf_out);
 			return False;
 		}
 		nwritten += ret;
 	}
 
+	srv_free_buffer(buf_out);
 	return True;
 }
 

Modified: branches/SAMBA_3_0/source/libsmb/smb_seal.c
===================================================================
--- branches/SAMBA_3_0/source/libsmb/smb_seal.c	2007-03-19 17:45:13 UTC (rev 21875)
+++ branches/SAMBA_3_0/source/libsmb/smb_seal.c	2007-03-19 20:39:58 UTC (rev 21876)
@@ -30,12 +30,186 @@
 	return NT_STATUS_OK;
 }
 
-NTSTATUS srv_decrypt_buffer(char *buffer)
+/* Server state if we're encrypting SMBs. If NULL then enc is off. */
+
+static struct smb_trans_enc_state *srv_trans_enc_state;
+
+/******************************************************************************
+ Is server encryption on ?
+******************************************************************************/
+
+BOOL srv_encryption_on(void)
 {
+	return srv_trans_enc_state != NULL;
+}
+
+/******************************************************************************
+ Free an encryption-allocated buffer.
+******************************************************************************/
+
+void srv_free_buffer(char *buf_out)
+{
+	if (!srv_trans_enc_state) {
+		return;
+	}
+
+	if (srv_trans_enc_state->smb_enc_type == SMB_TRANS_ENC_NTLM) {
+		SAFE_FREE(buf_out);
+		return;
+	}
+
+#if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5)
+	/* gss-api free buffer.... */
+#endif
+}
+
+/******************************************************************************
+ gss-api decrypt an incoming buffer.
+******************************************************************************/
+
+#if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5)
+static NTSTATUS srv_gss_decrypt_buffer(gss_ctx_id_t context_handle, char *buf)
+{
+	return NT_STATUS_NOT_SUPPORTED;
+}
+#endif
+
+/******************************************************************************
+ NTLM decrypt an incoming buffer.
+******************************************************************************/
+
+static NTSTATUS srv_ntlm_decrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf)
+{
+	NTSTATUS status;
+	size_t orig_len = smb_len(buf);
+	size_t new_len = orig_len - NTLMSSP_SIG_SIZE;
+	DATA_BLOB sig;
+
+	if (orig_len < 8 + NTLMSSP_SIG_SIZE) {
+		return NT_STATUS_BUFFER_TOO_SMALL;
+	}
+
+	/* Save off the signature. */
+	sig = data_blob(buf+orig_len-NTLMSSP_SIG_SIZE, NTLMSSP_SIG_SIZE);
+
+	status = ntlmssp_unseal_packet(ntlmssp_state,
+		(unsigned char *)buf + 8, /* 4 byte len + 0xFF 'S' 'M' 'B' */
+		new_len - 8,
+		(unsigned char *)buf,
+		new_len,
+		&sig);
+
+	if (!NT_STATUS_IS_OK(status)) {
+		data_blob_free(&sig);
+		return status;
+	}
+	/* Reset the length. */
+	smb_setlen(buf, new_len);
 	return NT_STATUS_OK;
 }
 
-NTSTATUS srv_encrypt_buffer(char *buffer)
+/******************************************************************************
+ Decrypt an incoming buffer.
+******************************************************************************/
+
+NTSTATUS srv_decrypt_buffer(char *buf)
 {
+	if (!srv_trans_enc_state) {
+		/* Not decrypting. */
+		return NT_STATUS_OK;
+	}
+	if (srv_trans_enc_state->smb_enc_type == SMB_TRANS_ENC_NTLM) {
+		return srv_ntlm_decrypt_buffer(srv_trans_enc_state->ntlmssp_state, buf);
+	} else {
+#if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5)
+		return srv_gss_decrypt_buffer(srv_trans_enc_state->context_handle, buf);
+#else
+		return NT_STATUS_NOT_SUPPORTED;
+#endif
+	}
+}
+
+/******************************************************************************
+ gss-api encrypt an outgoing buffer. Return the encrypted pointer in buf_out.
+******************************************************************************/
+
+#if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5)
+static NTSTATUS srv_gss_encrypt_buffer(gss_ctx_id_t context_handle, char *buf, char **buf_out)
+{
+	return NT_STATUS_NOT_SUPPORTED;
+}
+#endif
+
+/******************************************************************************
+ NTLM encrypt an outgoing buffer. Return the encrypted pointer in ppbuf_out.
+******************************************************************************/
+
+static NTSTATUS srv_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf, char **ppbuf_out)
+{
+	NTSTATUS status;
+	char *buf_out;
+	size_t orig_len = smb_len(buf);
+	size_t new_len = orig_len + NTLMSSP_SIG_SIZE;
+	DATA_BLOB sig;
+
+	*ppbuf_out = NULL;
+
+	if (orig_len < 8) {
+		return NT_STATUS_BUFFER_TOO_SMALL;
+	}
+
+	/* 
+	 * We know smb_len can't return a value > 128k, so no int overflow
+	 * check needed.
+	 */
+
+	/* Copy the original buffer. */
+
+	buf_out = SMB_XMALLOC_ARRAY(char, new_len);
+	memcpy(buf_out, buf, orig_len);
+	/* Last 16 bytes undefined here... */
+
+	smb_setlen(buf_out, new_len);
+
+	sig = data_blob(NULL, NTLMSSP_SIG_SIZE);
+
+	status = ntlmssp_seal_packet(ntlmssp_state,
+		(unsigned char *)buf_out + 8, /* 4 byte len + 0xFF 'S' 'M' 'B' */
+		orig_len - 8,
+		(unsigned char *)buf_out,
+		orig_len,
+		&sig);
+
+	if (!NT_STATUS_IS_OK(status)) {
+		data_blob_free(&sig);
+		SAFE_FREE(buf_out);
+		return status;
+	}
+
+	memcpy(buf_out+orig_len, sig.data, NTLMSSP_SIG_SIZE);
+	*ppbuf_out = buf_out;
 	return NT_STATUS_OK;
 }
+
+/******************************************************************************
+ Encrypt an outgoing buffer. Return the encrypted pointer in buf_out.
+******************************************************************************/
+
+NTSTATUS srv_encrypt_buffer(char *buffer, char **buf_out)
+{
+	if (!srv_trans_enc_state) {
+		/* Not encrypting. */
+		*buf_out = buffer;
+		return NT_STATUS_OK;
+	}
+
+	if (srv_trans_enc_state->smb_enc_type == SMB_TRANS_ENC_NTLM) {
+		return srv_ntlm_encrypt_buffer(srv_trans_enc_state->ntlmssp_state, buffer, buf_out);
+	} else {
+#if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5)
+		return srv_gss_encrypt_buffer(srv_trans_enc_state->context_handle, buffer, buf_out);
+#else
+		return NT_STATUS_NOT_SUPPORTED;
+#endif
+	}
+}



More information about the samba-cvs mailing list