1 /*
2  *  OpenVPN -- An application to securely tunnel IP networks
3  *             over a single TCP/UDP port, with support for SSL/TLS-based
4  *             session authentication and key exchange,
5  *             packet encryption, packet authentication, and
6  *             packet compression.
7  *
8  *  Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net>
9  *
10  *  This program is free software; you can redistribute it and/or modify
11  *  it under the terms of the GNU General Public License version 2
12  *  as published by the Free Software Foundation.
13  *
14  *  This program is distributed in the hope that it will be useful,
15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *  GNU General Public License for more details.
18  *
19  *  You should have received a copy of the GNU General Public License along
20  *  with this program; if not, write to the Free Software Foundation, Inc.,
21  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22  */
23 #ifndef AUTH_TOKEN_H
24 #define AUTH_TOKEN_H
25 
26 /**
27  * Generate an auth token based on username and timestamp
28  *
29  * The idea of auth token is to be stateless, so that we can verify use it
30  * even after we have forgotten about it or server has been restarted.
31  *
32  * To achieve this even though we cannot trust the client we use HMAC
33  * to be able to verify the information.
34  *
35  * Format of the auth-token (before base64 encode)
36  *
37  * session id(12 bytes)|uint64 timestamp (8 bytes)|
38  * uint64 timestamp (8 bytes)|sha256-hmac(32 bytes)
39  *
40  * The first timestamp is the time the token was initially created and is used to
41  * determine the maximum renewable time of the token. We always include this even
42  * if tokens do not expire (this value is not used) to keep the code cleaner.
43  *
44  * The second timestamp is the time the token was renewed/regenerated and is used
45  * to determine if this token has been renewed in the acceptable time range
46  * (2 * renogiation timeout)
47  *
48  * The session id is a random string of 12 byte (or 16 in base64) that is not
49  * used by OpenVPN itself but kept intact so that external logging/managment
50  * can track the session multiple reconnects/servers. It is delibrately chosen
51  * be a multiple of 3 bytes to have a base64 encoding without padding.
52  *
53  * The hmac is calculated over the username contactinated with the
54  * raw auth-token bytes to include authentication of the username in the token
55  *
56  * We encode the auth-token with base64 and then prepend "SESS_ID_" before
57  * sending it to the client.
58  *
59  * This function will free() an existing multi->auth_token and keep the
60  * existing initial timestamp and session id contained in that token.
61  */
62 void
63 generate_auth_token(const struct user_pass *up, struct tls_multi *multi);
64 
65 /**
66  * Verifies the auth token to be in the format that generate_auth_token
67  * create and checks if the token is valid.
68  *
69  */
70 unsigned
71 verify_auth_token(struct user_pass *up, struct tls_multi *multi,
72                   struct tls_session *session);
73 
74 
75 
76 /**
77  * Loads an HMAC secret from a file or if no file is present generates a
78  * epheremal secret for the run time of the server and stores it into ctx
79  */
80 void
81 auth_token_init_secret(struct key_ctx *key_ctx, const char *key_file,
82                        bool key_inline);
83 
84 
85 /**
86  * Generate a auth-token server secret key, and write to file.
87  *
88  * @param filename          Filename of the server key file to create.
89  */
90 void auth_token_write_server_key_file(const char *filename);
91 
92 
93 /**
94  * Put the session id, and auth token status into the environment
95  * if auth-token is enabled
96  *
97  */
98 void add_session_token_env(struct tls_session *session, struct tls_multi *multi,
99                            const struct user_pass *up);
100 
101 /**
102  * Wipes the authentication token out of the memory, frees and cleans up
103  * related buffers and flags
104  *
105  *  @param multi  Pointer to a multi object holding the auth_token variables
106  */
107 void wipe_auth_token(struct tls_multi *multi);
108 
109 /**
110  * The prefix given to auth tokens start with, this prefix is special
111  * cased to not show up in log files in OpenVPN 2 and 3
112  *
113  * We also prefix this with _AT_ to only act on auth token generated by us.
114  */
115 #define SESSION_ID_PREFIX "SESS_ID_AT_"
116 
117 /**
118  * Return if the password string has the format of a password.
119  *
120  * This fuction will always read as many bytes as SESSION_ID_PREFIX is longer
121  * the caller needs ensure that password memory is at least that long (true for
122  * calling with struct user_pass)
123  * @param password
124  * @return whether the password string starts with the session token prefix
125  */
126 static inline bool
is_auth_token(const char * password)127 is_auth_token(const char *password)
128 {
129     return (memcmp_constant_time(SESSION_ID_PREFIX, password,
130                                  strlen(SESSION_ID_PREFIX)) == 0);
131 }
132 #endif /* AUTH_TOKEN_H */
133