tpws: specify oob byte . tamper pos range limiter

This commit is contained in:
bol-van 2024-03-05 14:59:44 +03:00
parent 8b38cccee2
commit 663a2bb2a4
14 changed files with 53 additions and 18 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -50,6 +50,7 @@ struct params_s
bool split_any_protocol; bool split_any_protocol;
int split_pos; int split_pos;
bool disorder, oob; bool disorder, oob;
uint8_t oob_byte;
int ttl_default; int ttl_default;
char pidfile[256]; char pidfile[256];
@ -60,6 +61,8 @@ struct params_s
int hostlist_auto_fail_threshold, hostlist_auto_fail_time; int hostlist_auto_fail_threshold, hostlist_auto_fail_time;
hostfail_pool *hostlist_auto_fail_counters; hostfail_pool *hostlist_auto_fail_counters;
unsigned int tamper_start,tamper_cutoff;
int debug; int debug;
#if defined(BSD) #if defined(BSD)

View File

@ -176,7 +176,7 @@ static void exithelp(void)
#else #else
" --disorder\t\t\t\t; when splitting simulate sending second fragment first\n" " --disorder\t\t\t\t; when splitting simulate sending second fragment first\n"
#endif #endif
" --oob\t\t\t\t\t; when splitting send out of band zero byte\n" " --oob[=<char>|0xHEX]\t\t\t; when splitting send out of band byte. default is HEX 0x00.\n"
" --hostcase\t\t\t\t; change Host: => host:\n" " --hostcase\t\t\t\t; change Host: => host:\n"
" --hostspell\t\t\t\t; exact spelling of \"Host\" header. must be 4 chars. default is \"host\"\n" " --hostspell\t\t\t\t; exact spelling of \"Host\" header. must be 4 chars. default is \"host\"\n"
" --hostdot\t\t\t\t; add \".\" after Host: name\n" " --hostdot\t\t\t\t; add \".\" after Host: name\n"
@ -188,7 +188,9 @@ static void exithelp(void)
" --methodeol\t\t\t\t; add end-of-line before method\n" " --methodeol\t\t\t\t; add end-of-line before method\n"
" --unixeol\t\t\t\t; replace 0D0A to 0A\n" " --unixeol\t\t\t\t; replace 0D0A to 0A\n"
" --tlsrec=sni\t\t\t\t; make 2 TLS records. split at SNI. don't split if SNI is not present\n" " --tlsrec=sni\t\t\t\t; make 2 TLS records. split at SNI. don't split if SNI is not present\n"
" --tlsrec-pos=<pos>\t\t\t; make 2 TLS records. split at specified pos\n", " --tlsrec-pos=<pos>\t\t\t; make 2 TLS records. split at specified pos\n"
" --tamper-start=<pos>\t\t\t; start tampering only from specified outbound stream position. default is 0.\n"
" --tamper-cutoff=<pos>\t\t\t; do not tamper anymore after specified outbound stream position. default is unlimited.\n",
HOSTLIST_AUTO_FAIL_THRESHOLD_DEFAULT, HOSTLIST_AUTO_FAIL_TIME_DEFAULT HOSTLIST_AUTO_FAIL_THRESHOLD_DEFAULT, HOSTLIST_AUTO_FAIL_TIME_DEFAULT
); );
exit(1); exit(1);
@ -295,7 +297,7 @@ void parse_params(int argc, char *argv[])
{ "split-pos",required_argument,0,0 },// optidx=24 { "split-pos",required_argument,0,0 },// optidx=24
{ "split-any-protocol",optional_argument,0,0},// optidx=25 { "split-any-protocol",optional_argument,0,0},// optidx=25
{ "disorder",no_argument,0,0 },// optidx=26 { "disorder",no_argument,0,0 },// optidx=26
{ "oob",no_argument,0,0 },// optidx=27 { "oob",optional_argument,0,0 },// optidx=27
{ "methodspace",no_argument,0,0 },// optidx=28 { "methodspace",no_argument,0,0 },// optidx=28
{ "methodeol",no_argument,0,0 },// optidx=29 { "methodeol",no_argument,0,0 },// optidx=29
{ "hosttab",no_argument,0,0 },// optidx=30 { "hosttab",no_argument,0,0 },// optidx=30
@ -317,8 +319,10 @@ void parse_params(int argc, char *argv[])
{ "socks",no_argument,0,0 },// optidx=46 { "socks",no_argument,0,0 },// optidx=46
{ "no-resolve",no_argument,0,0 },// optidx=47 { "no-resolve",no_argument,0,0 },// optidx=47
{ "skip-nodelay",no_argument,0,0 },// optidx=48 { "skip-nodelay",no_argument,0,0 },// optidx=48
{ "tamper-start",required_argument,0,0 },// optidx=49
{ "tamper-cutoff",required_argument,0,0 },// optidx=50
#if defined(BSD) && !defined(__OpenBSD__) && !defined(__APPLE__) #if defined(BSD) && !defined(__OpenBSD__) && !defined(__APPLE__)
{ "enable-pf",no_argument,0,0 },// optidx=49 { "enable-pf",no_argument,0,0 },// optidx=51
#endif #endif
{ "hostlist-auto-retrans-threshold",optional_argument,0,0}, // ignored. for nfqws command line compatibility { "hostlist-auto-retrans-threshold",optional_argument,0,0}, // ignored. for nfqws command line compatibility
{ NULL,0,NULL,0 } { NULL,0,NULL,0 }
@ -508,6 +512,18 @@ void parse_params(int argc, char *argv[])
save_default_ttl(); save_default_ttl();
break; break;
case 27: /* oob */ case 27: /* oob */
if (optarg)
{
size_t l = strlen(optarg);
unsigned int bt;
if (l==1) params.oob_byte = (uint8_t)*optarg;
else if (l!=4 || sscanf(optarg,"0x%02X",&bt)!=1)
{
fprintf(stderr, "Invalid argument for oob\n");
exit_clean(1);
}
else params.oob_byte = (uint8_t)bt;
}
params.oob = true; params.oob = true;
break; break;
case 28: /* methodspace */ case 28: /* methodspace */
@ -653,8 +669,14 @@ void parse_params(int argc, char *argv[])
case 48: /* skip-nodelay */ case 48: /* skip-nodelay */
params.skip_nodelay = true; params.skip_nodelay = true;
break; break;
case 49: /* tamper-start */
params.tamper_start = atoi(optarg);
break;
case 50: /* tamper-cutoff */
params.tamper_cutoff = atoi(optarg);
break;
#if defined(BSD) && !defined(__OpenBSD__) && !defined(__APPLE__) #if defined(BSD) && !defined(__OpenBSD__) && !defined(__APPLE__)
case 49: /* enable-pf */ case 51: /* enable-pf */
params.pf_enable = true; params.pf_enable = true;
break; break;
#endif #endif
@ -798,7 +820,7 @@ static bool set_ulimit(void)
// additional 1/2 for unpaired remote legs sending buffers // additional 1/2 for unpaired remote legs sending buffers
// 16 for listen_fd, epoll, hostlist, ... // 16 for listen_fd, epoll, hostlist, ...
#ifdef SPLICE_PRESENT #ifdef SPLICE_PRESENT
fdmax = (params.tamper ? 4 : 6) * params.maxconn; fdmax = (params.tamper && !params.tamper_start && !params.tamper_cutoff ? 4 : 6) * params.maxconn;
#else #else
fdmax = 2 * params.maxconn; fdmax = 2 * params.maxconn;
#endif #endif

