mirror of
https://repo.or.cz/socat.git
synced 2025-05-23 05:12:40 +00:00
Protect SSL_connect(); Nanosleep() with decimal output
This commit is contained in:
parent
416fe38e33
commit
ed11b3d2c5
5 changed files with 38 additions and 18 deletions
4
CHANGES
4
CHANGES
|
@ -52,6 +52,10 @@ Corrections:
|
|||
Thanks to Brian Woo for reporting this issue.
|
||||
Test: UDP_LISTEN_BIND4
|
||||
|
||||
Protected SSL_connect() from SIGCHLD,SIGUSR1.
|
||||
|
||||
Nanosleep() trace output now in decimal form.
|
||||
|
||||
Features:
|
||||
POSIXMQ-RECV now takes option o-nonblock; this, in combination with -T,
|
||||
makes it possible to terminate Socat in case the queue is empty.
|
||||
|
|
1
sslcls.c
1
sslcls.c
|
@ -368,6 +368,7 @@ int sycSSL_connect(SSL *ssl) {
|
|||
int result;
|
||||
Debug1("SSL_connect(%p)", ssl);
|
||||
result = SSL_connect(ssl);
|
||||
if (!diag_in_handler) diag_flush();
|
||||
Debug1("SSL_connect() -> %d", result);
|
||||
return result;
|
||||
}
|
||||
|
|
4
sycls.c
4
sycls.c
|
@ -1421,11 +1421,11 @@ unsigned int Sleep(unsigned int seconds) {
|
|||
#if HAVE_NANOSLEEP
|
||||
unsigned int Nanosleep(const struct timespec *req, struct timespec *rem) {
|
||||
int retval, _errno;
|
||||
Debug3("nanosleep({"F_time",%ld},%p)", req->tv_sec, req->tv_nsec, rem);
|
||||
Debug3("nanosleep({"F_time".%09ld}, %p)", req->tv_sec, req->tv_nsec, rem);
|
||||
retval = nanosleep(req, rem);
|
||||
_errno = errno;
|
||||
if (rem) {
|
||||
Debug3("nanosleep(,{"F_time",%ld}) -> %d",
|
||||
Debug3("nanosleep(,{"F_time".%09ld}) -> %d",
|
||||
rem->tv_sec, rem->tv_nsec, retval);
|
||||
} else {
|
||||
Debug1("nanosleep() -> %d", retval);
|
||||
|
|
32
test.sh
32
test.sh
|
@ -152,7 +152,7 @@ fi
|
|||
if [ -z "$val_t" ]; then
|
||||
# Determine the time Socat needs for an empty run
|
||||
$SOCAT /dev/null /dev/null # populate caches
|
||||
MILLIs=$(bash -c 'time $SOCAT /dev/null /dev/null' 2>&1 |grep ^real |sed 's/.*m\(.*\)s.*/\1/' |tr -d ,.)
|
||||
MILLIs=$(bash -c 'time $SOCAT $opts /dev/null /dev/null' 2>&1 |grep ^real |sed 's/.*m\(.*\)s.*/\1/' |tr -d ,.)
|
||||
while [ "${MILLIs:0:1}" = '0' ]; do MILLIs=${MILLIs##0}; done # strip leading '0' to avoid octal
|
||||
[ -z "$MILLIs" ] && MILLIs=1
|
||||
[ "$DEFS" ] && echo "MILLIs=\"$MILLIs\" (1)" >&2
|
||||
|
@ -5206,11 +5206,12 @@ newport tcp4; PORT3=$PORT
|
|||
newport tcp4; PORT4=$PORT
|
||||
newport tcp4; PORT5=$PORT
|
||||
# this is the server in the protected network that we want to reach
|
||||
CMD1="$TRACE $SOCAT $opts -lpserver -t$(reltime 10) TCP4-L:$PORT1,reuseaddr,bind=$LOCALHOST,fork ECHO"
|
||||
CMD1="$TRACE $SOCAT $opts -lpserver -t$(reltime 100) TCP4-L:$PORT1,reuseaddr,bind=$LOCALHOST,fork ECHO"
|
||||
# this is the proxy in the protected network that provides a way out
|
||||
# note: the proxy.sh script starts one or two more socat processes without
|
||||
# setting the program name
|
||||
CMD2="$TRACE $SOCAT $opts -lpproxy -t$(reltime 10) TCP4-L:$PORT2,reuseaddr,bind=$LOCALHOST,fork EXEC:./proxy.sh"
|
||||
export SOCAT_OPTS="$OPTS" # for proxy.sh
|
||||
CMD2="$TRACE $SOCAT $opts -lpproxy -t$(reltime 100) TCP4-L:$PORT2,reuseaddr,bind=$LOCALHOST,fork EXEC:./proxy.sh"
|
||||
# this is our proxy connect wrapper in the protected network
|
||||
CMD3="$TRACE $SOCAT $opts -lpwrapper -t$(reltime 30) TCP4-L:$PORT3,reuseaddr,bind=$LOCALHOST,fork PROXY:$LOCALHOST:$LOCALHOST:$PORT4,pf=ip4,proxyport=$PORT2,resolve"
|
||||
# this is our double client in the protected network using SSL
|
||||
|
@ -5238,19 +5239,21 @@ eval "$CMD5 2>\"${te}5\" &"
|
|||
pid5=$!
|
||||
waittcp4port $PORT5 1 50 || $PRINTF "$FAILED: port $PORT5\n" >&2 </dev/null
|
||||
# and this is the outside client:
|
||||
echo "$da1" |$CMD6 >${tf}_1 2>"${te}6_1" &
|
||||
{ echo "$da1"; relsleep 100; } |$CMD6 >${tf}_1 2>"${te}6_1" &
|
||||
pid6_1=$!
|
||||
echo "$da2" |$CMD6 >${tf}_2 2>"${te}6_2" &
|
||||
relsleep 20
|
||||
{ echo "$da2"; relsleep 100; } |$CMD6 >${tf}_2 2>"${te}6_2" &
|
||||
pid6_2=$!
|
||||
echo "$da3" |$CMD6 >${tf}_3 2>"${te}6_3" &
|
||||
relsleep 20
|
||||
{ echo "$da3"; relsleep 100; } |$CMD6 >${tf}_3 2>"${te}6_3" &
|
||||
pid6_3=$!
|
||||
wait $pid6_1 $pid6_2 $pid6_3
|
||||
kill $pid1 $pid2 $pid3 $pid4 $pid5 $(childpids $pid5) 2>/dev/null
|
||||
# (On BSDs a child of pid5 likes to hang)
|
||||
#
|
||||
(echo "$da1"; relsleep 2) |diff - "${tf}_1" >"${tdiff}1"
|
||||
(echo "$da2"; relsleep 2) |diff - "${tf}_2" >"${tdiff}2"
|
||||
(echo "$da3"; relsleep 2) |diff - "${tf}_3" >"${tdiff}3"
|
||||
echo "$da1" |diff - "${tf}_1" >"${tdiff}1"
|
||||
echo "$da2" |diff - "${tf}_2" >"${tdiff}2"
|
||||
echo "$da3" |diff - "${tf}_3" >"${tdiff}3"
|
||||
if test -s "${tdiff}1" -o -s "${tdiff}2" -o -s "${tdiff}3"; then
|
||||
# FAILED only when none of the three transfers succeeded
|
||||
if test -s "${tdiff}1" -a -s "${tdiff}2" -a -s "${tdiff}3"; then
|
||||
|
@ -15565,7 +15568,8 @@ elif ! runsip4 >/dev/null; then
|
|||
cant
|
||||
else
|
||||
# We need a hanging connection attempt, guess an address for this
|
||||
HANGIP=0.0.0.1
|
||||
#HANGIP=0.0.0.1 # some OSes refuse to end to this address
|
||||
HANGIP=8.8.8.9 # 2025 this hangs...
|
||||
te1="$td/test$N.stderr1"
|
||||
tk1="$td/test$N.kill1"
|
||||
te2="$td/test$N.stderr2"
|
||||
|
@ -15590,8 +15594,12 @@ CMD2="$TRACE $SOCAT $opts - DTLS:$HANGIP:1,verify=0,so-rcvtimeo=$(reltime 1)"
|
|||
$CMD2 >"$te1" 2>$te2 </dev/null &
|
||||
pid2=$!
|
||||
relsleep 8 # in OpenSSL 1.1.1f DTLS takes two timeouts
|
||||
if kill $pid2 2>"$tk2"; then
|
||||
$PRINTF "$FAILED\n"
|
||||
sleep 0.02 # in OpenSSL 3.0.13 SSL_CTX_clear_mode() needs e.g. 0.02s
|
||||
kill $pid2 2>"$tk2"
|
||||
prc2=$?
|
||||
wait
|
||||
if [ $prc2 -eq 0 ]; then
|
||||
$PRINTF "$FAILED (not timeout)\n"
|
||||
echo "$CMD2" >&2
|
||||
cat "$te2" >&2
|
||||
cat "$tk2" >&2
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
(not only tcp, but also pipes, stdin, files...)
|
||||
for tcp we want to provide support for socks and proxy.
|
||||
read and write functions must use the openssl crypt versions.
|
||||
but currently only plain tcp4 is implemented.
|
||||
*/
|
||||
|
||||
/* Linux: "man 3 ssl" */
|
||||
|
@ -1976,12 +1975,20 @@ static int xioSSL_set_fd(struct single *sfd, int level) {
|
|||
should not retry for any reason. */
|
||||
static int xioSSL_connect(struct single *sfd, const char *opt_commonname,
|
||||
bool opt_ver, int level) {
|
||||
sigset_t masksigs, oldsigs;
|
||||
char error_string[256];
|
||||
int errint, status, ret;
|
||||
int errint, status, _errno, ret;
|
||||
unsigned long err;
|
||||
|
||||
sigemptyset(&masksigs);
|
||||
sigaddset(&masksigs, SIGCHLD);
|
||||
sigaddset(&masksigs, SIGUSR1);
|
||||
Sigprocmask(SIG_BLOCK, &masksigs, &oldsigs);
|
||||
/* connect via SSL by performing handshake */
|
||||
if ((ret = sycSSL_connect(sfd->para.openssl.ssl)) <= 0) {
|
||||
ret = sycSSL_connect(sfd->para.openssl.ssl);
|
||||
_errno = errno;
|
||||
Sigprocmask(SIG_SETMASK, &oldsigs, NULL);
|
||||
if (ret <= 0) {
|
||||
/*if (ERR_peek_error() == 0) Msg(level, "SSL_connect() failed");*/
|
||||
errint = SSL_get_error(sfd->para.openssl.ssl, ret);
|
||||
switch (errint) {
|
||||
|
@ -2005,7 +2012,7 @@ static int xioSSL_connect(struct single *sfd, const char *opt_commonname,
|
|||
if (ret == 0) {
|
||||
Msg(level, "SSL_connect(): socket closed by peer");
|
||||
} else if (ret == -1) {
|
||||
Msg1(level, "SSL_connect(): %s", strerror(errno));
|
||||
Msg1(level, "SSL_connect(): %s", strerror(_errno));
|
||||
}
|
||||
} else {
|
||||
Msg(level, "I/O error"); /*!*/
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue