summaryrefslogtreecommitdiff
path: root/accel-pppd/ctrl
diff options
context:
space:
mode:
authorVladislav Grishenko <themiron@mail.ru>2020-06-29 02:32:13 +0500
committerVladislav Grishenko <themiron@mail.ru>2020-06-29 04:38:42 +0500
commit0f2c18df473d131ff4c696078923e622e1bb4682 (patch)
tree523efa084b8d985783f72c08cb949862f822bc95 /accel-pppd/ctrl
parent7dd9766a72d9ad26f4db09c8a52067d1dd4e777c (diff)
downloadaccel-ppp-0f2c18df473d131ff4c696078923e622e1bb4682.tar.gz
accel-ppp-0f2c18df473d131ff4c696078923e622e1bb4682.zip
sstp: fix MITM w/o SSTP_MSG_CALL_CONNECTED is being sent
3.3.2.1 Negotiation Timer When establishing the SSTP connection, the SSTP server starts the negotiation timer. 2. After sending the Call Connect Acknowledge message, if the server does not receive a Call Connected message before the Negotiation timer expires then it MUST send a Call Abort message and start the process of bringing down (disconnecting) the connection. The server MAY implement different timer values for the Call Connected message and the Call Connect Request message. 3.3.7.1 Server-Side Interface with PPP When the server receives a PPP data frame from the PPP layer, the server MUST perform the following steps: * If CurrentState is set to Server_Call_Connected: Generate an SSTP data packet (section 2.2.3) with the PPP frame as the higher-layer payload and send the packet to the HTTPS layer. * Else, drop the PPP frame. sstp-client is known to be broken, it doesn't send SSTP_MSG_CALL_CONNECTED with PAP and CHAP-MD5 auth, no network data flow and disconnect by negotiation timer is expected.
Diffstat (limited to 'accel-pppd/ctrl')
-rw-r--r--accel-pppd/ctrl/sstp/sstp.c30
1 files changed, 26 insertions, 4 deletions
diff --git a/accel-pppd/ctrl/sstp/sstp.c b/accel-pppd/ctrl/sstp/sstp.c
index a90ab959..7f60e6de 100644
--- a/accel-pppd/ctrl/sstp/sstp.c
+++ b/accel-pppd/ctrl/sstp/sstp.c
@@ -1483,10 +1483,6 @@ static int sstp_recv_msg_call_connect_request(struct sstp_conn_t *conn, struct s
conn->ppp_state = STATE_FINISHED;
goto error;
}
-
- if (conn->timeout_timer.tpd)
- triton_timer_del(&conn->timeout_timer);
-
return 0;
error:
@@ -1504,6 +1500,7 @@ static int sstp_recv_msg_call_connected(struct sstp_conn_t *conn, struct sstp_ct
} __attribute__((packed)) *msg = (void *)hdr;
uint8_t hash;
unsigned int len;
+ struct npioctl np;
#ifdef CRYPTO_OPENSSL
typeof(*msg) buf;
uint8_t md[EVP_MAX_MD_SIZE], *ptr;
@@ -1602,8 +1599,28 @@ static int sstp_recv_msg_call_connected(struct sstp_conn_t *conn, struct sstp_ct
#endif
}
+ if (conn->timeout_timer.tpd)
+ triton_timer_del(&conn->timeout_timer);
conn->sstp_state = STATE_SERVER_CALL_CONNECTED;
+ conn->ctrl.ppp_npmode = NPMODE_PASS;
+ switch (conn->ppp_state) {
+ case STATE_STARTED:
+ if (conn->ppp.ses.ipv4) {
+ np.protocol = PPP_IP;
+ np.mode = conn->ctrl.ppp_npmode;
+ if (net->ppp_ioctl(conn->ppp.unit_fd, PPPIOCSNPMODE, &np))
+ log_ppp_error("failed to set NP (IPv4) mode: %s\n", strerror(errno));
+ }
+ if (conn->ppp.ses.ipv6) {
+ np.protocol = PPP_IPV6;
+ np.mode = conn->ctrl.ppp_npmode;
+ if (net->ppp_ioctl(conn->ppp.unit_fd, PPPIOCSNPMODE, &np))
+ log_ppp_error("failed to set NP (IPv6) mode: %s\n", strerror(errno));
+ }
+ break;
+ }
+
_free(conn->nonce);
conn->nonce = NULL;
_free(conn->hlak_key);
@@ -2088,6 +2105,10 @@ static void sstp_timeout(struct triton_timer_t *t)
case STATE_CALL_DISCONNECT_ACK_PENDING:
triton_context_call(&conn->ctx, (triton_event_func)sstp_disconnect, conn);
break;
+ case STATE_SERVER_CONNECT_REQUEST_PENDING:
+ case STATE_SERVER_CALL_CONNECTED_PENDING:
+ log_ppp_warn("sstp: negotiation timeout\n");
+ /* fall through */
default:
sstp_abort(conn, 0);
break;
@@ -2333,6 +2354,7 @@ static int sstp_connect(struct triton_md_handler_t *h)
conn->ctrl.max_mtu = conf_ppp_max_mtu;
conn->ctrl.type = CTRL_TYPE_SSTP;
conn->ctrl.ppp = 1;
+ conn->ctrl.ppp_npmode = NPMODE_DROP;
conn->ctrl.name = "sstp";
conn->ctrl.ifname = "";
conn->ctrl.mppe = MPPE_DENY;