View File

@ -400,7 +400,7 @@ static tproxy_conn_t *new_conn(int fd, bool remote)
#ifdef SPLICE_PRESENT #ifdef SPLICE_PRESENT
// if dont tamper - both legs are spliced, create 2 pipes // if dont tamper - both legs are spliced, create 2 pipes
// otherwise create pipe only in local leg // otherwise create pipe only in local leg
if((!params.tamper || !remote) && pipe2(conn->splice_pipe, O_NONBLOCK) != 0) if ((!remote || !params.tamper || params.tamper_start || params.tamper_cutoff ) && pipe2(conn->splice_pipe, O_NONBLOCK) != 0)
{ {
fprintf(stderr, "Could not create the splice pipe\n"); fprintf(stderr, "Could not create the splice pipe\n");
free_conn(conn); free_conn(conn);
@ -905,10 +905,13 @@ static void tamper(tproxy_conn_t *conn, uint8_t *segment, size_t segment_buffer_
tamper_in(&conn->partner->track,segment,segment_buffer_size,segment_size); tamper_in(&conn->partner->track,segment,segment_buffer_size,segment_size);
} }
} }
else else if (conn->trd >= params.tamper_start && (!params.tamper_cutoff || conn->trd < params.tamper_cutoff))
{ {
DBGPRINT("tamper_out stream pos %zu. tamper range %u-%u", conn->trd, params.tamper_start, params.tamper_cutoff)
tamper_out(&conn->track,segment,segment_buffer_size,segment_size,split_pos); tamper_out(&conn->track,segment,segment_buffer_size,segment_size,split_pos);
} }
else
DBGPRINT("stream pos %zu is out of tamper range %u-%u", conn->trd, params.tamper_start, params.tamper_cutoff)
} }
} }
@ -963,8 +966,13 @@ static bool handle_epoll(tproxy_conn_t *conn, struct tailhead *conn_list, uint32
DBGPRINT("numbytes=%d",numbytes) DBGPRINT("numbytes=%d",numbytes)
if (numbytes>0) if (numbytes>0)
{ {
if (conn->remote)
VPRINT("remote leg stream pos R/W : %zu/%zu",conn->trd,conn->twr)
else
VPRINT("local leg stream pos : %zu/%zu",conn->trd,conn->twr)
#ifdef SPLICE_PRESENT #ifdef SPLICE_PRESENT
if (!params.tamper || conn->remote && conn->partner->track.bTamperInCutoff) if (!params.tamper || conn->remote && conn->partner->track.bTamperInCutoff ||
!conn->remote && (conn->trd < params.tamper_start || params.tamper_cutoff && conn->trd >= params.tamper_cutoff))
{ {
// incoming data from remote leg we splice without touching // incoming data from remote leg we splice without touching
// pipe is in the local leg, so its in conn->partner->splice_pipe // pipe is in the local leg, so its in conn->partner->splice_pipe
@ -998,26 +1006,28 @@ static bool handle_epoll(tproxy_conn_t *conn, struct tailhead *conn_list, uint32
if (rd<0 && errno==EAGAIN) rd=0; if (rd<0 && errno==EAGAIN) rd=0;
if (rd>0) if (rd>0)
{ {
conn->trd+=rd;
size_t split_pos; size_t split_pos;
bs = rd; bs = rd;
// tamper needs to know stream position of the block start
tamper(conn, buf, sizeof(buf), &bs, &split_pos); tamper(conn, buf, sizeof(buf), &bs, &split_pos);
// increase after tamper
conn->trd+=rd;
if (split_pos) if (split_pos)
{ {
uint8_t oob;
VPRINT("Splitting at pos %zu", split_pos) VPRINT("Splitting at pos %zu", split_pos)
if (params.oob) if (params.oob)
{ {
oob = buf[split_pos]; uint8_t oob_save;
buf[split_pos] = 0; oob_save = buf[split_pos];
buf[split_pos] = params.oob_byte;
wr = send_or_buffer(conn->partner->wr_buf, conn->partner->fd, buf, split_pos+1, MSG_OOB, params.disorder ? 1 : 0);
buf[split_pos] = oob_save;
} }
wr = send_or_buffer(conn->partner->wr_buf, conn->partner->fd, buf, split_pos+1, params.oob ? MSG_OOB : 0, params.disorder ? 1 : 0); else
if (params.oob) buf[split_pos] = oob; wr = send_or_buffer(conn->partner->wr_buf, conn->partner->fd, buf, split_pos, 0, params.disorder ? 1 : 0);
DBGPRINT("send_or_buffer(1) fd=%d wr=%zd err=%d",conn->partner->fd,wr,errno) DBGPRINT("send_or_buffer(1) fd=%d wr=%zd err=%d",conn->partner->fd,wr,errno)
if (wr >= 0) if (wr >= 0)
{ {