Date: Wed, 10 Nov 2004 16:59:53 +0000 (GMT) From: rik <freebsd-ports@rikrose.net> To: FreeBSD-gnats-submit@FreeBSD.org Subject: ports/73783: security update through port update: socat 1.4.0.0 -> socat 1.4.0.3 Message-ID: <20041110165953.913928B803@lost.little-black-kitty.net> Resent-Message-ID: <200411101700.iAAH0foK087476@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 73783 >Category: ports >Synopsis: security update through port update: socat 1.4.0.0 -> socat 1.4.0.3 >Confidential: no >Severity: serious >Priority: high >Responsible: freebsd-ports-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: maintainer-update >Submitter-Id: current-users >Arrival-Date: Wed Nov 10 17:00:41 GMT 2004 >Closed-Date: >Last-Modified: >Originator: rik >Release: FreeBSD 4.10-STABLE i386 >Organization: N/A >Environment: System: FreeBSD integration-5.internal 4.10-STABLE FreeBSD 4.10-STABLE #0: Fri Oct 29 21:35:01 BST 2004 root@buildbox-1.internal:/usr/obj/usr/src/sys/STANDARD i386 >Description: socat < 1.4.0.3 has a remote code execution vulnerabiliyt. socat 1.4.0.3 has had this bug fixed. Update is therefore required See also: http://vuxml.FreeBSD.org/f3017ce1-32a4-11d9-a9e7-0001020eed82.html >How-To-Repeat: >Fix: Since the files/xio-socks.c file is unneeded anymore, both it and the files directory can be deleted. The patch is below. diff -ruN socat/Makefile socat-new/Makefile --- socat/Makefile Tue Jul 20 00:33:07 2004 +++ socat-new/Makefile Wed Nov 10 16:57:33 2004 @@ -7,7 +7,7 @@ # PORTNAME= socat -PORTVERSION= 1.4.0.0 +PORTVERSION= 1.4.0.3 PORTREVISION= 1 CATEGORIES= net MASTER_SITES= http://www.dest-unreach.org/socat/download/ @@ -31,9 +31,6 @@ MAN1= socat.1 PORTDOCS= EXAMPLES README SECURITY FAQ PLIST_FILES= bin/filan bin/procan bin/socat - -post-patch: - @${CP} ${FILESDIR}/xio-socks.c ${WRKSRC}/xio-socks.c .if !defined(NOPORTDOCS) post-install: diff -ruN socat/files/xio-socks.c socat-new/files/xio-socks.c --- socat/files/xio-socks.c Tue Jul 20 00:33:07 2004 +++ socat-new/files/xio-socks.c Thu Jan 1 01:00:00 1970 @@ -1,393 +0,0 @@ -/* $Id: xio-socks.c,v 1.21 2004/07/10 15:21:38 gerhard Exp $ */ -/* Copyright Gerhard Rieger 2001-2004 */ -/* Published under the GNU General Public License V.2, see file COPYING */ - -/* this file contains the source for opening addresses of socks4 type */ - -#include "xiosysincludes.h" -#include "xioopen.h" -#include "xio-socket.h" -#include "xio-ipapp.h" - -#include "xio-socks.h" - - -#if WITH_SOCKS4 || WITH_SOCKS4A -enum { - SOCKS_CD_GRANTED = 90, - SOCKS_CD_FAILED, - SOCKS_CD_NOIDENT, - SOCKS_CD_IDENTFAILED -} ; - -#define SOCKSPORT "1080" -#define BUFF_LEN (SIZEOF_STRUCT_SOCKS4+512) - -static int xioopen_socks4_connect(char *a1, int rw, xiofile_t *fd, - unsigned groups, int dummy1, int dummy2, - void *dummyp1); - -const struct optdesc opt_socksport = { "socksport", NULL, OPT_SOCKSPORT, GROUP_IP_SOCKS4, PH_LATE, TYPE_STRING, OFUNC_SPEC }; -const struct optdesc opt_socksuser = { "socksuser", NULL, OPT_SOCKSUSER, GROUP_IP_SOCKS4, PH_LATE, TYPE_NAME, OFUNC_SPEC }; - -const struct addrdesc addr_socks4_connect = { "socks4", 3, xioopen_socks4_connect, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_IP_TCP|GROUP_IP_SOCKS4|GROUP_CHILD|GROUP_RETRY, 0, 0, NULL HELP(":<socks-server>:<host>:<port>") }; - -const struct addrdesc addr_socks4a_connect = { "socks4a", 3, xioopen_socks4_connect, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_IP_TCP|GROUP_IP_SOCKS4|GROUP_CHILD|GROUP_RETRY, 1, 0, NULL HELP(":<socks-server>:<host>:<port>") }; - -static int xioopen_socks4_connect(char *a1, int rw, xiofile_t *xxfd, - unsigned groups, int socks4a, int dummy2, - void *dummyp1) { - /* we expect the form: host:host:port */ - char *a2, *a3, *a4; - struct single *xfd = &xxfd->stream; - struct opt *opts = NULL, *opts0 = NULL; - char *sockdname = a1, *socksport = NULL; - const char *targetname; - const char *protname = "tcp"; - bool dofork = false; - struct sockaddr_in us_sa, *us = &us_sa; - struct sockaddr_in themsa, *them = &themsa; - bool needbind = false; - bool lowport = false; - unsigned char buff[BUFF_LEN]; - struct socks4 *sockhead = (struct socks4 *)buff; - size_t buflen = sizeof(buff); - int socktype = SOCK_STREAM; - int level; - int result; - - a2 = strchr(a1, ':'); - if (!a2) { - Error1("xioopen_socks4_connect(\"%s\",,): missing target address", a1); - return STAT_NORETRY; - } - *a2 = '\0', ++a2; - targetname = a2; - - if ((a3 = strchr(a2, ':')) == NULL) { - Error2("xioopen_socks4_connect(\"%s:%s\",,): missing target port", a1, a2); - return STAT_NORETRY; - } - *a3 = '\0', ++a3; - - a4 = strchr(a3, ','); - if (a4) *a4 = '\0', ++a4; - - if (parseopts(a4, groups, &opts) < 0) { - return STAT_NORETRY; - } - - socket_in_init(us); - - applyopts(-1, opts, PH_INIT); - applyopts_single(xfd, opts, PH_INIT); - - retropt_int(opts, OPT_SO_TYPE, &socktype); - - retropt_bool(opts, OPT_FORK, &dofork); - - result = _xioopen_socks4_prepare(a3, opts, &socksport, sockhead, &buflen); - if (result != STAT_OK) return result; - - result = _xioopen_ip4app_prepare(opts, &opts0, sockdname, socksport, - protname, them, us, - &needbind, &lowport, &socktype); - if (result != STAT_OK) return result; - - Notice5("opening connection to %s:%u via socks4 server %s:%s as user \"%s\"", - a2, - ntohs(sockhead->port), - a1, socksport, sockhead->userid); - - do { /* loop over failed connect and socks-request attempts */ - -#if WITH_RETRY - if (xfd->forever || xfd->retry) { - level = E_INFO; - } else -#endif /* WITH_RETRY */ - level = E_ERROR; - - /* we try to resolve the target address _before_ connecting to the socks - server: this avoids unnecessary socks connects and timeouts */ - result = - _xioopen_socks4_connect0(xfd, targetname, socks4a, sockhead, - (ssize_t *)&buflen, level); - switch (result) { - case STAT_OK: break; -#if WITH_RETRY - case STAT_RETRYLATER: - case STAT_RETRYNOW: - if (xfd->forever || xfd->retry--) { - if (result == STAT_RETRYLATER) Nanosleep(&xfd->intervall, NULL); - continue; - } -#endif /* WITH_RETRY */ - default: - return result; - } - - /* this cannot fork because we retrieved fork option above */ - result = - _xioopen_connect (xfd, - needbind?(struct sockaddr *)us:NULL, sizeof(*us), - (struct sockaddr *)them, sizeof(struct sockaddr_in), - opts, PF_INET, socktype, IPPROTO_TCP, lowport, level); - switch (result) { - case STAT_OK: break; -#if WITH_RETRY - case STAT_RETRYLATER: - case STAT_RETRYNOW: - if (xfd->forever || xfd->retry--) { - if (result == STAT_RETRYLATER) Nanosleep(&xfd->intervall, NULL); - continue; - } -#endif /* WITH_RETRY */ - default: - return result; - } - - applyopts(xfd->fd, opts, PH_ALL); - - if ((result = _xio_openlate(xfd, opts)) < 0) - return result; - - result = _xioopen_socks4_connect(xfd, sockhead, buflen, level); - switch (result) { - case STAT_OK: break; -#if WITH_RETRY - case STAT_RETRYLATER: - case STAT_RETRYNOW: - if (xfd->forever || xfd->retry--) { - if (result == STAT_RETRYLATER) Nanosleep(&xfd->intervall, NULL); - continue; - } -#endif /* WITH_RETRY */ - default: - return result; - } - -#if WITH_RETRY - if (dofork) { - pid_t pid; - while ((pid = Fork()) < 0) { - int level = E_ERROR; - if (xfd->forever || xfd->retry) { - level = E_WARN; - } - Msg1(level, "fork(): %s", strerror(errno)); - if (xfd->forever || xfd->retry--) { - Nanosleep(&xfd->intervall, NULL); - continue; - } - return STAT_RETRYLATER; - } - if (pid == 0) { /* child process */ - Info1("just born: socks client process "F_pid, Getpid()); - xfd->forever = false; xfd->retry = 0; - break; - } - /* parent process */ - Notice1("forked off child process "F_pid, pid); - Close(xfd->fd); - Nanosleep(&xfd->intervall, NULL); - dropopts(opts, PH_ALL); opts = copyopts(opts0, GROUP_ALL); - continue; - } else -#endif /* WITH_RETRY */ - { - break; - } - - } while (true); /* end of complete open loop - drop out on success */ - return 0; -} - - -int _xioopen_socks4_prepare(const char *targetport, struct opt *opts, char **socksport, struct socks4 *sockhead, size_t *headlen) { - struct servent *se; - char *userid; - - /* generate socks header - points to final target */ - sockhead->version = 4; - sockhead->action = 1; - sockhead->port = parseport(targetport, "tcp"); - - if (retropt_string(opts, OPT_SOCKSPORT, socksport) < 0) { - if ((se = getservbyname("socks", "tcp")) != NULL) { - Debug1("\"socks/tcp\" resolves to %u", ntohs(se->s_port)); - if ((*socksport = Malloc(6)) == NULL) { - return -1; - } - sprintf(*socksport, "%u", ntohs(se->s_port)); - } else { - Debug1("cannot resolve service \"socks/tcp\", using %s", SOCKSPORT); - if ((*socksport = strdup(SOCKSPORT)) == NULL) { - errno = ENOMEM; return -1; - } - } - } - - if (retropt_string(opts, OPT_SOCKSUSER, &userid) < 0) { - if ((userid = getenv("LOGNAME")) == NULL) { - if ((userid = getenv("USER")) == NULL) { - userid = "anonymous"; - } - } - } - strncpy(sockhead->userid, userid, *headlen-SIZEOF_STRUCT_SOCKS4); - *headlen = SIZEOF_STRUCT_SOCKS4+strlen(userid)+1; - return STAT_OK; -} - - -/* called within retry/fork loop, before connect() */ -int - _xioopen_socks4_connect0(struct single *xfd, - const char *hostname, /* socks target host */ - int socks4a, - struct socks4 *sockhead, - ssize_t *headlen, /* get available space, - return used length*/ - int level) { - struct hostent *host = NULL; - int result; - - if (!socks4a) { - if ((result = xioGethostbyname(hostname, &host, level)) != STAT_OK) { - return result; - } - } - - if (!socks4a || host != NULL) { - memcpy(&sockhead->dest, host->h_addr_list[0], 4); - } -#if WITH_SOCKS4A - else { - /*! noresolve */ - sockhead->dest = htonl(0x00000001); /* three bytes zero */ - } -#endif /* WITH_SOCKS4A */ -#if WITH_SOCKS4A - if (host == NULL) { - /* SOCKS4A requires us to append the host name to resolve - after the user name's trailing 0 byte. */ - char* insert_position = (char*) sockhead + *headlen; - - strncpy(insert_position, hostname, BUFF_LEN-*headlen); - ((char *)sockhead)[BUFF_LEN-1] = 0; //insert_position[BUFF_LEN-1] = 0; - *headlen += strlen(hostname) + 1; - if (*headlen > BUFF_LEN) { - *headlen = BUFF_LEN; - } - } -#endif /* WITH_SOCKS4A */ - return STAT_OK; -} - - -/* perform socks4 client dialog on existing FD. - Called within fork/retry loop, after connect() */ -int _xioopen_socks4_connect(struct single *xfd, - struct socks4 *sockhead, - size_t headlen, - int level) { - ssize_t bytes; - int result; - unsigned char buff[SIZEOF_STRUCT_SOCKS4]; - struct socks4 *replyhead = (struct socks4 *)buff; - - /* send socks header (target addr+port, +auth) */ - Info("sending socks request"); - do { - result = Write(xfd->fd, sockhead, headlen); - } while (result < 0 && errno == EINTR); - if (result < 0) { - Msg4(level, "write(%d, %p, "F_Zu"): %s", - xfd->fd, sockhead, headlen, strerror(errno)); - if (Close(xfd->fd) < 0) { - Warn2("close(%d): %s", xfd->fd, strerror(errno)); - } - return STAT_RETRYLATER; /* retry complete open cycle */ - } - - bytes = 0; - Info("waiting for socks reply"); - while (bytes >= 0) { /* loop over answer chunks until complete or error */ - /* receive socks answer */ - do { - result = Read(xfd->fd, buff+bytes, SIZEOF_STRUCT_SOCKS4-bytes); - } while (result < 0 && errno == EINTR); - if (result < 0) { - Msg4(level, "read(%d, %p, "F_Zu"): %s", - xfd->fd, buff+bytes, SIZEOF_STRUCT_SOCKS4-bytes, - strerror(errno)); - if (Close(xfd->fd) < 0) { - Warn2("close(%d): %s", xfd->fd, strerror(errno)); - } - } - if (result == 0) { - Msg(level, "read(): EOF during read of socks reply"); - if (Close(xfd->fd) < 0) { - Warn2("close(%d): %s", xfd->fd, strerror(errno)); - } - return STAT_RETRYLATER; - } - bytes += result; - if (bytes == SIZEOF_STRUCT_SOCKS4) { - Debug1("received all "F_Zd" bytes", bytes); - break; - } - Debug2("received "F_Zd" bytes, waiting for "F_Zu" more bytes", - result, SIZEOF_STRUCT_SOCKS4-bytes); - } - if (result <= 0) { /* we had a problem while reading socks answer */ - return STAT_RETRYLATER; /* retry complete open cycle */ - } - - Info7("socks answer: {%u, %u, %u, %u.%u.%u.%u}", - replyhead->version, replyhead->action, ntohs(replyhead->port), - ((uint8_t *)&replyhead->dest)[0], - ((uint8_t *)&replyhead->dest)[1], - ((uint8_t *)&replyhead->dest)[2], - ((uint8_t *)&replyhead->dest)[3]); - if (replyhead->version != 0) { - Warn1("socks: reply code version is not 0 (%d)", - replyhead->version); - } - - switch (replyhead->action) { - case SOCKS_CD_GRANTED: - /* Notice("socks: connect request succeeded"); */ -#if 0 - if (Getsockname(xfd->fd, (struct sockaddr *)&us, &uslen) < 0) { - Warn4("getsockname(%d, %p, {%d}): %s", - xfd->fd, &us, uslen, strerror(errno)); - } - Notice1("successfully connected from %s via socks", - sockaddr_info((struct sockaddr *)&us, infobuff, sizeof(infobuff))); -#else - Notice("successfully connected via socks"); -#endif - break; - - case SOCKS_CD_FAILED: - Msg(level, "socks: connect request rejected or failed"); - return STAT_RETRYLATER; - - case SOCKS_CD_NOIDENT: - Msg(level, "socks: ident refused by client"); - return STAT_RETRYLATER; - - case SOCKS_CD_IDENTFAILED: - Msg(level, "socks: ident failed"); - return STAT_RETRYLATER; - - default: - Msg1(level, "socks: undefined status %u", replyhead->action); - } - - return STAT_OK; -} -#endif /* WITH_SOCKS4 || WITH_SOCKS4A */ - >Release-Note: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20041110165953.913928B803>