aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2006-09-20 15:10:21 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2006-09-22 18:20:16 -0400
commit87a0117afdfe64473a6c802501bc15aee145ebb8 (patch)
tree7c31d2ade86cc3de46a9256aaf707d7a838df79a /net/ipv4
parent4c651756d502e72a68b0bc6fb20bb18c68785227 (diff)
[NETFILTER]: PPTP conntrack: clean up debugging cruft
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>
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/netfilter/ip_conntrack_helper_pptp.c128
1 files changed, 51 insertions, 77 deletions
diff --git a/net/ipv4/netfilter/ip_conntrack_helper_pptp.c b/net/ipv4/netfilter/ip_conntrack_helper_pptp.c
index 9a98a6ce1901..7b6d5aaca4da 100644
--- a/net/ipv4/netfilter/ip_conntrack_helper_pptp.c
+++ b/net/ipv4/netfilter/ip_conntrack_helper_pptp.c
@@ -301,7 +301,7 @@ pptp_inbound_pkt(struct sk_buff **pskb,
301{ 301{
302 struct ip_ct_pptp_master *info = &ct->help.ct_pptp_info; 302 struct ip_ct_pptp_master *info = &ct->help.ct_pptp_info;
303 u_int16_t msg; 303 u_int16_t msg;
304 __be16 cid, pcid; 304 __be16 cid = 0, pcid = 0;
305 305
306 msg = ntohs(ctlh->messageType); 306 msg = ntohs(ctlh->messageType);
307 DEBUGP("inbound control message %s\n", pptp_msg_name[msg]); 307 DEBUGP("inbound control message %s\n", pptp_msg_name[msg]);
@@ -309,11 +309,8 @@ pptp_inbound_pkt(struct sk_buff **pskb,
309 switch (msg) { 309 switch (msg) {
310 case PPTP_START_SESSION_REPLY: 310 case PPTP_START_SESSION_REPLY:
311 /* server confirms new control session */ 311 /* server confirms new control session */
312 if (info->sstate < PPTP_SESSION_REQUESTED) { 312 if (info->sstate < PPTP_SESSION_REQUESTED)
313 DEBUGP("%s without START_SESS_REQUEST\n", 313 goto invalid;
314 pptp_msg_name[msg]);
315 break;
316 }
317 if (pptpReq->srep.resultCode == PPTP_START_OK) 314 if (pptpReq->srep.resultCode == PPTP_START_OK)
318 info->sstate = PPTP_SESSION_CONFIRMED; 315 info->sstate = PPTP_SESSION_CONFIRMED;
319 else 316 else
@@ -322,11 +319,8 @@ pptp_inbound_pkt(struct sk_buff **pskb,
322 319
323 case PPTP_STOP_SESSION_REPLY: 320 case PPTP_STOP_SESSION_REPLY:
324 /* server confirms end of control session */ 321 /* server confirms end of control session */
325 if (info->sstate > PPTP_SESSION_STOPREQ) { 322 if (info->sstate > PPTP_SESSION_STOPREQ)
326 DEBUGP("%s without STOP_SESS_REQUEST\n", 323 goto invalid;
327 pptp_msg_name[msg]);
328 break;
329 }
330 if (pptpReq->strep.resultCode == PPTP_STOP_OK) 324 if (pptpReq->strep.resultCode == PPTP_STOP_OK)
331 info->sstate = PPTP_SESSION_NONE; 325 info->sstate = PPTP_SESSION_NONE;
332 else 326 else
@@ -335,15 +329,12 @@ pptp_inbound_pkt(struct sk_buff **pskb,
335 329
336 case PPTP_OUT_CALL_REPLY: 330 case PPTP_OUT_CALL_REPLY:
337 /* server accepted call, we now expect GRE frames */ 331 /* server accepted call, we now expect GRE frames */
338 if (info->sstate != PPTP_SESSION_CONFIRMED) { 332 if (info->sstate != PPTP_SESSION_CONFIRMED)
339 DEBUGP("%s but no session\n", pptp_msg_name[msg]); 333 goto invalid;
340 break;
341 }
342 if (info->cstate != PPTP_CALL_OUT_REQ && 334 if (info->cstate != PPTP_CALL_OUT_REQ &&
343 info->cstate != PPTP_CALL_OUT_CONF) { 335 info->cstate != PPTP_CALL_OUT_CONF)
344 DEBUGP("%s without OUTCALL_REQ\n", pptp_msg_name[msg]); 336 goto invalid;
345 break; 337
346 }
347 if (pptpReq->ocack.resultCode != PPTP_OUTCALL_CONNECT) { 338 if (pptpReq->ocack.resultCode != PPTP_OUTCALL_CONNECT) {
348 info->cstate = PPTP_CALL_NONE; 339 info->cstate = PPTP_CALL_NONE;
349 break; 340 break;
@@ -354,11 +345,8 @@ pptp_inbound_pkt(struct sk_buff **pskb,
354 345
355 info->pac_call_id = cid; 346 info->pac_call_id = cid;
356 347
357 if (info->pns_call_id != pcid) { 348 if (info->pns_call_id != pcid)
358 DEBUGP("%s for unknown callid %u\n", 349 goto invalid;
359 pptp_msg_name[msg], ntohs(pcid));
360 break;
361 }
362 350
363 DEBUGP("%s, CID=%X, PCID=%X\n", pptp_msg_name[msg], 351 DEBUGP("%s, CID=%X, PCID=%X\n", pptp_msg_name[msg],
364 ntohs(cid), ntohs(pcid)); 352 ntohs(cid), ntohs(pcid));
@@ -370,10 +358,9 @@ pptp_inbound_pkt(struct sk_buff **pskb,
370 358
371 case PPTP_IN_CALL_REQUEST: 359 case PPTP_IN_CALL_REQUEST:
372 /* server tells us about incoming call request */ 360 /* server tells us about incoming call request */
373 if (info->sstate != PPTP_SESSION_CONFIRMED) { 361 if (info->sstate != PPTP_SESSION_CONFIRMED)
374 DEBUGP("%s but no session\n", pptp_msg_name[msg]); 362 goto invalid;
375 break; 363
376 }
377 pcid = pptpReq->icack.peersCallID; 364 pcid = pptpReq->icack.peersCallID;
378 DEBUGP("%s, PCID=%X\n", pptp_msg_name[msg], ntohs(pcid)); 365 DEBUGP("%s, PCID=%X\n", pptp_msg_name[msg], ntohs(pcid));
379 info->cstate = PPTP_CALL_IN_REQ; 366 info->cstate = PPTP_CALL_IN_REQ;
@@ -382,25 +369,17 @@ pptp_inbound_pkt(struct sk_buff **pskb,
382 369
383 case PPTP_IN_CALL_CONNECT: 370 case PPTP_IN_CALL_CONNECT:
384 /* server tells us about incoming call established */ 371 /* server tells us about incoming call established */
385 if (info->sstate != PPTP_SESSION_CONFIRMED) { 372 if (info->sstate != PPTP_SESSION_CONFIRMED)
386 DEBUGP("%s but no session\n", pptp_msg_name[msg]); 373 goto invalid;
387 break; 374 if (info->cstate != PPTP_CALL_IN_REP &&
388 } 375 info->cstate != PPTP_CALL_IN_CONF)
389 if (info->cstate != PPTP_CALL_IN_REP 376 goto invalid;
390 && info->cstate != PPTP_CALL_IN_CONF) {
391 DEBUGP("%s but never sent IN_CALL_REPLY\n",
392 pptp_msg_name[msg]);
393 break;
394 }
395 377
396 pcid = pptpReq->iccon.peersCallID; 378 pcid = pptpReq->iccon.peersCallID;
397 cid = info->pac_call_id; 379 cid = info->pac_call_id;
398 380
399 if (info->pns_call_id != pcid) { 381 if (info->pns_call_id != pcid)
400 DEBUGP("%s for unknown CallID %u\n", 382 goto invalid;
401 pptp_msg_name[msg], ntohs(pcid));
402 break;
403 }
404 383
405 DEBUGP("%s, PCID=%X\n", pptp_msg_name[msg], ntohs(pcid)); 384 DEBUGP("%s, PCID=%X\n", pptp_msg_name[msg], ntohs(pcid));
406 info->cstate = PPTP_CALL_IN_CONF; 385 info->cstate = PPTP_CALL_IN_CONF;
@@ -425,18 +404,21 @@ pptp_inbound_pkt(struct sk_buff **pskb,
425 /* I don't have to explain these ;) */ 404 /* I don't have to explain these ;) */
426 break; 405 break;
427 default: 406 default:
428 DEBUGP("invalid %s (TY=%d)\n", (msg <= PPTP_MSG_MAX) 407 goto invalid;
429 ? pptp_msg_name[msg]:pptp_msg_name[0], msg);
430 break;
431 } 408 }
432 409
433
434 if (ip_nat_pptp_hook_inbound) 410 if (ip_nat_pptp_hook_inbound)
435 return ip_nat_pptp_hook_inbound(pskb, ct, ctinfo, ctlh, 411 return ip_nat_pptp_hook_inbound(pskb, ct, ctinfo, ctlh,
436 pptpReq); 412 pptpReq);
437
438 return NF_ACCEPT; 413 return NF_ACCEPT;
439 414
415invalid:
416 DEBUGP("invalid %s: type=%d cid=%u pcid=%u "
417 "cstate=%d sstate=%d pns_cid=%u pac_cid=%u\n",
418 msg <= PPTP_MSG_MAX ? pptp_msg_name[msg] : pptp_msg_name[0],
419 msg, ntohs(cid), ntohs(pcid), info->cstate, info->sstate,
420 ntohs(info->pns_call_id), ntohs(info->pac_call_id));
421 return NF_ACCEPT;
440} 422}
441 423
442static inline int 424static inline int
@@ -449,7 +431,7 @@ pptp_outbound_pkt(struct sk_buff **pskb,
449{ 431{
450 struct ip_ct_pptp_master *info = &ct->help.ct_pptp_info; 432 struct ip_ct_pptp_master *info = &ct->help.ct_pptp_info;
451 u_int16_t msg; 433 u_int16_t msg;
452 __be16 cid, pcid; 434 __be16 cid = 0, pcid = 0;
453 435
454 msg = ntohs(ctlh->messageType); 436 msg = ntohs(ctlh->messageType);
455 DEBUGP("outbound control message %s\n", pptp_msg_name[msg]); 437 DEBUGP("outbound control message %s\n", pptp_msg_name[msg]);
@@ -457,10 +439,8 @@ pptp_outbound_pkt(struct sk_buff **pskb,
457 switch (msg) { 439 switch (msg) {
458 case PPTP_START_SESSION_REQUEST: 440 case PPTP_START_SESSION_REQUEST:
459 /* client requests for new control session */ 441 /* client requests for new control session */
460 if (info->sstate != PPTP_SESSION_NONE) { 442 if (info->sstate != PPTP_SESSION_NONE)
461 DEBUGP("%s but we already have one", 443 goto invalid;
462 pptp_msg_name[msg]);
463 }
464 info->sstate = PPTP_SESSION_REQUESTED; 444 info->sstate = PPTP_SESSION_REQUESTED;
465 break; 445 break;
466 case PPTP_STOP_SESSION_REQUEST: 446 case PPTP_STOP_SESSION_REQUEST:
@@ -470,11 +450,8 @@ pptp_outbound_pkt(struct sk_buff **pskb,
470 450
471 case PPTP_OUT_CALL_REQUEST: 451 case PPTP_OUT_CALL_REQUEST:
472 /* client initiating connection to server */ 452 /* client initiating connection to server */
473 if (info->sstate != PPTP_SESSION_CONFIRMED) { 453 if (info->sstate != PPTP_SESSION_CONFIRMED)
474 DEBUGP("%s but no session\n", 454 goto invalid;
475 pptp_msg_name[msg]);
476 break;
477 }
478 info->cstate = PPTP_CALL_OUT_REQ; 455 info->cstate = PPTP_CALL_OUT_REQ;
479 /* track PNS call id */ 456 /* track PNS call id */
480 cid = pptpReq->ocreq.callID; 457 cid = pptpReq->ocreq.callID;
@@ -483,22 +460,17 @@ pptp_outbound_pkt(struct sk_buff **pskb,
483 break; 460 break;
484 case PPTP_IN_CALL_REPLY: 461 case PPTP_IN_CALL_REPLY:
485 /* client answers incoming call */ 462 /* client answers incoming call */
486 if (info->cstate != PPTP_CALL_IN_REQ 463 if (info->cstate != PPTP_CALL_IN_REQ &&
487 && info->cstate != PPTP_CALL_IN_REP) { 464 info->cstate != PPTP_CALL_IN_REP)
488 DEBUGP("%s without incall_req\n", 465 goto invalid;
489 pptp_msg_name[msg]); 466
490 break;
491 }
492 if (pptpReq->icack.resultCode != PPTP_INCALL_ACCEPT) { 467 if (pptpReq->icack.resultCode != PPTP_INCALL_ACCEPT) {
493 info->cstate = PPTP_CALL_NONE; 468 info->cstate = PPTP_CALL_NONE;
494 break; 469 break;
495 } 470 }
496 pcid = pptpReq->icack.peersCallID; 471 pcid = pptpReq->icack.peersCallID;
497 if (info->pac_call_id != pcid) { 472 if (info->pac_call_id != pcid)
498 DEBUGP("%s for unknown call %u\n", 473 goto invalid;
499 pptp_msg_name[msg], ntohs(pcid));
500 break;
501 }
502 DEBUGP("%s, CID=%X\n", pptp_msg_name[msg], ntohs(pcid)); 474 DEBUGP("%s, CID=%X\n", pptp_msg_name[msg], ntohs(pcid));
503 /* part two of the three-way handshake */ 475 /* part two of the three-way handshake */
504 info->cstate = PPTP_CALL_IN_REP; 476 info->cstate = PPTP_CALL_IN_REP;
@@ -507,10 +479,8 @@ pptp_outbound_pkt(struct sk_buff **pskb,
507 479
508 case PPTP_CALL_CLEAR_REQUEST: 480 case PPTP_CALL_CLEAR_REQUEST:
509 /* client requests hangup of call */ 481 /* client requests hangup of call */
510 if (info->sstate != PPTP_SESSION_CONFIRMED) { 482 if (info->sstate != PPTP_SESSION_CONFIRMED)
511 DEBUGP("CLEAR_CALL but no session\n"); 483 goto invalid;
512 break;
513 }
514 /* FUTURE: iterate over all calls and check if 484 /* FUTURE: iterate over all calls and check if
515 * call ID is valid. We don't do this without newnat, 485 * call ID is valid. We don't do this without newnat,
516 * because we only know about last call */ 486 * because we only know about last call */
@@ -522,16 +492,20 @@ pptp_outbound_pkt(struct sk_buff **pskb,
522 /* I don't have to explain these ;) */ 492 /* I don't have to explain these ;) */
523 break; 493 break;
524 default: 494 default:
525 DEBUGP("invalid %s (TY=%d)\n", (msg <= PPTP_MSG_MAX)? 495 goto invalid;
526 pptp_msg_name[msg]:pptp_msg_name[0], msg);
527 /* unknown: no need to create GRE masq table entry */
528 break;
529 } 496 }
530 497
531 if (ip_nat_pptp_hook_outbound) 498 if (ip_nat_pptp_hook_outbound)
532 return ip_nat_pptp_hook_outbound(pskb, ct, ctinfo, ctlh, 499 return ip_nat_pptp_hook_outbound(pskb, ct, ctinfo, ctlh,
533 pptpReq); 500 pptpReq);
501 return NF_ACCEPT;
534 502
503invalid:
504 DEBUGP("invalid %s: type=%d cid=%u pcid=%u "
505 "cstate=%d sstate=%d pns_cid=%u pac_cid=%u\n",
506 msg <= PPTP_MSG_MAX ? pptp_msg_name[msg] : pptp_msg_name[0],
507 msg, ntohs(cid), ntohs(pcid), info->cstate, info->sstate,
508 ntohs(info->pns_call_id), ntohs(info->pac_call_id));
535 return NF_ACCEPT; 509 return NF_ACCEPT;
536} 510}
537 511