From patchwork Thu Sep 17 19:40:12 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Seiderer X-Patchwork-Id: 7210071 Return-Path: X-Original-To: patchwork-cifs-client@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 92D919F39B for ; Thu, 17 Sep 2015 19:40:34 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 9B35B2077E for ; Thu, 17 Sep 2015 19:40:33 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 77F0F2074B for ; Thu, 17 Sep 2015 19:40:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752010AbbIQTkb (ORCPT ); Thu, 17 Sep 2015 15:40:31 -0400 Received: from mout.gmx.net ([212.227.17.22]:59976 "EHLO mout.gmx.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752009AbbIQTka (ORCPT ); Thu, 17 Sep 2015 15:40:30 -0400 Received: from linux.local ([178.2.24.70]) by mail.gmx.com (mrgmx102) with ESMTPSA (Nemesis) id 0MP1PX-1ZYVlg1s5H-006KV3; Thu, 17 Sep 2015 21:40:15 +0200 From: Peter Seiderer To: linux-kernel@vger.kernel.org Cc: Steve French , linux-cifs@vger.kernel.org, samba-technical@lists.samba.org Subject: [PATCH v1] cifs: use server timestamp for ntlmv2 authentication Date: Thu, 17 Sep 2015 21:40:12 +0200 Message-Id: <1442518812-30494-1-git-send-email-ps.report@gmx.net> X-Mailer: git-send-email 2.1.4 X-Provags-ID: V03:K0:KUyKG60RSKsXK+nTSl4o8rqeL2ej6F4pn4g7jRxxxbK30ezDuf6 V1o3XJw55+RoMnJC1f6QJQQna4oBrrcyBpSWVOSqo/G+FWK1eTkyttc+nQRIKVqGlI1W+fp POqxtzfrZJ6vyuwtfmgEtZOZCHOivfm6I26WkcKebbkhi0xQGqn8fk8bE2PLjPsUO8k2lnW OtSRy7b7NK6XMpb9zpOvQ== X-UI-Out-Filterresults: notjunk:1; V01:K0:YcwnXD92/Yw=:y5JdJFZT6gphfBULeH4KTo pnZ3syWVmL5JyjArNuDIOwOZobPgWNwvu4ATILAk4v4mJzABNySMeSbIR6d+PtxUx4Nw5P2r+ J6KWfiP4fvlyaCM+c/LEdpMu1/mI5CvuGsJQ0UYVgHgmewfKBRSdt0B4UyS85cRJG9ym8zJlG qW+l7GSFMxE/VU2XwQZz6VWDGFdeWoTnaZjmemX6ZKZLOuikR/AFp9VWvjDXth0A8eIH+XU2C jKoAWcE7CSa8T+WmTtA5h2KKJtj7R9N9ytY6PKBwAMx6SDG8MKH2KkxMCx2VnvKAY/0DUfvNR QD6n5WtDSq84yWcNGIATBPmxKAs+1wdruEOE3baNt2PGYmYQx5JtirclAlAJqYVBEW4DaLrB+ CZm6WTLZ/8W7q6faXnm1ZGH4XRTzdlnFLEfvkF9/nR4tHNioXVuYECBNmx8KyHkfhy/EjWWFQ nGjHcMkgZWnuCM/AKx7ui0LvJjJztulzUPrxaBpweC5GgEnt/TNx0NwvMsfD4bzTOnjul/h/E cDGrBN5D85riAKVHwmykw2bwShV3+Ltttm8v1AguRvZRuRgGUt5RUDfwsCBUH2ZHTbTCXSUcO 6YAtF70tktJ9cy4+rI/hZqLs55TXkCkrKAPIymVolVUGGAJE9ktR4qIDlXU9s3wDdqO9OQacB V1lXDHsxBk9hllh1qVPsGa4bWvYgVeHB+zO1Hu6b1pGlE3+K4XNKVuEGnyzV0TlvXgVoNctZI EfQmZ5oVLbMrOIbW Sender: linux-cifs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00,FREEMAIL_FROM, RCVD_IN_DNSWL_HI,T_RP_MATCHES_RCVD,UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Linux cifs mount with ntlmssp against an Mac OS X (Yosemite 10.10.5) share fails in case the clocks differ more than +/-2h: digest-service: digest-request: od failed with 2 proto=ntlmv2 digest-service: digest-request: kdc failed with -1561745592 proto=ntlmv2 Fix this by (re-)using the given server timestamp for the ntlmv2 authentication (as Windows 7 does). Signed-off-by: Peter Seiderer --- fs/cifs/cifsencrypt.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 2 deletions(-) diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c index aa0dc25..e6bfa92 100644 --- a/fs/cifs/cifsencrypt.c +++ b/fs/cifs/cifsencrypt.c @@ -444,6 +444,48 @@ find_domain_name(struct cifs_ses *ses, const struct nls_table *nls_cp) return 0; } +/* Server has provided av pairs/target info in the type 2 challenge + * packet and we have plucked it and stored within smb session. + * We parse that blob here to find the server given timestamp + * as part of ntlmv2 authentication (or local current time as + * default in case of failure) + */ +static u64 +find_timestamp(struct cifs_ses *ses) +{ + unsigned int attrsize; + unsigned int type; + unsigned int onesize = sizeof(struct ntlmssp2_name); + unsigned char *blobptr; + unsigned char *blobend; + struct ntlmssp2_name *attrptr; + + if (!ses->auth_key.len || !ses->auth_key.response) + return 0; + + blobptr = ses->auth_key.response; + blobend = blobptr + ses->auth_key.len; + + while (blobptr + onesize < blobend) { + attrptr = (struct ntlmssp2_name *) blobptr; + type = le16_to_cpu(attrptr->type); + if (type == NTLMSSP_AV_EOL) + break; + blobptr += 2; /* advance attr type */ + attrsize = le16_to_cpu(attrptr->length); + blobptr += 2; /* advance attr size */ + if (blobptr + attrsize > blobend) + break; + if (type == NTLMSSP_AV_TIMESTAMP) { + if (attrsize == sizeof(u64)) + return *((u64 *)blobptr); + } + blobptr += attrsize; /* advance attr value */ + } + + return cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME)); +} + static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash, const struct nls_table *nls_cp) { @@ -641,6 +683,7 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp) struct ntlmv2_resp *ntlmv2; char ntlmv2_hash[16]; unsigned char *tiblob = NULL; /* target info blob */ + u64 rsp_timestamp; if (ses->server->negflavor == CIFS_NEGFLAVOR_EXTENDED) { if (!ses->domainName) { @@ -659,6 +702,12 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp) } } + /* Must be within 5 minutes of the server (or in range +/-2h + * in case of Mac OS X), so simply carry over server timestamp + * (as Windows 7 does) + */ + rsp_timestamp = find_timestamp(ses); + baselen = CIFS_SESS_KEY_SIZE + sizeof(struct ntlmv2_resp); tilen = ses->auth_key.len; tiblob = ses->auth_key.response; @@ -675,8 +724,8 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp) (ses->auth_key.response + CIFS_SESS_KEY_SIZE); ntlmv2->blob_signature = cpu_to_le32(0x00000101); ntlmv2->reserved = 0; - /* Must be within 5 minutes of the server */ - ntlmv2->time = cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME)); + ntlmv2->time = rsp_timestamp; + get_random_bytes(&ntlmv2->client_chal, sizeof(ntlmv2->client_chal)); ntlmv2->reserved2 = 0;