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-2025 OpenVPN Inc <sales@openvpn.net>
9 * Copyright (C) 2014-2015 David Sommerseth <davids@redhat.com>
10 * Copyright (C) 2016-2025 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, see <https://www.gnu.org/licenses/>.
23 */
24
25#ifdef HAVE_CONFIG_H
26#include "config.h"
27#endif
28
29#include "syshead.h"
30
31#include "buffer.h"
32#include "misc.h"
33#include "base64.h"
34#include "tun.h"
35#include "error.h"
36#include "otime.h"
37#include "plugin.h"
38#include "options.h"
39#include "manage.h"
40#include "crypto.h"
41#include "route.h"
42#include "console.h"
43#include "win32.h"
44
45#include "memdbg.h"
46
47#ifdef ENABLE_IPROUTE
48const char *iproute_path = IPROUTE_PATH; /* GLOBAL */
49#endif
50
51/*
52 * Set standard file descriptors to /dev/null
53 */
54void
55set_std_files_to_null(bool stdin_only)
56{
57#if defined(HAVE_DUP) && defined(HAVE_DUP2)
58 int fd;
59 if ((fd = open("/dev/null", O_RDWR, 0)) != -1)
60 {
61 dup2(fd, 0);
62 if (!stdin_only)
63 {
64 dup2(fd, 1);
65 dup2(fd, 2);
66 }
67 if (fd > 2)
68 {
69 close(fd);
70 }
71 }
72#endif
73}
74
75#ifdef ENABLE_MANAGEMENT
76/* Get username/password from the management interface */
77static bool
78auth_user_pass_mgmt(struct user_pass *up, const char *prefix, const unsigned int flags,
79 const char *auth_challenge)
80{
81 const char *sc = NULL;
82
84 {
85 management_auth_failure(management, prefix, "previous auth credentials failed");
86 }
87
89 {
90 sc = auth_challenge;
91 }
92 if (!management_query_user_pass(management, up, prefix, flags, sc))
93 {
94 if ((flags & GET_USER_PASS_NOFATAL) != 0)
95 {
96 return false;
97 }
98 else
99 {
100 msg(M_FATAL,
101 "ERROR: could not read %s username/password/ok/string from management interface",
102 prefix);
103 }
104 }
105 return true;
106}
107
121static struct auth_challenge_info *
123{
125
126 struct auth_challenge_info *ac;
127 const int len = strlen(auth_challenge);
128 char *work = (char *)gc_malloc(len + 1, false, gc);
129 char *cp;
130
131 struct buffer b;
133
135
136 /* parse prefix */
137 if (!buf_parse(&b, ':', work, len))
138 {
139 return NULL;
140 }
141 if (strcmp(work, "CRV1"))
142 {
143 return NULL;
144 }
145
146 /* parse flags */
147 if (!buf_parse(&b, ':', work, len))
148 {
149 return NULL;
150 }
151 for (cp = work; *cp != '\0'; ++cp)
152 {
153 const char c = *cp;
154 if (c == 'E')
155 {
156 ac->flags |= CR_ECHO;
157 }
158 else if (c == 'R')
159 {
160 ac->flags |= CR_RESPONSE;
161 }
162 }
163
164 /* parse state ID */
165 if (!buf_parse(&b, ':', work, len))
166 {
167 return NULL;
168 }
169 ac->state_id = string_alloc(work, gc);
170
171 /* parse user name */
172 if (!buf_parse(&b, ':', work, len))
173 {
174 return NULL;
175 }
176 ac->user = (char *)gc_malloc(strlen(work) + 1, true, gc);
177 openvpn_base64_decode(work, (void *)ac->user, -1);
178
179 /* parse challenge text */
180 ac->challenge_text = string_alloc(BSTR(&b), gc);
181
182 return ac;
183}
184
185#endif /* ifdef ENABLE_MANAGEMENT */
186
187/*
188 * Get and store a username/password
189 */
190
191bool
192get_user_pass_cr(struct user_pass *up, const char *auth_file, const char *prefix,
193 const unsigned int flags, const char *auth_challenge)
194{
195 struct gc_arena gc = gc_new();
196
197 if (!up->defined)
198 {
199 bool from_authfile = (auth_file && !streq(auth_file, "stdin"));
200 bool username_from_stdin = false;
201 bool password_from_stdin = false;
202 bool response_from_stdin = true;
203
206 {
207 msg(M_WARN, "Note: previous '%s' credentials failed", prefix);
208 }
209
210#ifdef ENABLE_MANAGEMENT
211 /*
212 * Get username/password from management interface?
213 */
214 if (management && (!from_authfile && (flags & GET_USER_PASS_MANAGEMENT))
216 {
217 response_from_stdin = false;
218 if (!auth_user_pass_mgmt(up, prefix, flags, auth_challenge))
219 {
220 return false;
221 }
222 }
223 else
224#endif /* ifdef ENABLE_MANAGEMENT */
225 /*
226 * Get NEED_OK confirmation from the console
227 */
228 if (flags & GET_USER_PASS_NEED_OK)
229 {
230 struct buffer user_prompt = alloc_buf_gc(128, &gc);
231
232 buf_printf(&user_prompt, "NEED-OK|%s|%s:", prefix, up->username);
234 USER_PASS_LEN, false))
235 {
236 msg(M_FATAL, "ERROR: could not read %s ok-confirmation from stdin", prefix);
237 }
238
239 if (!strlen(up->password))
240 {
241 strcpy(up->password, "ok");
242 }
243 }
244 else if (flags & GET_USER_PASS_INLINE_CREDS)
245 {
246 struct buffer buf;
247 buf_set_read(&buf, (uint8_t *)auth_file, strlen(auth_file) + 1);
248 if (!(flags & GET_USER_PASS_PASSWORD_ONLY))
249 {
250 buf_parse(&buf, '\n', up->username, USER_PASS_LEN);
251 }
252 buf_parse(&buf, '\n', up->password, USER_PASS_LEN);
253
254 if (strlen(up->password) == 0)
255 {
257 }
258 }
259 /*
260 * Read from auth file unless this is a dynamic challenge request.
261 */
262 else if (from_authfile && !(flags & GET_USER_PASS_DYNAMIC_CHALLENGE))
263 {
264 /*
265 * Try to get username/password from a file.
266 */
267 FILE *fp;
268 char password_buf[USER_PASS_LEN] = { '\0' };
269
270 fp = platform_fopen(auth_file, "r");
271 if (!fp)
272 {
273 msg(M_ERR, "Error opening '%s' auth file: %s", prefix, auth_file);
274 }
275
276 if ((flags & GET_USER_PASS_PASSWORD_ONLY) == 0)
277 {
278 /* Read username first */
279 if (fgets(up->username, USER_PASS_LEN, fp) == NULL)
280 {
281 msg(M_FATAL, "Error reading username from %s authfile: %s", prefix,
282 auth_file);
283 }
284 }
285 chomp(up->username);
286
288 {
290 }
291
292 if (flags & GET_USER_PASS_PASSWORD_ONLY && !password_buf[0])
293 {
294 msg(M_FATAL, "Error reading password from %s authfile: %s", prefix, auth_file);
295 }
296
297 if (password_buf[0])
298 {
300 }
301 /* The auth-file does not have the password: get both username
302 * and password from the management interface if possible.
303 * Otherwise set to read password from console.
304 */
305#if defined(ENABLE_MANAGEMENT)
306 else if (management && (flags & GET_USER_PASS_MANAGEMENT)
308 {
309 msg(D_LOW,
310 "No password found in %s authfile '%s'. Querying the management interface",
311 prefix, auth_file);
312 if (!auth_user_pass_mgmt(up, prefix, flags, auth_challenge))
313 {
314 fclose(fp);
315 return false;
316 }
317 }
318#endif
319 else
320 {
322 }
323
324 fclose(fp);
325
326 if (!(flags & GET_USER_PASS_PASSWORD_ONLY) && strlen(up->username) == 0)
327 {
328 msg(M_FATAL, "ERROR: username from %s authfile '%s' is empty", prefix,
329 auth_file);
330 }
331 }
332 else
333 {
334 username_from_stdin = true;
335 password_from_stdin = true;
336 }
337
338 /*
339 * Get username/password from standard input?
340 */
342 {
343#ifdef ENABLE_MANAGEMENT
345 {
347 if (ac)
348 {
349 char *response = (char *)gc_malloc(USER_PASS_LEN, false, &gc);
351
352 challenge = alloc_buf_gc(14 + strlen(ac->challenge_text), &gc);
353 buf_printf(&challenge, "CHALLENGE: %s", ac->challenge_text);
355
356 if (!query_user_SINGLE(BSTR(&challenge), BLEN(&challenge), response,
357 USER_PASS_LEN, BOOL_CAST(ac->flags & CR_ECHO)))
358 {
359 msg(M_FATAL, "ERROR: could not read challenge response from stdin");
360 }
361 strncpynt(up->username, ac->user, USER_PASS_LEN);
362 buf_printf(&packed_resp, "CRV1::%s::%s", ac->state_id, response);
363 }
364 else
365 {
366 msg(M_FATAL, "ERROR: received malformed challenge request from server");
367 }
368 }
369 else
370#endif /* ifdef ENABLE_MANAGEMENT */
371 {
372 struct buffer user_prompt = alloc_buf_gc(128, &gc);
373 struct buffer pass_prompt = alloc_buf_gc(128, &gc);
374
376 buf_printf(&user_prompt, "Enter %s Username:", prefix);
377 buf_printf(&pass_prompt, "Enter %s Password:", prefix);
378
380 {
382 USER_PASS_LEN, true);
383 }
384
386 {
388 USER_PASS_LEN, false);
389 }
390
391 if (!query_user_exec())
392 {
393 msg(M_FATAL, "ERROR: Failed retrieving username or password");
394 }
395
396 if (!(flags & GET_USER_PASS_PASSWORD_ONLY))
397 {
398 if (strlen(up->username) == 0)
399 {
400 msg(M_FATAL, "ERROR: %s username is empty", prefix);
401 }
402 }
403
404#ifdef ENABLE_MANAGEMENT
407 {
408 char *response = (char *)gc_malloc(USER_PASS_LEN, false, &gc);
410 char *pw64 = NULL, *resp64 = NULL;
411
413 buf_printf(&challenge, "CHALLENGE: %s", auth_challenge);
414
415 if (!query_user_SINGLE(BSTR(&challenge), BLEN(&challenge), response,
418 {
419 msg(M_FATAL, "ERROR: could not retrieve static challenge response");
420 }
422 {
423 if (openvpn_base64_encode(up->password, strlen(up->password), &pw64) == -1
424 || openvpn_base64_encode(response, strlen(response), &resp64) == -1)
425 {
426 msg(M_FATAL, "ERROR: could not base64-encode password/static_response");
427 }
429 buf_printf(&packed_resp, "SCRV1:%s:%s", pw64, resp64);
431 free(pw64);
433 free(resp64);
434 }
435 else
436 {
437 if (strlen(up->password) + strlen(response) >= USER_PASS_LEN)
438 {
439 msg(M_FATAL,
440 "ERROR: could not concatenate password/static_response: string too long");
441 }
442 strncat(up->password, response, USER_PASS_LEN - strlen(up->password) - 1);
443 }
444 }
445#endif /* ifdef ENABLE_MANAGEMENT */
446 }
447 }
448
451
452 up->defined = true;
453 }
454
455#if 0
456 msg(M_INFO, "GET_USER_PASS %s u='%s' p='%s'", prefix, up->username, up->password);
457#endif
458
459 gc_free(&gc);
460
461 return true;
462}
463
464void
465purge_user_pass(struct user_pass *up, const bool force)
466{
467 const bool nocache = up->nocache;
468 static bool warn_shown = false;
469 if (nocache || force)
470 {
471 secure_memzero(up, sizeof(*up));
472 up->nocache = nocache;
473 }
474 else
475 {
477 /*
478 * don't show warning if the pass has been replaced by a token: this is an
479 * artificial "auth-nocache"
480 */
481 if (!warn_shown)
482 {
483 msg(M_WARN,
484 "WARNING: this configuration may cache passwords in memory -- use the auth-nocache option to prevent this");
485 warn_shown = true;
486 }
487 }
488}
489
490void
491set_auth_token(struct user_pass *tk, const char *token)
492{
493 if (strlen(token))
494 {
496 strncpynt(tk->password, token, USER_PASS_LEN);
497 tk->token_defined = true;
498
499 /*
500 * If username already set, tk is fully defined.
501 */
502 if (strlen(tk->username))
503 {
504 tk->defined = true;
505 }
507 }
508}
509
510void
511set_auth_token_user(struct user_pass *tk, const char *username)
512{
513 if (strlen(username))
514 {
516 /* Clear the username before decoding to ensure no old material is left
517 * and also allow decoding to not use all space to ensure the last byte is
518 * always 0 */
519 CLEAR(tk->username);
520 int len = openvpn_base64_decode(username, tk->username, USER_PASS_LEN - 1);
521 tk->defined = len > 0;
522 if (!tk->defined)
523 {
524 msg(D_PUSH, "Error decoding auth-token-username");
525 }
527 }
528}
529
530
531/*
532 * Process string received by untrusted peer before
533 * printing to console or log file.
534 *
535 * Assumes that string has been null terminated.
536 */
537const char *
538safe_print(const char *str, struct gc_arena *gc)
539{
540 return string_mod_const(str, CC_PRINT, CC_CRLF, '.', gc);
541}
542
543const char **
544make_arg_array(const char *first, const char *parms, struct gc_arena *gc)
545{
546 char **ret = NULL;
547 int base = 0;
548 const int max_parms = MAX_PARMS + 2;
549 int n = 0;
550
551 /* alloc return array */
552 ALLOC_ARRAY_CLEAR_GC(ret, char *, max_parms, gc);
553
554 /* process first parameter, if provided */
555 if (first)
556 {
557 ret[base++] = string_alloc(first, gc);
558 }
559
560 if (parms)
561 {
562 n = parse_line(parms, &ret[base], max_parms - base - 1, "make_arg_array", 0, M_WARN, gc);
563 ASSERT(n >= 0 && n + base + 1 <= max_parms);
564 }
565 ret[base + n] = NULL;
566
567 return (const char **)ret;
568}
569
570static const char **
571make_inline_array(const char *str, struct gc_arena *gc)
572{
574 struct buffer buf;
575 int len = 0;
576 char **ret = NULL;
577 int i = 0;
578
579 buf_set_read(&buf, (const uint8_t *)str, strlen(str));
580 while (buf_parse(&buf, '\n', line, sizeof(line)))
581 {
582 ++len;
583 }
584
585 /* alloc return array */
586 ALLOC_ARRAY_CLEAR_GC(ret, char *, len + 1, gc);
587
588 buf_set_read(&buf, (const uint8_t *)str, strlen(str));
589 while (buf_parse(&buf, '\n', line, sizeof(line)))
590 {
591 chomp(line);
592 ASSERT(i < len);
594 ++i;
595 }
596 ASSERT(i <= len);
597 ret[i] = NULL;
598 return (const char **)ret;
599}
600
601static const char **
602make_arg_copy(char **p, struct gc_arena *gc)
603{
604 char **ret = NULL;
605 const int len = string_array_len((const char **)p);
606 const int max_parms = len + 1;
607 int i;
608
609 /* alloc return array */
610 ALLOC_ARRAY_CLEAR_GC(ret, char *, max_parms, gc);
611
612 for (i = 0; i < len; ++i)
613 {
614 ret[i] = p[i];
615 }
616
617 return (const char **)ret;
618}
619
620const char **
622{
623 const int argc = string_array_len((const char **)p);
624 if (is_inline)
625 {
626 return make_inline_array(p[0], gc);
627 }
628 else if (argc == 0)
629 {
630 return make_arg_array(NULL, NULL, gc);
631 }
632 else if (argc == 1)
633 {
634 return make_arg_array(p[0], NULL, gc);
635 }
636 else if (argc == 2)
637 {
638 return make_arg_array(p[0], p[1], gc);
639 }
640 else
641 {
642 return make_arg_copy(p, gc);
643 }
644}
645
646/*
647 * Remove security-sensitive strings from control message
648 * so that they will not be output to log file.
649 */
650const char *
652{
653 char *ret = gc_malloc(strlen(src) + 1, false, gc);
654 char *dest = ret;
655 bool redact = false;
656 int skip = 0;
657
658 for (;;)
659 {
660 const char c = *src;
661 if (c == '\0')
662 {
663 break;
664 }
665 if (c == 'S' && !strncmp(src, "SESS_ID_", 8))
666 {
667 skip = 7;
668 redact = true;
669 }
670 else if (c == 'e' && !strncmp(src, "echo ", 5))
671 {
672 skip = 4;
673 redact = true;
674 }
675 else if (!check_debug_level(D_SHOW_KEYS) && (c == 'a' && !strncmp(src, "auth-token ", 11)))
676 {
677 /* Unless --verb is 7 or higher (D_SHOW_KEYS), hide
678 * the auth-token value coming in the src string
679 */
680 skip = 10;
681 redact = true;
682 }
683
684 if (c == ',') /* end of redacted item? */
685 {
686 skip = 0;
687 redact = false;
688 }
689
690 if (redact)
691 {
692 if (skip > 0)
693 {
694 --skip;
695 *dest++ = c;
696 }
697 }
698 else
699 {
700 *dest++ = c;
701 }
702
703 ++src;
704 }
705 *dest = '\0';
706 return ret;
707}
708
709/* helper to parse peer_info received from multi client, validate
710 * (this is untrusted data) and put into environment
711 */
712bool
714{
715 uint8_t c;
716 int state = 0;
717 while (*line)
718 {
719 c = *line;
720 switch (state)
721 {
722 case 0:
723 case 1:
724 if (c == '=' && state == 1)
725 {
726 state = 2;
727 }
728 else if (isalnum(c) || c == '_')
729 {
730 state = 1;
731 }
732 else
733 {
734 return false;
735 }
736
737 case 2:
738 /* after the '=', replace non-printable or shell meta with '_' */
739 if (!isprint(c) || isspace(c) || c == '$' || c == '(' || c == '`')
740 {
741 *line = '_';
742 }
743 }
744 line++;
745 }
746 return (state == 2);
747}
748
749void
750output_peer_info_env(struct env_set *es, const char *peer_info)
751{
752 char line[256];
753 struct buffer buf;
754 buf_set_read(&buf, (const uint8_t *)peer_info, strlen(peer_info));
755 while (buf_parse(&buf, '\n', line, sizeof(line)))
756 {
757 chomp(line);
759 && (strncmp(line, "IV_", 3) == 0 || strncmp(line, "UV_", 3) == 0))
760 {
761 msg(M_INFO, "peer info: %s", line);
763 }
764 else
765 {
766 msg(M_WARN, "validation failed on peer_info line received from client");
767 }
768 }
769}
770
771struct buffer
772prepend_dir(const char *dir, const char *path, struct gc_arena *gc)
773{
774 size_t len = strlen(dir) + strlen(PATH_SEPARATOR_STR) + strlen(path) + 1;
777 ASSERT(combined_path.len > 0);
778
779 return combined_path;
780}
781
782void
784{
785 if (up->protected)
786 {
787 return;
788 }
789#ifdef _WIN32
790 if (protect_buffer_win32(up->username, sizeof(up->username))
791 && protect_buffer_win32(up->password, sizeof(up->password)))
792 {
793 up->protected = true;
794 }
795 else
796 {
797 purge_user_pass(up, true);
798 }
799#endif
800}
801
802void
804{
805 if (!up->protected)
806 {
807 return;
808 }
809#ifdef _WIN32
810 if (unprotect_buffer_win32(up->username, sizeof(up->username))
811 && unprotect_buffer_win32(up->password, sizeof(up->password)))
812 {
813 up->protected = false;
814 }
815 else
816 {
817 purge_user_pass(up, true);
818 }
819#endif
820}
const char * skip_leading_whitespace(const char *str)
Definition buffer.c:579
bool buf_printf(struct buffer *buf, const char *format,...)
Definition buffer.c:241
void string_clear(char *str)
Definition buffer.c:691
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:89
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:1091
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:128
#define ALLOC_ARRAY_CLEAR_GC(dptr, type, n, gc)
Definition buffer.h:1064
#define CC_CRLF
carriage return or newline
Definition buffer.h:904
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:1079
#define BLEN(buf)
Definition buffer.h:126
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:1015
#define CC_PRINT
printable (>= 32, != 127)
Definition buffer.h:875
static struct gc_arena gc_new(void)
Definition buffer.h:1007
void query_user_clear(void)
Wipes all data put into all of the query_user structs.
Definition console.c:44
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:56
static bool query_user_exec(void)
Wrapper function enabling query_user_exec() if no alternative methods have been enabled.
Definition console.h:105
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:120
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:82
#define D_SHOW_KEYS
Definition errlevel.h:120
#define D_LOW
Definition errlevel.h:96
#define M_INFO
Definition errlevel.h:54
void management_auth_failure(struct management *man, const char *type, const char *reason)
Definition manage.c:3106
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:3505
static bool management_query_user_pass_enabled(const struct management *man)
Definition manage.h:419
static const char ** make_inline_array(const char *str, struct gc_arena *gc)
Definition misc.c:571
void unprotect_user_pass(struct user_pass *up)
Decrypt username and password buffers in user_pass.
Definition misc.c:803
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:192
const char ** make_arg_array(const char *first, const char *parms, struct gc_arena *gc)
Definition misc.c:544
void purge_user_pass(struct user_pass *up, const bool force)
Definition misc.c:465
bool validate_peer_info_line(char *line)
Definition misc.c:713
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:511
void set_std_files_to_null(bool stdin_only)
Definition misc.c:55
void output_peer_info_env(struct env_set *es, const char *peer_info)
Definition misc.c:750
struct buffer prepend_dir(const char *dir, const char *path, struct gc_arena *gc)
Prepend a directory to a path.
Definition misc.c:772
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:122
void protect_user_pass(struct user_pass *up)
Encrypt username and password buffers in user_pass.
Definition misc.c:783
const char ** make_extended_arg_array(char **p, bool is_inline, struct gc_arena *gc)
Definition misc.c:621
static const char ** make_arg_copy(char **p, struct gc_arena *gc)
Definition misc.c:602
const char * safe_print(const char *str, struct gc_arena *gc)
Definition misc.c:538
const char * sanitize_control_message(const char *src, struct gc_arena *gc)
Definition misc.c:651
static bool auth_user_pass_mgmt(struct user_pass *up, const char *prefix, const unsigned int flags, const char *auth_challenge)
Definition misc.c:78
void set_auth_token(struct user_pass *tk, const char *token)
Sets the auth-token to token.
Definition misc.c:491
#define USER_PASS_LEN
Definition misc.h:64
#define GET_USER_PASS_STATIC_CHALLENGE_CONCAT
indicates password and response should be concatenated
Definition misc.h:125
#define GET_USER_PASS_MANAGEMENT
Definition misc.h:110
#define GET_USER_PASS_PASSWORD_ONLY
Definition misc.h:112
#define GET_USER_PASS_STATIC_CHALLENGE_ECHO
SCRV1 protocol – echo response.
Definition misc.h:120
#define CR_ECHO
Definition misc.h:77
#define CR_RESPONSE
Definition misc.h:78
#define GET_USER_PASS_INLINE_CREDS
indicates that auth_file is actually inline creds
Definition misc.h:123
#define GET_USER_PASS_STATIC_CHALLENGE
SCRV1 protocol – static challenge.
Definition misc.h:119
#define GET_USER_PASS_NEED_OK
Definition misc.h:113
#define GET_USER_PASS_NOFATAL
Definition misc.h:114
#define GET_USER_PASS_PREVIOUS_CREDS_FAILED
Definition misc.h:116
#define GET_USER_PASS_DYNAMIC_CHALLENGE
CRV1 protocol – dynamic challenge.
Definition misc.h:118
#define BOOL_CAST(x)
Definition basic.h:26
#define CLEAR(x)
Definition basic.h:32
#define M_FATAL
Definition error.h:88
static bool check_debug_level(unsigned int level)
Definition error.h:257
#define M_ERR
Definition error.h:104
#define msg(flags,...)
Definition error.h:150
#define ASSERT(x)
Definition error.h:217
#define M_WARN
Definition error.h:90
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:4968
#define streq(x, y)
Definition options.h:727
#define MAX_PARMS
Definition options.h:51
#define OPTION_LINE_SIZE
Definition options.h:57
FILE * platform_fopen(const char *path, const char *mode)
Definition platform.c:504
int openvpn_base64_decode(const char *str, void *data, int size)
Definition base64.c:157
int openvpn_base64_encode(const void *data, int size, char **str)
Definition base64.c:51
static char * auth_challenge
Definition ssl.c:284
Wrapper structure for dynamically allocated memory.
Definition buffer.h:60
int len
Length in bytes of the actual content within the allocated memory.
Definition buffer.h:65
Garbage collection arena used to keep track of dynamically allocated memory.
Definition buffer.h:116
bool protected
Definition misc.h:58
bool defined
Definition misc.h:53
char password[USER_PASS_LEN]
Definition misc.h:68
bool nocache
Definition misc.h:57
char username[USER_PASS_LEN]
Definition misc.h:67
#define PATH_SEPARATOR_STR
Definition syshead.h:428
struct env_set * es
struct gc_arena gc
Definition test_ssl.c:154
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:1618
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:1600