From patchwork Tue Dec 6 22:02:30 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Shilovskiy X-Patchwork-Id: 9463321 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 8CBC960231 for ; Tue, 6 Dec 2016 22:17:52 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7D7FA284F0 for ; Tue, 6 Dec 2016 22:17:52 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7277E284F4; Tue, 6 Dec 2016 22:17:52 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2E917284F0 for ; Tue, 6 Dec 2016 22:17:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752043AbcLFWRu (ORCPT ); Tue, 6 Dec 2016 17:17:50 -0500 Received: from mail-bn3nam01on0099.outbound.protection.outlook.com ([104.47.33.99]:15924 "EHLO NAM01-BN3-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1751618AbcLFWRs (ORCPT ); Tue, 6 Dec 2016 17:17:48 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=bfawo6uwQ1Fv+iM72EL/I/rk8lX+x1aGNHtNEqdsCdM=; b=iCOV+o4xURTQDMviA3xwShbBLwNd+2Mfz0cQTZL5eVrSS5IamyO/Gu857TpoSltdCyfmgSQ5E5qJy+j8Wx+QU6TlC7DsARLcSNlnXOyIGIyaxiastHyBeFQ3ycxxZhCv9ztvs/w+2qeIOsGsz2LGkigkRngk9u3toW91WMz+/VU= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=pshilov@microsoft.com; Received: from ubuntu-vm.corp.microsoft.com (2001:4898:80e8:2::63b) by CY4PR03MB2549.namprd03.prod.outlook.com (10.173.41.148) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384) id 15.1.761.9; Tue, 6 Dec 2016 22:02:48 +0000 From: Pavel Shilovsky To: linux-cifs@vger.kernel.org Subject: [PATCH 07/15] CIFS: Add capability to transform requests before sending Date: Tue, 6 Dec 2016 14:02:30 -0800 Message-Id: <1481061758-52020-8-git-send-email-pshilov@microsoft.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1481061758-52020-1-git-send-email-pshilov@microsoft.com> References: <1481061758-52020-1-git-send-email-pshilov@microsoft.com> MIME-Version: 1.0 X-Originating-IP: [2001:4898:80e8:2::63b] X-ClientProxiedBy: CY1PR17CA0004.namprd17.prod.outlook.com (10.163.68.14) To CY4PR03MB2549.namprd03.prod.outlook.com (10.173.41.148) X-MS-Office365-Filtering-Correlation-Id: e58d172a-9c11-4c99-5098-08d41e239da7 X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(22001); SRVR:CY4PR03MB2549; X-Microsoft-Exchange-Diagnostics: 1; CY4PR03MB2549; 3:HWiVPf34wMwugaLqKNwYrz9sfzxt02twHNKddq/7bv3oSC39EQZtDYluNO81YbZOU5eKJXG9P4RsSreceSFAgc6e+OQs8xuQ2FGU0Xj6u1soz110Cja7x8fWrk+kcak4VTUiqX4ei7G7iogVMgPxc2dJIyiaSs8fxX3TKhW8PaNJsZYEdyywZtAB0w9As1NeSg0gCuZDhMXztyJ8ocn2fl4VAKUgxKPCjdhAEnYCMXzblsjr+wcNfLXLmmFFO5YRKEfZKxf0P6RRxG5hf+o+EQ== X-Microsoft-Exchange-Diagnostics: 1; CY4PR03MB2549; 25:hBzgaqOi9Cv2T0R5+FJhA9jN5XlCgmRV8RstuHT4WFiRINvSosg61YCTnoIqlcGHB1d6N7Z0seV0/dKMOSvxzjMjao1Y2H66yV+TtcSWKppB32gXK1M7w9djls/7CMdmLOv7VpLp7atj9CFsfo3FSLaA63tjW2amibPIskfvqLzU69txc5yEOyyYezj56UKHE76UP+knwtL3aOHdqH15KmcfKyfhzDvn+eSSuUXu12X6nkmznjBNaLdfYC++z1fSLzvZW7cqULXBV7eiEHnp7629YMtdAVTCAz2xdHGCPC3gQC57ev4RxiBYNBZVjmQzFaJlv+6nQIRFbBDBvNC1y3ZQHl9AI/0YQt8n85c2414v8vyZgUkBOLkvfC9CQ1O+KGhyHv7X1VGiLpKDpQtULncej6pIFUQbPJtlcw7MiNZfn77IlK8Xc230VPBwvdGCN5QgfqIzkuAjgcWuiTL9ZhUBGsgpsSwdWbAMSEXoOE7F8XAl2VbHriFUAhltjjcQKZ+ZZLfr7Kz0eWjnZO81hNDch0SsZhet1GvbSasRbObJxP1qCSn+ANmkzHR0UVuJUJ9OqNMYcyqm/hJm+F2xss83dhAuNWxKvPoTeEqdBk20T38ZlYRTtM1VdaTzgiH3ThSFIQVsbTKo5n9H930/W/Fz7CnBjrUAK5/bi6ZHmxWbjo0MV+yYiJE11pEahDUT4sZQJbxvzmjNyQN1DC8cmfGWBIF0a2ElFpOa8okLtGcRBx58fSGKu0PBIip3eHTY+Tix1six+2/saJflajXyIfss3tqCWrllwc0JAUv1QKu9/idc4VTHdJTqm6TJMnjQ X-Microsoft-Exchange-Diagnostics: 1; CY4PR03MB2549; 31:zdYIpCBhO11Jt22MH9LVqsdQVpdtnSNg3/Poy5faiHnTowFnt47ePrObF1MexMopytyNDwd1AxiAq2/FGMy/aRZ3VRyIn8+bSuESkRJ19D0dEsEJhmQq3NIdq0+HgEDU5kGLZWuLPop9YoJvTJigk0iQsPjbBkOWhK4GoZbjt8O2H3rwsUYQ7EXa6uoT6qY3VGy6XqQMVqRs7+jjlbh+l7wJ5jmrWaxhRNDEzPytNwoViP7yfP2uoZNnxH3uyo6C7XJpKBPsuQbWQV0CfUoOZ5ABkNO6JNu/hvYnONkqBH8=; 20:RpDZx+P+12a++O2JQxURG8tf12/2P38nYsV0N5PdE61DnST8EYQveew+KtSXuDh30e2oRLM4Kd+EYLqMPi3wXP/YlQ7lZdyTB20IM/H/opB1ergbtBLnl4HW/19fqe0+sUdqsi8R91HbX7sQuWET0+FTUmArlZOG7LH0eAXZdXZoUj5KJnPGayoiu4ESz6Q8qZaHh2L35vQ2al5fW8qvlyBRJtDLJsPfbuV8liB2aoMBxEakzOdsmHFD2f/GEdhZnmCi5e/O8T56hbaqOG0swq370GAviq5KZHpoRhRe4Tw251rFDahm++AftE9W4MzASKs9zVUZxZPaYmfn63Cj2oWCD+K70cZOwqfeRWT4NxNWZUC1R8DZ2x5MmG5BkqyG0Uy+wFqO8aIh9hxZ1S8Yip7w2xpXsR6JtGeuKYxp/XE/zBxb0W9xFuT5TulqiYctgv7/xAWpTxwAv6HRKFxuQTakfuVDxi4oSpYLdul9KpXAjROdocHwTjim24U80esX X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(158342451672863)(192374486261705); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(6040375)(601004)(2401047)(5005006)(8121501046)(3002001)(10201501046)(6055026)(6041248)(20161123560025)(20161123562025)(20161123564025)(20161123555025)(6047074)(6072148); SRVR:CY4PR03MB2549; BCL:0; PCL:0; RULEID:; SRVR:CY4PR03MB2549; X-Microsoft-Exchange-Diagnostics: 1; CY4PR03MB2549; 4:EzHhjZug4rlQX3bq8ozYiFFUZhLUdne+AqAkH3freCP6A1WGEg3BrxaZNsAvKSrz8id7xtgC/Ds2X8e5o54iII0oPWJ0wzjtrJvAV/Bnj+PFIwPbbss90KPivVT62QE5uQTotvYLJP/LPWftAxrMymQBii4GLU7kFW70/p3JXAmbfhyfEJeCj5G/kUrPKKFoP6/XD30lqC3ayXs9nd+ixfVO9pYALOxz6heFRVhZBaR8Hdoiu47OZutk0hkDjhbw017ndPWTw/wiWFgDpqCaYCNXH7/AkB+V2sQmIOhyT9nAuYk43GBe/OdG4IkbbAuAN67W423QScKrQ8f/Er7qYBHCD75P84P++x55gbAOWC0GRyyWSfaARJsWrNJNog/azqPpa7Yv/mgyQTgr1v0UnjxbfO6LKq4X5Xsl+hE212iyr3OIgsRwk7KH/GBBcXNVbBRrsQqATGq1LRcllN+Fd/NSh7aVphHQijv24JSOJeGpeTFznuwgj6e1p7TPO9HFuXlwMlM6SAvI/2SIUMQ4tBO37XtQQZyr+zsq7RSfOz++zjOXln9LO+WNKhHfY0WW0mUeAPAPcXr8hqE3WwwDpj7vdSau6Xe2TlAeTM/ulrFZWvzevIPmtXQfgkqEgLv3q6VlzkdqbXfGyIDobTLo9+29ANEfb2JOV8FfIe1lSVVguULJdRQtZTtMwBqybHEf X-Forefront-PRVS: 01480965DA X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10019020)(4630300001)(6009001)(7916002)(69234005)(199003)(189002)(50466002)(92566002)(101416001)(86362001)(33646002)(47776003)(48376002)(2950100002)(6916009)(106356001)(105586002)(6666003)(50986999)(42186005)(39860400001)(39850400001)(39840400001)(86612001)(76176999)(2361001)(110136003)(2351001)(450100001)(189998001)(5660300001)(10090500001)(5003940100001)(10290500002)(38730400001)(5005710100001)(8676002)(6116002)(36756003)(107886002)(39410400001)(733004)(7846002)(2906002)(39450400002)(6486002)(7736002)(50226002)(68736007)(305945005)(81156014)(97736004)(81166006); DIR:OUT; SFP:1102; SCL:1; SRVR:CY4PR03MB2549; H:ubuntu-vm.corp.microsoft.com; FPR:; SPF:None; PTR:InfoNoRecords; A:1; MX:1; LANG:en; Received-SPF: None (protection.outlook.com: microsoft.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; CY4PR03MB2549; 23:ioxflNUZKrzFWH1nRoDgbnzzVd0rhyoO7QVL3R5pU?= =?us-ascii?Q?oo9aH2PhiZL9OSNsIO6+d1Z4cHDX8UEF3IehABQvnB3ve8qrskNMeTRL/78v?= =?us-ascii?Q?F+JAIN2msdO6s+zRQROKTCyMn+fUHWqSPMdj5wLrrhIu9tzSN5Q3I+ReYN9s?= =?us-ascii?Q?sD8fEsYE3ytweoUDDf2rcJIQ9jv8d3557x/PN+ycuAUrad3sl7uLGJPKxom5?= =?us-ascii?Q?7z2Uc4Ohks2ThdctifCgbAoS4InqR+77GgWLIzXYniQdYinqEWjpb5KZEnl7?= =?us-ascii?Q?BuMY7uk3o6YuusNdgoug4ajiYdzjfebq4TMaWsLpS4NL6K6eptu+y/mJvM9p?= =?us-ascii?Q?4FmWh4UfvlPqjjoQbe+HFW4G5ZIqln9KnqDGjtjc+DVG1Hrscs0sGKJftdhO?= =?us-ascii?Q?HU7GDfVz46kWoOlCw09KSFbZ+pboD0fLz2b5hpS/oknT0hiUMr/daufscacq?= =?us-ascii?Q?rRA+hMdKOcH2MoNlYg9DSLG6/PYdTNUh8RAxsn4pZdy6/wxT02VWV6sLfzAX?= =?us-ascii?Q?Jy7+i78zgIBwOWTuxNSwADLcLoIhVGjY0z+6b7G1wQdx88Z/HzFAUNAyVG0Z?= =?us-ascii?Q?HHhe96TvaxQuPPkqTQcjHhB2htkaF8nkzBf3rfFp+AF0zuP9TZIT8kJGar4I?= =?us-ascii?Q?EJphoSCA459EROpyYpfAT9ccl4LfLIr/k8hTNAGdJqfN6GOP6MR6Mj6eY6Xq?= =?us-ascii?Q?qOmo94Jyu+mvxP2qYMXP57Oa4hXOWQnNy9ympQ0hTmDWpas8Dczxmj4D2kDG?= =?us-ascii?Q?qqJsp+uizGhuo7LCUoyHMby/kxLz1dzTaolUUeL9hqnUBFw4GZD4UpV3lvxJ?= =?us-ascii?Q?i8/Les4s2Yk204UWFu7yWwZQ7ew53bpguoaF51NcIE2nfL0ovqSkXwCo9gDK?= =?us-ascii?Q?NisWl3WU90yffb0Mk66lMItmVlvN84crhSH6KqJFiuOGOvpXxNEGies4VoiK?= =?us-ascii?Q?TNfLdzMRgAZC71MZ0AL6HJk1j0973vwaaieYKJKO+tqsUuagZ5+HG8zxd/N4?= =?us-ascii?Q?NLoyCNEDdau6Vx1hYa1IVaPlsiderDrbOhC8uAwFGNR55WwAQyr7yPFLoYfy?= =?us-ascii?Q?E1HkxG5ivfDVVjrSEGtzEeul7+cQUVDDWhqryweh3BYrrGWAszG+oW5/N6/R?= =?us-ascii?Q?i2cvj4G7nAKKFA/40h0762UcO4l9j+TIWeKLuq09p4WaJC2yen+ax86Agm0o?= =?us-ascii?Q?Fw6hbb+jXYpX5uE3Eq0lbxao3EycQAZ1pqvI7qJbSoDAJQS9DhEyArzOdHvW?= =?us-ascii?Q?lRbWOohR1f0FOkajpvsi8A3lGHNrKwDPzmnDX91DGzdHd4yBTea4sKRHz/bt?= =?us-ascii?Q?KsY8q8PcfJxckn+CplJ3fA=3D?= X-Microsoft-Exchange-Diagnostics: 1; CY4PR03MB2549; 6:/EQ8QUqYrYPeLVpLiypGINuAxkkQ0Q/WDIDeya/rjOa8mRjNowH095ejdVvU1AZ132Fw0KEu6Qdq7mu3tT7RvvV8Rbtob3PfCcfcafF5TqXjJ+eqfwjWZPualRzBNxgRiR7488O+pFMXZiFXjwKP6hcNSvbdAlHhlIErdUXepBzxPzsmX6yBfVPc/lYxzKoywJT8EdVHwMjh9Mn0tjZWJZeFyjeU/l5AvzmgzWr+dfnkK8cAln7JfPmAjfQYe1D8aFEMbjlKJ89MjuF2BkOE/w+Wbheorb/URWmztXCzYjIvlybzq2SqFnmM2PwO4e9BA9TN81h+VrtllIPWDl9dmuj8d1ePkhRMJmpbIsj7znvpmKWtOqWq/8Dud2wd3pdqVIp/ZKlQUivH33fdkQEVuC1fKUJlBmUxWp0AaVGwththBtkN7tYUWAhOAikW4/Mxzp+aJem1fcDexl8OMg7YmQ==; 5:dbpwGFkr32qsjq6gsrO4M9TY7/7RDB8kArYfD20gBv1HCFScG/4U3sCKBZKEY9G3sa57us2KCIJApCWWGEjLOguKhxZ0v7vwPvd8MLvc+WZLYC0hsHCuyCNqdIze4VmytmOk2KSYIg8rgfheyBvguncrA0uK60sAsqEpukhEiTY=; 24:lD6aHCc4lhWDS+lcKXdQRX4SRt2N8mkbLTMUPrXBgu9pZjOSMBhnfTa7oqESWM8+sUjF/mjXyc3W/EChq5kXAV45TAdjblJtmEuscTAwMrs= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; CY4PR03MB2549; 7:7sjbQQKL07BWNJaNVMrEZ/2d1hEPPBDeFTilOAMRt8tQuXOEzR38Nfg/ClClsohGrvKOEIJ8Rt5EIlElyil89sKbefzrJ8OoMAzmyT6+iBVarUYdMSigUvamhOaCrXVMKYByAh7cHUgAcl5GfQOSxnhAcsP9nK2hhL6LIVRlclThSoj2bzhqmQ29ej3PQmMaCKcCLl3YoFAVXXZ5Ir9fL5v3nVRqRzR/NpqykIZIPEuM3Vx6S+Zu8ng3QvJH3JL9fzE6w6AH2DvVzxnruSVn0Mavkv6Y9Bb3AvlYWB4P5Yw8hbxDE2w1YHfVyFvzGkaTTInrlesyLOA9QMFZJpKGawrRMYkdAgmnZ8O5RQuM3Zy4ZZsdwrMqTl46pXvbIouF7vcdnw6JKTi1beKcd6mzoppXBdB6GlErf3wlvd49FwzEWM1iWTZaE+2B3onJdSyFA9p4FX1eJN6jO6ehYolY8g== X-OriginatorOrg: microsoft.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 06 Dec 2016 22:02:48.2868 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: CY4PR03MB2549 Sender: linux-cifs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This will allow us to do protocol specific tranformations of packets before sending to the server. For SMB3 it can be used to support encryption. Signed-off-by: Pavel Shilovsky --- fs/cifs/cifsglob.h | 7 +++ fs/cifs/smb2pdu.c | 129 ++++++++++++++++++++++++++++++++++++++++++---------- fs/cifs/transport.c | 33 ++++++++++---- 3 files changed, 136 insertions(+), 33 deletions(-) diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 5a89875..8ec9e1a 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -433,6 +433,11 @@ struct smb_version_operations { bool (*dir_needs_close)(struct cifsFileInfo *); long (*fallocate)(struct file *, struct cifs_tcon *, int, loff_t, loff_t); + /* init transform request - used for encryption for now */ + int (*init_transform_rq)(struct TCP_Server_Info *, struct smb_rqst *, + struct smb_rqst *); + /* free transform request */ + void (*free_transform_rq)(struct smb_rqst *); }; struct smb_version_values { @@ -1473,7 +1478,9 @@ static inline void free_dfs_info_array(struct dfs_info3_param *param, #define CIFS_OBREAK_OP 0x0100 /* oplock break request */ #define CIFS_NEG_OP 0x0200 /* negotiate request */ #define CIFS_OP_MASK 0x0380 /* mask request type */ + #define CIFS_HAS_CREDITS 0x0400 /* already has credits */ +#define CIFS_TRANSFORM_REQ 0x0800 /* transform request before sending */ /* Security Flags: indicate type of session setup needed */ #define CIFSSEC_MAY_SIGN 0x00001 diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index d1a9037..bf5b693 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c @@ -77,6 +77,13 @@ static const int smb2_req_struct_sizes[NUMBER_OF_SMB2_COMMANDS] = { /* SMB2_OPLOCK_BREAK */ 24 /* BB this is 36 for LEASE_BREAK variant */ }; +static int encryption_required(const struct cifs_tcon *tcon) +{ + if ((tcon->ses->session_flags & SMB2_SESSION_FLAG_ENCRYPT_DATA) || + (tcon->share_flags & SHI1005_FLAGS_ENCRYPT_DATA)) + return 1; + return 0; +} static void smb2_hdr_assemble(struct smb2_sync_hdr *shdr, __le16 smb2_cmd, @@ -130,7 +137,8 @@ smb2_hdr_assemble(struct smb2_sync_hdr *shdr, __le16 smb2_cmd, /* if (tcon->share_flags & SHI1005_FLAGS_DFS) shdr->Flags |= SMB2_FLAGS_DFS_OPERATIONS; */ - if (tcon->ses && tcon->ses->server && tcon->ses->server->sign) + if (tcon->ses && tcon->ses->server && tcon->ses->server->sign && + !encryption_required(tcon)) shdr->Flags |= SMB2_FLAGS_SIGNED; out: return; @@ -423,7 +431,6 @@ static void assemble_neg_contexts(struct smb2_negotiate_req *req) } #endif /* SMB311 */ - /* * * SMB2 Worker functions follow: @@ -1070,6 +1077,7 @@ SMB2_logoff(const unsigned int xid, struct cifs_ses *ses) struct smb2_logoff_req *req; /* response is also trivial struct */ int rc = 0; struct TCP_Server_Info *server; + int flags = 0; cifs_dbg(FYI, "disconnect session %p\n", ses); @@ -1088,10 +1096,13 @@ SMB2_logoff(const unsigned int xid, struct cifs_ses *ses) /* since no tcon, smb2_init can not do this, so do here */ req->hdr.sync_hdr.SessionId = ses->Suid; - if (server->sign) + + if (ses->session_flags & SMB2_SESSION_FLAG_ENCRYPT_DATA) + flags |= CIFS_TRANSFORM_REQ; + else if (server->sign) req->hdr.sync_hdr.Flags |= SMB2_FLAGS_SIGNED; - rc = SendReceiveNoRsp(xid, ses, (char *) req, 0); + rc = SendReceiveNoRsp(xid, ses, (char *) req, flags); cifs_small_buf_release(req); /* * No tcon so can't do @@ -1130,6 +1141,7 @@ SMB2_tcon(const unsigned int xid, struct cifs_ses *ses, const char *tree, int unc_path_len; struct TCP_Server_Info *server; __le16 *unc_path = NULL; + int flags = 0; cifs_dbg(FYI, "TCON\n"); @@ -1164,6 +1176,9 @@ SMB2_tcon(const unsigned int xid, struct cifs_ses *ses, const char *tree, return rc; } + if (ses->session_flags & SMB2_SESSION_FLAG_ENCRYPT_DATA) + flags |= CIFS_TRANSFORM_REQ; + if (tcon == NULL) { /* since no tcon, smb2_init can not do this, so do here */ req->hdr.sync_hdr.SessionId = ses->Suid; @@ -1184,7 +1199,7 @@ SMB2_tcon(const unsigned int xid, struct cifs_ses *ses, const char *tree, inc_rfc1001_len(req, unc_path_len - 1 /* pad */); - rc = SendReceive2(xid, ses, iov, 2, &resp_buftype, 0, &rsp_iov); + rc = SendReceive2(xid, ses, iov, 2, &resp_buftype, flags, &rsp_iov); cifs_small_buf_release(req); rsp = (struct smb2_tree_connect_rsp *)rsp_iov.iov_base; @@ -1252,6 +1267,7 @@ SMB2_tdis(const unsigned int xid, struct cifs_tcon *tcon) int rc = 0; struct TCP_Server_Info *server; struct cifs_ses *ses = tcon->ses; + int flags = 0; cifs_dbg(FYI, "Tree Disconnect\n"); @@ -1267,7 +1283,10 @@ SMB2_tdis(const unsigned int xid, struct cifs_tcon *tcon) if (rc) return rc; - rc = SendReceiveNoRsp(xid, ses, (char *)req, 0); + if (encryption_required(tcon)) + flags |= CIFS_TRANSFORM_REQ; + + rc = SendReceiveNoRsp(xid, ses, (char *)req, flags); cifs_small_buf_release(req); if (rc) cifs_stats_fail_inc(tcon, SMB2_TREE_DISCONNECT_HE); @@ -1539,6 +1558,7 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path, unsigned int n_iov = 2; __u32 file_attributes = 0; char *dhc_buf = NULL, *lc_buf = NULL; + int flags = 0; cifs_dbg(FYI, "create/open\n"); @@ -1551,6 +1571,9 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path, if (rc) return rc; + if (encryption_required(tcon)) + flags |= CIFS_TRANSFORM_REQ; + if (oparms->create_options & CREATE_OPTION_READONLY) file_attributes |= ATTR_READONLY; if (oparms->create_options & CREATE_OPTION_SPECIAL) @@ -1630,7 +1653,7 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path, dhc_buf = iov[n_iov-1].iov_base; } - rc = SendReceive2(xid, ses, iov, n_iov, &resp_buftype, 0, &rsp_iov); + rc = SendReceive2(xid, ses, iov, n_iov, &resp_buftype, flags, &rsp_iov); cifs_small_buf_release(req); rsp = (struct smb2_create_rsp *)rsp_iov.iov_base; @@ -1684,6 +1707,7 @@ SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid, int resp_buftype; int n_iov; int rc = 0; + int flags = 0; cifs_dbg(FYI, "SMB2 IOCTL\n"); @@ -1708,6 +1732,9 @@ SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid, if (rc) return rc; + if (encryption_required(tcon)) + flags |= CIFS_TRANSFORM_REQ; + req->CtlCode = cpu_to_le32(opcode); req->PersistentFileId = persistent_fid; req->VolatileFileId = volatile_fid; @@ -1758,7 +1785,7 @@ SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid, iov[0].iov_len = get_rfc1002_length(req) + 4; - rc = SendReceive2(xid, ses, iov, n_iov, &resp_buftype, 0, &rsp_iov); + rc = SendReceive2(xid, ses, iov, n_iov, &resp_buftype, flags, &rsp_iov); cifs_small_buf_release(req); rsp = (struct smb2_ioctl_rsp *)rsp_iov.iov_base; @@ -1847,6 +1874,7 @@ SMB2_close(const unsigned int xid, struct cifs_tcon *tcon, struct kvec rsp_iov; int resp_buftype; int rc = 0; + int flags = 0; cifs_dbg(FYI, "Close\n"); @@ -1859,6 +1887,9 @@ SMB2_close(const unsigned int xid, struct cifs_tcon *tcon, if (rc) return rc; + if (encryption_required(tcon)) + flags |= CIFS_TRANSFORM_REQ; + req->PersistentFileId = persistent_fid; req->VolatileFileId = volatile_fid; @@ -1866,7 +1897,7 @@ SMB2_close(const unsigned int xid, struct cifs_tcon *tcon, /* 4 for rfc1002 length field */ iov[0].iov_len = get_rfc1002_length(req) + 4; - rc = SendReceive2(xid, ses, iov, 1, &resp_buftype, 0, &rsp_iov); + rc = SendReceive2(xid, ses, iov, 1, &resp_buftype, flags, &rsp_iov); cifs_small_buf_release(req); rsp = (struct smb2_close_rsp *)rsp_iov.iov_base; @@ -1952,6 +1983,7 @@ query_info(const unsigned int xid, struct cifs_tcon *tcon, int resp_buftype; struct TCP_Server_Info *server; struct cifs_ses *ses = tcon->ses; + int flags = 0; cifs_dbg(FYI, "Query Info\n"); @@ -1964,6 +1996,9 @@ query_info(const unsigned int xid, struct cifs_tcon *tcon, if (rc) return rc; + if (encryption_required(tcon)) + flags |= CIFS_TRANSFORM_REQ; + req->InfoType = SMB2_O_INFO_FILE; req->FileInfoClass = info_class; req->PersistentFileId = persistent_fid; @@ -1977,7 +2012,7 @@ query_info(const unsigned int xid, struct cifs_tcon *tcon, /* 4 for rfc1002 length field */ iov[0].iov_len = get_rfc1002_length(req) + 4; - rc = SendReceive2(xid, ses, iov, 1, &resp_buftype, 0, &rsp_iov); + rc = SendReceive2(xid, ses, iov, 1, &resp_buftype, flags, &rsp_iov); cifs_small_buf_release(req); rsp = (struct smb2_query_info_rsp *)rsp_iov.iov_base; @@ -2137,6 +2172,7 @@ SMB2_flush(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid, struct kvec rsp_iov; int resp_buftype; int rc = 0; + int flags = 0; cifs_dbg(FYI, "Flush\n"); @@ -2149,6 +2185,9 @@ SMB2_flush(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid, if (rc) return rc; + if (encryption_required(tcon)) + flags |= CIFS_TRANSFORM_REQ; + req->PersistentFileId = persistent_fid; req->VolatileFileId = volatile_fid; @@ -2156,7 +2195,7 @@ SMB2_flush(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid, /* 4 for rfc1002 length field */ iov[0].iov_len = get_rfc1002_length(req) + 4; - rc = SendReceive2(xid, ses, iov, 1, &resp_buftype, 0, &rsp_iov); + rc = SendReceive2(xid, ses, iov, 1, &resp_buftype, flags, &rsp_iov); cifs_small_buf_release(req); if (rc != 0) @@ -2326,6 +2365,9 @@ smb2_async_readv(struct cifs_readdata *rdata) return rc; } + if (encryption_required(io_parms.tcon)) + flags |= CIFS_TRANSFORM_REQ; + req_len = cpu_to_be32(total_len); rdata->iov[0].iov_base = &req_len; @@ -2344,7 +2386,7 @@ smb2_async_readv(struct cifs_readdata *rdata) le16_to_cpu(shdr->CreditCharge); spin_unlock(&server->req_lock); wake_up(&server->request_q); - flags = CIFS_HAS_CREDITS; + flags |= CIFS_HAS_CREDITS; } kref_get(&rdata->refcount); @@ -2374,12 +2416,17 @@ SMB2_read(const unsigned int xid, struct cifs_io_parms *io_parms, __be32 req_len; struct smb_rqst rqst = { .rq_iov = iov, .rq_nvec = 2 }; + int flags = CIFS_LOG_ERROR; + struct cifs_ses *ses = io_parms->tcon->ses; *nbytes = 0; rc = smb2_new_read_req((void **)&req, &total_len, io_parms, 0, 0); if (rc) return rc; + if (encryption_required(io_parms->tcon)) + flags |= CIFS_TRANSFORM_REQ; + req_len = cpu_to_be32(total_len); iov[0].iov_base = &req_len; @@ -2387,8 +2434,7 @@ SMB2_read(const unsigned int xid, struct cifs_io_parms *io_parms, iov[1].iov_base = req; iov[1].iov_len = total_len; - rc = cifs_send_recv(xid, io_parms->tcon->ses, &rqst, &resp_buftype, - CIFS_LOG_ERROR, &rsp_iov); + rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, &rsp_iov); cifs_small_buf_release(req); rsp = (struct smb2_read_rsp *)rsp_iov.iov_base; @@ -2507,6 +2553,9 @@ smb2_async_writev(struct cifs_writedata *wdata, goto async_writev_out; } + if (encryption_required(tcon)) + flags |= CIFS_TRANSFORM_REQ; + shdr = get_sync_hdr(req); shdr->ProcessId = cpu_to_le32(wdata->cfile->pid); @@ -2550,7 +2599,7 @@ smb2_async_writev(struct cifs_writedata *wdata, le16_to_cpu(shdr->CreditCharge); spin_unlock(&server->req_lock); wake_up(&server->request_q); - flags = CIFS_HAS_CREDITS; + flags |= CIFS_HAS_CREDITS; } kref_get(&wdata->refcount); @@ -2582,6 +2631,7 @@ SMB2_write(const unsigned int xid, struct cifs_io_parms *io_parms, struct smb2_write_rsp *rsp = NULL; int resp_buftype; struct kvec rsp_iov; + int flags = 0; *nbytes = 0; @@ -2595,6 +2645,9 @@ SMB2_write(const unsigned int xid, struct cifs_io_parms *io_parms, if (io_parms->tcon->ses->server == NULL) return -ECONNABORTED; + if (encryption_required(io_parms->tcon)) + flags |= CIFS_TRANSFORM_REQ; + req->hdr.sync_hdr.ProcessId = cpu_to_le32(io_parms->pid); req->PersistentFileId = io_parms->persistent_fid; @@ -2617,7 +2670,7 @@ SMB2_write(const unsigned int xid, struct cifs_io_parms *io_parms, inc_rfc1001_len(req, io_parms->length - 1 /* Buffer */); rc = SendReceive2(xid, io_parms->tcon->ses, iov, n_vec + 1, - &resp_buftype, 0, &rsp_iov); + &resp_buftype, flags, &rsp_iov); cifs_small_buf_release(req); rsp = (struct smb2_write_rsp *)rsp_iov.iov_base; @@ -2693,6 +2746,7 @@ SMB2_query_directory(const unsigned int xid, struct cifs_tcon *tcon, char *end_of_smb; unsigned int output_size = CIFSMaxBufSize; size_t info_buf_size; + int flags = 0; if (ses && (ses->server)) server = ses->server; @@ -2703,6 +2757,9 @@ SMB2_query_directory(const unsigned int xid, struct cifs_tcon *tcon, if (rc) return rc; + if (encryption_required(tcon)) + flags |= CIFS_TRANSFORM_REQ; + switch (srch_inf->info_level) { case SMB_FIND_FILE_DIRECTORY_INFO: req->FileInformationClass = FILE_DIRECTORY_INFORMATION; @@ -2747,7 +2804,7 @@ SMB2_query_directory(const unsigned int xid, struct cifs_tcon *tcon, inc_rfc1001_len(req, len - 1 /* Buffer */); - rc = SendReceive2(xid, ses, iov, 2, &resp_buftype, 0, &rsp_iov); + rc = SendReceive2(xid, ses, iov, 2, &resp_buftype, flags, &rsp_iov); cifs_small_buf_release(req); rsp = (struct smb2_query_directory_rsp *)rsp_iov.iov_base; @@ -2815,6 +2872,7 @@ send_set_info(const unsigned int xid, struct cifs_tcon *tcon, unsigned int i; struct TCP_Server_Info *server; struct cifs_ses *ses = tcon->ses; + int flags = 0; if (ses && (ses->server)) server = ses->server; @@ -2834,6 +2892,9 @@ send_set_info(const unsigned int xid, struct cifs_tcon *tcon, return rc; } + if (encryption_required(tcon)) + flags |= CIFS_TRANSFORM_REQ; + req->hdr.sync_hdr.ProcessId = cpu_to_le32(pid); req->InfoType = SMB2_O_INFO_FILE; @@ -2861,7 +2922,7 @@ send_set_info(const unsigned int xid, struct cifs_tcon *tcon, iov[i].iov_len = size[i]; } - rc = SendReceive2(xid, ses, iov, num, &resp_buftype, 0, &rsp_iov); + rc = SendReceive2(xid, ses, iov, num, &resp_buftype, flags, &rsp_iov); cifs_small_buf_release(req); rsp = (struct smb2_set_info_rsp *)rsp_iov.iov_base; @@ -2991,19 +3052,22 @@ SMB2_oplock_break(const unsigned int xid, struct cifs_tcon *tcon, { int rc; struct smb2_oplock_break *req = NULL; + int flags = CIFS_OBREAK_OP; cifs_dbg(FYI, "SMB2_oplock_break\n"); rc = small_smb2_init(SMB2_OPLOCK_BREAK, tcon, (void **) &req); - if (rc) return rc; + if (encryption_required(tcon)) + flags |= CIFS_TRANSFORM_REQ; + req->VolatileFid = volatile_fid; req->PersistentFid = persistent_fid; req->OplockLevel = oplock_level; req->hdr.sync_hdr.CreditRequest = cpu_to_le16(1); - rc = SendReceiveNoRsp(xid, tcon->ses, (char *) req, CIFS_OBREAK_OP); + rc = SendReceiveNoRsp(xid, tcon->ses, (char *) req, flags); cifs_small_buf_release(req); if (rc) { @@ -3069,6 +3133,7 @@ SMB2_QFS_info(const unsigned int xid, struct cifs_tcon *tcon, int resp_buftype; struct cifs_ses *ses = tcon->ses; struct smb2_fs_full_size_info *info = NULL; + int flags = 0; rc = build_qfs_info_req(&iov, tcon, FS_FULL_SIZE_INFORMATION, sizeof(struct smb2_fs_full_size_info), @@ -3076,7 +3141,10 @@ SMB2_QFS_info(const unsigned int xid, struct cifs_tcon *tcon, if (rc) return rc; - rc = SendReceive2(xid, ses, &iov, 1, &resp_buftype, 0, &rsp_iov); + if (encryption_required(tcon)) + flags |= CIFS_TRANSFORM_REQ; + + rc = SendReceive2(xid, ses, &iov, 1, &resp_buftype, flags, &rsp_iov); cifs_small_buf_release(iov.iov_base); if (rc) { cifs_stats_fail_inc(tcon, SMB2_QUERY_INFO_HE); @@ -3108,6 +3176,7 @@ SMB2_QFS_attr(const unsigned int xid, struct cifs_tcon *tcon, int resp_buftype, max_len, min_len; struct cifs_ses *ses = tcon->ses; unsigned int rsp_len, offset; + int flags = 0; if (level == FS_DEVICE_INFORMATION) { max_len = sizeof(FILE_SYSTEM_DEVICE_INFO); @@ -3128,7 +3197,10 @@ SMB2_QFS_attr(const unsigned int xid, struct cifs_tcon *tcon, if (rc) return rc; - rc = SendReceive2(xid, ses, &iov, 1, &resp_buftype, 0, &rsp_iov); + if (encryption_required(tcon)) + flags |= CIFS_TRANSFORM_REQ; + + rc = SendReceive2(xid, ses, &iov, 1, &resp_buftype, flags, &rsp_iov); cifs_small_buf_release(iov.iov_base); if (rc) { cifs_stats_fail_inc(tcon, SMB2_QUERY_INFO_HE); @@ -3173,6 +3245,7 @@ smb2_lockv(const unsigned int xid, struct cifs_tcon *tcon, struct kvec rsp_iov; int resp_buf_type; unsigned int count; + int flags = CIFS_NO_RESP; cifs_dbg(FYI, "smb2_lockv num lock %d\n", num_lock); @@ -3180,6 +3253,9 @@ smb2_lockv(const unsigned int xid, struct cifs_tcon *tcon, if (rc) return rc; + if (encryption_required(tcon)) + flags |= CIFS_TRANSFORM_REQ; + req->hdr.sync_hdr.ProcessId = cpu_to_le32(pid); req->LockCount = cpu_to_le16(num_lock); @@ -3196,7 +3272,7 @@ smb2_lockv(const unsigned int xid, struct cifs_tcon *tcon, iov[1].iov_len = count; cifs_stats_inc(&tcon->stats.cifs_stats.num_locks); - rc = SendReceive2(xid, tcon->ses, iov, 2, &resp_buf_type, CIFS_NO_RESP, + rc = SendReceive2(xid, tcon->ses, iov, 2, &resp_buf_type, flags, &rsp_iov); cifs_small_buf_release(req); if (rc) { @@ -3230,13 +3306,16 @@ SMB2_lease_break(const unsigned int xid, struct cifs_tcon *tcon, { int rc; struct smb2_lease_ack *req = NULL; + int flags = CIFS_OBREAK_OP; cifs_dbg(FYI, "SMB2_lease_break\n"); rc = small_smb2_init(SMB2_OPLOCK_BREAK, tcon, (void **) &req); - if (rc) return rc; + if (encryption_required(tcon)) + flags |= CIFS_TRANSFORM_REQ; + req->hdr.sync_hdr.CreditRequest = cpu_to_le16(1); req->StructureSize = cpu_to_le16(36); inc_rfc1001_len(req, 12); @@ -3244,7 +3323,7 @@ SMB2_lease_break(const unsigned int xid, struct cifs_tcon *tcon, memcpy(req->LeaseKey, lease_key, 16); req->LeaseState = lease_state; - rc = SendReceiveNoRsp(xid, tcon->ses, (char *) req, CIFS_OBREAK_OP); + rc = SendReceiveNoRsp(xid, tcon->ses, (char *) req, flags); cifs_small_buf_release(req); if (rc) { diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index 713981b2..bc5f55f 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c @@ -220,7 +220,7 @@ rqst_len(struct smb_rqst *rqst) } static int -smb_send_rqst(struct TCP_Server_Info *server, struct smb_rqst *rqst) +__smb_send_rqst(struct TCP_Server_Info *server, struct smb_rqst *rqst) { int rc; struct kvec *iov = rqst->rq_iov; @@ -312,12 +312,27 @@ smb_send_rqst(struct TCP_Server_Info *server, struct smb_rqst *rqst) } static int -smb_sendv(struct TCP_Server_Info *server, struct kvec *iov, int n_vec) +smb_send_rqst(struct TCP_Server_Info *server, struct smb_rqst *rqst, int flags) { - struct smb_rqst rqst = { .rq_iov = iov, - .rq_nvec = n_vec }; + struct smb_rqst cur_rqst; + int rc; + + if (!(flags & CIFS_TRANSFORM_REQ)) + return __smb_send_rqst(server, rqst); + + if (!server->ops->init_transform_rq || + !server->ops->free_transform_rq) { + cifs_dbg(VFS, "Encryption requested but transform callbacks are missed\n"); + return -EIO; + } - return smb_send_rqst(server, &rqst); + rc = server->ops->init_transform_rq(server, &cur_rqst, rqst); + if (rc) + return rc; + + rc = __smb_send_rqst(server, &cur_rqst); + server->ops->free_transform_rq(&cur_rqst); + return rc; } int @@ -325,13 +340,15 @@ smb_send(struct TCP_Server_Info *server, struct smb_hdr *smb_buffer, unsigned int smb_buf_length) { struct kvec iov[2]; + struct smb_rqst rqst = { .rq_iov = iov, + .rq_nvec = 2 }; iov[0].iov_base = smb_buffer; iov[0].iov_len = 4; iov[1].iov_base = (char *)smb_buffer + 4; iov[1].iov_len = smb_buf_length; - return smb_sendv(server, iov, 2); + return __smb_send_rqst(server, &rqst); } static int @@ -523,7 +540,7 @@ cifs_call_async(struct TCP_Server_Info *server, struct smb_rqst *rqst, cifs_in_send_inc(server); - rc = smb_send_rqst(server, rqst); + rc = smb_send_rqst(server, rqst, flags); cifs_in_send_dec(server); cifs_save_when_sent(mid); @@ -717,7 +734,7 @@ cifs_send_recv(const unsigned int xid, struct cifs_ses *ses, midQ->mid_state = MID_REQUEST_SUBMITTED; cifs_in_send_inc(ses->server); - rc = smb_send_rqst(ses->server, rqst); + rc = smb_send_rqst(ses->server, rqst, flags); cifs_in_send_dec(ses->server); cifs_save_when_sent(midQ);