2 Unix SMB/CIFS implementation.
3 SMB Transport encryption (sealing) code.
4 Copyright (C) Jeremy Allison 2007.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 /******************************************************************************
24 Generic code for client and server.
25 Is encryption turned on ?
26 ******************************************************************************/
28 BOOL common_encryption_on(struct smb_trans_enc_state *es)
30 return ((es != NULL) && es->enc_on);
33 /******************************************************************************
34 Generic code for client and server.
35 NTLM decrypt an incoming buffer.
36 ******************************************************************************/
38 NTSTATUS common_ntlm_decrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf)
41 size_t buf_len = smb_len(buf) + 4; /* Don't forget the 4 length bytes. */
44 if (buf_len < 8 + NTLMSSP_SIG_SIZE) {
45 return NT_STATUS_BUFFER_TOO_SMALL;
48 /* Adjust for the signature. */
49 buf_len -= NTLMSSP_SIG_SIZE;
51 /* Save off the signature. */
52 sig = data_blob(buf+buf_len, NTLMSSP_SIG_SIZE);
54 status = ntlmssp_unseal_packet(ntlmssp_state,
55 (unsigned char *)buf + 8, /* 4 byte len + 0xFF 'S' 'M' 'B' */
57 (unsigned char *)buf + 8,
61 if (!NT_STATUS_IS_OK(status)) {
66 /* Reset the length. */
67 smb_setlen(buf, smb_len(buf) - NTLMSSP_SIG_SIZE);
71 /******************************************************************************
72 Generic code for client and server.
73 NTLM encrypt an outgoing buffer. Return the encrypted pointer in ppbuf_out.
74 ******************************************************************************/
76 NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf, char **ppbuf_out)
80 size_t buf_len = smb_len(buf) + 4; /* Don't forget the 4 length bytes. */
86 return NT_STATUS_BUFFER_TOO_SMALL;
90 * We know smb_len can't return a value > 128k, so no int overflow
94 /* Copy the original buffer. */
96 buf_out = SMB_XMALLOC_ARRAY(char, buf_len + NTLMSSP_SIG_SIZE);
97 memcpy(buf_out, buf, buf_len);
98 /* Last 16 bytes undefined here... */
100 smb_setlen(buf_out, smb_len(buf) + NTLMSSP_SIG_SIZE);
102 sig = data_blob(NULL, NTLMSSP_SIG_SIZE);
104 status = ntlmssp_seal_packet(ntlmssp_state,
105 (unsigned char *)buf_out + 8, /* 4 byte len + 0xFF 'S' 'M' 'B' */
107 (unsigned char *)buf_out + 8,
111 if (!NT_STATUS_IS_OK(status)) {
112 data_blob_free(&sig);
117 memcpy(buf_out+buf_len, sig.data, NTLMSSP_SIG_SIZE);
118 *ppbuf_out = buf_out;
122 /******************************************************************************
123 Generic code for client and server.
124 gss-api decrypt an incoming buffer.
125 ******************************************************************************/
127 #if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5)
128 NTSTATUS common_gss_decrypt_buffer(gss_ctx_id_t context_handle, char *buf)
130 return NT_STATUS_NOT_SUPPORTED;
134 /******************************************************************************
135 Generic code for client and server.
136 gss-api encrypt an outgoing buffer. Return the alloced encrypted pointer in buf_out.
137 ******************************************************************************/
139 #if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5)
140 NTSTATUS common_gss_encrypt_buffer(gss_ctx_id_t context_handle, char *buf, char **buf_out)
142 return NT_STATUS_NOT_SUPPORTED;
146 /******************************************************************************
147 Generic code for client and server.
148 Encrypt an outgoing buffer. Return the alloced encrypted pointer in buf_out.
149 ******************************************************************************/
151 NTSTATUS common_encrypt_buffer(struct smb_trans_enc_state *es, char *buffer, char **buf_out)
153 if (!common_encryption_on(es)) {
154 /* Not encrypting. */
159 /* Ignore session keepalives. */
160 if(CVAL(buffer,0) == SMBkeepalive) {
165 if (es->smb_enc_type == SMB_TRANS_ENC_NTLM) {
166 return common_ntlm_encrypt_buffer(es->ntlmssp_state, buffer, buf_out);
168 #if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5)
169 return common_gss_encrypt_buffer(es->context_handle, buffer, buf_out);
171 return NT_STATUS_NOT_SUPPORTED;
176 /******************************************************************************
177 Generic code for client and server.
178 Decrypt an incoming SMB buffer. Replaces the data within it.
179 New data must be less than or equal to the current length.
180 ******************************************************************************/
182 NTSTATUS common_decrypt_buffer(struct smb_trans_enc_state *es, char *buf)
184 if (!common_encryption_on(es)) {
185 /* Not decrypting. */
189 /* Ignore session keepalives. */
190 if(CVAL(buf,0) == SMBkeepalive) {
194 if (es->smb_enc_type == SMB_TRANS_ENC_NTLM) {
195 return common_ntlm_decrypt_buffer(es->ntlmssp_state, buf);
197 #if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5)
198 return common_gss_decrypt_buffer(es->context_handle, buf);
200 return NT_STATUS_NOT_SUPPORTED;
205 /******************************************************************************
206 Shutdown an encryption state.
207 ******************************************************************************/
209 void common_free_encryption_state(struct smb_trans_enc_state **pp_es)
211 struct smb_trans_enc_state *es = *pp_es;
217 if (es->smb_enc_type == SMB_TRANS_ENC_NTLM) {
218 if (es->ntlmssp_state) {
219 ntlmssp_end(&es->ntlmssp_state);
222 #if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5)
223 if (es->smb_enc_type == SMB_TRANS_ENC_GSS) {
224 /* Free the gss context handle. */
231 /******************************************************************************
232 Free an encryption-allocated buffer.
233 ******************************************************************************/
235 void common_free_enc_buffer(struct smb_trans_enc_state *es, char *buf)
237 if (!common_encryption_on(es)) {
241 /* We know this is an smb buffer, and we
242 * didn't malloc, only copy, for a keepalive,
243 * so ignore session keepalives. */
245 if(CVAL(buf,0) == SMBkeepalive) {
249 if (es->smb_enc_type == SMB_TRANS_ENC_NTLM) {
254 #if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5)
255 /* gss-api free buffer.... */
259 /******************************************************************************
260 Client side encryption.
261 ******************************************************************************/
263 /******************************************************************************
264 Is client encryption on ?
265 ******************************************************************************/
267 BOOL cli_encryption_on(struct cli_state *cli)
269 return common_encryption_on(cli->trans_enc_state);
272 /******************************************************************************
273 Shutdown a client encryption state.
274 ******************************************************************************/
276 void cli_free_encryption_context(struct cli_state *cli)
278 common_free_encryption_state(&cli->trans_enc_state);
281 /******************************************************************************
282 Free an encryption-allocated buffer.
283 ******************************************************************************/
285 void cli_free_enc_buffer(struct cli_state *cli, char *buf)
287 common_free_enc_buffer(cli->trans_enc_state, buf);
290 /******************************************************************************
291 Decrypt an incoming buffer.
292 ******************************************************************************/
294 NTSTATUS cli_decrypt_message(struct cli_state *cli)
296 return common_decrypt_buffer(cli->trans_enc_state, cli->inbuf);
299 /******************************************************************************
300 Encrypt an outgoing buffer. Return the encrypted pointer in buf_out.
301 ******************************************************************************/
303 NTSTATUS cli_encrypt_message(struct cli_state *cli, char **buf_out)
305 return common_encrypt_buffer(cli->trans_enc_state, cli->outbuf, buf_out);