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 orig_len = smb_len(buf);
42 size_t new_len = orig_len - NTLMSSP_SIG_SIZE;
45 if (orig_len < 8 + NTLMSSP_SIG_SIZE) {
46 return NT_STATUS_BUFFER_TOO_SMALL;
49 /* Save off the signature. */
50 sig = data_blob(buf+orig_len-NTLMSSP_SIG_SIZE, NTLMSSP_SIG_SIZE);
52 status = ntlmssp_unseal_packet(ntlmssp_state,
53 (unsigned char *)buf + 8, /* 4 byte len + 0xFF 'S' 'M' 'B' */
59 if (!NT_STATUS_IS_OK(status)) {
63 /* Reset the length. */
64 smb_setlen(buf, new_len);
68 /******************************************************************************
69 Generic code for client and server.
70 NTLM encrypt an outgoing buffer. Return the encrypted pointer in ppbuf_out.
71 ******************************************************************************/
73 NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf, char **ppbuf_out)
77 size_t orig_len = smb_len(buf);
78 size_t new_len = orig_len + NTLMSSP_SIG_SIZE;
84 return NT_STATUS_BUFFER_TOO_SMALL;
88 * We know smb_len can't return a value > 128k, so no int overflow
92 /* Copy the original buffer. */
94 buf_out = SMB_XMALLOC_ARRAY(char, new_len);
95 memcpy(buf_out, buf, orig_len);
96 /* Last 16 bytes undefined here... */
98 smb_setlen(buf_out, new_len);
100 sig = data_blob(NULL, NTLMSSP_SIG_SIZE);
102 status = ntlmssp_seal_packet(ntlmssp_state,
103 (unsigned char *)buf_out + 8, /* 4 byte len + 0xFF 'S' 'M' 'B' */
105 (unsigned char *)buf_out,
109 if (!NT_STATUS_IS_OK(status)) {
110 data_blob_free(&sig);
115 memcpy(buf_out+orig_len, sig.data, NTLMSSP_SIG_SIZE);
116 *ppbuf_out = buf_out;
120 /******************************************************************************
121 Generic code for client and server.
122 gss-api decrypt an incoming buffer.
123 ******************************************************************************/
125 #if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5)
126 NTSTATUS common_gss_decrypt_buffer(gss_ctx_id_t context_handle, char *buf)
128 return NT_STATUS_NOT_SUPPORTED;
132 /******************************************************************************
133 Generic code for client and server.
134 gss-api encrypt an outgoing buffer. Return the alloced encrypted pointer in buf_out.
135 ******************************************************************************/
137 #if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5)
138 NTSTATUS common_gss_encrypt_buffer(gss_ctx_id_t context_handle, char *buf, char **buf_out)
140 return NT_STATUS_NOT_SUPPORTED;
144 /******************************************************************************
145 Generic code for client and server.
146 Encrypt an outgoing buffer. Return the alloced encrypted pointer in buf_out.
147 ******************************************************************************/
149 NTSTATUS common_encrypt_buffer(struct smb_trans_enc_state *es, char *buffer, char **buf_out)
151 if (!common_encryption_on(es)) {
152 /* Not encrypting. */
157 if (es->smb_enc_type == SMB_TRANS_ENC_NTLM) {
158 return common_ntlm_encrypt_buffer(es->ntlmssp_state, buffer, buf_out);
160 #if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5)
161 return common_gss_encrypt_buffer(es->context_handle, buffer, buf_out);
163 return NT_STATUS_NOT_SUPPORTED;
168 /******************************************************************************
169 Generic code for client and server.
170 Decrypt an incoming SMB buffer. Replaces the data within it.
171 New data must be less than or equal to the current length.
172 ******************************************************************************/
174 NTSTATUS common_decrypt_buffer(struct smb_trans_enc_state *es, char *buf)
176 if (!common_encryption_on(es)) {
177 /* Not decrypting. */
180 if (es->smb_enc_type == SMB_TRANS_ENC_NTLM) {
181 return common_ntlm_decrypt_buffer(es->ntlmssp_state, buf);
183 #if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5)
184 return common_gss_decrypt_buffer(es->context_handle, buf);
186 return NT_STATUS_NOT_SUPPORTED;
191 /******************************************************************************
192 Shutdown an encryption state.
193 ******************************************************************************/
195 void common_free_encryption_state(struct smb_trans_enc_state **pp_es)
197 struct smb_trans_enc_state *es = *pp_es;
203 if (es->smb_enc_type == SMB_TRANS_ENC_NTLM) {
204 if (es->ntlmssp_state) {
205 ntlmssp_end(&es->ntlmssp_state);
208 #if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5)
209 if (es->smb_enc_type == SMB_TRANS_ENC_GSS) {
210 /* Free the gss context handle. */
217 /******************************************************************************
218 Free an encryption-allocated buffer.
219 ******************************************************************************/
221 void common_free_enc_buffer(struct smb_trans_enc_state *es, char *buf)
223 if (!common_encryption_on(es)) {
227 if (es->smb_enc_type == SMB_TRANS_ENC_NTLM) {
232 #if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5)
233 /* gss-api free buffer.... */
237 /******************************************************************************
238 Client side encryption.
239 ******************************************************************************/
241 /******************************************************************************
242 Is client encryption on ?
243 ******************************************************************************/
245 BOOL cli_encryption_on(struct cli_state *cli)
247 return common_encryption_on(cli->trans_enc_state);
250 /******************************************************************************
251 Shutdown a client encryption state.
252 ******************************************************************************/
254 void cli_free_encryption_context(struct cli_state *cli)
256 return common_free_encryption_state(&cli->trans_enc_state);
259 /******************************************************************************
260 Free an encryption-allocated buffer.
261 ******************************************************************************/
263 void cli_free_enc_buffer(struct cli_state *cli, char *buf)
265 return common_free_enc_buffer(cli->trans_enc_state, buf);
268 /******************************************************************************
269 Decrypt an incoming buffer.
270 ******************************************************************************/
272 NTSTATUS cli_decrypt_message(struct cli_state *cli)
274 return common_decrypt_buffer(cli->trans_enc_state, cli->inbuf);
277 /******************************************************************************
278 Encrypt an outgoing buffer. Return the encrypted pointer in buf_out.
279 ******************************************************************************/
281 NTSTATUS cli_encrypt_message(struct cli_state *cli, char **buf_out)
283 return common_encrypt_buffer(cli->trans_enc_state, cli->outbuf, buf_out);