From c8021cb841f31f530a68c3b15a3673240417089b Mon Sep 17 00:00:00 2001 From: Thomas Bernard Date: Tue, 24 Apr 2012 00:50:20 +0200 Subject: [PATCH] implementing UpdatePinhole() and CheckPinholeWorking() WANIPv6FirewallControl upnpredirect : cleanup : upnp_add_inboundpinhole fix : upnp_get_pinhole_info implement : upnp_update_inboundpinhole upnpsoap : implement : UpdatePinhole implement : CheckPinholeWorking --- miniupnpd/upnpredirect.c | 74 ++++++----------- miniupnpd/upnpredirect.h | 10 ++- miniupnpd/upnpsoap.c | 174 +++++++++++++++------------------------ 3 files changed, 94 insertions(+), 164 deletions(-) diff --git a/miniupnpd/upnpredirect.c b/miniupnpd/upnpredirect.c index 8cae9e8..afe5665 100644 --- a/miniupnpd/upnpredirect.c +++ b/miniupnpd/upnpredirect.c @@ -1,4 +1,4 @@ -/* $Id: upnpredirect.c,v 1.72 2012/04/22 23:25:22 nanard Exp $ */ +/* $Id: upnpredirect.c,v 1.75 2012/04/23 22:36:57 nanard Exp $ */ /* MiniUPnP project * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ * (c) 2006-2012 Thomas Bernard @@ -579,10 +579,10 @@ upnp_get_portmappings_in_range(unsigned short startport, } #ifdef ENABLE_6FC_SERVICE +#if 0 int upnp_check_outbound_pinhole(int proto, int * timeout) { -#if 0 int s, tmptimeout, tmptime_out; switch(proto) { @@ -618,9 +618,9 @@ upnp_check_outbound_pinhole(int proto, int * timeout) return -5; break; } -#endif return 0; } +#endif /* upnp_add_inboundpinhole() * returns: 0 on success @@ -639,24 +639,17 @@ upnp_add_inboundpinhole(const char * raddr, int * uid) { int r; -#if 0 - char iaddr_old[40]="", idfound[5]=""; /* IPv6 Modification*/ - unsigned short iport_old = 0; -#endif time_t current; unsigned int timestamp; - struct in6_addr address; /* IPv6 Modification*/ + struct in6_addr address; - if(inet_pton(AF_INET6, iaddr, &address) < 0) /* IPv6 Modification */ + if(inet_pton(AF_INET6, iaddr, &address) < 0) { syslog(LOG_ERR, "inet_pton(%s) : %m", iaddr); return 0; } current = time(NULL); timestamp = current + leasetime; -#if 0 - r = get_rule_from_file(raddr, rport, iaddr_old, &iport_old, proto, 0, 0, idfound); -#endif r = 0; #if 0 @@ -676,26 +669,11 @@ upnp_add_inboundpinhole(const char * raddr, return 1; #else return -42; /* not implemented */ -#endif -#if 0 - s = upnp_add_inboundpinhole_internal(raddr, rport, iaddr, iport, protocol, uid); - if(rule_file_add(raddr, rport, iaddr, iport, protocol, leaseTmp, uid)<0) - return -8; - else - { - if(nextpinholetoclean_timestamp == 0 || (atoi(leaseTmp) <= nextpinholetoclean_timestamp)) - { - printf("Initializing the nextpinholetoclean variables. uid = %d\n", *uid); - snprintf(nextpinholetoclean_uid, 5, "%.4d", *uid); - nextpinholetoclean_timestamp = atoi(leaseTmp); - } - return s; - } #endif } -return 0; } +#if 0 int upnp_add_inboundpinhole_internal(const char * raddr, unsigned short rport, const char * iaddr, unsigned short iport, @@ -762,6 +740,7 @@ upnp_add_inboundpinhole_internal(const char * raddr, unsigned short rport, printf("\t_add_ uid: %s\n", cuid); return 1; } +#endif /* upnp_get_pinhole_info() * return values : @@ -790,12 +769,14 @@ upnp_get_pinhole_info(unsigned short uid, iaddr, iaddrlen, iport, proto, ×tamp, &packets_tmp, &bytes_tmp); if(r >= 0) { - time_t current_time; - current_time = time(NULL); - if(timestamp > current_time) - *leasetime = timestamp - current_time; - else - *leasetime = 0; + if(leasetime) { + time_t current_time; + current_time = time(NULL); + if(timestamp > current_time) + *leasetime = timestamp - current_time; + else + *leasetime = 0; + } if(packets) *packets = (unsigned int)packets_tmp; } @@ -806,23 +787,14 @@ upnp_get_pinhole_info(unsigned short uid, } int -upnp_update_inboundpinhole(const char * uid, const char * leasetime) +upnp_update_inboundpinhole(unsigned short uid, unsigned int leasetime) { - /* TODO : to be implemented */ -#if 0 - int r, n; - syslog(LOG_INFO, "Updating pinhole for inbound traffic with ID: %s", uid); - r = check_rule_from_file(uid, 0); - if(r < 0) - return r; - else - { - n = rule_file_update(uid, leasetime); - upnp_update_expiredpinhole(); - return n; - } +#ifdef USE_PF + unsigned int timestamp; + timestamp = time(NULL) + leasetime; + return update_pinhole(uid, timestamp); #else - return -1; + return -42; /* not implemented */ #endif } @@ -1049,7 +1021,7 @@ upnp_check_pinhole_working(const char * uid, fclose(fd); return res; #else - return -4; + return -42; /* to be implemented */ #endif } @@ -1059,7 +1031,7 @@ upnp_clean_expired_pinholes(unsigned int * next_timestamp) #ifdef USE_PF return clean_pinhole_list(next_timestamp); #else - return 0; + return 0; /* nothing to do */ #endif } #endif diff --git a/miniupnpd/upnpredirect.h b/miniupnpd/upnpredirect.h index 3710bd4..5c0d34c 100644 --- a/miniupnpd/upnpredirect.h +++ b/miniupnpd/upnpredirect.h @@ -1,4 +1,4 @@ -/* $Id: upnpredirect.h,v 1.31 2012/04/22 23:08:48 nanard Exp $ */ +/* $Id: upnpredirect.h,v 1.32 2012/04/23 21:46:16 nanard Exp $ */ /* MiniUPnP project * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ * (c) 2006-2012 Thomas Bernard @@ -109,11 +109,13 @@ upnp_get_portmappings_in_range(unsigned short startport, unsigned int * number); #ifdef ENABLE_6FC_SERVICE -/* function to be used by WANIPv6_FirewallControl implementation */ +/* functions to be used by WANIPv6_FirewallControl implementation */ -/* retreive outbound pinhole timeout*/ +#if 0 +/* retrieve outbound pinhole timeout */ int upnp_check_outbound_pinhole(int proto, int * timeout); +#endif /* add an inbound pinehole * return value : @@ -141,7 +143,7 @@ upnp_get_pinhole_info(unsigned short uid, /* update the lease time */ int -upnp_update_inboundpinhole(const char * uid, const char * leasetime); +upnp_update_inboundpinhole(unsigned short uid, unsigned int leasetime); /* remove the inbound pinhole */ int diff --git a/miniupnpd/upnpsoap.c b/miniupnpd/upnpsoap.c index cd62848..b4125c8 100644 --- a/miniupnpd/upnpsoap.c +++ b/miniupnpd/upnpsoap.c @@ -1,4 +1,4 @@ -/* $Id: upnpsoap.c,v 1.104 2012/04/22 23:36:20 nanard Exp $ */ +/* $Id: upnpsoap.c,v 1.106 2012/04/23 22:38:06 nanard Exp $ */ /* MiniUPnP project * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ * (c) 2006-2012 Thomas Bernard @@ -1431,65 +1431,65 @@ clear_and_exit: static void UpdatePinhole(struct upnphttp * h, const char * action) { - int r/*, n*/; static const char resp[] = "" ""; struct NameValueParserData data; - const char * uid, * leaseTime; -#if 0 - char iaddr[40], proto[6], lt[12]; + const char * uid_str, * leaseTime; + char iaddr[INET6_ADDRSTRLEN]; unsigned short iport; -#endif - int ltime = -1; + int ltime; + int uid; + int n; if(CheckStatus(h)==0) return; ParseNameValue(h->req_buf + h->req_contentoff, h->req_contentlen, &data); - uid = GetValueFromNameValueList(&data, "UniqueID"); + uid_str = GetValueFromNameValueList(&data, "UniqueID"); leaseTime = GetValueFromNameValueList(&data, "NewLeaseTime"); - if(leaseTime) - ltime = atoi(leaseTime); + uid = uid_str ? atoi(uid_str) : -1; + ltime = leaseTime ? atoi(leaseTime) : -1; + ClearNameValueList(&data); - if(!uid || ltime <= 0 || ltime > 86400) + if(uid < 0 || uid > 65535 || ltime <= 0 || ltime > 86400) { - ClearNameValueList(&data); SoapError(h, 402, "Invalid Args"); return; } - /* Check that client is not deleting an pinhole + /* Check that client is not updating an pinhole * it doesn't have access to, because of its public access */ -#if 0 - n = upnp_get_pinhole_info(0, 0, iaddr, &iport, proto, uid, lt); - if (n > 0) + n = upnp_get_pinhole_info(uid, NULL, 0, NULL, + iaddr, sizeof(iaddr), &iport, + NULL, NULL, NULL); + if (n >= 0) { - if(PinholeVerification(h, iaddr, iport)==0) - { - ClearNameValueList(&data); - return ; - } + if(PinholeVerification(h, iaddr, iport) <= 0) + return; } -#endif - - syslog(LOG_INFO, "%s: (inbound) updating lease duration to %s for pinhole with ID: %s", action, leaseTime, uid); - - r = upnp_update_inboundpinhole(uid, leaseTime); - - if(r < 0) + else if(n == -2) { - if(r == -4 || r == -1) - SoapError(h, 704, "NoSuchEntry"); - else - SoapError(h, 501, "ActionFailed"); + SoapError(h, 704, "NoSuchEntry"); + return; } else { - BuildSendAndCloseSoapResp(h, resp, sizeof(resp)-1); + SoapError(h, 501, "ActionFailed"); + return; } - ClearNameValueList(&data); + + syslog(LOG_INFO, "%s: (inbound) updating lease duration to %d for pinhole with ID: %d", + action, ltime, uid); + + n = upnp_update_inboundpinhole(uid, ltime); + if(n == -1) + SoapError(h, 704, "NoSuchEntry"); + else if(n < 0) + SoapError(h, 501, "ActionFailed"); + else + BuildSendAndCloseSoapResp(h, resp, sizeof(resp)-1); } static void @@ -1529,12 +1529,15 @@ GetOutboundPinholeTimeout(struct upnphttp * h, const char * action) syslog(LOG_INFO, "%s: retrieving timeout for outbound pinhole from [%s]:%hu to [%s]:%hu protocol %s", action, int_ip, iport,rem_host, rport, protocol); - r = upnp_check_outbound_pinhole(proto, &opt); + /* TODO */ + r = -1;/*upnp_check_outbound_pinhole(proto, &opt);*/ switch(r) { case 1: /* success */ - bodylen = snprintf(body, sizeof(body), resp, action, "urn:schemas-upnp-org:service:WANIPv6FirewallControl:1", opt, action); + bodylen = snprintf(body, sizeof(body), resp, + action, "urn:schemas-upnp-org:service:WANIPv6FirewallControl:1", + opt, action); BuildSendAndCloseSoapResp(h, body, bodylen); break; case -5: /* Protocol not supported */ @@ -1585,7 +1588,7 @@ DeletePinhole(struct upnphttp * h, const char * action) &proto, &leasetime, NULL); if (n >= 0) { - if(!PinholeVerification(h, iaddr, iport)) + if(PinholeVerification(h, iaddr, iport) <= 0) return; } else if(n == -2) @@ -1615,7 +1618,6 @@ DeletePinhole(struct upnphttp * h, const char * action) static void CheckPinholeWorking(struct upnphttp * h, const char * action) { -#if 0 static const char resp[] = "" @@ -1623,96 +1625,52 @@ CheckPinholeWorking(struct upnphttp * h, const char * action) ""; char body[512]; int bodylen; - int r, d; -#endif + int r; struct NameValueParserData data; - const char * uid; -#if 0 - char eaddr[40], iaddr[40], proto[6], lt[12]; - unsigned short eport, iport; - int isWorking = 0; -#endif + const char * uid_str; + int uid; + char iaddr[INET6_ADDRSTRLEN]; + unsigned short iport; + unsigned int packets; if(CheckStatus(h)==0) return; ParseNameValue(h->req_buf + h->req_contentoff, h->req_contentlen, &data); - uid = GetValueFromNameValueList(&data, "UniqueID"); + uid_str = GetValueFromNameValueList(&data, "UniqueID"); + uid = uid_str ? atoi(uid_str) : -1; + ClearNameValueList(&data); - if(!uid) + if(uid < 0 || uid > 65535) { - ClearNameValueList(&data); SoapError(h, 402, "Invalid Args"); return; } /* Check that client is not checking a pinhole * it doesn't have access to, because of its public access */ -#if 0 - r = upnp_get_pinhole_info(eaddr, eport, iaddr, &iport, proto, uid, lt); - if (r > 0) + r = upnp_get_pinhole_info(uid, + NULL, 0, NULL, + iaddr, sizeof(iaddr), &iport, + NULL, NULL, &packets); + if (r >= 0) { - if(PinholeVerification(h, iaddr, iport)==0) - { - ClearNameValueList(&data); + if(PinholeVerification(h, iaddr, iport) <= 0) return ; - } - else + if(packets == 0) { - int rulenum_used, rulenum = 0; - d = upnp_check_pinhole_working(uid, eaddr, iaddr, &eport, &iport, proto, &rulenum_used); - if(d < 0) - { - if(d == -4) - { - syslog(LOG_INFO, "%s: rule for ID=%s, no trace found for this pinhole", action, uid); - SoapError(h, 709, "NoPacketSent"); - ClearNameValueList(&data); - return ; - } - else - { - /* d==-5 not same table // d==-6 not same chain // d==-7 not found a rule but policy traced */ - isWorking=0; - syslog(LOG_INFO, "%s: rule for ID=%s is not working, packet going through %s", action, uid, (d==-5)?"the wrong table":((d==-6)?"the wrong chain":"a chain policy")); - bodylen = snprintf(body, sizeof(body), resp, - action, "urn:schemas-upnp-org:service:WANIPv6FirewallControl:1", - isWorking, action); - BuildSendAndCloseSoapResp(h, body, bodylen); - } - } - else - { - /*check_rule_from_file(uid, &rulenum);*/ - if(rulenum_used == rulenum) - { - isWorking=1; - syslog(LOG_INFO, "%s: rule for ID=%s is working properly", action, uid); - } - else - { - isWorking=0; - syslog(LOG_INFO, "%s: rule for ID=%s is not working", action, uid); - } - bodylen = snprintf(body, sizeof(body), resp, - action, "urn:schemas-upnp-org:service:WANIPv6FirewallControl:1", - isWorking, action); - BuildSendAndCloseSoapResp(h, body, bodylen); - } + SoapError(h, 709, "NoPacketSent"); + return; } + bodylen = snprintf(body, sizeof(body), resp, + action, "urn:schemas-upnp-org:service:WANIPv6FirewallControl:1", + 1, action); + BuildSendAndCloseSoapResp(h, body, bodylen); } - else if(r == -4 || r == -1) - { + else if(r == -2) SoapError(h, 704, "NoSuchEntry"); - } else -#endif - { SoapError(h, 501, "ActionFailed"); - ClearNameValueList(&data); - return ; - } - ClearNameValueList(&data); } static void @@ -1756,10 +1714,8 @@ GetPinholePackets(struct upnphttp * h, const char * action) &proto, &leasetime, &packets); if (n >= 0) { - if(PinholeVerification(h, iaddr, iport)==0) - { + if(PinholeVerification(h, iaddr, iport)<=0) return ; - } } #if 0 else if(r == -4 || r == -1)