implementing UpdatePinhole() and CheckPinholeWorking()

WANIPv6FirewallControl

upnpredirect :
	cleanup : upnp_add_inboundpinhole
	fix : upnp_get_pinhole_info
	implement : upnp_update_inboundpinhole
upnpsoap :
	implement : UpdatePinhole
	implement : CheckPinholeWorking
This commit is contained in:
Thomas Bernard 2012-04-24 00:50:20 +02:00
parent 12825443b1
commit c8021cb841
3 changed files with 94 additions and 164 deletions

View File

@ -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 /* MiniUPnP project
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
* (c) 2006-2012 Thomas Bernard * (c) 2006-2012 Thomas Bernard
@ -579,10 +579,10 @@ upnp_get_portmappings_in_range(unsigned short startport,
} }
#ifdef ENABLE_6FC_SERVICE #ifdef ENABLE_6FC_SERVICE
#if 0
int int
upnp_check_outbound_pinhole(int proto, int * timeout) upnp_check_outbound_pinhole(int proto, int * timeout)
{ {
#if 0
int s, tmptimeout, tmptime_out; int s, tmptimeout, tmptime_out;
switch(proto) switch(proto)
{ {
@ -618,9 +618,9 @@ upnp_check_outbound_pinhole(int proto, int * timeout)
return -5; return -5;
break; break;
} }
#endif
return 0; return 0;
} }
#endif
/* upnp_add_inboundpinhole() /* upnp_add_inboundpinhole()
* returns: 0 on success * returns: 0 on success
@ -639,24 +639,17 @@ upnp_add_inboundpinhole(const char * raddr,
int * uid) int * uid)
{ {
int r; int r;
#if 0
char iaddr_old[40]="", idfound[5]=""; /* IPv6 Modification*/
unsigned short iport_old = 0;
#endif
time_t current; time_t current;
unsigned int timestamp; 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); syslog(LOG_ERR, "inet_pton(%s) : %m", iaddr);
return 0; return 0;
} }
current = time(NULL); current = time(NULL);
timestamp = current + leasetime; timestamp = current + leasetime;
#if 0
r = get_rule_from_file(raddr, rport, iaddr_old, &iport_old, proto, 0, 0, idfound);
#endif
r = 0; r = 0;
#if 0 #if 0
@ -676,26 +669,11 @@ upnp_add_inboundpinhole(const char * raddr,
return 1; return 1;
#else #else
return -42; /* not implemented */ 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 #endif
} }
return 0;
} }
#if 0
int int
upnp_add_inboundpinhole_internal(const char * raddr, unsigned short rport, upnp_add_inboundpinhole_internal(const char * raddr, unsigned short rport,
const char * iaddr, unsigned short iport, 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); printf("\t_add_ uid: %s\n", cuid);
return 1; return 1;
} }
#endif
/* upnp_get_pinhole_info() /* upnp_get_pinhole_info()
* return values : * return values :
@ -790,12 +769,14 @@ upnp_get_pinhole_info(unsigned short uid,
iaddr, iaddrlen, iport, proto, &timestamp, iaddr, iaddrlen, iport, proto, &timestamp,
&packets_tmp, &bytes_tmp); &packets_tmp, &bytes_tmp);
if(r >= 0) { if(r >= 0) {
time_t current_time; if(leasetime) {
current_time = time(NULL); time_t current_time;
if(timestamp > current_time) current_time = time(NULL);
*leasetime = timestamp - current_time; if(timestamp > current_time)
else *leasetime = timestamp - current_time;
*leasetime = 0; else
*leasetime = 0;
}
if(packets) if(packets)
*packets = (unsigned int)packets_tmp; *packets = (unsigned int)packets_tmp;
} }
@ -806,23 +787,14 @@ upnp_get_pinhole_info(unsigned short uid,
} }
int int
upnp_update_inboundpinhole(const char * uid, const char * leasetime) upnp_update_inboundpinhole(unsigned short uid, unsigned int leasetime)
{ {
/* TODO : to be implemented */ #ifdef USE_PF
#if 0 unsigned int timestamp;
int r, n; timestamp = time(NULL) + leasetime;
syslog(LOG_INFO, "Updating pinhole for inbound traffic with ID: %s", uid); return update_pinhole(uid, timestamp);
r = check_rule_from_file(uid, 0);
if(r < 0)
return r;
else
{
n = rule_file_update(uid, leasetime);
upnp_update_expiredpinhole();
return n;
}
#else #else
return -1; return -42; /* not implemented */
#endif #endif
} }
@ -1049,7 +1021,7 @@ upnp_check_pinhole_working(const char * uid,
fclose(fd); fclose(fd);
return res; return res;
#else #else
return -4; return -42; /* to be implemented */
#endif #endif
} }
@ -1059,7 +1031,7 @@ upnp_clean_expired_pinholes(unsigned int * next_timestamp)
#ifdef USE_PF #ifdef USE_PF
return clean_pinhole_list(next_timestamp); return clean_pinhole_list(next_timestamp);
#else #else
return 0; return 0; /* nothing to do */
#endif #endif
} }
#endif #endif

