Blame view
fs/cifs/smb2transport.c
15.6 KB
2dc7e1c03 CIFS: Make transp... |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
/* * fs/cifs/smb2transport.c * * Copyright (C) International Business Machines Corp., 2002, 2011 * Etersoft, 2012 * Author(s): Steve French (sfrench@us.ibm.com) * Jeremy Allison (jra@samba.org) 2006 * Pavel Shilovsky (pshilovsky@samba.org) 2012 * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See * the GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include <linux/fs.h> #include <linux/list.h> #include <linux/wait.h> #include <linux/net.h> #include <linux/delay.h> #include <linux/uaccess.h> #include <asm/processor.h> #include <linux/mempool.h> |
fb308a6f2 cifs: teach signi... |
33 |
#include <linux/highmem.h> |
2dc7e1c03 CIFS: Make transp... |
34 35 36 37 38 39 |
#include "smb2pdu.h" #include "cifsglob.h" #include "cifsproto.h" #include "smb2proto.h" #include "cifs_debug.h" #include "smb2status.h" |
3c1bf7e48 CIFS: Enable sign... |
40 |
#include "smb2glob.h" |
95dc8dd14 Limit allocation ... |
41 42 43 |
static int smb2_crypto_shash_allocate(struct TCP_Server_Info *server) { |
ba4820293 cifs: fix bad err... |
44 |
int rc; |
95dc8dd14 Limit allocation ... |
45 46 47 48 49 50 51 52 53 |
unsigned int size; if (server->secmech.sdeschmacsha256 != NULL) return 0; /* already allocated */ server->secmech.hmacsha256 = crypto_alloc_shash("hmac(sha256)", 0, 0); if (IS_ERR(server->secmech.hmacsha256)) { cifs_dbg(VFS, "could not allocate crypto hmacsha256 "); |
ba4820293 cifs: fix bad err... |
54 55 56 |
rc = PTR_ERR(server->secmech.hmacsha256); server->secmech.hmacsha256 = NULL; return rc; |
95dc8dd14 Limit allocation ... |
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
} size = sizeof(struct shash_desc) + crypto_shash_descsize(server->secmech.hmacsha256); server->secmech.sdeschmacsha256 = kmalloc(size, GFP_KERNEL); if (!server->secmech.sdeschmacsha256) { crypto_free_shash(server->secmech.hmacsha256); server->secmech.hmacsha256 = NULL; return -ENOMEM; } server->secmech.sdeschmacsha256->shash.tfm = server->secmech.hmacsha256; server->secmech.sdeschmacsha256->shash.flags = 0x0; return 0; } static int smb3_crypto_shash_allocate(struct TCP_Server_Info *server) { unsigned int size; int rc; if (server->secmech.sdesccmacaes != NULL) return 0; /* already allocated */ rc = smb2_crypto_shash_allocate(server); if (rc) return rc; server->secmech.cmacaes = crypto_alloc_shash("cmac(aes)", 0, 0); if (IS_ERR(server->secmech.cmacaes)) { cifs_dbg(VFS, "could not allocate crypto cmac-aes"); kfree(server->secmech.sdeschmacsha256); server->secmech.sdeschmacsha256 = NULL; crypto_free_shash(server->secmech.hmacsha256); server->secmech.hmacsha256 = NULL; |
ba4820293 cifs: fix bad err... |
93 94 95 |
rc = PTR_ERR(server->secmech.cmacaes); server->secmech.cmacaes = NULL; return rc; |
95dc8dd14 Limit allocation ... |
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
} size = sizeof(struct shash_desc) + crypto_shash_descsize(server->secmech.cmacaes); server->secmech.sdesccmacaes = kmalloc(size, GFP_KERNEL); if (!server->secmech.sdesccmacaes) { cifs_dbg(VFS, "%s: Can't alloc cmacaes ", __func__); kfree(server->secmech.sdeschmacsha256); server->secmech.sdeschmacsha256 = NULL; crypto_free_shash(server->secmech.hmacsha256); crypto_free_shash(server->secmech.cmacaes); server->secmech.hmacsha256 = NULL; server->secmech.cmacaes = NULL; return -ENOMEM; } server->secmech.sdesccmacaes->shash.tfm = server->secmech.cmacaes; server->secmech.sdesccmacaes->shash.flags = 0x0; return 0; } |
32811d242 cifs: Start using... |
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
static struct cifs_ses * smb2_find_smb_ses(struct smb2_hdr *smb2hdr, struct TCP_Server_Info *server) { struct cifs_ses *ses; spin_lock(&cifs_tcp_ses_lock); list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) { if (ses->Suid != smb2hdr->SessionId) continue; spin_unlock(&cifs_tcp_ses_lock); return ses; } spin_unlock(&cifs_tcp_ses_lock); return NULL; } |
95dc8dd14 Limit allocation ... |
133 |
|
38107d45c Do not send SMB2 ... |
134 |
int |
0b688cfc8 cifs: change smb2... |
135 |
smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server) |
3c1bf7e48 CIFS: Enable sign... |
136 |
{ |
16c568eff cifs: merge the h... |
137 |
int rc; |
3c1bf7e48 CIFS: Enable sign... |
138 139 |
unsigned char smb2_signature[SMB2_HMACSHA256_SIZE]; unsigned char *sigptr = smb2_signature; |
0b688cfc8 cifs: change smb2... |
140 |
struct kvec *iov = rqst->rq_iov; |
3c1bf7e48 CIFS: Enable sign... |
141 |
struct smb2_hdr *smb2_pdu = (struct smb2_hdr *)iov[0].iov_base; |
32811d242 cifs: Start using... |
142 143 144 145 146 147 148 149 |
struct cifs_ses *ses; ses = smb2_find_smb_ses(smb2_pdu, server); if (!ses) { cifs_dbg(VFS, "%s: Could not find session ", __func__); return 0; } |
3c1bf7e48 CIFS: Enable sign... |
150 151 152 |
memset(smb2_signature, 0x0, SMB2_HMACSHA256_SIZE); memset(smb2_pdu->Signature, 0x0, SMB2_SIGNATURE_SIZE); |
95dc8dd14 Limit allocation ... |
153 154 155 156 157 158 |
rc = smb2_crypto_shash_allocate(server); if (rc) { cifs_dbg(VFS, "%s: shah256 alloc failed ", __func__); return rc; } |
3c1bf7e48 CIFS: Enable sign... |
159 |
rc = crypto_shash_setkey(server->secmech.hmacsha256, |
32811d242 cifs: Start using... |
160 |
ses->auth_key.response, SMB2_NTLMV2_SESSKEY_SIZE); |
3c1bf7e48 CIFS: Enable sign... |
161 |
if (rc) { |
f96637be0 [CIFS] cifs: Rena... |
162 163 |
cifs_dbg(VFS, "%s: Could not update with response ", __func__); |
3c1bf7e48 CIFS: Enable sign... |
164 165 166 167 168 |
return rc; } rc = crypto_shash_init(&server->secmech.sdeschmacsha256->shash); if (rc) { |
95dc8dd14 Limit allocation ... |
169 |
cifs_dbg(VFS, "%s: Could not init sha256", __func__); |
3c1bf7e48 CIFS: Enable sign... |
170 171 |
return rc; } |
16c568eff cifs: merge the h... |
172 173 |
rc = __cifs_calc_signature(rqst, server, sigptr, &server->secmech.sdeschmacsha256->shash); |
3c1bf7e48 CIFS: Enable sign... |
174 |
|
16c568eff cifs: merge the h... |
175 176 |
if (!rc) memcpy(smb2_pdu->Signature, sigptr, SMB2_SIGNATURE_SIZE); |
3c1bf7e48 CIFS: Enable sign... |
177 178 179 |
return rc; } |
373512ec5 Prepare for encry... |
180 181 |
static int generate_key(struct cifs_ses *ses, struct kvec label, struct kvec context, __u8 *key, unsigned int key_size) |
429b46f4f [CIFS] SMB3 Signi... |
182 183 184 185 186 187 188 189 190 |
{ unsigned char zero = 0x0; __u8 i[4] = {0, 0, 0, 1}; __u8 L[4] = {0, 0, 0, 128}; int rc = 0; unsigned char prfhash[SMB2_HMACSHA256_SIZE]; unsigned char *hashptr = prfhash; memset(prfhash, 0x0, SMB2_HMACSHA256_SIZE); |
373512ec5 Prepare for encry... |
191 |
memset(key, 0x0, key_size); |
429b46f4f [CIFS] SMB3 Signi... |
192 |
|
32811d242 cifs: Start using... |
193 |
rc = smb3_crypto_shash_allocate(ses->server); |
95dc8dd14 Limit allocation ... |
194 195 196 197 198 |
if (rc) { cifs_dbg(VFS, "%s: crypto alloc failed ", __func__); goto smb3signkey_ret; } |
32811d242 cifs: Start using... |
199 200 |
rc = crypto_shash_setkey(ses->server->secmech.hmacsha256, ses->auth_key.response, SMB2_NTLMV2_SESSKEY_SIZE); |
429b46f4f [CIFS] SMB3 Signi... |
201 202 203 204 205 |
if (rc) { cifs_dbg(VFS, "%s: Could not set with session key ", __func__); goto smb3signkey_ret; } |
32811d242 cifs: Start using... |
206 |
rc = crypto_shash_init(&ses->server->secmech.sdeschmacsha256->shash); |
429b46f4f [CIFS] SMB3 Signi... |
207 208 209 210 211 |
if (rc) { cifs_dbg(VFS, "%s: Could not init sign hmac ", __func__); goto smb3signkey_ret; } |
32811d242 cifs: Start using... |
212 |
rc = crypto_shash_update(&ses->server->secmech.sdeschmacsha256->shash, |
429b46f4f [CIFS] SMB3 Signi... |
213 214 215 216 217 218 |
i, 4); if (rc) { cifs_dbg(VFS, "%s: Could not update with n ", __func__); goto smb3signkey_ret; } |
32811d242 cifs: Start using... |
219 |
rc = crypto_shash_update(&ses->server->secmech.sdeschmacsha256->shash, |
373512ec5 Prepare for encry... |
220 |
label.iov_base, label.iov_len); |
429b46f4f [CIFS] SMB3 Signi... |
221 222 223 224 225 |
if (rc) { cifs_dbg(VFS, "%s: Could not update with label ", __func__); goto smb3signkey_ret; } |
32811d242 cifs: Start using... |
226 |
rc = crypto_shash_update(&ses->server->secmech.sdeschmacsha256->shash, |
429b46f4f [CIFS] SMB3 Signi... |
227 228 229 230 231 232 |
&zero, 1); if (rc) { cifs_dbg(VFS, "%s: Could not update with zero ", __func__); goto smb3signkey_ret; } |
32811d242 cifs: Start using... |
233 |
rc = crypto_shash_update(&ses->server->secmech.sdeschmacsha256->shash, |
373512ec5 Prepare for encry... |
234 |
context.iov_base, context.iov_len); |
429b46f4f [CIFS] SMB3 Signi... |
235 236 237 238 239 |
if (rc) { cifs_dbg(VFS, "%s: Could not update with context ", __func__); goto smb3signkey_ret; } |
32811d242 cifs: Start using... |
240 |
rc = crypto_shash_update(&ses->server->secmech.sdeschmacsha256->shash, |
429b46f4f [CIFS] SMB3 Signi... |
241 242 243 244 245 246 |
L, 4); if (rc) { cifs_dbg(VFS, "%s: Could not update with L ", __func__); goto smb3signkey_ret; } |
32811d242 cifs: Start using... |
247 |
rc = crypto_shash_final(&ses->server->secmech.sdeschmacsha256->shash, |
429b46f4f [CIFS] SMB3 Signi... |
248 249 250 251 252 253 |
hashptr); if (rc) { cifs_dbg(VFS, "%s: Could not generate sha256 hash ", __func__); goto smb3signkey_ret; } |
373512ec5 Prepare for encry... |
254 |
memcpy(key, hashptr, key_size); |
429b46f4f [CIFS] SMB3 Signi... |
255 256 |
smb3signkey_ret: |
32811d242 cifs: Start using... |
257 |
return rc; |
429b46f4f [CIFS] SMB3 Signi... |
258 |
} |
373512ec5 Prepare for encry... |
259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 |
struct derivation { struct kvec label; struct kvec context; }; struct derivation_triplet { struct derivation signing; struct derivation encryption; struct derivation decryption; }; static int generate_smb3signingkey(struct cifs_ses *ses, const struct derivation_triplet *ptriplet) { int rc; rc = generate_key(ses, ptriplet->signing.label, ptriplet->signing.context, ses->smb3signingkey, SMB3_SIGN_KEY_SIZE); if (rc) return rc; rc = generate_key(ses, ptriplet->encryption.label, ptriplet->encryption.context, ses->smb3encryptionkey, SMB3_SIGN_KEY_SIZE); if (rc) return rc; return generate_key(ses, ptriplet->decryption.label, ptriplet->decryption.context, ses->smb3decryptionkey, SMB3_SIGN_KEY_SIZE); } int generate_smb30signingkey(struct cifs_ses *ses) { struct derivation_triplet triplet; struct derivation *d; d = &triplet.signing; d->label.iov_base = "SMB2AESCMAC"; d->label.iov_len = 12; d->context.iov_base = "SmbSign"; d->context.iov_len = 8; d = &triplet.encryption; d->label.iov_base = "SMB2AESCCM"; d->label.iov_len = 11; d->context.iov_base = "ServerIn "; d->context.iov_len = 10; d = &triplet.decryption; d->label.iov_base = "SMB2AESCCM"; d->label.iov_len = 11; d->context.iov_base = "ServerOut"; d->context.iov_len = 10; return generate_smb3signingkey(ses, &triplet); } int generate_smb311signingkey(struct cifs_ses *ses) { struct derivation_triplet triplet; struct derivation *d; d = &triplet.signing; d->label.iov_base = "SMB2AESCMAC"; d->label.iov_len = 12; d->context.iov_base = "SmbSign"; d->context.iov_len = 8; d = &triplet.encryption; d->label.iov_base = "SMB2AESCCM"; d->label.iov_len = 11; d->context.iov_base = "ServerIn "; d->context.iov_len = 10; d = &triplet.decryption; d->label.iov_base = "SMB2AESCCM"; d->label.iov_len = 11; d->context.iov_base = "ServerOut"; d->context.iov_len = 10; return generate_smb3signingkey(ses, &triplet); } |
429b46f4f [CIFS] SMB3 Signi... |
348 |
int |
38107d45c Do not send SMB2 ... |
349 350 |
smb3_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server) { |
32811d242 cifs: Start using... |
351 |
int rc = 0; |
429b46f4f [CIFS] SMB3 Signi... |
352 353 354 |
unsigned char smb3_signature[SMB2_CMACAES_SIZE]; unsigned char *sigptr = smb3_signature; struct kvec *iov = rqst->rq_iov; |
429b46f4f [CIFS] SMB3 Signi... |
355 |
struct smb2_hdr *smb2_pdu = (struct smb2_hdr *)iov[0].iov_base; |
32811d242 cifs: Start using... |
356 357 358 359 360 361 362 363 |
struct cifs_ses *ses; ses = smb2_find_smb_ses(smb2_pdu, server); if (!ses) { cifs_dbg(VFS, "%s: Could not find session ", __func__); return 0; } |
429b46f4f [CIFS] SMB3 Signi... |
364 365 366 367 368 |
memset(smb3_signature, 0x0, SMB2_CMACAES_SIZE); memset(smb2_pdu->Signature, 0x0, SMB2_SIGNATURE_SIZE); rc = crypto_shash_setkey(server->secmech.cmacaes, |
32811d242 cifs: Start using... |
369 |
ses->smb3signingkey, SMB2_CMACAES_SIZE); |
429b46f4f [CIFS] SMB3 Signi... |
370 371 372 373 374 |
if (rc) { cifs_dbg(VFS, "%s: Could not set key for cmac aes ", __func__); return rc; } |
95dc8dd14 Limit allocation ... |
375 376 377 378 379 |
/* * we already allocate sdesccmacaes when we init smb3 signing key, * so unlike smb2 case we do not have to check here if secmech are * initialized */ |
429b46f4f [CIFS] SMB3 Signi... |
380 381 382 383 384 385 |
rc = crypto_shash_init(&server->secmech.sdesccmacaes->shash); if (rc) { cifs_dbg(VFS, "%s: Could not init cmac aes ", __func__); return rc; } |
16c568eff cifs: merge the h... |
386 387 388 |
rc = __cifs_calc_signature(rqst, server, sigptr, &server->secmech.sdesccmacaes->shash); |
429b46f4f [CIFS] SMB3 Signi... |
389 |
|
16c568eff cifs: merge the h... |
390 391 |
if (!rc) memcpy(smb2_pdu->Signature, sigptr, SMB2_SIGNATURE_SIZE); |
429b46f4f [CIFS] SMB3 Signi... |
392 393 |
return rc; |
38107d45c Do not send SMB2 ... |
394 |
} |
3c1bf7e48 CIFS: Enable sign... |
395 396 |
/* must be called with server->srv_mutex held */ static int |
0b688cfc8 cifs: change smb2... |
397 |
smb2_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *server) |
3c1bf7e48 CIFS: Enable sign... |
398 399 |
{ int rc = 0; |
0b688cfc8 cifs: change smb2... |
400 |
struct smb2_hdr *smb2_pdu = rqst->rq_iov[0].iov_base; |
3c1bf7e48 CIFS: Enable sign... |
401 402 403 404 405 406 407 408 409 |
if (!(smb2_pdu->Flags & SMB2_FLAGS_SIGNED) || server->tcpStatus == CifsNeedNegotiate) return rc; if (!server->session_estab) { strncpy(smb2_pdu->Signature, "BSRSPYL", 8); return rc; } |
38107d45c Do not send SMB2 ... |
410 |
rc = server->ops->calc_signature(rqst, server); |
3c1bf7e48 CIFS: Enable sign... |
411 412 413 414 415 |
return rc; } int |
0b688cfc8 cifs: change smb2... |
416 |
smb2_verify_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server) |
3c1bf7e48 CIFS: Enable sign... |
417 418 419 |
{ unsigned int rc; char server_response_sig[16]; |
0b688cfc8 cifs: change smb2... |
420 |
struct smb2_hdr *smb2_pdu = (struct smb2_hdr *)rqst->rq_iov[0].iov_base; |
3c1bf7e48 CIFS: Enable sign... |
421 422 |
if ((smb2_pdu->Command == SMB2_NEGOTIATE) || |
32811d242 cifs: Start using... |
423 |
(smb2_pdu->Command == SMB2_SESSION_SETUP) || |
3c1bf7e48 CIFS: Enable sign... |
424 425 426 427 428 429 430 431 432 433 434 |
(smb2_pdu->Command == SMB2_OPLOCK_BREAK) || (!server->session_estab)) return 0; /* * BB what if signatures are supposed to be on for session but * server does not send one? BB */ /* Do not need to verify session setups with signature "BSRSPYL " */ if (memcmp(smb2_pdu->Signature, "BSRSPYL ", 8) == 0) |
f96637be0 [CIFS] cifs: Rena... |
435 436 437 |
cifs_dbg(FYI, "dummy signature received for smb command 0x%x ", smb2_pdu->Command); |
3c1bf7e48 CIFS: Enable sign... |
438 439 440 441 442 443 444 445 446 447 |
/* * Save off the origiginal signature so we can modify the smb and check * our calculated signature against what the server sent. */ memcpy(server_response_sig, smb2_pdu->Signature, SMB2_SIGNATURE_SIZE); memset(smb2_pdu->Signature, 0, SMB2_SIGNATURE_SIZE); mutex_lock(&server->srv_mutex); |
38107d45c Do not send SMB2 ... |
448 |
rc = server->ops->calc_signature(rqst, server); |
3c1bf7e48 CIFS: Enable sign... |
449 450 451 452 453 454 455 456 457 458 459 |
mutex_unlock(&server->srv_mutex); if (rc) return rc; if (memcmp(server_response_sig, smb2_pdu->Signature, SMB2_SIGNATURE_SIZE)) return -EACCES; else return 0; } |
2dc7e1c03 CIFS: Make transp... |
460 461 462 463 464 465 466 |
/* * Set message id for the request. Should be called after wait_for_free_request * and when srv_mutex is held. */ static inline void smb2_seq_num_into_buf(struct TCP_Server_Info *server, struct smb2_hdr *hdr) { |
cb7e9eabb CIFS: Use multicr... |
467 |
unsigned int i, num = le16_to_cpu(hdr->CreditCharge); |
3d378d3fd cifs: Make big en... |
468 |
hdr->MessageId = get_next_mid64(server); |
cb7e9eabb CIFS: Use multicr... |
469 470 471 |
/* skip message numbers according to CreditCharge field */ for (i = 1; i < num; i++) get_next_mid(server); |
2dc7e1c03 CIFS: Make transp... |
472 473 474 475 476 477 478 479 480 |
} static struct mid_q_entry * smb2_mid_entry_alloc(const struct smb2_hdr *smb_buffer, struct TCP_Server_Info *server) { struct mid_q_entry *temp; if (server == NULL) { |
f96637be0 [CIFS] cifs: Rena... |
481 482 |
cifs_dbg(VFS, "Null TCP session in smb2_mid_entry_alloc "); |
2dc7e1c03 CIFS: Make transp... |
483 484 485 486 487 488 489 490 |
return NULL; } temp = mempool_alloc(cifs_mid_poolp, GFP_NOFS); if (temp == NULL) return temp; else { memset(temp, 0, sizeof(struct mid_q_entry)); |
9235d0987 Convert MessageID... |
491 |
temp->mid = le64_to_cpu(smb_buffer->MessageId); |
2dc7e1c03 CIFS: Make transp... |
492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 |
temp->pid = current->pid; temp->command = smb_buffer->Command; /* Always LE */ temp->when_alloc = jiffies; temp->server = server; /* * The default is for the mid to be synchronous, so the * default callback just wakes up the current task. */ temp->callback = cifs_wake_up_task; temp->callback_data = current; } atomic_inc(&midCount); temp->mid_state = MID_REQUEST_ALLOCATED; return temp; } static int smb2_get_mid_entry(struct cifs_ses *ses, struct smb2_hdr *buf, struct mid_q_entry **mid) { if (ses->server->tcpStatus == CifsExiting) return -ENOENT; if (ses->server->tcpStatus == CifsNeedReconnect) { |
f96637be0 [CIFS] cifs: Rena... |
518 519 |
cifs_dbg(FYI, "tcp session dead - return to caller to retry "); |
2dc7e1c03 CIFS: Make transp... |
520 521 |
return -EAGAIN; } |
7f48558e6 cifs: Send a logo... |
522 |
if (ses->status == CifsNew) { |
2dc7e1c03 CIFS: Make transp... |
523 524 525 526 527 |
if ((buf->Command != SMB2_SESSION_SETUP) && (buf->Command != SMB2_NEGOTIATE)) return -EAGAIN; /* else ok - we are setting up session */ } |
7f48558e6 cifs: Send a logo... |
528 529 530 531 532 533 |
if (ses->status == CifsExiting) { if (buf->Command != SMB2_LOGOFF) return -EAGAIN; /* else ok - we are shutting down the session */ } |
2dc7e1c03 CIFS: Make transp... |
534 535 536 537 538 539 540 541 542 543 544 545 546 547 |
*mid = smb2_mid_entry_alloc(buf, ses->server); if (*mid == NULL) return -ENOMEM; spin_lock(&GlobalMid_Lock); list_add_tail(&(*mid)->qhead, &ses->server->pending_mid_q); spin_unlock(&GlobalMid_Lock); return 0; } int smb2_check_receive(struct mid_q_entry *mid, struct TCP_Server_Info *server, bool log_error) { unsigned int len = get_rfc1002_length(mid->resp_buf); |
0b688cfc8 cifs: change smb2... |
548 549 550 551 552 553 |
struct kvec iov; struct smb_rqst rqst = { .rq_iov = &iov, .rq_nvec = 1 }; iov.iov_base = (char *)mid->resp_buf; iov.iov_len = get_rfc1002_length(mid->resp_buf) + 4; |
2dc7e1c03 CIFS: Make transp... |
554 555 556 |
dump_smb(mid->resp_buf, min_t(u32, 80, len)); /* convert the length into a more usable form */ |
38d77c50b cifs: track the e... |
557 |
if (len > 24 && server->sign) { |
3c1bf7e48 CIFS: Enable sign... |
558 |
int rc; |
0b688cfc8 cifs: change smb2... |
559 |
rc = smb2_verify_signature(&rqst, server); |
3c1bf7e48 CIFS: Enable sign... |
560 |
if (rc) |
f96637be0 [CIFS] cifs: Rena... |
561 562 563 |
cifs_dbg(VFS, "SMB signature verification returned error = %d ", rc); |
3c1bf7e48 CIFS: Enable sign... |
564 |
} |
2dc7e1c03 CIFS: Make transp... |
565 566 567 |
return map_smb2_to_linux_error(mid->resp_buf, log_error); } |
fec344e3f cifs: change cifs... |
568 569 |
struct mid_q_entry * smb2_setup_request(struct cifs_ses *ses, struct smb_rqst *rqst) |
2dc7e1c03 CIFS: Make transp... |
570 571 |
{ int rc; |
fec344e3f cifs: change cifs... |
572 |
struct smb2_hdr *hdr = (struct smb2_hdr *)rqst->rq_iov[0].iov_base; |
2dc7e1c03 CIFS: Make transp... |
573 574 575 576 577 578 |
struct mid_q_entry *mid; smb2_seq_num_into_buf(ses->server, hdr); rc = smb2_get_mid_entry(ses, hdr, &mid); if (rc) |
fec344e3f cifs: change cifs... |
579 580 581 |
return ERR_PTR(rc); rc = smb2_sign_rqst(rqst, ses->server); if (rc) { |
3c1bf7e48 CIFS: Enable sign... |
582 |
cifs_delete_mid(mid); |
fec344e3f cifs: change cifs... |
583 584 585 |
return ERR_PTR(rc); } return mid; |
2dc7e1c03 CIFS: Make transp... |
586 |
} |
fec344e3f cifs: change cifs... |
587 588 |
struct mid_q_entry * smb2_setup_async_request(struct TCP_Server_Info *server, struct smb_rqst *rqst) |
c95b8eeda CIFS: Add SMB2 su... |
589 |
{ |
fec344e3f cifs: change cifs... |
590 591 |
int rc; struct smb2_hdr *hdr = (struct smb2_hdr *)rqst->rq_iov[0].iov_base; |
c95b8eeda CIFS: Add SMB2 su... |
592 593 594 595 596 597 |
struct mid_q_entry *mid; smb2_seq_num_into_buf(server, hdr); mid = smb2_mid_entry_alloc(hdr, server); if (mid == NULL) |
fec344e3f cifs: change cifs... |
598 |
return ERR_PTR(-ENOMEM); |
c95b8eeda CIFS: Add SMB2 su... |
599 |
|
fec344e3f cifs: change cifs... |
600 |
rc = smb2_sign_rqst(rqst, server); |
c95b8eeda CIFS: Add SMB2 su... |
601 602 |
if (rc) { DeleteMidQEntry(mid); |
fec344e3f cifs: change cifs... |
603 |
return ERR_PTR(rc); |
3c1bf7e48 CIFS: Enable sign... |
604 |
} |
fec344e3f cifs: change cifs... |
605 |
return mid; |
c95b8eeda CIFS: Add SMB2 su... |
606 |
} |