OpenVPN
misc.c
Go to the documentation of this file.
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-2024 OpenVPN Inc <sales@openvpn.net>
9 * Copyright (C) 2014-2015 David Sommerseth <davids@redhat.com>
10 * Copyright (C) 2016-2024 David Sommerseth <davids@openvpn.net>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2
14 * as published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 */
25
26#ifdef HAVE_CONFIG_H
27#include "config.h"
28#endif
29
30#include "syshead.h"
31
32#include "buffer.h"
33#include "misc.h"
34#include "base64.h"
35#include "tun.h"
36#include "error.h"
37#include "otime.h"
38#include "plugin.h"
39#include "options.h"
40#include "manage.h"
41#include "crypto.h"
42#include "route.h"
43#include "console.h"
44#include "win32.h"
45
46#include "memdbg.h"
47
48#ifdef ENABLE_IPROUTE
49const char *iproute_path = IPROUTE_PATH; /* GLOBAL */
50#endif
51
52/*
53 * Set standard file descriptors to /dev/null
54 */
55void
56set_std_files_to_null(bool stdin_only)
57{
58#if defined(HAVE_DUP) && defined(HAVE_DUP2)
59 int fd;
60 if ((fd = open("/dev/null", O_RDWR, 0)) != -1)
61 {
62 dup2(fd, 0);
63 if (!stdin_only)
64 {
65 dup2(fd, 1);
66 dup2(fd, 2);
67 }
68 if (fd > 2)
69 {
70 close(fd);
71 }
72 }
73#endif
74}
75
76/*
77 * Prepend a random string to hostname to prevent DNS caching.
78 * For example, foo.bar.gov would be modified to <random-chars>.foo.bar.gov.
79 * Of course, this requires explicit support in the DNS server (wildcard).
80 */
81const char *
82hostname_randomize(const char *hostname, struct gc_arena *gc)
83{
84#define n_rnd_bytes 6
85
86 uint8_t rnd_bytes[n_rnd_bytes];
87 const char *rnd_str;
88 struct buffer hname = alloc_buf_gc(strlen(hostname)+sizeof(rnd_bytes)*2+4, gc);
89
91 rnd_str = format_hex_ex(rnd_bytes, sizeof(rnd_bytes), 40, 0, NULL, gc);
92 buf_printf(&hname, "%s.%s", rnd_str, hostname);
93 return BSTR(&hname);
94#undef n_rnd_bytes
95}
96
97#ifdef ENABLE_MANAGEMENT
98/* Get username/password from the management interface */
99static bool
100auth_user_pass_mgmt(struct user_pass *up, const char *prefix, const unsigned int flags,
101 const char *auth_challenge)
102{
103 const char *sc = NULL;
104
106 {
107 management_auth_failure(management, prefix, "previous auth credentials failed");
108 }
109
111 {
113 }
114 if (!management_query_user_pass(management, up, prefix, flags, sc))
115 {
116 if ((flags & GET_USER_PASS_NOFATAL) != 0)
117 {
118 return false;
119 }
120 else
121 {
122 msg(M_FATAL, "ERROR: could not read %s username/password/ok/string from management interface", prefix);
123 }
124 }
125 return true;
126}
127
140static struct auth_challenge_info *
142{
144
145 struct auth_challenge_info *ac;
146 const int len = strlen(auth_challenge);
147 char *work = (char *) gc_malloc(len+1, false, gc);
148 char *cp;
149
150 struct buffer b;
152
154
155 /* parse prefix */
156 if (!buf_parse(&b, ':', work, len))
157 {
158 return NULL;
159 }
160 if (strcmp(work, "CRV1"))
161 {
162 return NULL;
163 }
164
165 /* parse flags */
166 if (!buf_parse(&b, ':', work, len))
167 {
168 return NULL;
169 }
170 for (cp = work; *cp != '\0'; ++cp)
171 {
172 const char c = *cp;
173 if (c == 'E')
174 {
175 ac->flags |= CR_ECHO;
176 }
177 else if (c == 'R')
178 {
179 ac->flags |= CR_RESPONSE;
180 }
181 }
182
183 /* parse state ID */
184 if (!buf_parse(&b, ':', work, len))
185 {
186 return NULL;
187 }
188 ac->state_id = string_alloc(work, gc);
189
190 /* parse user name */
191 if (!buf_parse(&b, ':', work, len))
192 {
193 return NULL;
194 }
195 ac->user = (char *) gc_malloc(strlen(work)+1, true, gc);
196 openvpn_base64_decode(work, (void *)ac->user, -1);
197
198 /* parse challenge text */
199 ac->challenge_text = string_alloc(BSTR(&b), gc);
200
201 return ac;
202}
203
204#endif /* ifdef ENABLE_MANAGEMENT */
205
206/*
207 * Get and store a username/password
208 */
209
210bool
212 const char *auth_file,
213 const char *prefix,
214 const unsigned int flags,
215 const char *auth_challenge)
216{
217 struct gc_arena gc = gc_new();
218
219 if (!up->defined)
220 {
221 bool from_authfile = (auth_file && !streq(auth_file, "stdin"));
222 bool username_from_stdin = false;
223 bool password_from_stdin = false;
224 bool response_from_stdin = true;
225
228 {
229 msg(M_WARN, "Note: previous '%s' credentials failed", prefix);
230 }
231
232#ifdef ENABLE_MANAGEMENT
233 /*
234 * Get username/password from management interface?
235 */
236 if (management
237 && (!from_authfile && (flags & GET_USER_PASS_MANAGEMENT))
239 {
240 response_from_stdin = false;
241 if (!auth_user_pass_mgmt(up, prefix, flags, auth_challenge))
242 {
243 return false;
244 }
245 }
246 else
247#endif /* ifdef ENABLE_MANAGEMENT */
248 /*
249 * Get NEED_OK confirmation from the console
250 */
251 if (flags & GET_USER_PASS_NEED_OK)
252 {
253 struct buffer user_prompt = alloc_buf_gc(128, &gc);
254
255 buf_printf(&user_prompt, "NEED-OK|%s|%s:", prefix, up->username);
257 up->password, USER_PASS_LEN, false))
258 {
259 msg(M_FATAL, "ERROR: could not read %s ok-confirmation from stdin", prefix);
260 }
261
262 if (!strlen(up->password))
263 {
264 strcpy(up->password, "ok");
265 }
266 }
267 else if (flags & GET_USER_PASS_INLINE_CREDS)
268 {
269 struct buffer buf;
270 buf_set_read(&buf, (uint8_t *) auth_file, strlen(auth_file) + 1);
271 if (!(flags & GET_USER_PASS_PASSWORD_ONLY))
272 {
273 buf_parse(&buf, '\n', up->username, USER_PASS_LEN);
274 }
275 buf_parse(&buf, '\n', up->password, USER_PASS_LEN);
276
277 if (strlen(up->password) == 0)
278 {
280 }
281 }
282 /*
283 * Read from auth file unless this is a dynamic challenge request.
284 */
285 else if (from_authfile && !(flags & GET_USER_PASS_DYNAMIC_CHALLENGE))
286 {
287 /*
288 * Try to get username/password from a file.
289 */
290 FILE *fp;
291 char password_buf[USER_PASS_LEN] = { '\0' };
292
293 fp = platform_fopen(auth_file, "r");
294 if (!fp)
295 {
296 msg(M_ERR, "Error opening '%s' auth file: %s", prefix, auth_file);
297 }
298
299 if ((flags & GET_USER_PASS_PASSWORD_ONLY) == 0)
300 {
301 /* Read username first */
302 if (fgets(up->username, USER_PASS_LEN, fp) == NULL)
303 {
304 msg(M_FATAL, "Error reading username from %s authfile: %s",
305 prefix,
306 auth_file);
307 }
308 }
309 chomp(up->username);
310
312 {
314 }
315
316 if (flags & GET_USER_PASS_PASSWORD_ONLY && !password_buf[0])
317 {
318 msg(M_FATAL, "Error reading password from %s authfile: %s", prefix, auth_file);
319 }
320
321 if (password_buf[0])
322 {
324 }
325 /* The auth-file does not have the password: get both username
326 * and password from the management interface if possible.
327 * Otherwise set to read password from console.
328 */
329#if defined(ENABLE_MANAGEMENT)
330 else if (management
331 && (flags & GET_USER_PASS_MANAGEMENT)
333 {
334 msg(D_LOW, "No password found in %s authfile '%s'. Querying the management interface", prefix, auth_file);
335 if (!auth_user_pass_mgmt(up, prefix, flags, auth_challenge))
336 {
337 fclose(fp);
338 return false;
339 }
340 }
341#endif
342 else
343 {
345 }
346
347 fclose(fp);
348
349 if (!(flags & GET_USER_PASS_PASSWORD_ONLY) && strlen(up->username) == 0)
350 {
351 msg(M_FATAL, "ERROR: username from %s authfile '%s' is empty", prefix, auth_file);
352 }
353 }
354 else
355 {
356 username_from_stdin = true;
357 password_from_stdin = true;
358 }
359
360 /*
361 * Get username/password from standard input?
362 */
364 {
365#ifdef ENABLE_MANAGEMENT
367 {
369 if (ac)
370 {
371 char *response = (char *) gc_malloc(USER_PASS_LEN, false, &gc);
373
374 challenge = alloc_buf_gc(14+strlen(ac->challenge_text), &gc);
375 buf_printf(&challenge, "CHALLENGE: %s", ac->challenge_text);
377
379 response, USER_PASS_LEN, BOOL_CAST(ac->flags&CR_ECHO)))
380 {
381 msg(M_FATAL, "ERROR: could not read challenge response from stdin");
382 }
383 strncpynt(up->username, ac->user, USER_PASS_LEN);
384 buf_printf(&packed_resp, "CRV1::%s::%s", ac->state_id, response);
385 }
386 else
387 {
388 msg(M_FATAL, "ERROR: received malformed challenge request from server");
389 }
390 }
391 else
392#endif /* ifdef ENABLE_MANAGEMENT */
393 {
394 struct buffer user_prompt = alloc_buf_gc(128, &gc);
395 struct buffer pass_prompt = alloc_buf_gc(128, &gc);
396
398 buf_printf(&user_prompt, "Enter %s Username:", prefix);
399 buf_printf(&pass_prompt, "Enter %s Password:", prefix);
400
402 {
404 up->username, USER_PASS_LEN, true);
405 }
406
408 {
410 up->password, USER_PASS_LEN, false);
411 }
412
413 if (!query_user_exec() )
414 {
415 msg(M_FATAL, "ERROR: Failed retrieving username or password");
416 }
417
418 if (!(flags & GET_USER_PASS_PASSWORD_ONLY))
419 {
420 if (strlen(up->username) == 0)
421 {
422 msg(M_FATAL, "ERROR: %s username is empty", prefix);
423 }
424 }
425
426#ifdef ENABLE_MANAGEMENT
428 {
429 char *response = (char *) gc_malloc(USER_PASS_LEN, false, &gc);
431 char *pw64 = NULL, *resp64 = NULL;
432
434 buf_printf(&challenge, "CHALLENGE: %s", auth_challenge);
435
437 response, USER_PASS_LEN,
439 {
440 msg(M_FATAL, "ERROR: could not retrieve static challenge response");
441 }
443 {
444 if (openvpn_base64_encode(up->password, strlen(up->password), &pw64) == -1
445 || openvpn_base64_encode(response, strlen(response), &resp64) == -1)
446 {
447 msg(M_FATAL, "ERROR: could not base64-encode password/static_response");
448 }
450 buf_printf(&packed_resp, "SCRV1:%s:%s", pw64, resp64);
452 free(pw64);
454 free(resp64);
455 }
456 else
457 {
458 if (strlen(up->password) + strlen(response) >= USER_PASS_LEN)
459 {
460 msg(M_FATAL, "ERROR: could not concatenate password/static_response: string too long");
461 }
462 strncat(up->password, response, USER_PASS_LEN - strlen(up->password) - 1);
463 }
464 }
465#endif /* ifdef ENABLE_MANAGEMENT */
466 }
467 }
468
471
472 up->defined = true;
473 }
474
475#if 0
476 msg(M_INFO, "GET_USER_PASS %s u='%s' p='%s'", prefix, up->username, up->password);
477#endif
478
479 gc_free(&gc);
480
481 return true;
482}
483
484void
485purge_user_pass(struct user_pass *up, const bool force)
486{
487 const bool nocache = up->nocache;
488 static bool warn_shown = false;
489 if (nocache || force)
490 {
491 secure_memzero(up, sizeof(*up));
492 up->nocache = nocache;
493 }
494 else
495 {
497 /*
498 * don't show warning if the pass has been replaced by a token: this is an
499 * artificial "auth-nocache"
500 */
501 if (!warn_shown)
502 {
503 msg(M_WARN, "WARNING: this configuration may cache passwords in memory -- use the auth-nocache option to prevent this");
504 warn_shown = true;
505 }
506 }
507}
508
509void
510set_auth_token(struct user_pass *tk, const char *token)
511{
512 if (strlen(token))
513 {
515 strncpynt(tk->password, token, USER_PASS_LEN);
516 tk->token_defined = true;
517
518 /*
519 * If username already set, tk is fully defined.
520 */
521 if (strlen(tk->username))
522 {
523 tk->defined = true;
524 }
526 }
527}
528
529void
530set_auth_token_user(struct user_pass *tk, const char *username)
531{
532 if (strlen(username))
533 {
535 /* Clear the username before decoding to ensure no old material is left
536 * and also allow decoding to not use all space to ensure the last byte is
537 * always 0 */
538 CLEAR(tk->username);
539 int len = openvpn_base64_decode(username, tk->username, USER_PASS_LEN - 1);
540 tk->defined = len > 0;
541 if (!tk->defined)
542 {
543 msg(D_PUSH, "Error decoding auth-token-username");
544 }
546 }
547}
548
549
550/*
551 * Process string received by untrusted peer before
552 * printing to console or log file.
553 *
554 * Assumes that string has been null terminated.
555 */
556const char *
557safe_print(const char *str, struct gc_arena *gc)
558{
559 return string_mod_const(str, CC_PRINT, CC_CRLF, '.', gc);
560}
561
562const char **
563make_arg_array(const char *first, const char *parms, struct gc_arena *gc)
564{
565 char **ret = NULL;
566 int base = 0;
567 const int max_parms = MAX_PARMS + 2;
568 int n = 0;
569
570 /* alloc return array */
571 ALLOC_ARRAY_CLEAR_GC(ret, char *, max_parms, gc);
572
573 /* process first parameter, if provided */
574 if (first)
575 {
576 ret[base++] = string_alloc(first, gc);
577 }
578
579 if (parms)
580 {
581 n = parse_line(parms, &ret[base], max_parms - base - 1, "make_arg_array", 0, M_WARN, gc);
582 ASSERT(n >= 0 && n + base + 1 <= max_parms);
583 }
584 ret[base + n] = NULL;
585
586 return (const char **)ret;
587}
588
589static const char **
590make_inline_array(const char *str, struct gc_arena *gc)
591{
593 struct buffer buf;
594 int len = 0;
595 char **ret = NULL;
596 int i = 0;
597
598 buf_set_read(&buf, (const uint8_t *) str, strlen(str));
599 while (buf_parse(&buf, '\n', line, sizeof(line)))
600 {
601 ++len;
602 }
603
604 /* alloc return array */
605 ALLOC_ARRAY_CLEAR_GC(ret, char *, len + 1, gc);
606
607 buf_set_read(&buf, (const uint8_t *) str, strlen(str));
608 while (buf_parse(&buf, '\n', line, sizeof(line)))
609 {
610 chomp(line);
611 ASSERT(i < len);
613 ++i;
614 }
615 ASSERT(i <= len);
616 ret[i] = NULL;
617 return (const char **)ret;
618}
619
620static const char **
621make_arg_copy(char **p, struct gc_arena *gc)
622{
623 char **ret = NULL;
624 const int len = string_array_len((const char **)p);
625 const int max_parms = len + 1;
626 int i;
627
628 /* alloc return array */
629 ALLOC_ARRAY_CLEAR_GC(ret, char *, max_parms, gc);
630
631 for (i = 0; i < len; ++i)
632 {
633 ret[i] = p[i];
634 }
635
636 return (const char **)ret;
637}
638
639const char **
641{
642 const int argc = string_array_len((const char **)p);
643 if (is_inline)
644 {
645 return make_inline_array(p[0], gc);
646 }
647 else if (argc == 0)
648 {
649 return make_arg_array(NULL, NULL, gc);
650 }
651 else if (argc == 1)
652 {
653 return make_arg_array(p[0], NULL, gc);
654 }
655 else if (argc == 2)
656 {
657 return make_arg_array(p[0], p[1], gc);
658 }
659 else
660 {
661 return make_arg_copy(p, gc);
662 }
663}
664
665/*
666 * Remove security-sensitive strings from control message
667 * so that they will not be output to log file.
668 */
669const char *
671{
672 char *ret = gc_malloc(strlen(src)+1, false, gc);
673 char *dest = ret;
674 bool redact = false;
675 int skip = 0;
676
677 for (;; )
678 {
679 const char c = *src;
680 if (c == '\0')
681 {
682 break;
683 }
684 if (c == 'S' && !strncmp(src, "SESS_ID_", 8))
685 {
686 skip = 7;
687 redact = true;
688 }
689 else if (c == 'e' && !strncmp(src, "echo ", 5))
690 {
691 skip = 4;
692 redact = true;
693 }
695 && (c == 'a' && !strncmp(src, "auth-token ", 11)))
696 {
697 /* Unless --verb is 7 or higher (D_SHOW_KEYS), hide
698 * the auth-token value coming in the src string
699 */
700 skip = 10;
701 redact = true;
702 }
703
704 if (c == ',') /* end of redacted item? */
705 {
706 skip = 0;
707 redact = false;
708 }
709
710 if (redact)
711 {
712 if (skip > 0)
713 {
714 --skip;
715 *dest++ = c;
716 }
717 }
718 else
719 {
720 *dest++ = c;
721 }
722
723 ++src;
724 }
725 *dest = '\0';
726 return ret;
727}
728
729/* helper to parse peer_info received from multi client, validate
730 * (this is untrusted data) and put into environment
731 */
732bool
734{
735 uint8_t c;
736 int state = 0;
737 while (*line)
738 {
739 c = *line;
740 switch (state)
741 {
742 case 0:
743 case 1:
744 if (c == '=' && state == 1)
745 {
746 state = 2;
747 }
748 else if (isalnum(c) || c == '_')
749 {
750 state = 1;
751 }
752 else
753 {
754 return false;
755 }
756
757 case 2:
758 /* after the '=', replace non-printable or shell meta with '_' */
759 if (!isprint(c) || isspace(c)
760 || c == '$' || c == '(' || c == '`')
761 {
762 *line = '_';
763 }
764 }
765 line++;
766 }
767 return (state == 2);
768}
769
770void
771output_peer_info_env(struct env_set *es, const char *peer_info)
772{
773 char line[256];
774 struct buffer buf;
775 buf_set_read(&buf, (const uint8_t *) peer_info, strlen(peer_info));
776 while (buf_parse(&buf, '\n', line, sizeof(line)))
777 {
778 chomp(line);
780 && (strncmp(line, "IV_", 3) == 0 || strncmp(line, "UV_", 3) == 0) )
781 {
782 msg(M_INFO, "peer info: %s", line);
784 }
785 else
786 {
787 msg(M_WARN, "validation failed on peer_info line received from client");
788 }
789 }
790}
791
792struct buffer
793prepend_dir(const char *dir, const char *path, struct gc_arena *gc)
794{
795 size_t len = strlen(dir) + strlen(PATH_SEPARATOR_STR) + strlen(path) + 1;
798 ASSERT(combined_path.len > 0);
799
800 return combined_path;
801}
802
803void
805{
806 if (up->protected)
807 {
808 return;
809 }
810#ifdef _WIN32
811 if (protect_buffer_win32(up->username, sizeof(up->username))
812 && protect_buffer_win32(up->password, sizeof(up->password)))
813 {
814 up->protected = true;
815 }
816 else
817 {
818 purge_user_pass(up, true);
819 }
820#endif
821}
822
823void
825{
826 if (!up->protected)
827 {
828 return;
829 }
830#ifdef _WIN32
831 if (unprotect_buffer_win32(up->username, sizeof(up->username))
832 && unprotect_buffer_win32(up->password, sizeof(up->password)))
833 {
834 up->protected = false;
835 }
836 else
837 {
838 purge_user_pass(up, true);
839 }
840#endif
841}
const char * skip_leading_whitespace(const char *str)
Definition buffer.c:579
bool buf_printf(struct buffer *buf, const char *format,...)
Definition buffer.c:240
void string_clear(char *str)
Definition buffer.c:691
char * format_hex_ex(const uint8_t *data, int size, int maxoutput, unsigned int space_break_flags, const char *separator, struct gc_arena *gc)
Definition buffer.c:483
void chomp(char *str)
Definition buffer.c:614
void * gc_malloc(size_t size, bool clear, struct gc_arena *a)
Definition buffer.c:336
struct buffer alloc_buf_gc(size_t size, struct gc_arena *gc)
Definition buffer.c:88
bool string_mod(char *str, const unsigned int inclusive, const unsigned int exclusive, const char replace)
Modifies a string in place by replacing certain classes of characters of it with a specified characte...
Definition buffer.c:1041
const char * string_mod_const(const char *str, const unsigned int inclusive, const unsigned int exclusive, const char replace, struct gc_arena *gc)
Returns a copy of a string with certain classes of characters of it replaced with a specified charact...
Definition buffer.c:1090
int string_array_len(const char **array)
Definition buffer.c:703
bool buf_parse(struct buffer *buf, const int delim, char *line, const int size)
Definition buffer.c:825
char * string_alloc(const char *str, struct gc_arena *gc)
Definition buffer.c:649
#define BSTR(buf)
Definition buffer.h:129
#define ALLOC_ARRAY_CLEAR_GC(dptr, type, n, gc)
Definition buffer.h:1082
#define CC_CRLF
carriage return or newline
Definition buffer.h:920
static void buf_set_write(struct buffer *buf, uint8_t *data, int size)
Definition buffer.h:331
static void buf_set_read(struct buffer *buf, const uint8_t *data, size_t size)
Definition buffer.h:348
static void secure_memzero(void *data, size_t len)
Securely zeroise memory.
Definition buffer.h:414
#define ALLOC_OBJ_CLEAR_GC(dptr, type, gc)
Definition buffer.h:1097
#define BLEN(buf)
Definition buffer.h:127
static void strncpynt(char *dest, const char *src, size_t maxlen)
Definition buffer.h:361
static void gc_free(struct gc_arena *a)
Definition buffer.h:1033
#define CC_PRINT
printable (>= 32, != 127)
Definition buffer.h:891
static struct gc_arena gc_new(void)
Definition buffer.h:1025
void query_user_clear(void)
Wipes all data put into all of the query_user structs.
Definition console.c:45
void query_user_add(char *prompt, size_t prompt_len, char *resp, size_t resp_len, bool echo)
Adds an item to ask the user for.
Definition console.c:57
static bool query_user_exec(void)
Wrapper function enabling query_user_exec() if no alternative methods have been enabled.
Definition console.h:107
static bool query_user_SINGLE(char *prompt, size_t prompt_len, char *resp, size_t resp_len, bool echo)
A plain "make Gert happy" wrapper.
Definition console.h:122
void prng_bytes(uint8_t *output, int len)
Definition crypto.c:1750
Data Channel Cryptography Module.
void env_set_add(struct env_set *es, const char *str)
Definition env_set.c:193
#define D_PUSH
Definition errlevel.h:83
#define D_SHOW_KEYS
Definition errlevel.h:121
#define D_LOW
Definition errlevel.h:97
#define M_INFO
Definition errlevel.h:55
void management_auth_failure(struct management *man, const char *type, const char *reason)
Definition manage.c:3092
bool management_query_user_pass(struct management *man, struct user_pass *up, const char *type, const unsigned int flags, const char *static_challenge)
Definition manage.c:3494
static bool management_query_user_pass_enabled(const struct management *man)
Definition manage.h:440
static const char ** make_inline_array(const char *str, struct gc_arena *gc)
Definition misc.c:590
void unprotect_user_pass(struct user_pass *up)
Decrypt username and password buffers in user_pass.
Definition misc.c:824
bool get_user_pass_cr(struct user_pass *up, const char *auth_file, const char *prefix, const unsigned int flags, const char *auth_challenge)
Retrieves the user credentials from various sources depending on the flags.
Definition misc.c:211
const char ** make_arg_array(const char *first, const char *parms, struct gc_arena *gc)
Definition misc.c:563
#define n_rnd_bytes
void purge_user_pass(struct user_pass *up, const bool force)
Definition misc.c:485
bool validate_peer_info_line(char *line)
Definition misc.c:733
void set_auth_token_user(struct user_pass *tk, const char *username)
Sets the auth-token username by base64 decoding the passed username.
Definition misc.c:530
void set_std_files_to_null(bool stdin_only)
Definition misc.c:56
void output_peer_info_env(struct env_set *es, const char *peer_info)
Definition misc.c:771
struct buffer prepend_dir(const char *dir, const char *path, struct gc_arena *gc)
Prepend a directory to a path.
Definition misc.c:793
static struct auth_challenge_info * parse_auth_challenge(const char *auth_challenge, struct gc_arena *gc)
Parses an authentication challenge string and returns an auth_challenge_info structure.
Definition misc.c:141
void protect_user_pass(struct user_pass *up)
Encrypt username and password buffers in user_pass.
Definition misc.c:804
const char ** make_extended_arg_array(char **p, bool is_inline, struct gc_arena *gc)
Definition misc.c:640
static const char ** make_arg_copy(char **p, struct gc_arena *gc)
Definition misc.c:621
const char * safe_print(const char *str, struct gc_arena *gc)
Definition misc.c:557
const char * sanitize_control_message(const char *src, struct gc_arena *gc)
Definition misc.c:670
static bool auth_user_pass_mgmt(struct user_pass *up, const char *prefix, const unsigned int flags, const char *auth_challenge)
Definition misc.c:100
const char * hostname_randomize(const char *hostname, struct gc_arena *gc)
Definition misc.c:82
void set_auth_token(struct user_pass *tk, const char *token)
Sets the auth-token to token.
Definition misc.c:510
#define USER_PASS_LEN
Definition misc.h:69
#define GET_USER_PASS_STATIC_CHALLENGE_CONCAT
Definition misc.h:122
#define GET_USER_PASS_MANAGEMENT
Definition misc.h:109
#define GET_USER_PASS_PASSWORD_ONLY
Definition misc.h:111
#define GET_USER_PASS_STATIC_CHALLENGE_ECHO
Definition misc.h:119
#define CR_ECHO
Definition misc.h:81
#define CR_RESPONSE
Definition misc.h:82
#define GET_USER_PASS_INLINE_CREDS
Definition misc.h:121
#define GET_USER_PASS_STATIC_CHALLENGE
Definition misc.h:118
#define GET_USER_PASS_NEED_OK
Definition misc.h:112
#define GET_USER_PASS_NOFATAL
Definition misc.h:113
#define GET_USER_PASS_PREVIOUS_CREDS_FAILED
Definition misc.h:115
#define GET_USER_PASS_DYNAMIC_CHALLENGE
Definition misc.h:117
#define BOOL_CAST(x)
Definition basic.h:27
#define CLEAR(x)
Definition basic.h:33
#define M_FATAL
Definition error.h:89
static bool check_debug_level(unsigned int level)
Definition error.h:220
#define M_ERR
Definition error.h:105
#define msg(flags,...)
Definition error.h:144
#define ASSERT(x)
Definition error.h:195
#define M_WARN
Definition error.h:91
int parse_line(const char *line, char *p[], const int n, const char *file, const int line_num, int msglevel, struct gc_arena *gc)
Definition options.c:5076
#define streq(x, y)
Definition options.h:725
#define MAX_PARMS
Definition options.h:52
#define OPTION_LINE_SIZE
Definition options.h:58
FILE * platform_fopen(const char *path, const char *mode)
Definition platform.c:501
int openvpn_base64_decode(const char *str, void *data, int size)
Definition base64.c:158
int openvpn_base64_encode(const void *data, int size, char **str)
Definition base64.c:52
static char * auth_challenge
Definition ssl.c:285
Wrapper structure for dynamically allocated memory.
Definition buffer.h:61
int len
Length in bytes of the actual content within the allocated memory.
Definition buffer.h:66
Garbage collection arena used to keep track of dynamically allocated memory.
Definition buffer.h:117
bool protected
Definition misc.h:63
bool defined
Definition misc.h:58
char password[USER_PASS_LEN]
Definition misc.h:73
bool nocache
Definition misc.h:62
char username[USER_PASS_LEN]
Definition misc.h:72
#define PATH_SEPARATOR_STR
Definition syshead.h:427
struct env_set * es
struct gc_arena gc
Definition test_ssl.c:155
bool unprotect_buffer_win32(char *buf, size_t len)
Decrypt a previously encrypted region of memory using CryptUnProtectMemory() with access restricted t...
Definition win32.c:1680
bool protect_buffer_win32(char *buf, size_t len)
Encrypt a region of memory using CryptProtectMemory() with access restricted to the current process.
Definition win32.c:1662