From ca7b1849a8fe7884f06fb8d8c4abb8f7866368a3 Mon Sep 17 00:00:00 2001 From: Justin Bailey Date: Thu, 9 Mar 2023 10:43:16 -0800 Subject: [PATCH] Allow longer username and password under Dynamic Challenge/Response Protocol. Based on patches found at https://github.com/samm-git/aws-vpn-client, this updates OpenVPN for compatibility with AWS' (and other vendors) use of the dynamic challenge/response protocol to implement SAML-based authentication. Those vendors submit the password via the management interface, which can be up to 50kb long. --- flake.lock | 218 ++++++++++++++++++++++++++++++++++++++++++ flake.nix | 48 ++++++++++ src/openvpn/common.h | 6 +- src/openvpn/manage.c | 4 +- src/openvpn/misc.h | 6 +- src/openvpn/options.h | 9 +- 6 files changed, 283 insertions(+), 8 deletions(-) create mode 100644 flake.lock create mode 100644 flake.nix diff --git a/flake.lock b/flake.lock new file mode 100644 index 00000000000..71594dfdc8c --- /dev/null +++ b/flake.lock @@ -0,0 +1,218 @@ +{ + "nodes": { + "devenv": { + "inputs": { + "flake-compat": "flake-compat", + "nix": "nix", + "nixpkgs": "nixpkgs", + "pre-commit-hooks": "pre-commit-hooks" + }, + "locked": { + "lastModified": 1679485772, + "narHash": "sha256-luKwPSKJ5kUa05AaAW4+WgOh41IsPHKc6kY+a465Mis=", + "owner": "cachix", + "repo": "devenv", + "rev": "7c7cc865f8660312948dee4515542df9d6d640b9", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "devenv", + "type": "github" + } + }, + "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1673956053, + "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-utils": { + "locked": { + "lastModified": 1667395993, + "narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "gitignore": { + "inputs": { + "nixpkgs": [ + "devenv", + "pre-commit-hooks", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1660459072, + "narHash": "sha256-8DFJjXG8zqoONA1vXtgeKXy68KdJL5UaXR8NtVMUbx8=", + "owner": "hercules-ci", + "repo": "gitignore.nix", + "rev": "a20de23b925fd8264fd7fad6454652e142fd7f73", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "gitignore.nix", + "type": "github" + } + }, + "lowdown-src": { + "flake": false, + "locked": { + "lastModified": 1633514407, + "narHash": "sha256-Dw32tiMjdK9t3ETl5fzGrutQTzh2rufgZV4A/BbxuD4=", + "owner": "kristapsdz", + "repo": "lowdown", + "rev": "d2c2b44ff6c27b936ec27358a2653caaef8f73b8", + "type": "github" + }, + "original": { + "owner": "kristapsdz", + "repo": "lowdown", + "type": "github" + } + }, + "nix": { + "inputs": { + "lowdown-src": "lowdown-src", + "nixpkgs": [ + "devenv", + "nixpkgs" + ], + "nixpkgs-regression": "nixpkgs-regression" + }, + "locked": { + "lastModified": 1676545802, + "narHash": "sha256-EK4rZ+Hd5hsvXnzSzk2ikhStJnD63odF7SzsQ8CuSPU=", + "owner": "domenkozar", + "repo": "nix", + "rev": "7c91803598ffbcfe4a55c44ac6d49b2cf07a527f", + "type": "github" + }, + "original": { + "owner": "domenkozar", + "ref": "relaxed-flakes", + "repo": "nix", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1678875422, + "narHash": "sha256-T3o6NcQPwXjxJMn2shz86Chch4ljXgZn746c2caGxd8=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "126f49a01de5b7e35a43fd43f891ecf6d3a51459", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-regression": { + "locked": { + "lastModified": 1643052045, + "narHash": "sha256-uGJ0VXIhWKGXxkeNnq4TvV3CIOkUJ3PAoLZ3HMzNVMw=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", + "type": "github" + }, + "original": { + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", + "type": "github" + } + }, + "nixpkgs-stable": { + "locked": { + "lastModified": 1673800717, + "narHash": "sha256-SFHraUqLSu5cC6IxTprex/nTsI81ZQAtDvlBvGDWfnA=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "2f9fd351ec37f5d479556cd48be4ca340da59b8f", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-22.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1679318992, + "narHash": "sha256-uoj5Oy6hruIHuxzfQZtcalObe5kPrX9v+ClUMFEOzmE=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "e2c97799da5f5cd87adfa5017fba971771e123ef", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-22.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "pre-commit-hooks": { + "inputs": { + "flake-compat": [ + "devenv", + "flake-compat" + ], + "flake-utils": "flake-utils", + "gitignore": "gitignore", + "nixpkgs": [ + "devenv", + "nixpkgs" + ], + "nixpkgs-stable": "nixpkgs-stable" + }, + "locked": { + "lastModified": 1678376203, + "narHash": "sha256-3tyYGyC8h7fBwncLZy5nCUjTJPrHbmNwp47LlNLOHSM=", + "owner": "cachix", + "repo": "pre-commit-hooks.nix", + "rev": "1a20b9708962096ec2481eeb2ddca29ed747770a", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "pre-commit-hooks.nix", + "type": "github" + } + }, + "root": { + "inputs": { + "devenv": "devenv", + "nixpkgs": "nixpkgs_2" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 00000000000..45c1fd1d135 --- /dev/null +++ b/flake.nix @@ -0,0 +1,48 @@ +{ + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-22.11"; + devenv.url = "github:cachix/devenv"; + }; + + outputs = { self, nixpkgs, devenv, ... } @ inputs: + let + systems = [ "x86_64-linux" "i686-linux" "x86_64-darwin" "aarch64-linux" "aarch64-darwin" ]; + forAllSystems = f: builtins.listToAttrs (map (name: { inherit name; value = f name; }) systems); + in + { + devShells = forAllSystems + (system: + let + pkgs = import nixpkgs { + inherit system; + }; + in + { + default = devenv.lib.mkShell { + inherit inputs pkgs; + modules = [ + { + # https://devenv.sh/reference/options/ + packages = [ + pkgs.autoconf + pkgs.automake + pkgs.libtool + pkgs.openssl_1_1 + pkgs.lz4 + pkgs.lzo + pkgs.pam + pkgs.cmocka + ]; + + languages.c.enable = true; + + enterShell = '' + # Allows autreconf to find libtool. + export ACLOCAL_PATH=${pkgs.libtool}/share/aclocal:$ACLOCAL_PATH + ''; + } + ]; + }; + }); + }; +} diff --git a/src/openvpn/common.h b/src/openvpn/common.h index f77685c8f32..16af2d77452 100644 --- a/src/openvpn/common.h +++ b/src/openvpn/common.h @@ -64,9 +64,11 @@ typedef unsigned long ptr_type; /* * This parameter controls the TLS channel buffer size and the * maximum size of a single TLS message (cleartext). - * This parameter must be >= PUSH_BUNDLE_SIZE + * This parameter must be >= PUSH_BUNDLE_SIZE. It must also be greater than + * the size of a long (>50Kb) password in the dyanmic challenge/response + * protocol, */ -#define TLS_CHANNEL_BUF_SIZE 2048 +#define TLS_CHANNEL_BUF_SIZE 65536 /* TLS control buffer minimum size * diff --git a/src/openvpn/manage.c b/src/openvpn/manage.c index db88e347911..fa79e6ce95f 100644 --- a/src/openvpn/manage.c +++ b/src/openvpn/manage.c @@ -2244,7 +2244,7 @@ man_read(struct management *man) /* * read command line from socket */ - unsigned char buf[256]; + unsigned char buf[TLS_CHANNEL_BUF_SIZE]; int len = 0; #ifdef TARGET_ANDROID @@ -2580,7 +2580,7 @@ man_connection_init(struct management *man) * Allocate helper objects for command line input and * command output from/to the socket. */ - man->connection.in = command_line_new(1024); + man->connection.in = command_line_new(TLS_CHANNEL_BUF_SIZE); man->connection.out = buffer_list_new(); /* diff --git a/src/openvpn/misc.h b/src/openvpn/misc.h index b000b729a18..2bf3dcdef3e 100644 --- a/src/openvpn/misc.h +++ b/src/openvpn/misc.h @@ -65,7 +65,11 @@ struct user_pass #ifdef ENABLE_PKCS11 #define USER_PASS_LEN 4096 #else -#define USER_PASS_LEN 128 +/* + * Increase the username and password length size to 65KB, in order + * to support long passwords under the dynamic challenge/response protocol. + */ +#define USER_PASS_LEN 65536 #endif /* Note that username and password are expected to be null-terminated */ char username[USER_PASS_LEN]; diff --git a/src/openvpn/options.h b/src/openvpn/options.h index 7df717f73f6..78ca5dabef5 100644 --- a/src/openvpn/options.h +++ b/src/openvpn/options.h @@ -52,10 +52,13 @@ #define MAX_PARMS 16 /* - * Max size of options line and parameter. + * Max size of options line and parameter. Note these + * must be able to accomodate large (>50Kb) values in + * order to support long passwords under the dynamic challenge-response + * protocol. */ -#define OPTION_PARM_SIZE 256 -#define OPTION_LINE_SIZE 256 +#define OPTION_PARM_SIZE USER_PASS_LEN +#define OPTION_LINE_SIZE OPTION_PARM_SIZE extern const char title_string[];