summaryrefslogtreecommitdiff
path: root/src/openvpn/auth_token.h
diff options
context:
space:
mode:
authorBernhard Schmidt <berni@debian.org>2020-09-01 16:52:17 +0200
committerBernhard Schmidt <berni@debian.org>2020-09-01 16:52:17 +0200
commit9fc3b98112217f2d92a67977dbde0987cc7a1803 (patch)
tree29fcc8654ee65d9dd89ade797bea2f3d9dfd9cfd /src/openvpn/auth_token.h
parenta8758c0e03eed188dcb9da0e4fd781a67c25bf1e (diff)
parent69b02b1f7fd609d84ace13ab04697158de2418a9 (diff)
Merge branch 'debian/experimental-2.5'
Diffstat (limited to 'src/openvpn/auth_token.h')
-rw-r--r--src/openvpn/auth_token.h132
1 files changed, 132 insertions, 0 deletions
diff --git a/src/openvpn/auth_token.h b/src/openvpn/auth_token.h
new file mode 100644
index 0000000..fe07945
--- /dev/null
+++ b/src/openvpn/auth_token.h
@@ -0,0 +1,132 @@
+/*
+ * OpenVPN -- An application to securely tunnel IP networks
+ * over a single TCP/UDP port, with support for SSL/TLS-based
+ * session authentication and key exchange,
+ * packet encryption, packet authentication, and
+ * packet compression.
+ *
+ * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef AUTH_TOKEN_H
+#define AUTH_TOKEN_H
+
+/**
+ * Generate an auth token based on username and timestamp
+ *
+ * The idea of auth token is to be stateless, so that we can verify use it
+ * even after we have forgotten about it or server has been restarted.
+ *
+ * To achieve this even though we cannot trust the client we use HMAC
+ * to be able to verify the information.
+ *
+ * Format of the auth-token (before base64 encode)
+ *
+ * session id(12 bytes)|uint64 timestamp (8 bytes)|
+ * uint64 timestamp (8 bytes)|sha256-hmac(32 bytes)
+ *
+ * The first timestamp is the time the token was initially created and is used to
+ * determine the maximum renewable time of the token. We always include this even
+ * if tokens do not expire (this value is not used) to keep the code cleaner.
+ *
+ * The second timestamp is the time the token was renewed/regenerated and is used
+ * to determine if this token has been renewed in the acceptable time range
+ * (2 * renogiation timeout)
+ *
+ * The session id is a random string of 12 byte (or 16 in base64) that is not
+ * used by OpenVPN itself but kept intact so that external logging/managment
+ * can track the session multiple reconnects/servers. It is delibrately chosen
+ * be a multiple of 3 bytes to have a base64 encoding without padding.
+ *
+ * The hmac is calculated over the username contactinated with the
+ * raw auth-token bytes to include authentication of the username in the token
+ *
+ * We encode the auth-token with base64 and then prepend "SESS_ID_" before
+ * sending it to the client.
+ *
+ * This function will free() an existing multi->auth_token and keep the
+ * existing initial timestamp and session id contained in that token.
+ */
+void
+generate_auth_token(const struct user_pass *up, struct tls_multi *multi);
+
+/**
+ * Verifies the auth token to be in the format that generate_auth_token
+ * create and checks if the token is valid.
+ *
+ */
+unsigned
+verify_auth_token(struct user_pass *up, struct tls_multi *multi,
+ struct tls_session *session);
+
+
+
+/**
+ * Loads an HMAC secret from a file or if no file is present generates a
+ * epheremal secret for the run time of the server and stores it into ctx
+ */
+void
+auth_token_init_secret(struct key_ctx *key_ctx, const char *key_file,
+ bool key_inline);
+
+
+/**
+ * Generate a auth-token server secret key, and write to file.
+ *
+ * @param filename Filename of the server key file to create.
+ */
+void auth_token_write_server_key_file(const char *filename);
+
+
+/**
+ * Put the session id, and auth token status into the environment
+ * if auth-token is enabled
+ *
+ */
+void add_session_token_env(struct tls_session *session, struct tls_multi *multi,
+ const struct user_pass *up);
+
+/**
+ * Wipes the authentication token out of the memory, frees and cleans up
+ * related buffers and flags
+ *
+ * @param multi Pointer to a multi object holding the auth_token variables
+ */
+void wipe_auth_token(struct tls_multi *multi);
+
+/**
+ * The prefix given to auth tokens start with, this prefix is special
+ * cased to not show up in log files in OpenVPN 2 and 3
+ *
+ * We also prefix this with _AT_ to only act on auth token generated by us.
+ */
+#define SESSION_ID_PREFIX "SESS_ID_AT_"
+
+/**
+ * Return if the password string has the format of a password.
+ *
+ * This fuction will always read as many bytes as SESSION_ID_PREFIX is longer
+ * the caller needs ensure that password memory is at least that long (true for
+ * calling with struct user_pass)
+ * @param password
+ * @return whether the password string starts with the session token prefix
+ */
+static inline bool
+is_auth_token(const char *password)
+{
+ return (memcmp_constant_time(SESSION_ID_PREFIX, password,
+ strlen(SESSION_ID_PREFIX)) == 0);
+}
+#endif /* AUTH_TOKEN_H */