View File

@ -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 /* MiniUPnP project
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
* (c) 2006-2012 Thomas Bernard * (c) 2006-2012 Thomas Bernard
@ -109,11 +109,13 @@ upnp_get_portmappings_in_range(unsigned short startport,
unsigned int * number); unsigned int * number);
#ifdef ENABLE_6FC_SERVICE #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 int
upnp_check_outbound_pinhole(int proto, int * timeout); upnp_check_outbound_pinhole(int proto, int * timeout);
#endif
/* add an inbound pinehole /* add an inbound pinehole
* return value : * return value :
@ -141,7 +143,7 @@ upnp_get_pinhole_info(unsigned short uid,
/* update the lease time */ /* update the lease time */
int int
upnp_update_inboundpinhole(const char * uid, const char * leasetime); upnp_update_inboundpinhole(unsigned short uid, unsigned int leasetime);
/* remove the inbound pinhole */ /* remove the inbound pinhole */
int int

View File

@ -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 /* MiniUPnP project
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
* (c) 2006-2012 Thomas Bernard * (c) 2006-2012 Thomas Bernard
@ -1431,65 +1431,65 @@ clear_and_exit:
static void static void
UpdatePinhole(struct upnphttp * h, const char * action) UpdatePinhole(struct upnphttp * h, const char * action)
{ {
int r/*, n*/;
static const char resp[] = static const char resp[] =
"<u:UpdatePinholeResponse " "<u:UpdatePinholeResponse "
"xmlns:u=\"urn:schemas-upnp-org:service:WANIPv6FirewallControl:1\">" "xmlns:u=\"urn:schemas-upnp-org:service:WANIPv6FirewallControl:1\">"
"</u:UpdatePinholeResponse>"; "</u:UpdatePinholeResponse>";
struct NameValueParserData data; struct NameValueParserData data;
const char * uid, * leaseTime; const char * uid_str, * leaseTime;
#if 0 char iaddr[INET6_ADDRSTRLEN];
char iaddr[40], proto[6], lt[12];
unsigned short iport; unsigned short iport;
#endif int ltime;
int ltime = -1; int uid;
int n;
if(CheckStatus(h)==0) if(CheckStatus(h)==0)
return; return;
ParseNameValue(h->req_buf + h->req_contentoff, h->req_contentlen, &data); ParseNameValue(h->req_buf + h->req_contentoff, h->req_contentlen, &data);
uid = GetValueFromNameValueList(&data, "UniqueID"); uid_str = GetValueFromNameValueList(&data, "UniqueID");
leaseTime = GetValueFromNameValueList(&data, "NewLeaseTime"); leaseTime = GetValueFromNameValueList(&data, "NewLeaseTime");
if(leaseTime) uid = uid_str ? atoi(uid_str) : -1;
ltime = atoi(leaseTime); 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"); SoapError(h, 402, "Invalid Args");
return; 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 */ * it doesn't have access to, because of its public access */
#if 0 n = upnp_get_pinhole_info(uid, NULL, 0, NULL,
n = upnp_get_pinhole_info(0, 0, iaddr, &iport, proto, uid, lt); iaddr, sizeof(iaddr), &iport,
if (n > 0) NULL, NULL, NULL);
if (n >= 0)
{ {
if(PinholeVerification(h, iaddr, iport)==0) if(PinholeVerification(h, iaddr, iport) <= 0)
{ return;
ClearNameValueList(&data);
return ;
}
} }
#endif else if(n == -2)
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)
{ {
if(r == -4 || r == -1) SoapError(h, 704, "NoSuchEntry");
SoapError(h, 704, "NoSuchEntry"); return;
else
SoapError(h, 501, "ActionFailed");
} }
else 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 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); 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) switch(r)
{ {
case 1: /* success */ 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); BuildSendAndCloseSoapResp(h, body, bodylen);
break; break;
case -5: /* Protocol not supported */ case -5: /* Protocol not supported */
@ -1585,7 +1588,7 @@ DeletePinhole(struct upnphttp * h, const char * action)
&proto, &leasetime, NULL); &proto, &leasetime, NULL);
if (n >= 0) if (n >= 0)
{ {
if(!PinholeVerification(h, iaddr, iport)) if(PinholeVerification(h, iaddr, iport) <= 0)
return; return;
} }
else if(n == -2) else if(n == -2)
@ -1615,7 +1618,6 @@ DeletePinhole(struct upnphttp * h, const char * action)
static void static void
CheckPinholeWorking(struct upnphttp * h, const char * action) CheckPinholeWorking(struct upnphttp * h, const char * action)
{ {
#if 0
static const char resp[] = static const char resp[] =
"<u:%sResponse " "<u:%sResponse "
"xmlns:u=\"%s\">" "xmlns:u=\"%s\">"
@ -1623,96 +1625,52 @@ CheckPinholeWorking(struct upnphttp * h, const char * action)
"</u:%sResponse>"; "</u:%sResponse>";
char body[512]; char body[512];
int bodylen; int bodylen;
int r, d; int r;
#endif
struct NameValueParserData data; struct NameValueParserData data;
const char * uid; const char * uid_str;
#if 0 int uid;
char eaddr[40], iaddr[40], proto[6], lt[12]; char iaddr[INET6_ADDRSTRLEN];
unsigned short eport, iport; unsigned short iport;
int isWorking = 0; unsigned int packets;
#endif
if(CheckStatus(h)==0) if(CheckStatus(h)==0)
return; return;
ParseNameValue(h->req_buf + h->req_contentoff, h->req_contentlen, &data); 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"); SoapError(h, 402, "Invalid Args");
return; return;
} }
/* Check that client is not checking a pinhole /* Check that client is not checking a pinhole
* it doesn't have access to, because of its public access */ * it doesn't have access to, because of its public access */
#if 0 r = upnp_get_pinhole_info(uid,
r = upnp_get_pinhole_info(eaddr, eport, iaddr, &iport, proto, uid, lt); NULL, 0, NULL,
if (r > 0) iaddr, sizeof(iaddr), &iport,
NULL, NULL, &packets);
if (r >= 0)
{ {
if(PinholeVerification(h, iaddr, iport)==0) if(PinholeVerification(h, iaddr, iport) <= 0)
{
ClearNameValueList(&data);
return ; return ;
} if(packets == 0)
else
{ {
int rulenum_used, rulenum = 0; SoapError(h, 709, "NoPacketSent");
d = upnp_check_pinhole_working(uid, eaddr, iaddr, &eport, &iport, proto, &rulenum_used); return;
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);
}
} }
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"); SoapError(h, 704, "NoSuchEntry");
}
else else
#endif
{
SoapError(h, 501, "ActionFailed"); SoapError(h, 501, "ActionFailed");
ClearNameValueList(&data);
return ;
}
ClearNameValueList(&data);
} }
static void static void
@ -1756,10 +1714,8 @@ GetPinholePackets(struct upnphttp * h, const char * action)
&proto, &leasetime, &packets); &proto, &leasetime, &packets);
if (n >= 0) if (n >= 0)
{ {
if(PinholeVerification(h, iaddr, iport)==0) if(PinholeVerification(h, iaddr, iport)<=0)
{
return ; return ;
}
} }
#if 0 #if 0
else if(r == -4 || r == -1) else if(r == -4 || r == -1)