diff options
| author | Denys Fedoryshchenko <denys.f@collabora.com> | 2026-08-16 09:13:39 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-08-16 09:13:39 +0300 |
| commit | 89637ee2417fc7f42e4213d417da38aa814047e4 (patch) | |
| tree | 18ea645dcd299593f12f448ce8b8d1167a6d66f1 | |
| parent | 77cae8318c00d9dda7a7bd1fbdb52e48e183ca85 (diff) | |
| parent | 9d47f220a09eb30750f85973dc2f0d4157eb78be (diff) | |
| download | accel-ppp-89637ee2417fc7f42e4213d417da38aa814047e4.tar.gz accel-ppp-89637ee2417fc7f42e4213d417da38aa814047e4.zip | |
Merge pull request #350 from nuclearcat/pptp-fixes
PPTP fixes
| -rw-r--r-- | accel-pppd/accel-ppp.conf.5 | 2 | ||||
| -rw-r--r-- | accel-pppd/ctrl/pptp/pptp.c | 59 |
2 files changed, 45 insertions, 16 deletions
diff --git a/accel-pppd/accel-ppp.conf.5 b/accel-pppd/accel-ppp.conf.5 index ad0858e8..5ee7fd15 100644 --- a/accel-pppd/accel-ppp.conf.5 +++ b/accel-pppd/accel-ppp.conf.5 @@ -716,7 +716,7 @@ If this option is given and greater than zero then pptp module will send echo-re seconds. .TP .BI "echo-failure=" n -Specifies maximum number of echo-requests may be sent without valid echo-reply, if exceeds connection will be terminated. +Specifies maximum number of echo-requests may be sent without valid echo-reply, if exceeds connection will be terminated. Zero disables the check: echo-requests are still sent, but missing replies never terminate the connection (default 3). .TP .BI "timeout=" n Timeout waiting reply from client in seconds (default 5). diff --git a/accel-pppd/ctrl/pptp/pptp.c b/accel-pppd/ctrl/pptp/pptp.c index eb5b40f5..dac7c041 100644 --- a/accel-pppd/ctrl/pptp/pptp.c +++ b/accel-pppd/ctrl/pptp/pptp.c @@ -202,6 +202,7 @@ again: if ( n<size ) { memcpy(conn->out_buf, (uint8_t *)buf + n, size - n); + conn->out_size = size - n; triton_md_enable_handler(&conn->hnd, MD_MODE_WRITE); } @@ -359,7 +360,10 @@ static int pptp_out_call_rqst(struct pptp_conn_t *conn) src_addr.sa_protocol = PX_PROTO_PPTP; src_addr.sa_addr.pptp.call_id = 0; addrlen = sizeof(addr); - getsockname(conn->hnd.fd, (struct sockaddr*)&addr, &addrlen); + if (getsockname(conn->hnd.fd, (struct sockaddr*)&addr, &addrlen)) { + log_ppp_error("pptp: getsockname: %s\n", strerror(errno)); + return -1; + } src_addr.sa_addr.pptp.sin_addr = addr.sin_addr; memset(&dst_addr, 0, sizeof(dst_addr)); @@ -367,7 +371,10 @@ static int pptp_out_call_rqst(struct pptp_conn_t *conn) dst_addr.sa_protocol = PX_PROTO_PPTP; dst_addr.sa_addr.pptp.call_id = htons(msg->call_id); addrlen = sizeof(addr); - getpeername(conn->hnd.fd, (struct sockaddr*)&addr, &addrlen); + if (getpeername(conn->hnd.fd, (struct sockaddr*)&addr, &addrlen)) { + log_ppp_error("pptp: getpeername: %s\n", strerror(errno)); + return -1; + } dst_addr.sa_addr.pptp.sin_addr = addr.sin_addr; pptp_sock = socket(AF_PPPOX, SOCK_STREAM, PX_PROTO_PPTP); @@ -384,7 +391,11 @@ static int pptp_out_call_rqst(struct pptp_conn_t *conn) return -1; } addrlen = sizeof(src_addr); - getsockname(pptp_sock, (struct sockaddr*)&src_addr, &addrlen); + if (getsockname(pptp_sock, (struct sockaddr*)&src_addr, &addrlen)) { + log_ppp_error("pptp: getsockname: %s\n", strerror(errno)); + close(pptp_sock); + return -1; + } if (connect(pptp_sock, (struct sockaddr*)&dst_addr, sizeof(dst_addr))) { log_ppp_error("failed to connect PPTP socket (%s)\n", strerror(errno)); @@ -392,11 +403,13 @@ static int pptp_out_call_rqst(struct pptp_conn_t *conn) return -1; } - if (send_pptp_out_call_rply(conn, msg, src_addr.sa_addr.pptp.call_id, PPTP_CALL_RES_OK, 0)) + if (send_pptp_out_call_rply(conn, msg, src_addr.sa_addr.pptp.call_id, PPTP_CALL_RES_OK, 0)) { + close(pptp_sock); return -1; + } conn->call_id = src_addr.sa_addr.pptp.call_id; - conn->peer_call_id = msg->call_id; + conn->peer_call_id = ntohs(msg->call_id); conn->ppp.fd = pptp_sock; conn->ppp.ses.chan_name = _strdup(inet_ntoa(dst_addr.sa_addr.pptp.sin_addr)); @@ -495,7 +508,7 @@ static void pptp_send_echo(struct triton_timer_t *t) .header = PPTP_HEADER_CTRL(PPTP_ECHO_RQST), }; - if (++conn->echo_sent == conf_echo_failure) { + if (conf_echo_failure && ++conn->echo_sent >= conf_echo_failure) { log_ppp_warn("pptp: no echo reply\n"); disconnect(conn); return; @@ -566,6 +579,10 @@ static int pptp_read(struct triton_md_handler_t *h) log_ppp_error("pptp: invalid magic\n"); goto drop; } + if (ntohs(hdr->length) < sizeof(*hdr)) { + log_ppp_error("pptp: message is too short\n"); + goto drop; + } if (ntohs(hdr->length) >= PPTP_CTRL_SIZE_MAX) { log_ppp_error("pptp: message is too long\n"); goto drop; @@ -680,12 +697,13 @@ static void ppp_finished(struct ap_session *ses) static int pptp_connect(struct triton_md_handler_t *h) { - struct sockaddr_in addr; - socklen_t size = sizeof(addr); + struct sockaddr_in addr, laddr; + socklen_t size; int sock; struct pptp_conn_t *conn; while(1) { + size = sizeof(addr); sock = accept(h->fd, (struct sockaddr *)&addr, &size); if (sock < 0) { if (errno == EAGAIN) @@ -722,6 +740,13 @@ static int pptp_connect(struct triton_md_handler_t *h) continue; } + size = sizeof(laddr); + if (getsockname(sock, (struct sockaddr *)&laddr, &size)) { + log_error("pptp: getsockname: %s, closing connection...\n", strerror(errno)); + close(sock); + continue; + } + if (fcntl(sock, F_SETFL, O_NONBLOCK)) { log_error("pptp: failed to set nonblocking mode: %s, closing connection...\n", strerror(errno)); close(sock); @@ -754,8 +779,7 @@ static int pptp_connect(struct triton_md_handler_t *h) conn->ctrl.calling_station_id = _malloc(17); conn->ctrl.called_station_id = _malloc(17); u_inet_ntoa(addr.sin_addr.s_addr, conn->ctrl.calling_station_id); - getsockname(sock, (struct sockaddr*)&addr, &size); - u_inet_ntoa(addr.sin_addr.s_addr, conn->ctrl.called_station_id); + u_inet_ntoa(laddr.sin_addr.s_addr, conn->ctrl.called_station_id); ppp_init(&conn->ppp); conn->ppp.ses.ctrl = &conn->ctrl; @@ -871,7 +895,7 @@ static void pptp_init(void) { struct sockaddr_in addr; char *opt; - int fd; + int fd, f = 1; fd = socket(AF_PPPOX, SOCK_STREAM, PX_PROTO_PPTP); if (fd >= 0) @@ -887,12 +911,17 @@ static void pptp_init(void) fcntl(serv.hnd.fd, F_SETFD, fcntl(serv.hnd.fd, F_GETFD) | FD_CLOEXEC); + memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; opt = conf_get_opt("pptp", "bind"); - if (opt) - addr.sin_addr.s_addr = inet_addr(opt); - else + if (opt) { + if (!inet_aton(opt, &addr.sin_addr)) { + log_emerg("pptp: failed to parse bind address '%s'\n", opt); + close(serv.hnd.fd); + return; + } + } else addr.sin_addr.s_addr = htonl(INADDR_ANY); opt = conf_get_opt("pptp", "port"); @@ -901,7 +930,7 @@ static void pptp_init(void) else addr.sin_port = htons(PPTP_PORT); - setsockopt(serv.hnd.fd, SOL_SOCKET, SO_REUSEADDR, &serv.hnd.fd, 4); + setsockopt(serv.hnd.fd, SOL_SOCKET, SO_REUSEADDR, &f, sizeof(f)); if (bind (serv.hnd.fd, (struct sockaddr *) &addr, sizeof (addr)) < 0) { log_emerg("pptp: failed to bind socket: %s\n", strerror(errno)); close(serv.hnd.fd); |
