1/* 2 Unix SMB/CIFS implementation. 3 SMB Transport encryption (sealing) code. 4 Copyright (C) Jeremy Allison 2007. 5 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 3 of the License, or 9 (at your option) any later version. 10 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. 15 16 You should have received a copy of the GNU General Public License 17 along with this program. If not, see <http://www.gnu.org/licenses/>. 18*/ 19 20#include "includes.h" 21 22/****************************************************************************** 23 Pull out the encryption context for this packet. 0 means global context. 24******************************************************************************/ 25 26NTSTATUS get_enc_ctx_num(const uint8_t *buf, uint16 *p_enc_ctx_num) 27{ 28 if (smb_len(buf) < 8) { 29 return NT_STATUS_INVALID_BUFFER_SIZE; 30 } 31 32 if (buf[4] == 0xFF) { 33 if (buf[5] == 'S' && buf [6] == 'M' && buf[7] == 'B') { 34 /* Not an encrypted buffer. */ 35 return NT_STATUS_NOT_FOUND; 36 } 37 if (buf[5] == 'E') { 38 *p_enc_ctx_num = SVAL(buf,6); 39 return NT_STATUS_OK; 40 } 41 } 42 return NT_STATUS_INVALID_NETWORK_RESPONSE; 43} 44 45/****************************************************************************** 46 Generic code for client and server. 47 Is encryption turned on ? 48******************************************************************************/ 49 50bool common_encryption_on(struct smb_trans_enc_state *es) 51{ 52 return ((es != NULL) && es->enc_on); 53} 54 55/****************************************************************************** 56 Generic code for client and server. 57 NTLM decrypt an incoming buffer. 58 Abartlett tells me that SSPI puts the signature first before the encrypted 59 output, so cope with the same for compatibility. 60******************************************************************************/ 61 62NTSTATUS common_ntlm_decrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf) 63{ 64 NTSTATUS status; 65 size_t buf_len = smb_len(buf) + 4; /* Don't forget the 4 length bytes. */ 66 size_t data_len; 67 char *inbuf; 68 DATA_BLOB sig; 69 70 if (buf_len < 8 + NTLMSSP_SIG_SIZE) { 71 return NT_STATUS_BUFFER_TOO_SMALL; 72 } 73 74 inbuf = (char *)smb_xmemdup(buf, buf_len); 75 76 /* Adjust for the signature. */ 77 data_len = buf_len - 8 - NTLMSSP_SIG_SIZE; 78 79 /* Point at the signature. */ 80 sig = data_blob_const(inbuf+8, NTLMSSP_SIG_SIZE); 81 82 status = ntlmssp_unseal_packet(ntlmssp_state, 83 (unsigned char *)inbuf + 8 + NTLMSSP_SIG_SIZE, /* 4 byte len + 0xFF 'E' <enc> <ctx> */ 84 data_len, 85 (unsigned char *)inbuf + 8 + NTLMSSP_SIG_SIZE, 86 data_len, 87 &sig); 88 89 if (!NT_STATUS_IS_OK(status)) { 90 SAFE_FREE(inbuf); 91 return status; 92 } 93 94 memcpy(buf + 8, inbuf + 8 + NTLMSSP_SIG_SIZE, data_len); 95 96 /* Reset the length and overwrite the header. */ 97 smb_setlen(buf,data_len + 4); 98 99 SAFE_FREE(inbuf); 100 return NT_STATUS_OK; 101} 102 103/****************************************************************************** 104 Generic code for client and server. 105 NTLM encrypt an outgoing buffer. Return the encrypted pointer in ppbuf_out. 106 Abartlett tells me that SSPI puts the signature first before the encrypted 107 output, so do the same for compatibility. 108******************************************************************************/ 109 110NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, 111 uint16 enc_ctx_num, 112 char *buf, 113 char **ppbuf_out) 114{ 115 NTSTATUS status; 116 char *buf_out; 117 size_t data_len = smb_len(buf) - 4; /* Ignore the 0xFF SMB bytes. */ 118 DATA_BLOB sig; 119 120 *ppbuf_out = NULL; 121 122 if (data_len == 0) { 123 return NT_STATUS_BUFFER_TOO_SMALL; 124 } 125 126 /* 127 * We know smb_len can't return a value > 128k, so no int overflow 128 * check needed. 129 */ 130 131 buf_out = SMB_XMALLOC_ARRAY(char, 8 + NTLMSSP_SIG_SIZE + data_len); 132 133 /* Copy the data from the original buffer. */ 134 135 memcpy(buf_out + 8 + NTLMSSP_SIG_SIZE, buf + 8, data_len); 136 137 smb_set_enclen(buf_out, smb_len(buf) + NTLMSSP_SIG_SIZE, enc_ctx_num); 138 139 ZERO_STRUCT(sig); 140 141 status = ntlmssp_seal_packet(ntlmssp_state, 142 (unsigned char *)buf_out + 8 + NTLMSSP_SIG_SIZE, /* 4 byte len + 0xFF 'S' <enc> <ctx> */ 143 data_len, 144 (unsigned char *)buf_out + 8 + NTLMSSP_SIG_SIZE, 145 data_len, 146 &sig); 147 148 if (!NT_STATUS_IS_OK(status)) { 149 data_blob_free(&sig); 150 SAFE_FREE(buf_out); 151 return status; 152 } 153 154 /* First 16 data bytes are signature for SSPI compatibility. */ 155 memcpy(buf_out + 8, sig.data, NTLMSSP_SIG_SIZE); 156 data_blob_free(&sig); 157 *ppbuf_out = buf_out; 158 return NT_STATUS_OK; 159} 160 161/****************************************************************************** 162 Generic code for client and server. 163 gss-api decrypt an incoming buffer. We insist that the size of the 164 unwrapped buffer must be smaller or identical to the incoming buffer. 165******************************************************************************/ 166 167#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) 168static NTSTATUS common_gss_decrypt_buffer(struct smb_tran_enc_state_gss *gss_state, char *buf) 169{ 170 gss_ctx_id_t gss_ctx = gss_state->gss_ctx; 171 OM_uint32 ret = 0; 172 OM_uint32 minor = 0; 173 int flags_got = 0; 174 gss_buffer_desc in_buf, out_buf; 175 size_t buf_len = smb_len(buf) + 4; /* Don't forget the 4 length bytes. */ 176 177 if (buf_len < 8) { 178 return NT_STATUS_BUFFER_TOO_SMALL; 179 } 180 181 in_buf.value = buf + 8; 182 in_buf.length = buf_len - 8; 183 184 ret = gss_unwrap(&minor, 185 gss_ctx, 186 &in_buf, 187 &out_buf, 188 &flags_got, /* did we get sign+seal ? */ 189 (gss_qop_t *) NULL); 190 191 if (ret != GSS_S_COMPLETE) { 192 ADS_STATUS adss = ADS_ERROR_GSS(ret, minor); 193 DEBUG(0,("common_gss_encrypt_buffer: gss_unwrap failed. Error %s\n", 194 ads_errstr(adss) )); 195 return map_nt_error_from_gss(ret, minor); 196 } 197 198 if (out_buf.length > in_buf.length) { 199 DEBUG(0,("common_gss_encrypt_buffer: gss_unwrap size (%u) too large (%u) !\n", 200 (unsigned int)out_buf.length, 201 (unsigned int)in_buf.length )); 202 gss_release_buffer(&minor, &out_buf); 203 return NT_STATUS_INVALID_PARAMETER; 204 } 205 206 memcpy(buf + 8, out_buf.value, out_buf.length); 207 /* Reset the length and overwrite the header. */ 208 smb_setlen(buf, out_buf.length + 4); 209 210 gss_release_buffer(&minor, &out_buf); 211 return NT_STATUS_OK; 212} 213 214/****************************************************************************** 215 Generic code for client and server. 216 gss-api encrypt an outgoing buffer. Return the alloced encrypted pointer in buf_out. 217******************************************************************************/ 218 219static NTSTATUS common_gss_encrypt_buffer(struct smb_tran_enc_state_gss *gss_state, 220 uint16 enc_ctx_num, 221 char *buf, 222 char **ppbuf_out) 223{ 224 gss_ctx_id_t gss_ctx = gss_state->gss_ctx; 225 OM_uint32 ret = 0; 226 OM_uint32 minor = 0; 227 int flags_got = 0; 228 gss_buffer_desc in_buf, out_buf; 229 size_t buf_len = smb_len(buf) + 4; /* Don't forget the 4 length bytes. */ 230 231 *ppbuf_out = NULL; 232 233 if (buf_len < 8) { 234 return NT_STATUS_BUFFER_TOO_SMALL; 235 } 236 237 in_buf.value = buf + 8; 238 in_buf.length = buf_len - 8; 239 240 ret = gss_wrap(&minor, 241 gss_ctx, 242 true, /* we want sign+seal. */ 243 GSS_C_QOP_DEFAULT, 244 &in_buf, 245 &flags_got, /* did we get sign+seal ? */ 246 &out_buf); 247 248 if (ret != GSS_S_COMPLETE) { 249 ADS_STATUS adss = ADS_ERROR_GSS(ret, minor); 250 DEBUG(0,("common_gss_encrypt_buffer: gss_wrap failed. Error %s\n", 251 ads_errstr(adss) )); 252 return map_nt_error_from_gss(ret, minor); 253 } 254 255 if (!flags_got) { 256 /* Sign+seal not supported. */ 257 gss_release_buffer(&minor, &out_buf); 258 return NT_STATUS_NOT_SUPPORTED; 259 } 260 261 /* Ya see - this is why I *hate* gss-api. I don't 262 * want to have to malloc another buffer of the 263 * same size + 8 bytes just to get a continuous 264 * header + buffer, but gss won't let me pass in 265 * a pre-allocated buffer. Bastards (and you know 266 * who you are....). I might fix this by 267 * going to "encrypt_and_send" passing in a file 268 * descriptor and doing scatter-gather write with 269 * TCP cork on Linux. But I shouldn't have to 270 * bother :-*(. JRA. 271 */ 272 273 *ppbuf_out = (char *)SMB_MALLOC(out_buf.length + 8); /* We know this can't wrap. */ 274 if (!*ppbuf_out) { 275 gss_release_buffer(&minor, &out_buf); 276 return NT_STATUS_NO_MEMORY; 277 } 278 279 memcpy(*ppbuf_out+8, out_buf.value, out_buf.length); 280 smb_set_enclen(*ppbuf_out, out_buf.length + 4, enc_ctx_num); 281 282 gss_release_buffer(&minor, &out_buf); 283 return NT_STATUS_OK; 284} 285#endif 286 287/****************************************************************************** 288 Generic code for client and server. 289 Encrypt an outgoing buffer. Return the alloced encrypted pointer in buf_out. 290******************************************************************************/ 291 292NTSTATUS common_encrypt_buffer(struct smb_trans_enc_state *es, char *buffer, char **buf_out) 293{ 294 if (!common_encryption_on(es)) { 295 /* Not encrypting. */ 296 *buf_out = buffer; 297 return NT_STATUS_OK; 298 } 299 300 switch (es->smb_enc_type) { 301 case SMB_TRANS_ENC_NTLM: 302 return common_ntlm_encrypt_buffer(es->s.ntlmssp_state, es->enc_ctx_num, buffer, buf_out); 303#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) 304 case SMB_TRANS_ENC_GSS: 305 return common_gss_encrypt_buffer(es->s.gss_state, es->enc_ctx_num, buffer, buf_out); 306#endif 307 default: 308 return NT_STATUS_NOT_SUPPORTED; 309 } 310} 311 312/****************************************************************************** 313 Generic code for client and server. 314 Decrypt an incoming SMB buffer. Replaces the data within it. 315 New data must be less than or equal to the current length. 316******************************************************************************/ 317 318NTSTATUS common_decrypt_buffer(struct smb_trans_enc_state *es, char *buf) 319{ 320 if (!common_encryption_on(es)) { 321 /* Not decrypting. */ 322 return NT_STATUS_OK; 323 } 324 325 switch (es->smb_enc_type) { 326 case SMB_TRANS_ENC_NTLM: 327 return common_ntlm_decrypt_buffer(es->s.ntlmssp_state, buf); 328#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) 329 case SMB_TRANS_ENC_GSS: 330 return common_gss_decrypt_buffer(es->s.gss_state, buf); 331#endif 332 default: 333 return NT_STATUS_NOT_SUPPORTED; 334 } 335} 336 337#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) 338/****************************************************************************** 339 Shutdown a gss encryption state. 340******************************************************************************/ 341 342static void common_free_gss_state(struct smb_tran_enc_state_gss **pp_gss_state) 343{ 344 OM_uint32 minor = 0; 345 struct smb_tran_enc_state_gss *gss_state = *pp_gss_state; 346 347 if (gss_state->creds != GSS_C_NO_CREDENTIAL) { 348 gss_release_cred(&minor, &gss_state->creds); 349 } 350 if (gss_state->gss_ctx != GSS_C_NO_CONTEXT) { 351 gss_delete_sec_context(&minor, &gss_state->gss_ctx, NULL); 352 } 353 SAFE_FREE(*pp_gss_state); 354} 355#endif 356 357/****************************************************************************** 358 Shutdown an encryption state. 359******************************************************************************/ 360 361void common_free_encryption_state(struct smb_trans_enc_state **pp_es) 362{ 363 struct smb_trans_enc_state *es = *pp_es; 364 365 if (es == NULL) { 366 return; 367 } 368 369 if (es->smb_enc_type == SMB_TRANS_ENC_NTLM) { 370 if (es->s.ntlmssp_state) { 371 ntlmssp_end(&es->s.ntlmssp_state); 372 } 373 } 374#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) 375 if (es->smb_enc_type == SMB_TRANS_ENC_GSS) { 376 /* Free the gss context handle. */ 377 if (es->s.gss_state) { 378 common_free_gss_state(&es->s.gss_state); 379 } 380 } 381#endif 382 SAFE_FREE(es); 383 *pp_es = NULL; 384} 385 386/****************************************************************************** 387 Free an encryption-allocated buffer. 388******************************************************************************/ 389 390void common_free_enc_buffer(struct smb_trans_enc_state *es, char *buf) 391{ 392 uint16_t enc_ctx_num; 393 394 if (!common_encryption_on(es)) { 395 return; 396 } 397 398 if (!NT_STATUS_IS_OK(get_enc_ctx_num((const uint8_t *)buf, 399 &enc_ctx_num))) { 400 return; 401 } 402 403 if (es->smb_enc_type == SMB_TRANS_ENC_NTLM) { 404 SAFE_FREE(buf); 405 return; 406 } 407 408#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) 409 if (es->smb_enc_type == SMB_TRANS_ENC_GSS) { 410 OM_uint32 min; 411 gss_buffer_desc rel_buf; 412 rel_buf.value = buf; 413 rel_buf.length = smb_len(buf) + 4; 414 gss_release_buffer(&min, &rel_buf); 415 } 416#endif 417} 418 419/****************************************************************************** 420 Client side encryption. 421******************************************************************************/ 422 423/****************************************************************************** 424 Is client encryption on ? 425******************************************************************************/ 426 427bool cli_encryption_on(struct cli_state *cli) 428{ 429 /* If we supported multiple encrytion contexts 430 * here we'd look up based on tid. 431 */ 432 return common_encryption_on(cli->trans_enc_state); 433} 434 435/****************************************************************************** 436 Shutdown a client encryption state. 437******************************************************************************/ 438 439void cli_free_encryption_context(struct cli_state *cli) 440{ 441 common_free_encryption_state(&cli->trans_enc_state); 442} 443 444/****************************************************************************** 445 Free an encryption-allocated buffer. 446******************************************************************************/ 447 448void cli_free_enc_buffer(struct cli_state *cli, char *buf) 449{ 450 /* We know this is an smb buffer, and we 451 * didn't malloc, only copy, for a keepalive, 452 * so ignore non-session messages. */ 453 454 if(CVAL(buf,0)) { 455 return; 456 } 457 458 /* If we supported multiple encrytion contexts 459 * here we'd look up based on tid. 460 */ 461 common_free_enc_buffer(cli->trans_enc_state, buf); 462} 463 464/****************************************************************************** 465 Decrypt an incoming buffer. 466******************************************************************************/ 467 468NTSTATUS cli_decrypt_message(struct cli_state *cli) 469{ 470 NTSTATUS status; 471 uint16 enc_ctx_num; 472 473 /* Ignore non-session messages. */ 474 if(CVAL(cli->inbuf,0)) { 475 return NT_STATUS_OK; 476 } 477 478 status = get_enc_ctx_num((const uint8_t *)cli->inbuf, &enc_ctx_num); 479 if (!NT_STATUS_IS_OK(status)) { 480 return status; 481 } 482 483 if (enc_ctx_num != cli->trans_enc_state->enc_ctx_num) { 484 return NT_STATUS_INVALID_HANDLE; 485 } 486 487 return common_decrypt_buffer(cli->trans_enc_state, cli->inbuf); 488} 489 490/****************************************************************************** 491 Encrypt an outgoing buffer. Return the encrypted pointer in buf_out. 492******************************************************************************/ 493 494NTSTATUS cli_encrypt_message(struct cli_state *cli, char *buf, char **buf_out) 495{ 496 /* Ignore non-session messages. */ 497 if (CVAL(buf,0)) { 498 return NT_STATUS_OK; 499 } 500 501 /* If we supported multiple encrytion contexts 502 * here we'd look up based on tid. 503 */ 504 return common_encrypt_buffer(cli->trans_enc_state, buf, buf_out); 505} 506