Lines Matching +full:buffered +full:- +full:positive

1 /*	$OpenBSD: ftp-proxy.c,v 1.19 2008/06/13 07:25:26 claudio Exp $ */
136 logmsg(LOG_INFO, "#%d client close", s->id); in client_error()
138 logmsg(LOG_ERR, "#%d client reset connection", s->id); in client_error()
140 logmsg(LOG_ERR, "#%d client timeout", s->id); in client_error()
142 logmsg(LOG_ERR, "#%d client write error: %d", s->id, what); in client_error()
144 logmsg(LOG_ERR, "#%d abnormal client error: %d", s->id, what); in client_error()
153 s->cmd = CMD_NONE; in client_parse()
154 s->port = 0; in client_parse()
167 * waiting for a positive reply from the server. Some in client_parse()
171 if (s->cmd == CMD_PORT || s->cmd == CMD_EPRT) in client_parse()
188 logmsg(LOG_DEBUG, "#%d proxy: %s", s->id, linebuf); in client_parse_anon()
192 bufferevent_write(s->client_bufev, linebuf, linelen); in client_parse_anon()
206 s->cmd = CMD_PASV; in client_parse_cmd()
208 s->cmd = CMD_PORT; in client_parse_cmd()
210 s->cmd = CMD_EPSV; in client_parse_cmd()
212 s->cmd = CMD_EPRT; in client_parse_cmd()
216 if (ipv6_mode && (s->cmd == CMD_PASV || s->cmd == CMD_PORT)) { in client_parse_cmd()
221 if (s->cmd == CMD_PORT || s->cmd == CMD_EPRT) { in client_parse_cmd()
222 s->port = parse_port(s->cmd); in client_parse_cmd()
223 if (s->port < MIN_PORT) { in client_parse_cmd()
224 logmsg(LOG_CRIT, "#%d bad port in '%s'", s->id, in client_parse_cmd()
228 s->proxy_port = pick_proxy_port(); in client_parse_cmd()
229 proxy_reply(s->cmd, sstosa(&s->proxy_ss), s->proxy_port); in client_parse_cmd()
230 logmsg(LOG_DEBUG, "#%d proxy: %s", s->id, linebuf); in client_parse_cmd()
244 buf_avail = sizeof s->cbuf - s->cbuf_valid; in client_read()
245 clientread = bufferevent_read(bufev, s->cbuf + s->cbuf_valid, in client_read()
247 s->cbuf_valid += clientread; in client_read()
249 while ((n = get_line(s->cbuf, &s->cbuf_valid)) > 0) { in client_read()
250 logmsg(LOG_DEBUG, "#%d client: %s", s->id, linebuf); in client_read()
255 bufferevent_write(s->server_bufev, linebuf, linelen); in client_read()
258 if (n == -1) { in client_read()
260 " clean", s->id); in client_read()
278 setgroups(1, &pw->pw_gid) != 0 || in drop_privs()
279 setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) != 0 || in drop_privs()
280 setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) != 0) in drop_privs()
291 logmsg(LOG_INFO, "#%d ending session", s->id); in end_session()
294 if (s->client_bufev && s->client_fd != -1) in end_session()
295 evbuffer_write(s->client_bufev->output, s->client_fd); in end_session()
296 if (s->server_bufev && s->server_fd != -1) in end_session()
297 evbuffer_write(s->server_bufev->output, s->server_fd); in end_session()
299 if (s->client_fd != -1) in end_session()
300 close(s->client_fd); in end_session()
301 if (s->server_fd != -1) in end_session()
302 close(s->server_fd); in end_session()
304 if (s->client_bufev) in end_session()
305 bufferevent_free(s->client_bufev); in end_session()
306 if (s->server_bufev) in end_session()
307 bufferevent_free(s->server_bufev); in end_session()
311 if (prepare_commit(s->id) == -1) in end_session()
313 else if (do_commit() == -1) { in end_session()
318 logmsg(LOG_ERR, "#%d pf rule removal failed: %s", s->id, in end_session()
323 session_count--; in end_session()
348 return (-1); in get_line()
354 return (-1); in get_line()
365 return (-1); in get_line()
370 *valid -= linelen; in get_line()
415 s->client_fd = client_fd; in handle_connection()
416 memcpy(sstosa(&s->client_ss), client_sa, client_sa->sa_len); in handle_connection()
419 client_sa = sstosa(&s->client_ss); in handle_connection()
420 server_sa = sstosa(&s->server_ss); in handle_connection()
422 proxy_to_server_sa = sstosa(&s->proxy_ss); in handle_connection()
426 logmsg(LOG_DEBUG, "#%d accepted connection from %s", s->id, in handle_connection()
433 if ((getsockname(s->client_fd, client_to_proxy_sa, &len)) < 0) { in handle_connection()
434 logmsg(LOG_CRIT, "#%d getsockname failed: %s", s->id, in handle_connection()
439 logmsg(LOG_CRIT, "#%d server lookup failed (no rdr?)", s->id); in handle_connection()
443 memcpy(sstosa(&s->orig_server_ss), server_sa, in handle_connection()
444 server_sa->sa_len); in handle_connection()
445 memcpy(server_sa, fixed_server_sa, fixed_server_sa->sa_len); in handle_connection()
453 if ((s->server_fd = socket(server_sa->sa_family, SOCK_STREAM, in handle_connection()
455 logmsg(LOG_CRIT, "#%d server socket failed: %s", s->id, in handle_connection()
459 if (fixed_proxy && bind(s->server_fd, sstosa(&fixed_proxy_ss), in handle_connection()
462 s->id, strerror(errno)); in handle_connection()
466 /* Use non-blocking connect(), see CONNECT_TIMEOUT below. */ in handle_connection()
467 if ((fc = fcntl(s->server_fd, F_GETFL)) == -1 || in handle_connection()
468 fcntl(s->server_fd, F_SETFL, fc | O_NONBLOCK) == -1) { in handle_connection()
469 logmsg(LOG_CRIT, "#%d cannot mark socket non-blocking: %s", in handle_connection()
470 s->id, strerror(errno)); in handle_connection()
473 if (connect(s->server_fd, server_sa, server_sa->sa_len) < 0 && in handle_connection()
476 s->id, sock_ntop(server_sa), strerror(errno)); in handle_connection()
481 if ((getsockname(s->server_fd, proxy_to_server_sa, &len)) < 0) { in handle_connection()
482 logmsg(LOG_CRIT, "#%d getsockname failed: %s", s->id, in handle_connection()
488 "%s via proxy %s ", s->id, session_count, max_sessions, in handle_connection()
494 setsockopt(s->client_fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, in handle_connection()
496 setsockopt(s->server_fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, in handle_connection()
500 * Setup buffered events. in handle_connection()
502 s->client_bufev = bufferevent_new(s->client_fd, &client_read, NULL, in handle_connection()
504 if (s->client_bufev == NULL) { in handle_connection()
505 logmsg(LOG_CRIT, "#%d bufferevent_new client failed", s->id); in handle_connection()
508 bufferevent_settimeout(s->client_bufev, timeout, 0); in handle_connection()
509 bufferevent_enable(s->client_bufev, EV_READ | EV_TIMEOUT); in handle_connection()
511 s->server_bufev = bufferevent_new(s->server_fd, &server_read, NULL, in handle_connection()
513 if (s->server_bufev == NULL) { in handle_connection()
514 logmsg(LOG_CRIT, "#%d bufferevent_new server failed", s->id); in handle_connection()
517 bufferevent_settimeout(s->server_bufev, CONNECT_TIMEOUT, 0); in handle_connection()
518 bufferevent_enable(s->server_bufev, EV_READ | EV_TIMEOUT); in handle_connection()
548 s->id = id_count++; in init_session()
549 s->client_fd = -1; in init_session()
550 s->server_fd = -1; in init_session()
551 s->cbuf[0] = '\0'; in init_session()
552 s->cbuf_valid = 0; in init_session()
553 s->sbuf[0] = '\0'; in init_session()
554 s->sbuf_valid = 0; in init_session()
555 s->client_bufev = NULL; in init_session()
556 s->server_bufev = NULL; in init_session()
557 s->cmd = CMD_NONE; in init_session()
558 s->port = 0; in init_session()
626 while ((ch = getopt(argc, argv, "6Aa:b:D:dm:P:p:q:R:rT:t:v")) != -1) { in main()
700 if (setrlimit(RLIMIT_NOFILE, &rlp) == -1) in main()
712 memcpy(&fixed_proxy_ss, res->ai_addr, res->ai_addrlen); in main()
727 memcpy(&fixed_server_ss, res->ai_addr, res->ai_addrlen); in main()
742 if ((listenfd = socket(res->ai_family, SOCK_STREAM, IPPROTO_TCP)) == -1) in main()
748 if (bind(listenfd, (struct sockaddr *)res->ai_addr, in main()
749 (socklen_t)res->ai_addrlen) != 0) in main()
759 if (daemon(0, 0) == -1) in main()
804 /* Find the last space or left-parenthesis. */ in parse_port()
805 for (p = linebuf + linelen; p > linebuf; p--) in parse_port()
837 n = sscanf(p, " |2|%*[a-fA-F0-9:]|%u|", &port); in parse_port()
853 arc4random_uniform(IPPORT_HILASTAUTO - IPPORT_HIFIRSTAUTO)); in pick_proxy_port()
874 if (sa->sa_family == AF_INET) in proxy_reply()
877 else if (sa->sa_family == AF_INET6) in proxy_reply()
909 logmsg(LOG_INFO, "#%d server close", s->id); in server_error()
911 logmsg(LOG_ERR, "#%d server refused connection", s->id); in server_error()
913 logmsg(LOG_ERR, "#%d server write error: %d", s->id, what); in server_error()
915 logmsg(LOG_NOTICE, "#%d server timeout", s->id); in server_error()
917 logmsg(LOG_ERR, "#%d abnormal server error: %d", s->id, what); in server_error()
925 if (s->cmd == CMD_NONE || linelen < 4 || linebuf[0] != '2') in server_parse()
928 if ((s->cmd == CMD_PASV && strncmp("227 ", linebuf, 4) == 0) || in server_parse()
929 (s->cmd == CMD_EPSV && strncmp("229 ", linebuf, 4) == 0)) in server_parse()
933 s->cmd = CMD_NONE; in server_parse()
934 s->port = 0; in server_parse()
957 client_sa = sstosa(&s->client_ss); in allow_data_connection()
958 server_sa = sstosa(&s->server_ss); in allow_data_connection()
959 proxy_sa = sstosa(&s->proxy_ss); in allow_data_connection()
963 orig_sa = sstosa(&s->orig_server_ss); in allow_data_connection()
966 orig_sa = sstosa(&s->server_ss); in allow_data_connection()
969 if (s->cmd == CMD_PASV || s->cmd == CMD_EPSV) { in allow_data_connection()
970 s->port = parse_port(s->cmd); in allow_data_connection()
971 if (s->port < MIN_PORT) { in allow_data_connection()
972 logmsg(LOG_CRIT, "#%d bad port in '%s'", s->id, in allow_data_connection()
976 s->proxy_port = pick_proxy_port(); in allow_data_connection()
978 " via port %d", s->id, s->port, s->proxy_port); in allow_data_connection()
980 if (prepare_commit(s->id) == -1) in allow_data_connection()
984 proxy_reply(s->cmd, orig_sa, s->proxy_port); in allow_data_connection()
985 logmsg(LOG_DEBUG, "#%d proxy: %s", s->id, linebuf); in allow_data_connection()
987 /* rdr from $client to $orig_server port $proxy_port -> $server in allow_data_connection()
989 if (add_rdr(s->id, client_sa, orig_sa, s->proxy_port, in allow_data_connection()
990 server_sa, s->port) == -1) in allow_data_connection()
993 /* nat from $client to $server port $port -> $proxy */ in allow_data_connection()
994 if (add_nat(s->id, client_sa, server_sa, s->port, proxy_sa, in allow_data_connection()
995 PF_NAT_PROXY_PORT_LOW, PF_NAT_PROXY_PORT_HIGH) == -1) in allow_data_connection()
999 if (add_filter(s->id, PF_IN, client_sa, server_sa, in allow_data_connection()
1000 s->port) == -1) in allow_data_connection()
1004 if (add_filter(s->id, PF_OUT, proxy_sa, server_sa, in allow_data_connection()
1005 s->port) == -1) in allow_data_connection()
1010 if (s->cmd == CMD_PORT || s->cmd == CMD_EPRT) { in allow_data_connection()
1012 " via port %d", s->id, s->port, s->proxy_port); in allow_data_connection()
1014 if (prepare_commit(s->id) == -1) in allow_data_connection()
1018 /* rdr from $server to $proxy port $proxy_port -> $client port in allow_data_connection()
1020 if (add_rdr(s->id, server_sa, proxy_sa, s->proxy_port, in allow_data_connection()
1021 client_sa, s->port) == -1) in allow_data_connection()
1024 /* nat from $server to $client port $port -> $orig_server port in allow_data_connection()
1026 if (rfc_mode && s->cmd == CMD_PORT) { in allow_data_connection()
1028 if (add_nat(s->id, server_sa, client_sa, s->port, in allow_data_connection()
1029 orig_sa, 20, 20) == -1) in allow_data_connection()
1033 if (add_nat(s->id, server_sa, client_sa, s->port, in allow_data_connection()
1035 PF_NAT_PROXY_PORT_HIGH) == -1) in allow_data_connection()
1040 if (add_filter(s->id, PF_IN, server_sa, client_sa, s->port) == in allow_data_connection()
1041 -1) in allow_data_connection()
1045 if (add_filter(s->id, PF_OUT, orig_sa, client_sa, s->port) == in allow_data_connection()
1046 -1) in allow_data_connection()
1051 if (prepared && (do_commit() == -1)) { in allow_data_connection()
1056 if (do_commit() == -1) in allow_data_connection()
1060 s->cmd = CMD_NONE; in allow_data_connection()
1061 s->port = 0; in allow_data_connection()
1066 logmsg(LOG_CRIT, "#%d pf operation failed: %s", s->id, strerror(errno)); in allow_data_connection()
1082 buf_avail = sizeof s->sbuf - s->sbuf_valid; in server_read()
1083 srvread = bufferevent_read(bufev, s->sbuf + s->sbuf_valid, in server_read()
1085 s->sbuf_valid += srvread; in server_read()
1087 while ((n = get_line(s->sbuf, &s->sbuf_valid)) > 0) { in server_read()
1088 logmsg(LOG_DEBUG, "#%d server: %s", s->id, linebuf); in server_read()
1093 bufferevent_write(s->client_bufev, linebuf, linelen); in server_read()
1096 if (n == -1) { in server_read()
1098 " clean", s->id); in server_read()
1114 if (sa->sa_family == AF_INET) { in sock_ntop()
1117 return (inet_ntop(AF_INET, &sin->sin_addr, ntop_buf[n], in sock_ntop()
1121 if (sa->sa_family == AF_INET6) { in sock_ntop()
1124 return (inet_ntop(AF_INET6, &sin6->sin6_addr, ntop_buf[n], in sock_ntop()
1134 fprintf(stderr, "usage: %s [-6Adrv] [-a address] [-b address]" in usage()
1135 " [-D level] [-m maxsessions]\n [-P port]" in usage()
1136 " [-p port] [-q queue] [-R address] [-T tag]\n" in usage()
1137 " [-t timeout]\n", __progname); in usage()