From patchwork Fri Nov 3 17:18:12 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "its_Giaan (Code Review)" X-Patchwork-Id: 3413 Return-Path: Delivered-To: patchwork@openvpn.net Received: by 2002:a05:7300:8e12:b0:f2:62eb:61c1 with SMTP id j18csp1355308dys; Fri, 3 Nov 2023 10:19:06 -0700 (PDT) X-Google-Smtp-Source: AGHT+IE8AeKy5L/I6q8J8hJyFBAOheGetoqVzeVtQt6EOuFPL0N6B5+Gam+eZApfrQiZLuv62Az8 X-Received: by 2002:a05:6a21:a59d:b0:163:d382:ba84 with SMTP id gd29-20020a056a21a59d00b00163d382ba84mr28010050pzc.5.1699031946692; Fri, 03 Nov 2023 10:19:06 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1699031946; cv=none; d=google.com; s=arc-20160816; b=SjDt6z2EgosBhhfyYkICeue7pW1aJ0xY/ocHOG8ItR9aSGx1/MiNr1OA4Zsuph3JSt Gqn6PuVSLbi97dt7BxzXEzeT+GZxKOzpe+tfHOHnLQ5fWiYsbJYQxkgnIaTH+W2bHCCh fKcCPojTS9zc996uEY0TdUzaUvF881ITT93yhBAKy/wp+7Yw943ugxoMkljBmUeV9W5v 1OMRa3//tbaq7Esq5Iv61JZ5vHEWva8FNqluaYpYe39CFRL3mlqPBOzLpJ5BL3eBhwry OgZpd2UMBXfb5SkB4WVSK2yLGJYU2SkB/4+qZbwdhIqfZM0uNxRHShYaV9yGvRr82dRK 2RCw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=errors-to:cc:reply-to:list-subscribe:list-help:list-post :list-archive:list-unsubscribe:list-id:precedence:subject:user-agent :mime-version:message-id:references:auto-submitted:to:date:from :dkim-signature:dkim-signature:dkim-signature; bh=FTY1ytxdYhu6v8BoJUl8KvZQFPrXcVYy/nKUUiTjmlM=; fh=GFP4qDxgyJ2WEPo/oeLZg3Mj4NqvY1j2nTvTt7psNwg=; b=xjdUVIeR7UhFfuobiLfwFkxWGS12SpS6Lt2iVlDR0tNMOe6mhducpnnegw6q97gaM7 /4pSejUZ7UwxERQTh86YLwUF1ijp6y5gR159fGxcJ940/ZUVgTd54GaB0CP08aBttRNW uS4XdGHxt9JoZtPJzRLhdseSlMBgaP6oC+ATMB4aGXIzeNfRggqGaNgsU3MIMLsm+Lk9 FFbICehGCmvJcqVEG5APR1xtadXPBgCjDRJ7B7XzrZwVSfm6EER8tFZoXyUhItwF2VkV uVO4C8r1RUgNIuTZbS6K6l8mFhvE+LADGDWE8tu4iqYKPWfMmjGoXPRLluFUTDqJNENb G5jw== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=QMoxvZjw; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=N3T5jmOG; dkim=neutral (body hash did not verify) header.i=@openvpn.net header.s=google header.b=OOJ2nMIC; spf=pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) smtp.mailfrom=openvpn-devel-bounces@lists.sourceforge.net; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=openvpn.net Received: from lists.sourceforge.net (lists.sourceforge.net. [216.105.38.7]) by mx.google.com with ESMTPS id jc16-20020a056a006c9000b006c0fe1a6e78si1963050pfb.22.2023.11.03.10.19.06 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Fri, 03 Nov 2023 10:19:06 -0700 (PDT) Received-SPF: pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) client-ip=216.105.38.7; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=QMoxvZjw; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=N3T5jmOG; dkim=neutral (body hash did not verify) header.i=@openvpn.net header.s=google header.b=OOJ2nMIC; spf=pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) smtp.mailfrom=openvpn-devel-bounces@lists.sourceforge.net; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=openvpn.net Received: from [127.0.0.1] (helo=sfs-ml-3.v29.lw.sourceforge.com) by sfs-ml-3.v29.lw.sourceforge.com with esmtp (Exim 4.95) (envelope-from ) id 1qyxoW-0003AM-Tw; Fri, 03 Nov 2023 17:18:31 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-3.v29.lw.sourceforge.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.95) (envelope-from ) id 1qyxoS-0003AC-HA for openvpn-devel@lists.sourceforge.net; Fri, 03 Nov 2023 17:18:27 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Type:Content-Transfer-Encoding:MIME-Version :Message-ID:Reply-To:References:Subject:List-Unsubscribe:List-Id:Cc:To:Date: From:Sender:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:List-Help: List-Subscribe:List-Post:List-Owner:List-Archive; bh=tsO+8cv7mnaF/9cpMfh4tXH/S5DBHifEMYt4goka2Kk=; b=QMoxvZjwPtncfujD/e40z5inQ6 jfAbgMvixJOxmC5PLfRNAVvClI1EHVu6sYtHFadsAvX720RqMb8U1EyTTax0D/W6cihoRY/dWev6W +6Nk/lNbZjQuL6tdP0DLd0l/YQ1Xav1eBRdETjSWe2wfFTQCqGc/rTqR4Hr1xOSJhRoY=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Type:Content-Transfer-Encoding:MIME-Version:Message-ID:Reply-To: References:Subject:List-Unsubscribe:List-Id:Cc:To:Date:From:Sender:Content-ID :Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To: Resent-Cc:Resent-Message-ID:In-Reply-To:List-Help:List-Subscribe:List-Post: List-Owner:List-Archive; bh=tsO+8cv7mnaF/9cpMfh4tXH/S5DBHifEMYt4goka2Kk=; b=N 3T5jmOG68P8ZnLl5uLOJ7mXxVMlQW3d9LYGjn2A0ZLU+/s+oVeXyYpaPLixQYDHDT+L8bPz2Z3kpX dXbKEalPa7+kgSLkZt7/vIH/pSXLa4+FPbbkwy5jBKEj+kNhPjnS/I/9vwYFjT+Xmz2xHwW5/XlRF ICKJTOAqstU0KkQU=; Received: from mail-wm1-f46.google.com ([209.85.128.46]) by sfi-mx-2.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES128-GCM-SHA256:128) (Exim 4.95) id 1qyxoK-0004B0-Nz for openvpn-devel@lists.sourceforge.net; Fri, 03 Nov 2023 17:18:26 +0000 Received: by mail-wm1-f46.google.com with SMTP id 5b1f17b1804b1-40839807e82so14759595e9.0 for ; Fri, 03 Nov 2023 10:18:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=openvpn.net; s=google; t=1699031894; x=1699636694; darn=lists.sourceforge.net; h=user-agent:content-disposition:content-transfer-encoding :mime-version:message-id:reply-to:references:subject :list-unsubscribe:list-id:auto-submitted:cc:to:date:from:from:to:cc :subject:date:message-id:reply-to; bh=tsO+8cv7mnaF/9cpMfh4tXH/S5DBHifEMYt4goka2Kk=; b=OOJ2nMICe5iZqUVeNBnsznt4fUhqxwgCL82UCw2/Al5Da+h57LcZDpTVmQZhr/vZwZ VhzSu3jDTnVJV5fSymx3Ov4sr4WiVNpbL0ZfQE+6Ig1QD5ihtPi21rtSKaM1OXhsBtWf KsazBp00yx+inpOtZOeaAm3oDDglXcosCTG6emsahIWdHAa5fgPOYL6s5XzI9hOYK+5f jOtFzb1frc/SRLuA/4ybNuAD+E3x1+KsgVamHulh9yx8Ch4o8k4d/D+WJ0hh0oASy6aB PTlO6zAN+PsRtsi7uOY3eUCgQHdUZuJAOdEZpE3NNuF8kaGLYXCJ0Ghs2LyOANi/pLyK Rj+g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1699031894; x=1699636694; h=user-agent:content-disposition:content-transfer-encoding :mime-version:message-id:reply-to:references:subject :list-unsubscribe:list-id:auto-submitted:cc:to:date:from :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=tsO+8cv7mnaF/9cpMfh4tXH/S5DBHifEMYt4goka2Kk=; b=K3Hu/UOOOVc6UFLuA0eaPYxqArStlqxpLJIY79n/F0qUZvggWI0VF9oSeaj/KI9QC8 8avzK8ZxsMuaTPpZQSz6ZlBAmqJhM1G0m3P/gS5RWB6RCd+0l+cZR2JpoXvgebIuZAzd hgZRIWcx42NCe/9tpLRQYkmRTSt+9jRKib6PKuFmKktsnuO+cibYdZl4t8CknM/a1neh AjFovGdnmjFvEdvGNB4qVFOgnNPIJ+OwPedISXzKeoLmmoLAfm7Ng5Fl0MfD075+Z+t4 btWer1G1u7wry/jAuVq9hvt9piyVGWZprzhZ0blYxEE2nhZnT2wec5/S8DFM8McKyuyb Sy4g== X-Gm-Message-State: AOJu0YyEyQyERvIICjz1VTcfwLM5A0GYqcV4sfWGqYbpSUsJuQBRhWK+ +ZjZCV8hWDgbEb8PAN6cq+VD6TUYPbeSBQrsvsE= X-Received: by 2002:a05:600c:5488:b0:408:3634:b81e with SMTP id iv8-20020a05600c548800b004083634b81emr4330724wmb.13.1699031893930; Fri, 03 Nov 2023 10:18:13 -0700 (PDT) Received: from gerrit.openvpn.in (ec2-18-159-0-78.eu-central-1.compute.amazonaws.com. [18.159.0.78]) by smtp.gmail.com with ESMTPSA id f13-20020a05600c4e8d00b0040596352951sm3000270wmq.5.2023.11.03.10.18.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 03 Nov 2023 10:18:13 -0700 (PDT) From: "flichtenheld (Code Review)" X-Google-Original-From: "flichtenheld (Code Review)" X-Gerrit-PatchSet: 1 Date: Fri, 3 Nov 2023 17:18:12 +0000 To: plaisthos Auto-Submitted: auto-generated X-Gerrit-MessageType: newchange X-Gerrit-Change-Id: I0dcb2dac4136f194da7050a8ea8495e9faba9dd9 X-Gerrit-Change-Number: 379 X-Gerrit-Project: openvpn X-Gerrit-ChangeURL: X-Gerrit-Commit: f2b6d619acb806bc8c889c133b4bf504b4896ff5 References: Message-ID: <2011f1ff33bbe2e5e215e29db9ab1ca62d21a992-HTML@gerrit.openvpn.net> MIME-Version: 1.0 User-Agent: Gerrit/3.8.2 X-Spam-Score: -0.2 (/) X-Spam-Report: Spam detection software, running on the system "util-spamd-2.v13.lw.sourceforge.com", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: Attention is currently required from: plaisthos. Hello plaisthos, I'd like you to do a code review. Please visit Content analysis details: (-0.2 points, 6.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [209.85.128.46 listed in list.dnswl.org] -0.0 RCVD_IN_MSPIKE_H2 RBL: Average reputation (+2) [209.85.128.46 listed in wl.mailspike.net] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.0 WEIRD_PORT URI: Uses non-standard port number for HTTP 0.0 HTML_MESSAGE BODY: HTML included in message -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid 0.0 T_KAM_HTML_FONT_INVALID Test for Invalidly Named or Formatted Colors in HTML -0.0 T_SCC_BODY_TEXT_LINE No description available. X-Headers-End: 1qyxoK-0004B0-Nz Subject: [Openvpn-devel] [L] Change in openvpn[master]: Remove support for NTLM v1 proxy authentication X-BeenThere: openvpn-devel@lists.sourceforge.net X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: frank@lichtenheld.com, arne-openvpn@rfc2549.org, openvpn-devel@lists.sourceforge.net Cc: openvpn-devel Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox X-GMAIL-THRID: =?utf-8?q?1781564122503289224?= X-GMAIL-MSGID: =?utf-8?q?1781564122503289224?= X-getmail-filter-classifier: gerrit message type newchange Attention is currently required from: plaisthos. Hello plaisthos, I'd like you to do a code review. Please visit http://gerrit.openvpn.net/c/openvpn/+/379?usp=email to review the following change. Change subject: Remove support for NTLM v1 proxy authentication ...................................................................... Remove support for NTLM v1 proxy authentication Due to the limitation of the protocol it is not considered secure. Better to use basic auth instead of a false sense of security. NTLM v2 remains supported for now. Change-Id: I0dcb2dac4136f194da7050a8ea8495e9faba9dd9 Signed-off-by: Frank Lichtenheld --- M doc/man-sections/proxy-options.rst M src/openvpn/crypto_backend.h M src/openvpn/crypto_mbedtls.c M src/openvpn/crypto_openssl.c M src/openvpn/ntlm.c M src/openvpn/options.c M src/openvpn/proxy.c M src/openvpn/proxy.h M tests/unit_tests/openvpn/test_crypto.c 9 files changed, 95 insertions(+), 225 deletions(-) git pull ssh://gerrit.openvpn.net:29418/openvpn refs/changes/79/379/1 diff --git a/doc/man-sections/proxy-options.rst b/doc/man-sections/proxy-options.rst index 465bea0..3fb1060 100644 --- a/doc/man-sections/proxy-options.rst +++ b/doc/man-sections/proxy-options.rst @@ -11,7 +11,7 @@ ``--http-proxy-user-pass`` option. (See section on inline files) The last optional argument is an ``auth-method`` which should be one - of :code:`none`, :code:`basic`, or :code:`ntlm`. + of :code:`none`, :code:`basic`, or :code:`ntlm2`. HTTP Digest authentication is supported as well, but only via the :code:`auto` or :code:`auto-nct` flags (below). This must replace @@ -33,7 +33,9 @@ http-proxy proxy.example.net 3128 authfile.txt http-proxy proxy.example.net 3128 stdin http-proxy proxy.example.net 3128 auto basic - http-proxy proxy.example.net 3128 auto-nct ntlm + http-proxy proxy.example.net 3128 auto-nct ntlm2 + + Note that support for NTLMv1 proxies was removed with OpenVPN 2.7. --http-proxy-option args Set extended HTTP proxy options. Requires an option ``type`` as argument diff --git a/src/openvpn/crypto_backend.h b/src/openvpn/crypto_backend.h index 842e73e..a5371c8 100644 --- a/src/openvpn/crypto_backend.h +++ b/src/openvpn/crypto_backend.h @@ -157,17 +157,6 @@ */ int rand_bytes(uint8_t *output, int len); -/** - * Encrypt the given block, using DES ECB mode - * - * @param key DES key to use. - * @param src Buffer containing the 8-byte source. - * @param dst Buffer containing the 8-byte destination - */ -void cipher_des_encrypt_ecb(const unsigned char key[DES_KEY_LENGTH], - unsigned char src[DES_KEY_LENGTH], - unsigned char dst[DES_KEY_LENGTH]); - /* * * Generic cipher key type functions diff --git a/src/openvpn/crypto_mbedtls.c b/src/openvpn/crypto_mbedtls.c index aaf6ef7..ea52f0c 100644 --- a/src/openvpn/crypto_mbedtls.c +++ b/src/openvpn/crypto_mbedtls.c @@ -758,17 +758,6 @@ return 1; } -void -cipher_des_encrypt_ecb(const unsigned char key[DES_KEY_LENGTH], - unsigned char src[DES_KEY_LENGTH], - unsigned char dst[DES_KEY_LENGTH]) -{ - mbedtls_des_context ctx; - - ASSERT(mbed_ok(mbedtls_des_setkey_enc(&ctx, key))); - ASSERT(mbed_ok(mbedtls_des_crypt_ecb(&ctx, src, dst))); -} - /* diff --git a/src/openvpn/crypto_openssl.c b/src/openvpn/crypto_openssl.c index fe1254f..e8ddf14 100644 --- a/src/openvpn/crypto_openssl.c +++ b/src/openvpn/crypto_openssl.c @@ -988,50 +988,6 @@ return cipher_ctx_final(ctx, dst, dst_len); } -void -cipher_des_encrypt_ecb(const unsigned char key[DES_KEY_LENGTH], - unsigned char src[DES_KEY_LENGTH], - unsigned char dst[DES_KEY_LENGTH]) -{ - /* We are using 3DES here with three times the same key to cheat - * and emulate DES as 3DES is better supported than DES */ - EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); - if (!ctx) - { - crypto_msg(M_FATAL, "%s: EVP_CIPHER_CTX_new() failed", __func__); - } - - unsigned char key3[DES_KEY_LENGTH*3]; - for (int i = 0; i < 3; i++) - { - memcpy(key3 + (i * DES_KEY_LENGTH), key, DES_KEY_LENGTH); - } - - if (!EVP_EncryptInit_ex(ctx, EVP_des_ede3_ecb(), NULL, key3, NULL)) - { - crypto_msg(M_FATAL, "%s: EVP_EncryptInit_ex() failed", __func__); - } - - int len; - - /* The EVP_EncryptFinal method will write to the dst+len pointer even - * though there is nothing to encrypt anymore, provide space for that to - * not overflow the stack */ - unsigned char dst2[DES_KEY_LENGTH * 2]; - if (!EVP_EncryptUpdate(ctx, dst2, &len, src, DES_KEY_LENGTH)) - { - crypto_msg(M_FATAL, "%s: EVP_EncryptUpdate() failed", __func__); - } - - if (!EVP_EncryptFinal(ctx, dst2 + len, &len)) - { - crypto_msg(M_FATAL, "%s: EVP_EncryptFinal() failed", __func__); - } - - memcpy(dst, dst2, DES_KEY_LENGTH); - - EVP_CIPHER_CTX_free(ctx); -} /* * diff --git a/src/openvpn/ntlm.c b/src/openvpn/ntlm.c index 2e77214..bc33f41 100644 --- a/src/openvpn/ntlm.c +++ b/src/openvpn/ntlm.c @@ -55,19 +55,6 @@ static void -create_des_keys(const unsigned char *hash, unsigned char *key) -{ - key[0] = hash[0]; - key[1] = ((hash[0] & 1) << 7) | (hash[1] >> 1); - key[2] = ((hash[1] & 3) << 6) | (hash[2] >> 2); - key[3] = ((hash[2] & 7) << 5) | (hash[3] >> 3); - key[4] = ((hash[3] & 15) << 4) | (hash[4] >> 4); - key[5] = ((hash[4] & 31) << 3) | (hash[5] >> 5); - key[6] = ((hash[5] & 63) << 2) | (hash[6] >> 6); - key[7] = ((hash[6] & 127) << 1); -} - -static void gen_md4_hash(const uint8_t *data, int data_len, uint8_t *result) { /* result is 16 byte md4 hash */ @@ -210,7 +197,7 @@ uint8_t phase3[464]; uint8_t md4_hash[MD4_DIGEST_LENGTH + 5]; - uint8_t challenge[8], ntlm_response[24]; + uint8_t challenge[8]; int i, ret_val; uint8_t ntlmv2_response[144]; @@ -227,8 +214,6 @@ char username[128]; char *separator; - bool ntlmv2_enabled = (p->auth_method == HTTP_AUTH_NTLM2); - ASSERT(strlen(p->up.username) > 0); ASSERT(strlen(p->up.password) > 0); @@ -282,126 +267,102 @@ challenge[i] = buf2[i+24]; } - if (ntlmv2_enabled) /* Generate NTLMv2 response */ + /* Generate NTLMv2 response */ + int tib_len; + + /* NTLMv2 hash */ + strcpy(userdomain, username); + my_strupr(userdomain); + if (strlen(username) + strlen(domain) < sizeof(userdomain)) { - int tib_len; - - /* NTLMv2 hash */ - strcpy(userdomain, username); - my_strupr(userdomain); - if (strlen(username) + strlen(domain) < sizeof(userdomain)) - { - strcat(userdomain, domain); - } - else - { - msg(M_INFO, "Warning: Username or domain too long"); - } - unicodize(userdomain_u, userdomain); - gen_hmac_md5((uint8_t *)userdomain_u, 2 * strlen(userdomain), md4_hash, - ntlmv2_hash); - - /* NTLMv2 Blob */ - memset(ntlmv2_blob, 0, 128); /* Clear blob buffer */ - ntlmv2_blob[0x00] = 1; /* Signature */ - ntlmv2_blob[0x01] = 1; /* Signature */ - ntlmv2_blob[0x04] = 0; /* Reserved */ - gen_timestamp(&ntlmv2_blob[0x08]); /* 64-bit Timestamp */ - gen_nonce(&ntlmv2_blob[0x10]); /* 64-bit Client Nonce */ - ntlmv2_blob[0x18] = 0; /* Unknown, zero should work */ - - /* Add target information block to the blob */ - - /* Check for Target Information block */ - /* The NTLM spec instructs to interpret these 4 consecutive bytes as a - * 32bit long integer. However, no endianness is specified. - * The code here and that found in other NTLM implementations point - * towards the assumption that the byte order on the wire has to - * match the order on the sending and receiving hosts. Probably NTLM has - * been thought to be always running on x86_64/i386 machine thus - * implying Little-Endian everywhere. - * - * This said, in case of future changes, we should keep in mind that the - * byte order on the wire for the NTLM header is LE. - */ - const size_t hoff = 0x14; - unsigned long flags = buf2[hoff] | (buf2[hoff + 1] << 8) - |(buf2[hoff + 2] << 16) | (buf2[hoff + 3] << 24); - if ((flags & 0x00800000) == 0x00800000) - { - tib_len = buf2[0x28]; /* Get Target Information block size */ - if (tib_len > 96) - { - tib_len = 96; - } - - { - uint8_t *tib_ptr; - uint8_t tib_pos = buf2[0x2c]; - if (tib_pos + tib_len > sizeof(buf2)) - { - return NULL; - } - /* Get Target Information block pointer */ - tib_ptr = buf2 + tib_pos; - /* Copy Target Information block into the blob */ - memcpy(&ntlmv2_blob[0x1c], tib_ptr, tib_len); - } - } - else - { - tib_len = 0; - } - - /* Unknown, zero works */ - ntlmv2_blob[0x1c + tib_len] = 0; - - /* Get blob length */ - ntlmv2_blob_size = 0x20 + tib_len; - - /* Add challenge from message 2 */ - memcpy(&ntlmv2_response[8], challenge, 8); - - /* hmac-md5 */ - gen_hmac_md5(&ntlmv2_response[8], ntlmv2_blob_size + 8, ntlmv2_hash, - ntlmv2_hmacmd5); - - /* Add hmac-md5 result to the blob. - * Note: This overwrites challenge previously written at - * ntlmv2_response[8..15] */ - memcpy(ntlmv2_response, ntlmv2_hmacmd5, MD5_DIGEST_LENGTH); + strcat(userdomain, domain); } - else /* Generate NTLM response */ + else { - unsigned char key1[DES_KEY_LENGTH], key2[DES_KEY_LENGTH]; - unsigned char key3[DES_KEY_LENGTH]; + msg(M_INFO, "Warning: Username or domain too long"); + } + unicodize(userdomain_u, userdomain); + gen_hmac_md5((uint8_t *)userdomain_u, 2 * strlen(userdomain), md4_hash, + ntlmv2_hash); - create_des_keys(md4_hash, key1); - cipher_des_encrypt_ecb(key1, challenge, ntlm_response); + /* NTLMv2 Blob */ + memset(ntlmv2_blob, 0, 128); /* Clear blob buffer */ + ntlmv2_blob[0x00] = 1; /* Signature */ + ntlmv2_blob[0x01] = 1; /* Signature */ + ntlmv2_blob[0x04] = 0; /* Reserved */ + gen_timestamp(&ntlmv2_blob[0x08]); /* 64-bit Timestamp */ + gen_nonce(&ntlmv2_blob[0x10]); /* 64-bit Client Nonce */ + ntlmv2_blob[0x18] = 0; /* Unknown, zero should work */ - create_des_keys(&md4_hash[DES_KEY_LENGTH - 1], key2); - cipher_des_encrypt_ecb(key2, challenge, &ntlm_response[DES_KEY_LENGTH]); + /* Add target information block to the blob */ - create_des_keys(&md4_hash[2 * (DES_KEY_LENGTH - 1)], key3); - cipher_des_encrypt_ecb(key3, challenge, - &ntlm_response[DES_KEY_LENGTH * 2]); + /* Check for Target Information block */ + /* The NTLM spec instructs to interpret these 4 consecutive bytes as a + * 32bit long integer. However, no endianness is specified. + * The code here and that found in other NTLM implementations point + * towards the assumption that the byte order on the wire has to + * match the order on the sending and receiving hosts. Probably NTLM has + * been thought to be always running on x86_64/i386 machine thus + * implying Little-Endian everywhere. + * + * This said, in case of future changes, we should keep in mind that the + * byte order on the wire for the NTLM header is LE. + */ + const size_t hoff = 0x14; + unsigned long flags = buf2[hoff] | (buf2[hoff + 1] << 8) + |(buf2[hoff + 2] << 16) | (buf2[hoff + 3] << 24); + if ((flags & 0x00800000) == 0x00800000) + { + tib_len = buf2[0x28]; /* Get Target Information block size */ + if (tib_len > 96) + { + tib_len = 96; + } + + { + uint8_t *tib_ptr; + uint8_t tib_pos = buf2[0x2c]; + if (tib_pos + tib_len > sizeof(buf2)) + { + return NULL; + } + /* Get Target Information block pointer */ + tib_ptr = buf2 + tib_pos; + /* Copy Target Information block into the blob */ + memcpy(&ntlmv2_blob[0x1c], tib_ptr, tib_len); + } + } + else + { + tib_len = 0; } + /* Unknown, zero works */ + ntlmv2_blob[0x1c + tib_len] = 0; + + /* Get blob length */ + ntlmv2_blob_size = 0x20 + tib_len; + + /* Add challenge from message 2 */ + memcpy(&ntlmv2_response[8], challenge, 8); + + /* hmac-md5 */ + gen_hmac_md5(&ntlmv2_response[8], ntlmv2_blob_size + 8, ntlmv2_hash, + ntlmv2_hmacmd5); + + /* Add hmac-md5 result to the blob. + * Note: This overwrites challenge previously written at + * ntlmv2_response[8..15] */ + memcpy(ntlmv2_response, ntlmv2_hmacmd5, MD5_DIGEST_LENGTH); memset(phase3, 0, sizeof(phase3)); /* clear reply */ strcpy((char *)phase3, "NTLMSSP\0"); /* signature */ phase3[8] = 3; /* type 3 */ - if (ntlmv2_enabled) /* NTLMv2 response */ - { - add_security_buffer(0x14, ntlmv2_response, ntlmv2_blob_size + 16, - phase3, &phase3_bufpos); - } - else /* NTLM response */ - { - add_security_buffer(0x14, ntlm_response, 24, phase3, &phase3_bufpos); - } + /* NTLMv2 response */ + add_security_buffer(0x14, ntlmv2_response, ntlmv2_blob_size + 16, + phase3, &phase3_bufpos); /* username in ascii */ add_security_buffer(0x24, username, strlen(username), phase3, diff --git a/src/openvpn/options.c b/src/openvpn/options.c index fbf54ef..7aa8514 100644 --- a/src/openvpn/options.c +++ b/src/openvpn/options.c @@ -144,7 +144,7 @@ " through an HTTP proxy at address s and port p.\n" " If proxy authentication is required,\n" " up is a file containing username/password on 2 lines, or\n" - " 'stdin' to prompt from console. Add auth='ntlm' if\n" + " 'stdin' to prompt from console. Add auth='ntlm2' if\n" " the proxy requires NTLM authentication.\n" "--http-proxy s p 'auto[-nct]' : Like the above directive, but automatically\n" " determine auth method and query for username/password\n" diff --git a/src/openvpn/proxy.c b/src/openvpn/proxy.c index 3b6f7df..5a1b4e1 100644 --- a/src/openvpn/proxy.c +++ b/src/openvpn/proxy.c @@ -354,7 +354,7 @@ { msg(D_PROXY, "PROXY AUTH NTLM: '%s'", buf); *data = NULL; - ret = HTTP_AUTH_NTLM; + ret = HTTP_AUTH_NTLM2; } #endif } @@ -517,9 +517,7 @@ #if NTLM else if (!strcmp(o->auth_method_string, "ntlm")) { - msg(M_INFO, "NTLM v1 authentication is deprecated and will be removed in " - "OpenVPN 2.7"); - p->auth_method = HTTP_AUTH_NTLM; + msg(M_FATAL, "ERROR: NTLM v1 support has been removed. For now, you can use NTLM v2 by selecting ntlm2 but it is deprecated as well."); } else if (!strcmp(o->auth_method_string, "ntlm2")) { @@ -534,13 +532,13 @@ } /* only basic and NTLM/NTLMv2 authentication supported so far */ - if (p->auth_method == HTTP_AUTH_BASIC || p->auth_method == HTTP_AUTH_NTLM || p->auth_method == HTTP_AUTH_NTLM2) + if (p->auth_method == HTTP_AUTH_BASIC || p->auth_method == HTTP_AUTH_NTLM2) { get_user_pass_http(p, true); } #if !NTLM - if (p->auth_method == HTTP_AUTH_NTLM || p->auth_method == HTTP_AUTH_NTLM2) + if (p->auth_method == HTTP_AUTH_NTLM2) { msg(M_FATAL, "Sorry, this version of " PACKAGE_NAME " was built without NTLM Proxy support."); } @@ -646,8 +644,7 @@ /* get user/pass if not previously given */ if (p->auth_method == HTTP_AUTH_BASIC - || p->auth_method == HTTP_AUTH_DIGEST - || p->auth_method == HTTP_AUTH_NTLM) + || p->auth_method == HTTP_AUTH_DIGEST) { get_user_pass_http(p, false); } @@ -697,7 +694,6 @@ break; #if NTLM - case HTTP_AUTH_NTLM: case HTTP_AUTH_NTLM2: /* keep-alive connection */ openvpn_snprintf(buf, sizeof(buf), "Proxy-Connection: Keep-Alive"); @@ -752,7 +748,7 @@ { processed = true; } - else if ((p->auth_method == HTTP_AUTH_NTLM || p->auth_method == HTTP_AUTH_NTLM2) && !processed) /* check for NTLM */ + else if ((p->auth_method == HTTP_AUTH_NTLM2) && !processed) /* check for NTLM */ { #if NTLM /* look for the phase 2 response */ diff --git a/src/openvpn/proxy.h b/src/openvpn/proxy.h index 83b799e..7900244 100644 --- a/src/openvpn/proxy.h +++ b/src/openvpn/proxy.h @@ -31,7 +31,7 @@ #define HTTP_AUTH_NONE 0 #define HTTP_AUTH_BASIC 1 #define HTTP_AUTH_DIGEST 2 -#define HTTP_AUTH_NTLM 3 +/* #define HTTP_AUTH_NTLM 3 removed in OpenVPN 2.7 */ #define HTTP_AUTH_NTLM2 4 #define HTTP_AUTH_N 5 /* number of HTTP_AUTH methods */ diff --git a/tests/unit_tests/openvpn/test_crypto.c b/tests/unit_tests/openvpn/test_crypto.c index 5564524..3b5e451 100644 --- a/tests/unit_tests/openvpn/test_crypto.c +++ b/tests/unit_tests/openvpn/test_crypto.c @@ -211,29 +211,6 @@ hmac_ctx_free(hmac); } -void -test_des_encrypt(void **state) -{ - /* We have a small des encrypt method that is only for NTLMv1. This unit - * test ensures that it is not accidentally broken */ - - const unsigned char des_key[DES_KEY_LENGTH] = {0x42, 0x23}; - - const char *src = "MoinWelt"; - - /* cipher_des_encrypt_ecb wants a non const */ - unsigned char *src2 = (unsigned char *) strdup(src); - - unsigned char dst[DES_KEY_LENGTH]; - cipher_des_encrypt_ecb(des_key, src2, dst); - - const unsigned char dst_good[DES_KEY_LENGTH] = {0xd3, 0x8f, 0x61, 0xf7, 0xbe, 0x27, 0xb6, 0xa2}; - - assert_memory_equal(dst, dst_good, DES_KEY_LENGTH); - - free(src2); -} - /* This test is in test_crypto as it calls into the functions that calculate * the crypto overhead */ static void