Skip to content

Commit

Permalink
[NETFILTER]: PPTP conntrack: clean up debugging cruft
Browse files Browse the repository at this point in the history
Also make sure not to hand packets received in an invalid state to the
NAT helper since it will mangle the packet with invalid data.

Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Patrick McHardy authored and David S. Miller committed Sep 22, 2006
1 parent 4c65175 commit 87a0117
Showing 1 changed file with 51 additions and 77 deletions.
128 changes: 51 additions & 77 deletions net/ipv4/netfilter/ip_conntrack_helper_pptp.c
Original file line number Diff line number Diff line change
Expand Up @@ -301,19 +301,16 @@ pptp_inbound_pkt(struct sk_buff **pskb,
{
struct ip_ct_pptp_master *info = &ct->help.ct_pptp_info;
u_int16_t msg;
__be16 cid, pcid;
__be16 cid = 0, pcid = 0;

msg = ntohs(ctlh->messageType);
DEBUGP("inbound control message %s\n", pptp_msg_name[msg]);

switch (msg) {
case PPTP_START_SESSION_REPLY:
/* server confirms new control session */
if (info->sstate < PPTP_SESSION_REQUESTED) {
DEBUGP("%s without START_SESS_REQUEST\n",
pptp_msg_name[msg]);
break;
}
if (info->sstate < PPTP_SESSION_REQUESTED)
goto invalid;
if (pptpReq->srep.resultCode == PPTP_START_OK)
info->sstate = PPTP_SESSION_CONFIRMED;
else
Expand All @@ -322,11 +319,8 @@ pptp_inbound_pkt(struct sk_buff **pskb,

case PPTP_STOP_SESSION_REPLY:
/* server confirms end of control session */
if (info->sstate > PPTP_SESSION_STOPREQ) {
DEBUGP("%s without STOP_SESS_REQUEST\n",
pptp_msg_name[msg]);
break;
}
if (info->sstate > PPTP_SESSION_STOPREQ)
goto invalid;
if (pptpReq->strep.resultCode == PPTP_STOP_OK)
info->sstate = PPTP_SESSION_NONE;
else
Expand All @@ -335,15 +329,12 @@ pptp_inbound_pkt(struct sk_buff **pskb,

case PPTP_OUT_CALL_REPLY:
/* server accepted call, we now expect GRE frames */
if (info->sstate != PPTP_SESSION_CONFIRMED) {
DEBUGP("%s but no session\n", pptp_msg_name[msg]);
break;
}
if (info->sstate != PPTP_SESSION_CONFIRMED)
goto invalid;
if (info->cstate != PPTP_CALL_OUT_REQ &&
info->cstate != PPTP_CALL_OUT_CONF) {
DEBUGP("%s without OUTCALL_REQ\n", pptp_msg_name[msg]);
break;
}
info->cstate != PPTP_CALL_OUT_CONF)
goto invalid;

if (pptpReq->ocack.resultCode != PPTP_OUTCALL_CONNECT) {
info->cstate = PPTP_CALL_NONE;
break;
Expand All @@ -354,11 +345,8 @@ pptp_inbound_pkt(struct sk_buff **pskb,

info->pac_call_id = cid;

if (info->pns_call_id != pcid) {
DEBUGP("%s for unknown callid %u\n",
pptp_msg_name[msg], ntohs(pcid));
break;
}
if (info->pns_call_id != pcid)
goto invalid;

DEBUGP("%s, CID=%X, PCID=%X\n", pptp_msg_name[msg],
ntohs(cid), ntohs(pcid));
Expand All @@ -370,10 +358,9 @@ pptp_inbound_pkt(struct sk_buff **pskb,

case PPTP_IN_CALL_REQUEST:
/* server tells us about incoming call request */
if (info->sstate != PPTP_SESSION_CONFIRMED) {
DEBUGP("%s but no session\n", pptp_msg_name[msg]);
break;
}
if (info->sstate != PPTP_SESSION_CONFIRMED)
goto invalid;

pcid = pptpReq->icack.peersCallID;
DEBUGP("%s, PCID=%X\n", pptp_msg_name[msg], ntohs(pcid));
info->cstate = PPTP_CALL_IN_REQ;
Expand All @@ -382,25 +369,17 @@ pptp_inbound_pkt(struct sk_buff **pskb,

case PPTP_IN_CALL_CONNECT:
/* server tells us about incoming call established */
if (info->sstate != PPTP_SESSION_CONFIRMED) {
DEBUGP("%s but no session\n", pptp_msg_name[msg]);
break;
}
if (info->cstate != PPTP_CALL_IN_REP
&& info->cstate != PPTP_CALL_IN_CONF) {
DEBUGP("%s but never sent IN_CALL_REPLY\n",
pptp_msg_name[msg]);
break;
}
if (info->sstate != PPTP_SESSION_CONFIRMED)
goto invalid;
if (info->cstate != PPTP_CALL_IN_REP &&
info->cstate != PPTP_CALL_IN_CONF)
goto invalid;

pcid = pptpReq->iccon.peersCallID;
cid = info->pac_call_id;

if (info->pns_call_id != pcid) {
DEBUGP("%s for unknown CallID %u\n",
pptp_msg_name[msg], ntohs(pcid));
break;
}
if (info->pns_call_id != pcid)
goto invalid;

DEBUGP("%s, PCID=%X\n", pptp_msg_name[msg], ntohs(pcid));
info->cstate = PPTP_CALL_IN_CONF;
Expand All @@ -425,18 +404,21 @@ pptp_inbound_pkt(struct sk_buff **pskb,
/* I don't have to explain these ;) */
break;
default:
DEBUGP("invalid %s (TY=%d)\n", (msg <= PPTP_MSG_MAX)
? pptp_msg_name[msg]:pptp_msg_name[0], msg);
break;
goto invalid;
}


if (ip_nat_pptp_hook_inbound)
return ip_nat_pptp_hook_inbound(pskb, ct, ctinfo, ctlh,
pptpReq);

return NF_ACCEPT;

invalid:
DEBUGP("invalid %s: type=%d cid=%u pcid=%u "
"cstate=%d sstate=%d pns_cid=%u pac_cid=%u\n",
msg <= PPTP_MSG_MAX ? pptp_msg_name[msg] : pptp_msg_name[0],
msg, ntohs(cid), ntohs(pcid), info->cstate, info->sstate,
ntohs(info->pns_call_id), ntohs(info->pac_call_id));
return NF_ACCEPT;
}

static inline int
Expand All @@ -449,18 +431,16 @@ pptp_outbound_pkt(struct sk_buff **pskb,
{
struct ip_ct_pptp_master *info = &ct->help.ct_pptp_info;
u_int16_t msg;
__be16 cid, pcid;
__be16 cid = 0, pcid = 0;

msg = ntohs(ctlh->messageType);
DEBUGP("outbound control message %s\n", pptp_msg_name[msg]);

switch (msg) {
case PPTP_START_SESSION_REQUEST:
/* client requests for new control session */
if (info->sstate != PPTP_SESSION_NONE) {
DEBUGP("%s but we already have one",
pptp_msg_name[msg]);
}
if (info->sstate != PPTP_SESSION_NONE)
goto invalid;
info->sstate = PPTP_SESSION_REQUESTED;
break;
case PPTP_STOP_SESSION_REQUEST:
Expand All @@ -470,11 +450,8 @@ pptp_outbound_pkt(struct sk_buff **pskb,

case PPTP_OUT_CALL_REQUEST:
/* client initiating connection to server */
if (info->sstate != PPTP_SESSION_CONFIRMED) {
DEBUGP("%s but no session\n",
pptp_msg_name[msg]);
break;
}
if (info->sstate != PPTP_SESSION_CONFIRMED)
goto invalid;
info->cstate = PPTP_CALL_OUT_REQ;
/* track PNS call id */
cid = pptpReq->ocreq.callID;
Expand All @@ -483,22 +460,17 @@ pptp_outbound_pkt(struct sk_buff **pskb,
break;
case PPTP_IN_CALL_REPLY:
/* client answers incoming call */
if (info->cstate != PPTP_CALL_IN_REQ
&& info->cstate != PPTP_CALL_IN_REP) {
DEBUGP("%s without incall_req\n",
pptp_msg_name[msg]);
break;
}
if (info->cstate != PPTP_CALL_IN_REQ &&
info->cstate != PPTP_CALL_IN_REP)
goto invalid;

if (pptpReq->icack.resultCode != PPTP_INCALL_ACCEPT) {
info->cstate = PPTP_CALL_NONE;
break;
}
pcid = pptpReq->icack.peersCallID;
if (info->pac_call_id != pcid) {
DEBUGP("%s for unknown call %u\n",
pptp_msg_name[msg], ntohs(pcid));
break;
}
if (info->pac_call_id != pcid)
goto invalid;
DEBUGP("%s, CID=%X\n", pptp_msg_name[msg], ntohs(pcid));
/* part two of the three-way handshake */
info->cstate = PPTP_CALL_IN_REP;
Expand All @@ -507,10 +479,8 @@ pptp_outbound_pkt(struct sk_buff **pskb,

case PPTP_CALL_CLEAR_REQUEST:
/* client requests hangup of call */
if (info->sstate != PPTP_SESSION_CONFIRMED) {
DEBUGP("CLEAR_CALL but no session\n");
break;
}
if (info->sstate != PPTP_SESSION_CONFIRMED)
goto invalid;
/* FUTURE: iterate over all calls and check if
* call ID is valid. We don't do this without newnat,
* because we only know about last call */
Expand All @@ -522,16 +492,20 @@ pptp_outbound_pkt(struct sk_buff **pskb,
/* I don't have to explain these ;) */
break;
default:
DEBUGP("invalid %s (TY=%d)\n", (msg <= PPTP_MSG_MAX)?
pptp_msg_name[msg]:pptp_msg_name[0], msg);
/* unknown: no need to create GRE masq table entry */
break;
goto invalid;
}

if (ip_nat_pptp_hook_outbound)
return ip_nat_pptp_hook_outbound(pskb, ct, ctinfo, ctlh,
pptpReq);
return NF_ACCEPT;

invalid:
DEBUGP("invalid %s: type=%d cid=%u pcid=%u "
"cstate=%d sstate=%d pns_cid=%u pac_cid=%u\n",
msg <= PPTP_MSG_MAX ? pptp_msg_name[msg] : pptp_msg_name[0],
msg, ntohs(cid), ntohs(pcid), info->cstate, info->sstate,
ntohs(info->pns_call_id), ntohs(info->pac_call_id));
return NF_ACCEPT;
}

Expand Down

0 comments on commit 87a0117

Please sign in to comment.