summaryrefslogtreecommitdiff
path: root/readconf.c
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2014-10-07 12:13:50 +0100
committerColin Watson <cjwatson@debian.org>2014-10-07 12:13:50 +0100
commit487bdb3a5ef6075887b830ccb8a0b14f6da78e93 (patch)
treea2cff6fec1e6c4b4153a170a3e172cfe6bfdec46 /readconf.c
parent796ba4fd011b5d0d9d78d592ba2f30fc9d5ed2e7 (diff)
parent28453d58058a4d60c3ebe7d7f0c31a510cbf6158 (diff)
Import openssh_6.7p1.orig.tar.gz
Diffstat (limited to 'readconf.c')
-rw-r--r--readconf.c235
1 files changed, 197 insertions, 38 deletions
diff --git a/readconf.c b/readconf.c
index dc884c9b1..7948ce1cd 100644
--- a/readconf.c
+++ b/readconf.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: readconf.c,v 1.218 2014/02/23 20:11:36 djm Exp $ */ 1/* $OpenBSD: readconf.c,v 1.220 2014/07/15 15:54:14 millert Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -18,6 +18,7 @@
18#include <sys/stat.h> 18#include <sys/stat.h>
19#include <sys/socket.h> 19#include <sys/socket.h>
20#include <sys/wait.h> 20#include <sys/wait.h>
21#include <sys/un.h>
21 22
22#include <netinet/in.h> 23#include <netinet/in.h>
23#include <netinet/in_systm.h> 24#include <netinet/in_systm.h>
@@ -48,9 +49,9 @@
48#include "pathnames.h" 49#include "pathnames.h"
49#include "log.h" 50#include "log.h"
50#include "key.h" 51#include "key.h"
52#include "misc.h"
51#include "readconf.h" 53#include "readconf.h"
52#include "match.h" 54#include "match.h"
53#include "misc.h"
54#include "buffer.h" 55#include "buffer.h"
55#include "kex.h" 56#include "kex.h"
56#include "mac.h" 57#include "mac.h"
@@ -149,6 +150,7 @@ typedef enum {
149 oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown, oProxyUseFdpass, 150 oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown, oProxyUseFdpass,
150 oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots, 151 oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots,
151 oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs, 152 oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs,
153 oStreamLocalBindMask, oStreamLocalBindUnlink,
152 oIgnoredUnknownOption, oDeprecated, oUnsupported 154 oIgnoredUnknownOption, oDeprecated, oUnsupported
153} OpCodes; 155} OpCodes;
154 156
@@ -261,6 +263,8 @@ static struct {
261 { "canonicalizehostname", oCanonicalizeHostname }, 263 { "canonicalizehostname", oCanonicalizeHostname },
262 { "canonicalizemaxdots", oCanonicalizeMaxDots }, 264 { "canonicalizemaxdots", oCanonicalizeMaxDots },
263 { "canonicalizepermittedcnames", oCanonicalizePermittedCNAMEs }, 265 { "canonicalizepermittedcnames", oCanonicalizePermittedCNAMEs },
266 { "streamlocalbindmask", oStreamLocalBindMask },
267 { "streamlocalbindunlink", oStreamLocalBindUnlink },
264 { "ignoreunknown", oIgnoreUnknown }, 268 { "ignoreunknown", oIgnoreUnknown },
265 269
266 { NULL, oBadOption } 270 { NULL, oBadOption }
@@ -272,12 +276,13 @@ static struct {
272 */ 276 */
273 277
274void 278void
275add_local_forward(Options *options, const Forward *newfwd) 279add_local_forward(Options *options, const struct Forward *newfwd)
276{ 280{
277 Forward *fwd; 281 struct Forward *fwd;
278#ifndef NO_IPPORT_RESERVED_CONCEPT 282#ifndef NO_IPPORT_RESERVED_CONCEPT
279 extern uid_t original_real_uid; 283 extern uid_t original_real_uid;
280 if (newfwd->listen_port < IPPORT_RESERVED && original_real_uid != 0) 284 if (newfwd->listen_port < IPPORT_RESERVED && original_real_uid != 0 &&
285 newfwd->listen_path == NULL)
281 fatal("Privileged ports can only be forwarded by root."); 286 fatal("Privileged ports can only be forwarded by root.");
282#endif 287#endif
283 options->local_forwards = xrealloc(options->local_forwards, 288 options->local_forwards = xrealloc(options->local_forwards,
@@ -287,8 +292,10 @@ add_local_forward(Options *options, const Forward *newfwd)
287 292
288 fwd->listen_host = newfwd->listen_host; 293 fwd->listen_host = newfwd->listen_host;
289 fwd->listen_port = newfwd->listen_port; 294 fwd->listen_port = newfwd->listen_port;
295 fwd->listen_path = newfwd->listen_path;
290 fwd->connect_host = newfwd->connect_host; 296 fwd->connect_host = newfwd->connect_host;
291 fwd->connect_port = newfwd->connect_port; 297 fwd->connect_port = newfwd->connect_port;
298 fwd->connect_path = newfwd->connect_path;
292} 299}
293 300
294/* 301/*
@@ -297,9 +304,9 @@ add_local_forward(Options *options, const Forward *newfwd)
297 */ 304 */
298 305
299void 306void
300add_remote_forward(Options *options, const Forward *newfwd) 307add_remote_forward(Options *options, const struct Forward *newfwd)
301{ 308{
302 Forward *fwd; 309 struct Forward *fwd;
303 310
304 options->remote_forwards = xrealloc(options->remote_forwards, 311 options->remote_forwards = xrealloc(options->remote_forwards,
305 options->num_remote_forwards + 1, 312 options->num_remote_forwards + 1,
@@ -308,8 +315,10 @@ add_remote_forward(Options *options, const Forward *newfwd)
308 315
309 fwd->listen_host = newfwd->listen_host; 316 fwd->listen_host = newfwd->listen_host;
310 fwd->listen_port = newfwd->listen_port; 317 fwd->listen_port = newfwd->listen_port;
318 fwd->listen_path = newfwd->listen_path;
311 fwd->connect_host = newfwd->connect_host; 319 fwd->connect_host = newfwd->connect_host;
312 fwd->connect_port = newfwd->connect_port; 320 fwd->connect_port = newfwd->connect_port;
321 fwd->connect_path = newfwd->connect_path;
313 fwd->handle = newfwd->handle; 322 fwd->handle = newfwd->handle;
314 fwd->allocated_port = 0; 323 fwd->allocated_port = 0;
315} 324}
@@ -321,7 +330,9 @@ clear_forwardings(Options *options)
321 330
322 for (i = 0; i < options->num_local_forwards; i++) { 331 for (i = 0; i < options->num_local_forwards; i++) {
323 free(options->local_forwards[i].listen_host); 332 free(options->local_forwards[i].listen_host);
333 free(options->local_forwards[i].listen_path);
324 free(options->local_forwards[i].connect_host); 334 free(options->local_forwards[i].connect_host);
335 free(options->local_forwards[i].connect_path);
325 } 336 }
326 if (options->num_local_forwards > 0) { 337 if (options->num_local_forwards > 0) {
327 free(options->local_forwards); 338 free(options->local_forwards);
@@ -330,7 +341,9 @@ clear_forwardings(Options *options)
330 options->num_local_forwards = 0; 341 options->num_local_forwards = 0;
331 for (i = 0; i < options->num_remote_forwards; i++) { 342 for (i = 0; i < options->num_remote_forwards; i++) {
332 free(options->remote_forwards[i].listen_host); 343 free(options->remote_forwards[i].listen_host);
344 free(options->remote_forwards[i].listen_path);
333 free(options->remote_forwards[i].connect_host); 345 free(options->remote_forwards[i].connect_host);
346 free(options->remote_forwards[i].connect_path);
334 } 347 }
335 if (options->num_remote_forwards > 0) { 348 if (options->num_remote_forwards > 0) {
336 free(options->remote_forwards); 349 free(options->remote_forwards);
@@ -345,6 +358,7 @@ add_identity_file(Options *options, const char *dir, const char *filename,
345 int userprovided) 358 int userprovided)
346{ 359{
347 char *path; 360 char *path;
361 int i;
348 362
349 if (options->num_identity_files >= SSH_MAX_IDENTITY_FILES) 363 if (options->num_identity_files >= SSH_MAX_IDENTITY_FILES)
350 fatal("Too many identity files specified (max %d)", 364 fatal("Too many identity files specified (max %d)",
@@ -355,6 +369,16 @@ add_identity_file(Options *options, const char *dir, const char *filename,
355 else 369 else
356 (void)xasprintf(&path, "%.100s%.100s", dir, filename); 370 (void)xasprintf(&path, "%.100s%.100s", dir, filename);
357 371
372 /* Avoid registering duplicates */
373 for (i = 0; i < options->num_identity_files; i++) {
374 if (options->identity_file_userprovided[i] == userprovided &&
375 strcmp(options->identity_files[i], path) == 0) {
376 debug2("%s: ignoring duplicate key %s", __func__, path);
377 free(path);
378 return;
379 }
380 }
381
358 options->identity_file_userprovided[options->num_identity_files] = 382 options->identity_file_userprovided[options->num_identity_files] =
359 userprovided; 383 userprovided;
360 options->identity_files[options->num_identity_files++] = path; 384 options->identity_files[options->num_identity_files++] = path;
@@ -704,7 +728,7 @@ process_config_line(Options *options, struct passwd *pw, const char *host,
704 LogLevel *log_level_ptr; 728 LogLevel *log_level_ptr;
705 long long val64; 729 long long val64;
706 size_t len; 730 size_t len;
707 Forward fwd; 731 struct Forward fwd;
708 const struct multistate *multistate_ptr; 732 const struct multistate *multistate_ptr;
709 struct allowed_cname *cname; 733 struct allowed_cname *cname;
710 734
@@ -794,7 +818,7 @@ parse_time:
794 goto parse_time; 818 goto parse_time;
795 819
796 case oGatewayPorts: 820 case oGatewayPorts:
797 intptr = &options->gateway_ports; 821 intptr = &options->fwd_opts.gateway_ports;
798 goto parse_flag; 822 goto parse_flag;
799 823
800 case oExitOnForwardFailure: 824 case oExitOnForwardFailure:
@@ -1394,6 +1418,21 @@ parse_int:
1394 intptr = &options->canonicalize_fallback_local; 1418 intptr = &options->canonicalize_fallback_local;
1395 goto parse_flag; 1419 goto parse_flag;
1396 1420
1421 case oStreamLocalBindMask:
1422 arg = strdelim(&s);
1423 if (!arg || *arg == '\0')
1424 fatal("%.200s line %d: Missing StreamLocalBindMask argument.", filename, linenum);
1425 /* Parse mode in octal format */
1426 value = strtol(arg, &endofnumber, 8);
1427 if (arg == endofnumber || value < 0 || value > 0777)
1428 fatal("%.200s line %d: Bad mask.", filename, linenum);
1429 options->fwd_opts.streamlocal_bind_mask = (mode_t)value;
1430 break;
1431
1432 case oStreamLocalBindUnlink:
1433 intptr = &options->fwd_opts.streamlocal_bind_unlink;
1434 goto parse_flag;
1435
1397 case oDeprecated: 1436 case oDeprecated:
1398 debug("%s line %d: Deprecated option \"%s\"", 1437 debug("%s line %d: Deprecated option \"%s\"",
1399 filename, linenum, keyword); 1438 filename, linenum, keyword);
@@ -1491,7 +1530,9 @@ initialize_options(Options * options)
1491 options->forward_x11_timeout = -1; 1530 options->forward_x11_timeout = -1;
1492 options->exit_on_forward_failure = -1; 1531 options->exit_on_forward_failure = -1;
1493 options->xauth_location = NULL; 1532 options->xauth_location = NULL;
1494 options->gateway_ports = -1; 1533 options->fwd_opts.gateway_ports = -1;
1534 options->fwd_opts.streamlocal_bind_mask = (mode_t)-1;
1535 options->fwd_opts.streamlocal_bind_unlink = -1;
1495 options->use_privileged_port = -1; 1536 options->use_privileged_port = -1;
1496 options->rsa_authentication = -1; 1537 options->rsa_authentication = -1;
1497 options->pubkey_authentication = -1; 1538 options->pubkey_authentication = -1;
@@ -1604,8 +1645,12 @@ fill_default_options(Options * options)
1604 options->exit_on_forward_failure = 0; 1645 options->exit_on_forward_failure = 0;
1605 if (options->xauth_location == NULL) 1646 if (options->xauth_location == NULL)
1606 options->xauth_location = _PATH_XAUTH; 1647 options->xauth_location = _PATH_XAUTH;
1607 if (options->gateway_ports == -1) 1648 if (options->fwd_opts.gateway_ports == -1)
1608 options->gateway_ports = 0; 1649 options->fwd_opts.gateway_ports = 0;
1650 if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1)
1651 options->fwd_opts.streamlocal_bind_mask = 0177;
1652 if (options->fwd_opts.streamlocal_bind_unlink == -1)
1653 options->fwd_opts.streamlocal_bind_unlink = 0;
1609 if (options->use_privileged_port == -1) 1654 if (options->use_privileged_port == -1)
1610 options->use_privileged_port = 0; 1655 options->use_privileged_port = 0;
1611 if (options->rsa_authentication == -1) 1656 if (options->rsa_authentication == -1)
@@ -1757,22 +1802,92 @@ fill_default_options(Options * options)
1757 /* options->preferred_authentications will be set in ssh */ 1802 /* options->preferred_authentications will be set in ssh */
1758} 1803}
1759 1804
1805struct fwdarg {
1806 char *arg;
1807 int ispath;
1808};
1809
1810/*
1811 * parse_fwd_field
1812 * parses the next field in a port forwarding specification.
1813 * sets fwd to the parsed field and advances p past the colon
1814 * or sets it to NULL at end of string.
1815 * returns 0 on success, else non-zero.
1816 */
1817static int
1818parse_fwd_field(char **p, struct fwdarg *fwd)
1819{
1820 char *ep, *cp = *p;
1821 int ispath = 0;
1822
1823 if (*cp == '\0') {
1824 *p = NULL;
1825 return -1; /* end of string */
1826 }
1827
1828 /*
1829 * A field escaped with square brackets is used literally.
1830 * XXX - allow ']' to be escaped via backslash?
1831 */
1832 if (*cp == '[') {
1833 /* find matching ']' */
1834 for (ep = cp + 1; *ep != ']' && *ep != '\0'; ep++) {
1835 if (*ep == '/')
1836 ispath = 1;
1837 }
1838 /* no matching ']' or not at end of field. */
1839 if (ep[0] != ']' || (ep[1] != ':' && ep[1] != '\0'))
1840 return -1;
1841 /* NUL terminate the field and advance p past the colon */
1842 *ep++ = '\0';
1843 if (*ep != '\0')
1844 *ep++ = '\0';
1845 fwd->arg = cp + 1;
1846 fwd->ispath = ispath;
1847 *p = ep;
1848 return 0;
1849 }
1850
1851 for (cp = *p; *cp != '\0'; cp++) {
1852 switch (*cp) {
1853 case '\\':
1854 memmove(cp, cp + 1, strlen(cp + 1) + 1);
1855 cp++;
1856 break;
1857 case '/':
1858 ispath = 1;
1859 break;
1860 case ':':
1861 *cp++ = '\0';
1862 goto done;
1863 }
1864 }
1865done:
1866 fwd->arg = *p;
1867 fwd->ispath = ispath;
1868 *p = cp;
1869 return 0;
1870}
1871
1760/* 1872/*
1761 * parse_forward 1873 * parse_forward
1762 * parses a string containing a port forwarding specification of the form: 1874 * parses a string containing a port forwarding specification of the form:
1763 * dynamicfwd == 0 1875 * dynamicfwd == 0
1764 * [listenhost:]listenport:connecthost:connectport 1876 * [listenhost:]listenport|listenpath:connecthost:connectport|connectpath
1877 * listenpath:connectpath
1765 * dynamicfwd == 1 1878 * dynamicfwd == 1
1766 * [listenhost:]listenport 1879 * [listenhost:]listenport
1767 * returns number of arguments parsed or zero on error 1880 * returns number of arguments parsed or zero on error
1768 */ 1881 */
1769int 1882int
1770parse_forward(Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd) 1883parse_forward(struct Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd)
1771{ 1884{
1885 struct fwdarg fwdargs[4];
1886 char *p, *cp;
1772 int i; 1887 int i;
1773 char *p, *cp, *fwdarg[4];
1774 1888
1775 memset(fwd, '\0', sizeof(*fwd)); 1889 memset(fwd, 0, sizeof(*fwd));
1890 memset(fwdargs, 0, sizeof(fwdargs));
1776 1891
1777 cp = p = xstrdup(fwdspec); 1892 cp = p = xstrdup(fwdspec);
1778 1893
@@ -1780,39 +1895,70 @@ parse_forward(Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd)
1780 while (isspace((u_char)*cp)) 1895 while (isspace((u_char)*cp))
1781 cp++; 1896 cp++;
1782 1897
1783 for (i = 0; i < 4; ++i) 1898 for (i = 0; i < 4; ++i) {
1784 if ((fwdarg[i] = hpdelim(&cp)) == NULL) 1899 if (parse_fwd_field(&cp, &fwdargs[i]) != 0)
1785 break; 1900 break;
1901 }
1786 1902
1787 /* Check for trailing garbage */ 1903 /* Check for trailing garbage */
1788 if (cp != NULL) 1904 if (cp != NULL && *cp != '\0') {
1789 i = 0; /* failure */ 1905 i = 0; /* failure */
1906 }
1790 1907
1791 switch (i) { 1908 switch (i) {
1792 case 1: 1909 case 1:
1793 fwd->listen_host = NULL; 1910 if (fwdargs[0].ispath) {
1794 fwd->listen_port = a2port(fwdarg[0]); 1911 fwd->listen_path = xstrdup(fwdargs[0].arg);
1912 fwd->listen_port = PORT_STREAMLOCAL;
1913 } else {
1914 fwd->listen_host = NULL;
1915 fwd->listen_port = a2port(fwdargs[0].arg);
1916 }
1795 fwd->connect_host = xstrdup("socks"); 1917 fwd->connect_host = xstrdup("socks");
1796 break; 1918 break;
1797 1919
1798 case 2: 1920 case 2:
1799 fwd->listen_host = xstrdup(cleanhostname(fwdarg[0])); 1921 if (fwdargs[0].ispath && fwdargs[1].ispath) {
1800 fwd->listen_port = a2port(fwdarg[1]); 1922 fwd->listen_path = xstrdup(fwdargs[0].arg);
1801 fwd->connect_host = xstrdup("socks"); 1923 fwd->listen_port = PORT_STREAMLOCAL;
1924 fwd->connect_path = xstrdup(fwdargs[1].arg);
1925 fwd->connect_port = PORT_STREAMLOCAL;
1926 } else if (fwdargs[1].ispath) {
1927 fwd->listen_host = NULL;
1928 fwd->listen_port = a2port(fwdargs[0].arg);
1929 fwd->connect_path = xstrdup(fwdargs[1].arg);
1930 fwd->connect_port = PORT_STREAMLOCAL;
1931 } else {
1932 fwd->listen_host = xstrdup(fwdargs[0].arg);
1933 fwd->listen_port = a2port(fwdargs[1].arg);
1934 fwd->connect_host = xstrdup("socks");
1935 }
1802 break; 1936 break;
1803 1937
1804 case 3: 1938 case 3:
1805 fwd->listen_host = NULL; 1939 if (fwdargs[0].ispath) {
1806 fwd->listen_port = a2port(fwdarg[0]); 1940 fwd->listen_path = xstrdup(fwdargs[0].arg);
1807 fwd->connect_host = xstrdup(cleanhostname(fwdarg[1])); 1941 fwd->listen_port = PORT_STREAMLOCAL;
1808 fwd->connect_port = a2port(fwdarg[2]); 1942 fwd->connect_host = xstrdup(fwdargs[1].arg);
1943 fwd->connect_port = a2port(fwdargs[2].arg);
1944 } else if (fwdargs[2].ispath) {
1945 fwd->listen_host = xstrdup(fwdargs[0].arg);
1946 fwd->listen_port = a2port(fwdargs[1].arg);
1947 fwd->connect_path = xstrdup(fwdargs[2].arg);
1948 fwd->connect_port = PORT_STREAMLOCAL;
1949 } else {
1950 fwd->listen_host = NULL;
1951 fwd->listen_port = a2port(fwdargs[0].arg);
1952 fwd->connect_host = xstrdup(fwdargs[1].arg);
1953 fwd->connect_port = a2port(fwdargs[2].arg);
1954 }
1809 break; 1955 break;
1810 1956
1811 case 4: 1957 case 4:
1812 fwd->listen_host = xstrdup(cleanhostname(fwdarg[0])); 1958 fwd->listen_host = xstrdup(fwdargs[0].arg);
1813 fwd->listen_port = a2port(fwdarg[1]); 1959 fwd->listen_port = a2port(fwdargs[1].arg);
1814 fwd->connect_host = xstrdup(cleanhostname(fwdarg[2])); 1960 fwd->connect_host = xstrdup(fwdargs[2].arg);
1815 fwd->connect_port = a2port(fwdarg[3]); 1961 fwd->connect_port = a2port(fwdargs[3].arg);
1816 break; 1962 break;
1817 default: 1963 default:
1818 i = 0; /* failure */ 1964 i = 0; /* failure */
@@ -1824,29 +1970,42 @@ parse_forward(Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd)
1824 if (!(i == 1 || i == 2)) 1970 if (!(i == 1 || i == 2))
1825 goto fail_free; 1971 goto fail_free;
1826 } else { 1972 } else {
1827 if (!(i == 3 || i == 4)) 1973 if (!(i == 3 || i == 4)) {
1828 goto fail_free; 1974 if (fwd->connect_path == NULL &&
1829 if (fwd->connect_port <= 0) 1975 fwd->listen_path == NULL)
1976 goto fail_free;
1977 }
1978 if (fwd->connect_port <= 0 && fwd->connect_path == NULL)
1830 goto fail_free; 1979 goto fail_free;
1831 } 1980 }
1832 1981
1833 if (fwd->listen_port < 0 || (!remotefwd && fwd->listen_port == 0)) 1982 if ((fwd->listen_port < 0 && fwd->listen_path == NULL) ||
1983 (!remotefwd && fwd->listen_port == 0))
1834 goto fail_free; 1984 goto fail_free;
1835
1836 if (fwd->connect_host != NULL && 1985 if (fwd->connect_host != NULL &&
1837 strlen(fwd->connect_host) >= NI_MAXHOST) 1986 strlen(fwd->connect_host) >= NI_MAXHOST)
1838 goto fail_free; 1987 goto fail_free;
1988 /* XXX - if connecting to a remote socket, max sun len may not match this host */
1989 if (fwd->connect_path != NULL &&
1990 strlen(fwd->connect_path) >= PATH_MAX_SUN)
1991 goto fail_free;
1839 if (fwd->listen_host != NULL && 1992 if (fwd->listen_host != NULL &&
1840 strlen(fwd->listen_host) >= NI_MAXHOST) 1993 strlen(fwd->listen_host) >= NI_MAXHOST)
1841 goto fail_free; 1994 goto fail_free;
1842 1995 if (fwd->listen_path != NULL &&
1996 strlen(fwd->listen_path) >= PATH_MAX_SUN)
1997 goto fail_free;
1843 1998
1844 return (i); 1999 return (i);
1845 2000
1846 fail_free: 2001 fail_free:
1847 free(fwd->connect_host); 2002 free(fwd->connect_host);
1848 fwd->connect_host = NULL; 2003 fwd->connect_host = NULL;
2004 free(fwd->connect_path);
2005 fwd->connect_path = NULL;
1849 free(fwd->listen_host); 2006 free(fwd->listen_host);
1850 fwd->listen_host = NULL; 2007 fwd->listen_host = NULL;
2008 free(fwd->listen_path);
2009 fwd->listen_path = NULL;
1851 return (0); 2010 return (0);
1852} 2011}