OpenVPN
ssl_util.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-2020 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 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #elif defined(_MSC_VER)
26 #include "config-msvc.h"
27 #endif
28 
29 #include "syshead.h"
30 
31 #include "ssl_util.h"
32 
33 char *
34 extract_var_peer_info(const char *peer_info, const char *var,
35  struct gc_arena *gc)
36 {
37  if (!peer_info)
38  {
39  return NULL;
40  }
41 
42  const char *var_start = strstr(peer_info, var);
43  if (!var_start)
44  {
45  /* variable not found in peer info */
46  return NULL;
47  }
48 
49  var_start += strlen(var);
50  const char *var_end = strstr(var_start, "\n");
51  if (!var_end)
52  {
53  /* var is at end of the peer_info list and no '\n' follows */
54  var_end = var_start + strlen(var_start);
55  }
56 
57  char *var_value = string_alloc(var_start, gc);
58  /* NULL terminate the copy at the right position */
59  var_value[var_end - var_start] = '\0';
60  return var_value;
61 }
62 
63 unsigned int
64 extract_iv_proto(const char *peer_info)
65 {
66  const char *optstr = peer_info ? strstr(peer_info, "IV_PROTO=") : NULL;
67  if (optstr)
68  {
69  int proto = 0;
70  int r = sscanf(optstr, "IV_PROTO=%d", &proto);
71  if (r == 1 && proto > 0)
72  {
73  return proto;
74  }
75  }
76  return 0;
77 }
78 
79 const char *
80 options_string_compat_lzo(const char *options, struct gc_arena *gc)
81 {
82  /* Example string without and with comp-lzo, i.e. input/output of this function */
83  /* w/o comp: 'V4,dev-type tun,link-mtu 1457,tun-mtu 1400,proto UDPv4,auth SHA1,keysize 128,key-method 2,tls-server' */
84  /* comp-lzo: 'V4,dev-type tun,link-mtu 1458,tun-mtu 1400,proto UDPv4,comp-lzo,auth SHA1,keysize 128,key-method 2,tls-server' */
85 
86  /* Note: since this function is used only in a very limited scope it makes
87  * assumptions how the string looks. Since we locally generated the string
88  * we can make these assumptions */
89 
90  /* Check that the link-mtu string is in options */
91  const char *tmp = strstr(options, ",link-mtu");
92  if (!tmp)
93  {
94  return options;
95  }
96 
97  /* Get old link_mtu size */
98  int link_mtu;
99  if (sscanf(tmp, ",link-mtu %d,", &link_mtu) != 1 || link_mtu < 100 || link_mtu > 9900)
100  {
101  return options;
102  }
103 
104  /* 1 byte for the possibility of 999 to 1000 and 1 byte for the null
105  * terminator */
106  struct buffer buf = alloc_buf_gc(strlen(options) + strlen(",comp-lzo") + 2, gc);
107 
108  buf_write(&buf, options, (int)(tmp - options));
109 
110  /* Increase link-mtu by one for the comp-lzo opcode */
111  buf_printf(&buf, ",link-mtu %d", link_mtu + 1);
112 
113  tmp += strlen(",link-mtu ") + (link_mtu < 1000 ? 3 : 4);
114 
115  buf_printf(&buf, "%s,comp-lzo", tmp);
116 
117  return BSTR(&buf);
118 }
char * string_alloc(const char *str, struct gc_arena *gc)
Definition: buffer.c:685
unsigned int extract_iv_proto(const char *peer_info)
Extracts the IV_PROTO variable and returns its value or 0 if it cannot be extracted.
Definition: ssl_util.c:64
const char * options_string_compat_lzo(const char *options, struct gc_arena *gc)
Takes a locally produced OCC string for TLS server mode and modifies as if the option comp-lzo was en...
Definition: ssl_util.c:80
bool buf_printf(struct buffer *buf, const char *format,...)
Definition: buffer.c:242
Wrapper structure for dynamically allocated memory.
Definition: buffer.h:60
struct buffer alloc_buf_gc(size_t size, struct gc_arena *gc)
Definition: buffer.c:90
Garbage collection arena used to keep track of dynamically allocated memory.
Definition: buffer.h:116
static bool buf_write(struct buffer *dest, const void *src, size_t size)
Definition: buffer.h:689
char * extract_var_peer_info(const char *peer_info, const char *var, struct gc_arena *gc)
Extracts a variable from peer info, the returned string will be allocated using the supplied gc_arena...
Definition: ssl_util.c:34
#define BSTR(buf)
Definition: buffer.h:129