2 * OpenVPN -- An application to securely tunnel IP networks
3 * over a single UDP port, with support for SSL/TLS-based
4 * session authentication and key exchange,
5 * packet encryption, packet authentication, and
8 * Copyright (C) 2002-2005 OpenVPN Solutions LLC <info@openvpn.net>
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.
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.
19 * You should have received a copy of the GNU General Public License
20 * along with this program (see the file COPYING included with this
21 * distribution); if not, write to the Free Software Foundation, Inc.,
22 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 #include "config-win32.h"
43 alloc_buf_debug (size_t size
, const char *file
, int line
)
45 alloc_buf (size_t size
)
49 return alloc_buf_gc_debug (size
, NULL
, file
, line
);
51 return alloc_buf_gc (size
, NULL
);
57 alloc_buf_gc_debug (size_t size
, struct gc_arena
*gc
, const char *file
, int line
)
59 alloc_buf_gc (size_t size
, struct gc_arena
*gc
)
63 buf
.capacity
= (int)size
;
67 buf
.data
= (uint8_t *) gc_malloc_debug (size
, false, gc
, file
, line
);
69 buf
.data
= (uint8_t *) gc_malloc (size
, false, gc
);
78 clone_buf_debug (const struct buffer
* buf
, const char *file
, int line
)
80 clone_buf (const struct buffer
* buf
)
84 ret
.capacity
= buf
->capacity
;
85 ret
.offset
= buf
->offset
;
88 ret
.data
= (uint8_t *) openvpn_dmalloc (file
, line
, buf
->capacity
);
90 ret
.data
= (uint8_t *) malloc (buf
->capacity
);
92 check_malloc_return (ret
.data
);
93 memcpy (BPTR (&ret
), BPTR (buf
), BLEN (buf
));
97 #ifdef BUF_INIT_TRACKING
100 buf_init_debug (struct buffer
*buf
, int offset
, const char *file
, int line
)
102 buf
->debug_file
= file
;
103 buf
->debug_line
= line
;
104 return buf_init_dowork (buf
, offset
);
108 buf_debug_line (const struct buffer
*buf
)
110 return buf
->debug_line
;
114 buf_debug_file (const struct buffer
*buf
)
116 return buf
->debug_file
;
121 #define buf_debug_line(buf) 0
122 #define buf_debug_file(buf) "[UNDEF]"
127 buf_clear (struct buffer
*buf
)
129 if (buf
->capacity
> 0)
130 memset (buf
->data
, 0, buf
->capacity
);
136 buf_assign (struct buffer
*dest
, const struct buffer
*src
)
138 if (!buf_init (dest
, src
->offset
))
140 return buf_write (dest
, BPTR (src
), BLEN (src
));
152 free_buf (struct buffer
*buf
)
160 * Return a buffer for write that is a subset of another buffer
163 buf_sub (struct buffer
*buf
, int size
, bool prepend
)
169 data
= prepend
? buf_prepend (buf
, size
) : buf_write_alloc (buf
, size
);
179 * printf append to a buffer with overflow check
182 buf_printf (struct buffer
*buf
, const char *format
, ...)
184 if (buf_defined (buf
))
187 uint8_t *ptr
= BEND (buf
);
188 int cap
= buf_forward_capacity (buf
);
192 va_start (arglist
, format
);
193 vsnprintf ((char *)ptr
, cap
, format
, arglist
);
195 *(buf
->data
+ buf
->capacity
- 1) = 0; /* windows vsnprintf needs this */
196 buf
->len
+= (int) strlen ((char *)ptr
);
202 * This is necessary due to certain buggy implementations of snprintf,
203 * that don't guarantee null termination for size > 0.
206 int openvpn_snprintf(char *str
, size_t size
, const char *format
, ...)
212 va_start (arglist
, format
);
213 ret
= vsnprintf (str
, size
, format
, arglist
);
221 * write a string to the end of a buffer that was
222 * truncated by buf_printf
225 buf_catrunc (struct buffer
*buf
, const char *str
)
227 if (buf_forward_capacity (buf
) <= 1)
229 int len
= (int) strlen (str
) + 1;
230 if (len
< buf_forward_capacity_total (buf
))
232 strncpynt ((char *)(buf
->data
+ buf
->capacity
- len
), str
, len
);
238 * convert a multi-line output to one line
241 convert_to_one_line (struct buffer
*buf
)
243 uint8_t *cp
= BPTR(buf
);
253 /* NOTE: requires that string be null terminated */
255 buf_write_string_file (const struct buffer
*buf
, const char *filename
, int fd
)
257 const int len
= strlen ((char *) BPTR (buf
));
258 const int size
= write (fd
, BPTR (buf
), len
);
260 msg (M_ERR
, "Write error on file '%s'", filename
);
269 gc_malloc_debug (size_t size
, bool clear
, struct gc_arena
*a
, const char *file
, int line
)
271 gc_malloc (size_t size
, bool clear
, struct gc_arena
*a
)
279 e
= (struct gc_entry
*) openvpn_dmalloc (file
, line
, size
+ sizeof (struct gc_entry
));
281 e
= (struct gc_entry
*) malloc (size
+ sizeof (struct gc_entry
));
283 check_malloc_return (e
);
284 ret
= (char *) e
+ sizeof (struct gc_entry
);
285 /*mutex_lock_static (L_GC_MALLOC);*/
288 /*mutex_unlock_static (L_GC_MALLOC);*/
293 ret
= openvpn_dmalloc (file
, line
, size
);
297 check_malloc_return (ret
);
299 #ifndef ZERO_BUFFER_ON_ALLOC
302 memset (ret
, 0, size
);
307 x_gc_free (struct gc_arena
*a
)
310 /*mutex_lock_static (L_GC_MALLOC);*/
313 /*mutex_unlock_static (L_GC_MALLOC);*/
317 struct gc_entry
*next
= e
->next
;
324 * Hex dump -- Output a binary buffer to a hex string and return it.
328 format_hex_ex (const uint8_t *data
, int size
, int maxoutput
,
329 int space_break
, const char* separator
,
332 struct buffer out
= alloc_buf_gc (maxoutput
? maxoutput
:
333 ((size
* 2) + (size
/ space_break
) * (int) strlen (separator
) + 2),
336 for (i
= 0; i
< size
; ++i
)
338 if (separator
&& i
&& !(i
% space_break
))
339 buf_printf (&out
, "%s", separator
);
340 buf_printf (&out
, "%02x", data
[i
]);
342 buf_catrunc (&out
, "[more...]");
343 return (char *)out
.data
;
347 * remove specific trailing character
351 buf_rmtail (struct buffer
*buf
, uint8_t remove
)
353 uint8_t *cp
= BLAST(buf
);
354 if (cp
&& *cp
== remove
)
362 * force a null termination even it requires
363 * truncation of the last char.
366 buf_null_terminate (struct buffer
*buf
)
368 char *last
= (char *) BLAST (buf
);
369 if (last
&& *last
== '\0') /* already terminated? */
372 if (!buf_safe (buf
, 1)) /* make space for trailing null */
373 buf_inc_len (buf
, -1);
375 buf_write_u8 (buf
, 0);
379 * Remove trailing \r and \n chars and ensure
383 buf_chomp (struct buffer
*buf
)
387 char *last
= (char *) BLAST (buf
);
390 if (char_class (*last
, CC_CRLF
|CC_NULL
))
392 if (!buf_inc_len (buf
, -1))
398 buf_null_terminate (buf
);
402 * like buf_null_terminate, but operate on strings
405 string_null_terminate (char *str
, int len
, int capacity
)
407 ASSERT (len
>= 0 && len
<= capacity
&& capacity
> 0);
410 else if (len
== capacity
)
411 *(str
+ len
- 1) = '\0';
415 * Remove trailing \r and \n chars.
422 const int len
= strlen (str
);
426 char *cp
= str
+ (len
- 1);
427 if (*cp
== '\n' || *cp
== '\r')
441 string_alloc_debug (const char *str
, struct gc_arena
*gc
, const char *file
, int line
)
443 string_alloc (const char *str
, struct gc_arena
*gc
)
448 const int n
= strlen (str
) + 1;
452 ret
= (char *) gc_malloc_debug (n
, false, gc
, file
, line
);
454 ret
= (char *) gc_malloc (n
, false, gc
);
456 memcpy (ret
, str
, n
);
464 * Allocate a string inside a buffer
468 string_alloc_buf_debug (const char *str
, struct gc_arena
*gc
, const char *file
, int line
)
470 string_alloc_buf (const char *str
, struct gc_arena
*gc
)
478 buf_set_read (&buf
, (uint8_t*) string_alloc_debug (str
, gc
, file
, line
), strlen (str
) + 1);
480 buf_set_read (&buf
, (uint8_t*) string_alloc (str
, gc
), strlen (str
) + 1);
483 if (buf
.len
> 0) /* Don't count trailing '\0' as part of length */
494 buf_string_match_head_str (const struct buffer
*src
, const char *match
)
496 const int size
= strlen (match
);
497 if (size
< 0 || size
> src
->len
)
499 return memcmp (BPTR (src
), match
, size
) == 0;
503 buf_string_compare_advance (struct buffer
*src
, const char *match
)
505 if (buf_string_match_head_str (src
, match
))
507 buf_advance (src
, strlen (match
));
515 buf_substring_len (const struct buffer
*buf
, int delim
)
518 struct buffer tmp
= *buf
;
521 while ((c
= buf_read_u8 (&tmp
)) >= 0)
535 buf_parse (struct buffer
*buf
, const int delim
, char *line
, const int size
)
545 c
= buf_read_u8 (buf
);
548 if (c
<= 0 || c
== delim
)
557 return !(eol
&& !strlen (line
));
561 * Classify and mutate strings based on character types.
565 char_class (const char c
, const unsigned int flags
)
572 if ((flags
& CC_NULL
) && c
== '\0')
575 if ((flags
& CC_ALNUM
) && isalnum (c
))
577 if ((flags
& CC_ALPHA
) && isalpha (c
))
579 if ((flags
& CC_ASCII
) && isascii (c
))
581 if ((flags
& CC_CNTRL
) && iscntrl (c
))
583 if ((flags
& CC_DIGIT
) && isdigit (c
))
585 if ((flags
& CC_PRINT
) && isprint (c
))
587 if ((flags
& CC_PUNCT
) && ispunct (c
))
589 if ((flags
& CC_SPACE
) && isspace (c
))
591 if ((flags
& CC_XDIGIT
) && isxdigit (c
))
594 if ((flags
& CC_BLANK
) && (c
== ' ' || c
== '\t'))
596 if ((flags
& CC_NEWLINE
) && c
== '\n')
598 if ((flags
& CC_CR
) && c
== '\r')
601 if ((flags
& CC_BACKSLASH
) && c
== '\\')
603 if ((flags
& CC_UNDERBAR
) && c
== '_')
605 if ((flags
& CC_DASH
) && c
== '-')
607 if ((flags
& CC_DOT
) && c
== '.')
609 if ((flags
& CC_COMMA
) && c
== ',')
611 if ((flags
& CC_COLON
) && c
== ':')
613 if ((flags
& CC_SLASH
) && c
== '/')
615 if ((flags
& CC_SINGLE_QUOTE
) && c
== '\'')
617 if ((flags
& CC_DOUBLE_QUOTE
) && c
== '\"')
619 if ((flags
& CC_REVERSE_QUOTE
) && c
== '`')
621 if ((flags
& CC_AT
) && c
== '@')
623 if ((flags
& CC_EQUAL
) && c
== '=')
630 char_inc_exc (const char c
, const unsigned int inclusive
, const unsigned int exclusive
)
632 return char_class (c
, inclusive
) && !char_class (c
, exclusive
);
636 string_class (const char *str
, const unsigned int inclusive
, const unsigned int exclusive
)
642 if (!char_inc_exc (c
, inclusive
, exclusive
))
649 * Modify string in place.
650 * Guaranteed to not increase string length.
653 string_mod (char *str
, const unsigned int inclusive
, const unsigned int exclusive
, const char replace
)
655 const char *in
= str
;
665 if (!char_inc_exc (c
, inclusive
, exclusive
))
683 string_mod_const (const char *str
,
684 const unsigned int inclusive
,
685 const unsigned int exclusive
,
691 char *buf
= string_alloc (str
, gc
);
692 string_mod (buf
, inclusive
, exclusive
, replace
);
699 #ifdef CHARACTER_CLASS_DEBUG
701 #define CC_INCLUDE (CC_PRINT)
702 #define CC_EXCLUDE (0)
703 #define CC_REPLACE ('.')
706 character_class_debug (void)
710 while (fgets (buf
, sizeof (buf
), stdin
) != NULL
)
712 string_mod (buf
, CC_INCLUDE
, CC_EXCLUDE
, CC_REPLACE
);
719 #ifdef VERIFY_ALIGNMENT
721 valign4 (const struct buffer
*buf
, const char *file
, const int line
)
725 int msglevel
= D_ALIGN_DEBUG
;
726 const unsigned int u
= (unsigned int) BPTR (buf
);
728 if (u
& (PAYLOAD_ALIGN
-1))
729 msglevel
= D_ALIGN_ERRORS
;
731 msg (msglevel
, "%sAlignment at %s/%d ptr=" ptr_format
" OLC=%d/%d/%d I=%s/%d",
732 (msglevel
== D_ALIGN_ERRORS
) ? "ERROR: " : "",
739 buf_debug_file (buf
),
740 buf_debug_line (buf
));