From patchwork Fri Jul 26 08:20:55 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "plaisthos (Code Review)" X-Patchwork-Id: 3776 Return-Path: Delivered-To: patchwork@openvpn.net Received: by 2002:a05:7000:bb85:b0:5a1:d4fc:4ac6 with SMTP id gl5csp329370mab; Fri, 26 Jul 2024 01:21:37 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCUcWGQWmfatLbXmTYQyY9eub169HznURmGHTU9wIedXDyMofZxfGXb/VaK9v61nSfbpYeOjiEX+kzte1wTX7CUSMg2O/VM= X-Google-Smtp-Source: AGHT+IERsuqzzmmewY47tL9reAX1IVYbV/xwHagElPGf3lkt1WSKzxu7tJb9XjJPbvs1nXfAOdyH X-Received: by 2002:a17:902:6b42:b0:1fb:12b4:79ef with SMTP id d9443c01a7336-1fed67455dfmr32975835ad.0.1721982097517; Fri, 26 Jul 2024 01:21:37 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1721982097; cv=none; d=google.com; s=arc-20160816; b=TuwVHNjMo2nS+X9zgCNQ3uaWrJNADl84aV5PVcc77SVsD4QrSrZUm4sbT5xsPlk26M ucJpARqwgc8DksiKJDrNxRsloSzEdpGfzLayRCdiddU7ceFEK2CeBlCFZk9e7LBqA8wO 5ODIvLUj42E9CAzQD5ZqlpGkwDpabZJ3Jol4TRqswqhTrfSi1tx3sILJCJwVIpJxCpGZ kbzE3p+ORTU+0pmvgwpJbvJpjd84SjeXEENDP1QOlcUBZ1L6dkxGPBF4VxDQVLpuiTXs lvLNWyOG22Ym3soXYmuQSw2eowkkAAVxtkgjovkTqmtM/lJf4pxVsO+xBfWRLqS8xFbD u59g== 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=KMcGFt17ovZe46fpJfUKNilA8XsdA9pjKz+WP0jVlfQ=; fh=U7wEyxtwz2o5+UdevFSA47vNeG9knhWH0KV//QhD5a0=; b=udThF0vMoBXU0U8xaLiJD75Tbo4tpeAQpNgSn6dLq3xKTBUa2PEDAaIlWxh1DWUnlq D1rmu0JFe3+LhVyJIS0+3O/Vqd0G0+Oa2T7JJwoFKWO2DL60Wdm7F/IKvR5P1EpyOwqM mX+VcdH7mEzVi+7LVIEasUmFJmr5ml8Jq+rwVGRu3sAsJ1hPd8fs1GadUBl94U9S64ch yYZo15HLv+CozbRBsa6Lf/0/a7pS2HQis0zdQndw4ovU5KFC1Jjsm6dzMheBinDgj8K5 VORMPHDp+6Gcq0B961V8cv+f3rfgqvWDVjOcIRHewU03fYeRePVEG6OpmBB1x5F8R6bg s6TQ==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=KKpH2FoY; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=HeUse9xI; dkim=neutral (body hash did not verify) header.i=@openvpn.net header.s=google header.b=WsjT8TLZ; 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; dara=fail header.i=@openvpn.net Received: from lists.sourceforge.net (lists.sourceforge.net. [216.105.38.7]) by mx.google.com with ESMTPS id d9443c01a7336-1fed7ee844csi34118715ad.234.2024.07.26.01.21.37 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Fri, 26 Jul 2024 01:21:37 -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=KKpH2FoY; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=HeUse9xI; dkim=neutral (body hash did not verify) header.i=@openvpn.net header.s=google header.b=WsjT8TLZ; 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; dara=fail header.i=@openvpn.net Received: from [127.0.0.1] (helo=sfs-ml-1.v29.lw.sourceforge.com) by sfs-ml-1.v29.lw.sourceforge.com with esmtp (Exim 4.95) (envelope-from ) id 1sXGCL-0003kK-PT; Fri, 26 Jul 2024 08:21:10 +0000 Received: from [172.30.29.67] (helo=mx.sourceforge.net) by sfs-ml-1.v29.lw.sourceforge.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.95) (envelope-from ) id 1sXGCH-0003iz-1C for openvpn-devel@lists.sourceforge.net; Fri, 26 Jul 2024 08:21:05 +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=vKyDKO+G6tH2zfOQ8Up+pB63u4r2ah53T8VBYwbba8k=; b=KKpH2FoYc5QhMk9S0k572YXi28 pMKsW3yzHArUAjazYQPI67gMMaLnFZRCV6hTiRLQZil0aC+dS1dhf5l0/fdDtExTHctaxvlja2ola J9EfE+Brw7W5F8F/+qOWSWTz1nGI+W7S7FiDcbMdpD7m2WcNbcoWo7hjBY44H/gJy5dk=; 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=vKyDKO+G6tH2zfOQ8Up+pB63u4r2ah53T8VBYwbba8k=; b=H eUse9xIXmg4dJnUB4Larf49r2hpab0GMSD0OGbcQKP9v9xIsLWOhxXsyBxnp8iYUmOmnS940gVnBp ZZXOUtBIEMq7M+Rxo4bL8GtvN2jQrYjvvkVkCXRbz5TEgJTTucu9KVZm7vUYLMZhj9ZCvvZlX5PDI j+7nlqMTIfsPc3fc=; Received: from mail-wm1-f45.google.com ([209.85.128.45]) by sfi-mx-2.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES128-GCM-SHA256:128) (Exim 4.95) id 1sXGCF-0000es-0E for openvpn-devel@lists.sourceforge.net; Fri, 26 Jul 2024 08:21:05 +0000 Received: by mail-wm1-f45.google.com with SMTP id 5b1f17b1804b1-4280ca0791bso2689315e9.1 for ; Fri, 26 Jul 2024 01:21:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=openvpn.net; s=google; t=1721982056; x=1722586856; 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=vKyDKO+G6tH2zfOQ8Up+pB63u4r2ah53T8VBYwbba8k=; b=WsjT8TLZLr6/o0TeBRUaLwLd8lU3QSm6nPpiD39Q/9bSovW6gs5DVJCdWOQnwei+FN g3Xe7ulzp4iO5Y5alVkvqmHJrYbe8AKht14LF2XQvzAHW3xbBtIa28alULztKYwhI2y/ /LPF8bqmQ7uilWfepocVw0K+tDd3ER9jS+V3/zjZnR0LHv+QFp2G8OK6datcW03GczeC +zHRE89kSe1to71ljNzJGahXn3SO0YjMxOUF5P1TLh5jy4ESURph0pvGUlI8+HVh5Gld M/GGONjnb8dLPI6CvZ+v9TSLluT+lJ+7Ikb97GceItub7NFOlxmv14b/bwVIhPjhbYkP xr5Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1721982056; x=1722586856; 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=vKyDKO+G6tH2zfOQ8Up+pB63u4r2ah53T8VBYwbba8k=; b=Le3OY9rJt6mm9dqSlSx3AX/657JnIl+aisuSekJGJxmm7zNXqS7xO511AU2NdY/HAq DZO4y1ammM9q1gKazjexYXRnko4cdL6LAGvRF8GlcdbcKqjUrsIxU/XxoLj+hV9Ja5rn DaMf9UKxibu1raXY0x5V/v81BMzX7ROk9+/Zl5NOApHOKKpz9XHzd8uQkrPjtKR0/HAM WZKqpDnkjVpO5m0skOdMoDPiN5pMgL55vb9xOveeMr46tP4H9N3GB8X41+/nsTTkPd9H rsCd+a1A676LIgUYAUQZO4Lo9pa+ySPCMC7hcK57Z3BP4a9VrA2HHK7wH2gaaAFhVyoW hJrw== X-Gm-Message-State: AOJu0Yx8Ci9CySGjOVOcht96mrKkAwsuLx596EWqwF4AJYAah8bfEun1 dVx2ti8ueKQUNh4YzUhTUNzJzQ0mdhVVmcg4OquKHei1tCOb2zBDvr5HODSIklY03tt+/sVF3Zr 6 X-Received: by 2002:a05:600c:4f92:b0:427:ffa4:32d0 with SMTP id 5b1f17b1804b1-42806bf4b38mr30304785e9.28.1721982056062; Fri, 26 Jul 2024 01:20:56 -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 5b1f17b1804b1-4280d13570bsm11684285e9.7.2024.07.26.01.20.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 26 Jul 2024 01:20:55 -0700 (PDT) From: "ralf_lici (Code Review)" X-Google-Original-From: "ralf_lici (Code Review)" X-Gerrit-PatchSet: 1 Date: Fri, 26 Jul 2024 08:20:55 +0000 To: plaisthos , flichtenheld Auto-Submitted: auto-generated X-Gerrit-MessageType: newchange X-Gerrit-Change-Id: Ia593f72f6baa6e16d2fd9b21b383b709682f9499 X-Gerrit-Change-Number: 686 X-Gerrit-Project: openvpn X-Gerrit-ChangeURL: X-Gerrit-Commit: 9a76cb904874a7f334490cc9c8d7ba2df9b8f5b0 References: Message-ID: <4b41e7fbc7214bc2edc607fad91eb430d960a29f-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: flichtenheld, plaisthos. Hello plaisthos, flichtenheld, 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 URIBL_BLOCKED ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [URIs: openvpn.net] 0.0 RCVD_IN_DNSWL_BLOCKED RBL: ADMINISTRATOR NOTICE: The query to DNSWL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [209.85.128.45 listed in list.dnswl.org] 0.0 RCVD_IN_VALIDITY_SAFE_BLOCKED RBL: ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. [209.85.128.45 listed in sa-trusted.bondedsender.org] 0.0 RCVD_IN_VALIDITY_RPBL_BLOCKED RBL: ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. [209.85.128.45 listed in bl.score.senderscore.com] -0.0 RCVD_IN_MSPIKE_H2 RBL: Average reputation (+2) [209.85.128.45 listed in wl.mailspike.net] 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 SPF_PASS SPF: sender matches 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_EF Message has a valid DKIM or DK signature from envelope-from domain -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_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 X-Headers-End: 1sXGCF-0000es-0E Subject: [Openvpn-devel] [L] Change in openvpn[master]: Add support for TLV parsing in the PROXY protocol 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: ralf@mandelbit.com, arne-openvpn@rfc2549.org, openvpn-devel@lists.sourceforge.net, frank@lichtenheld.com Cc: openvpn-devel Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox X-GMAIL-THRID: =?utf-8?q?1805629099863986044?= X-GMAIL-MSGID: =?utf-8?q?1805629099863986044?= X-getmail-filter-classifier: gerrit message type newchange Attention is currently required from: flichtenheld, plaisthos. Hello plaisthos, flichtenheld, I'd like you to do a code review. Please visit http://gerrit.openvpn.net/c/openvpn/+/686?usp=email to review the following change. Change subject: Add support for TLV parsing in the PROXY protocol ...................................................................... Add support for TLV parsing in the PROXY protocol Version 2 of the PROXY protocol appends extra data in Type-Length-Value vector format at the end of the header. This commit parses and processes or stores the additional information extracted from TLVs. Change-Id: Ia593f72f6baa6e16d2fd9b21b383b709682f9499 Signed-off-by: Ralf Lici --- M src/openvpn/proxy_protocol.c M src/openvpn/proxy_protocol.h 2 files changed, 372 insertions(+), 1 deletion(-) git pull ssh://gerrit.openvpn.net:29418/openvpn refs/changes/86/686/1 diff --git a/src/openvpn/proxy_protocol.c b/src/openvpn/proxy_protocol.c index 10a68c2..7f72313 100644 --- a/src/openvpn/proxy_protocol.c +++ b/src/openvpn/proxy_protocol.c @@ -38,6 +38,74 @@ PROXY_PROTOCOL_PARSING_STATE_IGNORE = 1, } proxy_protocol_parsing_state_t; +static const uint32_t CRC32C_TABLE[256] = +{ + 0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L, + 0xC79A971FL, 0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL, + 0x8AD958CFL, 0x78B2DBCCL, 0x6BE22838L, 0x9989AB3BL, + 0x4D43CFD0L, 0xBF284CD3L, 0xAC78BF27L, 0x5E133C24L, + 0x105EC76FL, 0xE235446CL, 0xF165B798L, 0x030E349BL, + 0xD7C45070L, 0x25AFD373L, 0x36FF2087L, 0xC494A384L, + 0x9A879FA0L, 0x68EC1CA3L, 0x7BBCEF57L, 0x89D76C54L, + 0x5D1D08BFL, 0xAF768BBCL, 0xBC267848L, 0x4E4DFB4BL, + 0x20BD8EDEL, 0xD2D60DDDL, 0xC186FE29L, 0x33ED7D2AL, + 0xE72719C1L, 0x154C9AC2L, 0x061C6936L, 0xF477EA35L, + 0xAA64D611L, 0x580F5512L, 0x4B5FA6E6L, 0xB93425E5L, + 0x6DFE410EL, 0x9F95C20DL, 0x8CC531F9L, 0x7EAEB2FAL, + 0x30E349B1L, 0xC288CAB2L, 0xD1D83946L, 0x23B3BA45L, + 0xF779DEAEL, 0x05125DADL, 0x1642AE59L, 0xE4292D5AL, + 0xBA3A117EL, 0x4851927DL, 0x5B016189L, 0xA96AE28AL, + 0x7DA08661L, 0x8FCB0562L, 0x9C9BF696L, 0x6EF07595L, + 0x417B1DBCL, 0xB3109EBFL, 0xA0406D4BL, 0x522BEE48L, + 0x86E18AA3L, 0x748A09A0L, 0x67DAFA54L, 0x95B17957L, + 0xCBA24573L, 0x39C9C670L, 0x2A993584L, 0xD8F2B687L, + 0x0C38D26CL, 0xFE53516FL, 0xED03A29BL, 0x1F682198L, + 0x5125DAD3L, 0xA34E59D0L, 0xB01EAA24L, 0x42752927L, + 0x96BF4DCCL, 0x64D4CECFL, 0x77843D3BL, 0x85EFBE38L, + 0xDBFC821CL, 0x2997011FL, 0x3AC7F2EBL, 0xC8AC71E8L, + 0x1C661503L, 0xEE0D9600L, 0xFD5D65F4L, 0x0F36E6F7L, + 0x61C69362L, 0x93AD1061L, 0x80FDE395L, 0x72966096L, + 0xA65C047DL, 0x5437877EL, 0x4767748AL, 0xB50CF789L, + 0xEB1FCBADL, 0x197448AEL, 0x0A24BB5AL, 0xF84F3859L, + 0x2C855CB2L, 0xDEEEDFB1L, 0xCDBE2C45L, 0x3FD5AF46L, + 0x7198540DL, 0x83F3D70EL, 0x90A324FAL, 0x62C8A7F9L, + 0xB602C312L, 0x44694011L, 0x5739B3E5L, 0xA55230E6L, + 0xFB410CC2L, 0x092A8FC1L, 0x1A7A7C35L, 0xE811FF36L, + 0x3CDB9BDDL, 0xCEB018DEL, 0xDDE0EB2AL, 0x2F8B6829L, + 0x82F63B78L, 0x709DB87BL, 0x63CD4B8FL, 0x91A6C88CL, + 0x456CAC67L, 0xB7072F64L, 0xA457DC90L, 0x563C5F93L, + 0x082F63B7L, 0xFA44E0B4L, 0xE9141340L, 0x1B7F9043L, + 0xCFB5F4A8L, 0x3DDE77ABL, 0x2E8E845FL, 0xDCE5075CL, + 0x92A8FC17L, 0x60C37F14L, 0x73938CE0L, 0x81F80FE3L, + 0x55326B08L, 0xA759E80BL, 0xB4091BFFL, 0x466298FCL, + 0x1871A4D8L, 0xEA1A27DBL, 0xF94AD42FL, 0x0B21572CL, + 0xDFEB33C7L, 0x2D80B0C4L, 0x3ED04330L, 0xCCBBC033L, + 0xA24BB5A6L, 0x502036A5L, 0x4370C551L, 0xB11B4652L, + 0x65D122B9L, 0x97BAA1BAL, 0x84EA524EL, 0x7681D14DL, + 0x2892ED69L, 0xDAF96E6AL, 0xC9A99D9EL, 0x3BC21E9DL, + 0xEF087A76L, 0x1D63F975L, 0x0E330A81L, 0xFC588982L, + 0xB21572C9L, 0x407EF1CAL, 0x532E023EL, 0xA145813DL, + 0x758FE5D6L, 0x87E466D5L, 0x94B49521L, 0x66DF1622L, + 0x38CC2A06L, 0xCAA7A905L, 0xD9F75AF1L, 0x2B9CD9F2L, + 0xFF56BD19L, 0x0D3D3E1AL, 0x1E6DCDEEL, 0xEC064EEDL, + 0xC38D26C4L, 0x31E6A5C7L, 0x22B65633L, 0xD0DDD530L, + 0x0417B1DBL, 0xF67C32D8L, 0xE52CC12CL, 0x1747422FL, + 0x49547E0BL, 0xBB3FFD08L, 0xA86F0EFCL, 0x5A048DFFL, + 0x8ECEE914L, 0x7CA56A17L, 0x6FF599E3L, 0x9D9E1AE0L, + 0xD3D3E1ABL, 0x21B862A8L, 0x32E8915CL, 0xC083125FL, + 0x144976B4L, 0xE622F5B7L, 0xF5720643L, 0x07198540L, + 0x590AB964L, 0xAB613A67L, 0xB831C993L, 0x4A5A4A90L, + 0x9E902E7BL, 0x6CFBAD78L, 0x7FAB5E8CL, 0x8DC0DD8FL, + 0xE330A81AL, 0x115B2B19L, 0x020BD8EDL, 0xF0605BEEL, + 0x24AA3F05L, 0xD6C1BC06L, 0xC5914FF2L, 0x37FACCF1L, + 0x69E9F0D5L, 0x9B8273D6L, 0x88D28022L, 0x7AB90321L, + 0xAE7367CAL, 0x5C18E4C9L, 0x4F48173DL, 0xBD23943EL, + 0xF36E6F75L, 0x0105EC76L, 0x12551F82L, 0xE03E9C81L, + 0x34F4F86AL, 0xC69F7B69L, 0xD5CF889DL, 0x27A40B9EL, + 0x79B737BAL, 0x8BDCB4B9L, 0x988C474DL, 0x6AE7C44EL, + 0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L, 0xAD7D5351L +}; + static const size_t PROXY_PROTOCOL_V2_ADDR_LEN_IPV4 = 12; static const size_t PROXY_PROTOCOL_V2_ADDR_LEN_IPV6 = 36; static const size_t PROXY_PROTOCOL_V2_ADDR_LEN_UNIX = 216; @@ -88,6 +156,17 @@ } } +uint32_t +proxy_protocol_crc32c(const uint8_t *data, int len) +{ + uint32_t crc = 0xFFFFFFFF; + while (len-- > 0) + { + crc = (crc >> 8) ^ CRC32C_TABLE[(crc ^ (*data++)) & 0xFF]; + } + return (crc ^ 0xFFFFFFFF); +} + /* * Parse a port number from a string. * @@ -316,6 +395,231 @@ } /* + * Parse a string based TLV and store the value in 'out'. + * + * @param ppi - The proxy protocol info structure used for memory allocation. + * @param out - The output variable to store the parsed value. + * @param type_str - A string representation of the TLV type (for logging). + * @param len - The length of the TLV value. + * @param value - The TLV value. + */ +void +proxy_protocol_parse_string_tlv(struct proxy_protocol_info *ppi, char **out, char *type_str, const uint16_t len, const uint8_t *value) +{ + if (len == 0) + { + msg(M_NONFATAL, "PROXY protocol v2: %s TLV empty", type_str); + return; + } + + *out = (char *)gc_malloc(8, false, &ppi->gc); + memcpy(*out, value, len); + (*out)[len] = '\0'; + + if (type_str) + { + msg(M_DEBUG, "PROXY protocol v2: %s TLV: %s", type_str, *out); + } +} + +/* + * Parse the CRC32C TLV and check if it matches the calculated CRC32C. + * If there's a mismatch the parsing state is set to invalid so that the header + * is dropped. + * + * @param len - The length of the TLV value. + * @param value - The TLV value. + * + * @return - true if the CRC32C value matches the calculated CRC32C. + */ +bool +proxy_protocol_parse_crc32c_tlv(const uint16_t len, const uint8_t *value) +{ + if (len != 4) + { + msg(M_NONFATAL, "PROXY protocol v2: CRC32C TLV invalid length"); + parsing_state = PROXY_PROTOCOL_PARSING_STATE_INVALID; + return false; + } + + uint32_t expected_crc32c = ntohl(*(uint32_t *)value); + + /* fill with 0s the crc32 field to calculate the actual crc32 */ + *(uint32_t *)value = 0; + uint32_t calculated_crc32c = proxy_protocol_crc32c((const uint8_t *)&header, header_len); + + if (expected_crc32c != calculated_crc32c) + { + msg(M_NONFATAL, "PROXY protocol v2: CRC32C mismatch, expected: 0x%08x calculated: 0x%08x. Dropping header", expected_crc32c, calculated_crc32c); + parsing_state = PROXY_PROTOCOL_PARSING_STATE_INVALID; + return false; + } + msg(M_DEBUG, "PROXY protocol v2: CRC32C match"); + return true; +} + +/* + * Parse the UNIQUE_ID TLV and store the value in ppi->unique_id + * (and ppi->unique_id_len). + * + * @param ppi - The proxy protocol info structure to store the parsed data. + * @param len - The length of the TLV value. + * @param value - The TLV value. + */ +void +proxy_protocol_parse_uid_tlv(struct proxy_protocol_info *ppi, const uint16_t len, const uint8_t *value) +{ + if (len == 0) + { + msg(M_NONFATAL, "PROXY protocol v2: UNIQUE_ID TLV empty"); + return; + } + else if (len > PROXY_PROTOCOL_V2_TLV_UNIQUE_ID_MAX_LEN) + { + msg(M_NONFATAL, "PROXY protocol v2: UNIQUE_ID TLV too long"); + return; + } + + ppi->unique_id_len = len; + memcpy(ppi->unique_id, value, len); + msg(M_DEBUG, "PROXY protocol v2: UNIQUE_ID: %.*s", (int)ppi->unique_id_len, ppi->unique_id); +} + +/* + * Parse the SSL TLV and store the value in ppi->ssl_client and ppi->ssl_verify. + * + * @param ppi - The proxy protocol info structure to store the parsed data. + * @param len - The length of the TLV value. + * @param value - The TLV value. + */ +void +proxy_protocol_parse_ssl_tlv(struct proxy_protocol_info *ppi, const uint16_t len, const uint8_t *value) +{ + const struct proxy_protocol_tlv_ssl *ssl = (const struct proxy_protocol_tlv_ssl *)(value); + + if (!ssl->client) + { + msg(M_NONFATAL, "PROXY protocol v2: SSL TLV invalid"); + return; + } + + if (ssl->client & PROXY_PROTOCOL_V2_CLIENT_SSL) + { + msg(M_DEBUG, "PROXY protocol v2: client connected over SSL/TLS"); + } + if (ssl->client & PROXY_PROTOCOL_V2_CLIENT_CERT_CONN) + { + msg(M_DEBUG, "PROXY protocol v2: client provided a certificate over the current connection"); + } + if (ssl->client & PROXY_PROTOCOL_V2_CLIENT_CERT_SESS) + { + msg(M_DEBUG, "PROXY protocol v2: client provided a certificate at least once over the TLS session this connection belongs to"); + } + + msg(M_DEBUG, "PROXY protocol v2: client certificate verification stat: %s", ssl->verify ? "failure" : "success"); + ppi->ssl_client = ssl->client; + ppi->ssl_verify = ssl->verify == 0; +} + +/* + * Parse a TLV and store the value in the proxy protocol info structure. + * + * @param ppi - The proxy protocol info structure to store the parsed data. + * @param type - The TLV type. + * @param len - The length of the TLV value. + * @param value - The TLV value. + */ +void +proxy_protocol_parse_tlv(struct proxy_protocol_info *ppi, const uint8_t type, const uint16_t len, const uint8_t *value) +{ + switch (type) + { + case PROXY_PROTOCOL_TLV_TYPE_ALPN: + proxy_protocol_parse_string_tlv(ppi, &ppi->alpn, "ALPN", len, value); + break; + + case PROXY_PROTOCOL_TLV_TYPE_AUTHORITY: + proxy_protocol_parse_string_tlv(ppi, &ppi->authority, "AUTHORITY", len, value); + break; + + case PROXY_PROTOCOL_TLV_TYPE_CRC32C: + proxy_protocol_parse_crc32c_tlv(len, value); + break; + + case PROXY_PROTOCOL_TLV_TYPE_NOOP: + break; + + case PROXY_PROTOCOL_TLV_TYPE_UNIQUE_ID: + proxy_protocol_parse_uid_tlv(ppi, len, value); + break; + + case PROXY_PROTOCOL_TLV_TYPE_SSL: + proxy_protocol_parse_ssl_tlv(ppi, len, value); + break; + + case PROXY_PROTOCOL_TLV_SUBTYPE_SSL_VERSION: + proxy_protocol_parse_string_tlv(ppi, &ppi->ssl_version, "SSL_VERSION", len, value); + break; + + case PROXY_PROTOCOL_TLV_SUBTYPE_SSL_CN: + proxy_protocol_parse_string_tlv(ppi, &ppi->ssl_cn, "SSL_CN", len, value); + break; + + case PROXY_PROTOCOL_TLV_SUBTYPE_SSL_CIPHER: + proxy_protocol_parse_string_tlv(ppi, &ppi->ssl_cipher, "SSL_CIPHER", len, value); + break; + + case PROXY_PROTOCOL_TLV_SUBTYPE_SSL_SIG_ALG: + proxy_protocol_parse_string_tlv(ppi, &ppi->ssl_sig_alg, "SSL_SIG_ALG", len, value); + break; + + case PROXY_PROTOCOL_TLV_SUBTYPE_SSL_KEY_ALG: + proxy_protocol_parse_string_tlv(ppi, &ppi->ssl_key_alg, "SSL_KEY_ALG", len, value); + break; + + case PROXY_PROTOCOL_TLV_TYPE_NETNS: + proxy_protocol_parse_string_tlv(ppi, &ppi->netns, "NETNS", len, value); + break; + + default: + msg(M_NONFATAL, "PROXY protocol v2: unknown TLV type 0x%02x", type); + break; + } +} + +/* + * Parse the TLVs in the PROXY protocol v2 header. + * + * @param ppi - The proxy protocol info structure to store the parsed data. + * @param buf - The buffer containing the TLVs. + * @param buf_len - The length of the buffer. + * + * @return - The number of bytes parsed or -1 if an error occurred. + */ +int +proxy_protocol_parse_tlvs(struct proxy_protocol_info *ppi, const uint8_t *buf, + const int buf_len) +{ + const uint8_t *end = buf + buf_len; + const uint8_t *start = buf; + + ppi->gc = gc_new(); + while (buf < end && parsing_state == PROXY_PROTOCOL_PARSING_STATE_OK) + { + const struct proxy_protocol_tlv *tlv = (const struct proxy_protocol_tlv *)buf; + uint16_t tlv_len = (tlv->length_hi << 8) | tlv->length_lo; + if (buf + sizeof(*tlv) + tlv_len > end) + { + msg(M_NONFATAL, "PROXY protocol v2: TLV length exceeds buffer size"); + return -1; + } + proxy_protocol_parse_tlv(ppi, tlv->type, tlv_len, tlv->value); + buf += sizeof(*tlv) + tlv_len; + } + return (int)(buf - start); +} + +/* * Parse the PROXY protocol v2 header. * * @param ppi - The proxy protocol info structure to store the parsed data. @@ -435,7 +739,7 @@ { if ((header.v2.ver_cmd & PROXY_PROTOCOL_V2_VER_MASK) == PROXY_PROTOCOL_V2_VER) { - proxy_protocol_parse_v2(ppi); + int pos = proxy_protocol_parse_v2(ppi); if (parsing_state == PROXY_PROTOCOL_PARSING_STATE_IGNORE) { msg(M_DEBUG, "PROXY protocol v2: ignoring header"); @@ -445,6 +749,21 @@ { return false; } + + if (pos < header_len) /* there's extra TLV data to parse */ + { + pos += proxy_protocol_parse_tlvs(ppi, (uint8_t *)(&header) + pos, + header_len - pos); + if (parsing_state == PROXY_PROTOCOL_PARSING_STATE_INVALID) + { + return false; + } + if (pos < header_len) + { + msg(M_NONFATAL, "PROXY protocol v2: could not correclty parse TLV data"); + } + } + msg(M_DEBUG, "PROXY protocol v2: header parsed"); return true; } diff --git a/src/openvpn/proxy_protocol.h b/src/openvpn/proxy_protocol.h index 8e9af03..a492f85 100644 --- a/src/openvpn/proxy_protocol.h +++ b/src/openvpn/proxy_protocol.h @@ -60,6 +60,25 @@ #define PROXY_PROTOCOL_V2_TP_STREAM (0x1 << 0) #define PROXY_PROTOCOL_V2_TP_DGRAM (0x2 << 0) +#define PROXY_PROTOCOL_TLV_TYPE_ALPN 0x01 +#define PROXY_PROTOCOL_TLV_TYPE_AUTHORITY 0x02 +#define PROXY_PROTOCOL_TLV_TYPE_CRC32C 0x03 +#define PROXY_PROTOCOL_TLV_TYPE_NOOP 0x04 +#define PROXY_PROTOCOL_TLV_TYPE_UNIQUE_ID 0x05 +#define PROXY_PROTOCOL_TLV_TYPE_SSL 0x20 +#define PROXY_PROTOCOL_TLV_SUBTYPE_SSL_VERSION 0x21 +#define PROXY_PROTOCOL_TLV_SUBTYPE_SSL_CN 0x22 +#define PROXY_PROTOCOL_TLV_SUBTYPE_SSL_CIPHER 0x23 +#define PROXY_PROTOCOL_TLV_SUBTYPE_SSL_SIG_ALG 0x24 +#define PROXY_PROTOCOL_TLV_SUBTYPE_SSL_KEY_ALG 0x25 +#define PROXY_PROTOCOL_TLV_TYPE_NETNS 0x30 + +#define PROXY_PROTOCOL_V2_CLIENT_SSL 0x01 +#define PROXY_PROTOCOL_V2_CLIENT_CERT_CONN 0x02 +#define PROXY_PROTOCOL_V2_CLIENT_CERT_SESS 0x04 + +#define PROXY_PROTOCOL_V2_TLV_UNIQUE_ID_MAX_LEN 128 + typedef enum { PROXY_PROTOCOL_VERSION_INVALID = -1, @@ -69,6 +88,22 @@ PROXY_PROTOCOL_VERSION_2, } proxy_protocol_version_t; +struct proxy_protocol_tlv +{ + uint8_t type; + uint8_t length_hi; + uint8_t length_lo; + uint8_t value[0]; +}; + +#pragma pack(push, 1) +struct proxy_protocol_tlv_ssl +{ + uint8_t client; + uint32_t verify; +} __attribute__((packed)); +#pragma pack(pop) + /* HAProxy PROXY protocol header */ typedef union { @@ -115,6 +150,23 @@ int sock_type; struct openvpn_sockaddr src; struct openvpn_sockaddr dst; + + /* data extracted from TLVs */ + char *alpn; + char *authority; + + uint8_t unique_id[PROXY_PROTOCOL_V2_TLV_UNIQUE_ID_MAX_LEN + 1]; + uint16_t unique_id_len; + + uint8_t ssl_client; + uint32_t ssl_verify; + char *ssl_version; + char *ssl_cn; + char *ssl_cipher; + char *ssl_sig_alg; + char *ssl_key_alg; + + char *netns; }; /*