Commit 591389c7 authored by Evan Hunt's avatar Evan Hunt

[master] 5011 tests and fixes

4056.	[bug]		Expanded automatic testing of trust anchor
			management and fixed several small bugs including
			a memory leak and a possible loss of key state
			information. [RT #38458]

4055.	[func]		"rndc managed-keys" can be used to check status
			of trust anchors or to force keys to be refreshed,
			Also, the managed keys data file has easier-to-read
			comments.  [RT #38458]
parent de283bda
4056. [bug] Expanded automatic testing of trust anchor
management and fixed several small bugs including
a memory leak and a possible loss of key state
information. [RT #38458]
4055. [func] "rndc managed-keys" can be used to check status
of trust anchors or to force keys to be refreshed,
Also, the managed keys data file has easier-to-read
comments. [RT #38458]
4054. [func] Added a new tool 'mdig', a light weight clone of
dig able to send multiple pipelined queries.
[RT #38261]
......
......@@ -160,7 +160,7 @@ ns_control_docommand(isccc_sexpr_t *message, isc_buffer_t **text) {
ns_server_dumpdb(ns_g_server, command);
result = ISC_R_SUCCESS;
} else if (command_compare(command, NS_COMMAND_SECROOTS)) {
result = ns_server_dumpsecroots(ns_g_server, command);
result = ns_server_dumpsecroots(ns_g_server, command, text);
} else if (command_compare(command, NS_COMMAND_TRACE)) {
result = ns_server_setdebuglevel(ns_g_server, command);
} else if (command_compare(command, NS_COMMAND_NOTRACE)) {
......@@ -220,6 +220,8 @@ ns_control_docommand(isccc_sexpr_t *message, isc_buffer_t **text) {
result = ns_server_nta(ns_g_server, command, text);
} else if (command_compare(command, NS_COMMAND_TESTGEN)) {
result = ns_server_testgen(command, text);
} else if (command_compare(command, NS_COMMAND_MKEYS)) {
result = ns_server_mkeys(ns_g_server, command, text);
} else {
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_CONTROL, ISC_LOG_WARNING,
......
......@@ -71,6 +71,7 @@
#define NS_COMMAND_ZONESTATUS "zonestatus"
#define NS_COMMAND_NTA "nta"
#define NS_COMMAND_TESTGEN "testgen"
#define NS_COMMAND_MKEYS "managed-keys"
isc_result_t
ns_controls_create(ns_server_t *server, ns_controls_t **ctrlsp);
......
......@@ -175,7 +175,6 @@ EXTERN isc_boolean_t ns_g_notcp INIT(ISC_FALSE);
EXTERN isc_boolean_t ns_g_disable6 INIT(ISC_FALSE);
EXTERN isc_boolean_t ns_g_disable4 INIT(ISC_FALSE);
#ifdef HAVE_GEOIP
EXTERN dns_geoip_databases_t *ns_g_geoip INIT(NULL);
#endif
......
......@@ -301,7 +301,7 @@ ns_server_dumpdb(ns_server_t *server, char *args);
* Dump the current security roots to the secroots file.
*/
isc_result_t
ns_server_dumpsecroots(ns_server_t *server, char *args);
ns_server_dumpsecroots(ns_server_t *server, char *args, isc_buffer_t **text);
/*%
* Change or increment the server debug level.
......@@ -426,4 +426,11 @@ ns_server_nta(ns_server_t *server, char *args, isc_buffer_t **text);
*/
isc_result_t
ns_server_testgen(char *args, isc_buffer_t **text);
/*%
* Force fefresh or print status for managed keys zones.
*/
isc_result_t
ns_server_mkeys(ns_server_t *server, char *args, isc_buffer_t **text);
#endif /* NAMED_SERVER_H */
......@@ -106,6 +106,9 @@
#endif
extern int isc_dscp_check_value;
extern unsigned int dns_zone_mkey_hour;
extern unsigned int dns_zone_mkey_day;
extern unsigned int dns_zone_mkey_month;
static isc_boolean_t want_stats = ISC_FALSE;
static char program_name[ISC_DIR_NAMEMAX] = "named";
......@@ -562,7 +565,38 @@ parse_command_line(int argc, char *argv[]) {
else if (!strncmp(isc_commandline_argument, "dscp=", 5))
isc_dscp_check_value =
atoi(isc_commandline_argument + 5);
else if (!strcmp(isc_commandline_argument, "notcp"))
else if (!strncmp(isc_commandline_argument,
"mkeytimers=", 11))
{
p = strtok(isc_commandline_argument + 11, "/");
if (p == NULL)
ns_main_earlyfatal("bad mkeytimer");
dns_zone_mkey_hour = atoi(p);
if (dns_zone_mkey_hour == 0)
ns_main_earlyfatal("bad mkeytimer");
p = strtok(NULL, "/");
if (p == NULL) {
dns_zone_mkey_day =
(24 * dns_zone_mkey_hour);
dns_zone_mkey_month =
(30 * dns_zone_mkey_day);
break;
}
dns_zone_mkey_day = atoi(p);
if (dns_zone_mkey_day < dns_zone_mkey_hour)
ns_main_earlyfatal("bad mkeytimer");
p = strtok(NULL, "/");
if (p == NULL) {
dns_zone_mkey_month =
(30 * dns_zone_mkey_day);
break;
}
dns_zone_mkey_month = atoi(p);
if (dns_zone_mkey_month < dns_zone_mkey_day)
ns_main_earlyfatal("bad mkeytimer");
} else if (!strcmp(isc_commandline_argument, "notcp"))
ns_g_notcp = ISC_TRUE;
else
fprintf(stderr, "unknown -T flag '%s\n",
......
......@@ -90,6 +90,7 @@
#include <dns/rdatastruct.h>
#include <dns/resolver.h>
#include <dns/rootns.h>
#include <dns/rriterator.h>
#include <dns/secalg.h>
#include <dns/soa.h>
#include <dns/stats.h>
......@@ -7857,7 +7858,7 @@ ns_server_dumpdb(ns_server_t *server, char *args) {
}
isc_result_t
ns_server_dumpsecroots(ns_server_t *server, char *args) {
ns_server_dumpsecroots(ns_server_t *server, char *args, isc_buffer_t **text) {
dns_view_t *view;
dns_keytable_t *secroots = NULL;
dns_ntatable_t *ntatable = NULL;
......@@ -7872,13 +7873,25 @@ ns_server_dumpsecroots(ns_server_t *server, char *args) {
if (ptr == NULL)
return (ISC_R_UNEXPECTEDEND);
/* "-" here means print the output instead of dumping to file */
ptr = next_token(&args, " \t");
if (ptr != NULL && strcmp(ptr, "-") == 0)
ptr = next_token(&args, " \t");
else {
result = isc_stdio_open(server->secrootsfile, "w", &fp);
if (result != ISC_R_SUCCESS) {
(void) putstr(text, "could not open ");
(void) putstr(text, server->secrootsfile);
CHECKMF(result, "could not open secroots dump file",
server->secrootsfile);
}
}
CHECKMF(isc_stdio_open(server->secrootsfile, "w", &fp),
"could not open secroots dump file", server->secrootsfile);
TIME_NOW(&now);
isc_time_formattimestamp(&now, tbuf, sizeof(tbuf));
fprintf(fp, "%s\n", tbuf);
CHECK(putstr(text, "secure roots as of "));
CHECK(putstr(text, tbuf));
CHECK(putstr(text, ":\n"));
do {
for (view = ISC_LIST_HEAD(server->viewlist);
......@@ -7894,12 +7907,10 @@ ns_server_dumpsecroots(ns_server_t *server, char *args) {
result = ISC_R_SUCCESS;
continue;
}
fprintf(fp, "\n Start view %s\n", view->name);
fprintf(fp, " Secure roots:\n\n");
result = dns_keytable_dump(secroots, fp);
if (result != ISC_R_SUCCESS)
fprintf(fp, " dumpsecroots failed: %s\n",
isc_result_totext(result));
CHECK(putstr(text, "\n Start view "));
CHECK(putstr(text, view->name));
CHECK(putstr(text, "\n Secure roots:\n\n"));
CHECK(dns_keytable_totext(secroots, text));
if (ntatable != NULL)
dns_ntatable_detach(&ntatable);
......@@ -7908,23 +7919,30 @@ ns_server_dumpsecroots(ns_server_t *server, char *args) {
result = ISC_R_SUCCESS;
continue;
}
fprintf(fp, "\n Negative trust anchors:\n\n");
result = dns_ntatable_dump(ntatable, fp);
if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
fprintf(fp, " dumpntatable failed: %s\n",
isc_result_totext(result));
CHECK(putstr(text, "\n Negative trust anchors:\n\n"));
CHECK(dns_ntatable_totext(ntatable, text));
}
if (ptr != NULL)
ptr = next_token(&args, " \t");
} while (ptr != NULL);
cleanup:
if (isc_buffer_usedlength(*text) > 0) {
if (fp != NULL)
(void)putstr(text, "\n");
else
(void)putnull(text);
}
if (secroots != NULL)
dns_keytable_detach(&secroots);
if (ntatable != NULL)
dns_ntatable_detach(&ntatable);
if (fp != NULL)
if (fp != NULL) {
fprintf(fp, "%.*s", (int) isc_buffer_usedlength(*text),
(char *) isc_buffer_base(*text));
isc_buffer_clear(*text);
(void)isc_stdio_close(fp);
}
if (result == ISC_R_SUCCESS)
isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
NS_LOGMODULE_SERVER, ISC_LOG_INFO,
......@@ -8297,7 +8315,9 @@ ns_server_status(ns_server_t *server, isc_buffer_t **text) {
unsigned int zonecount, xferrunning, xferdeferred, soaqueries;
unsigned int automatic;
const char *ob = "", *cb = "", *alt = "";
char boottime[80], configtime[80], line[1024];
char boottime[ISC_FORMATHTTPTIMESTAMP_SIZE];
char configtime[ISC_FORMATHTTPTIMESTAMP_SIZE];
char line[1024];
if (ns_g_server->version_set) {
ob = " (";
......@@ -10039,7 +10059,11 @@ ns_server_zonestatus(ns_server_t *server, char *args, isc_buffer_t **text) {
const char *type, *file, *zonename = NULL;
isc_uint32_t serial, signed_serial, nodes;
char serbuf[16], sserbuf[16], nodebuf[16], resignbuf[512];
char lbuf[80], xbuf[80], rbuf[80], kbuf[80], rtbuf[80];
char lbuf[ISC_FORMATHTTPTIMESTAMP_SIZE];
char xbuf[ISC_FORMATHTTPTIMESTAMP_SIZE];
char rbuf[ISC_FORMATHTTPTIMESTAMP_SIZE];
char kbuf[ISC_FORMATHTTPTIMESTAMP_SIZE];
char rtbuf[ISC_FORMATHTTPTIMESTAMP_SIZE];
isc_time_t loadtime, expiretime, refreshtime;
isc_time_t refreshkeytime, resigntime;
dns_zonetype_t zonetype;
......@@ -10217,7 +10241,7 @@ ns_server_zonestatus(ns_server_t *server, char *args, isc_buffer_t **text) {
}
if (! isc_time_isepoch(&refreshtime)) {
CHECK(putstr(text, "\nnext refresh: "));
CHECK(putstr(text, "\nnext managed-keys refresh: "));
CHECK(putstr(text, rbuf));
}
......@@ -10394,6 +10418,7 @@ ns_server_nta(ns_server_t *server, char *args, isc_buffer_t **text) {
}
CHECK(dns_ntatable_totext(ntatable, text));
}
CHECK(putnull(text));
goto cleanup;
}
......@@ -10555,3 +10580,275 @@ ns_server_loadnta(ns_server_t *server) {
return (ISC_R_SUCCESS);
}
static isc_result_t
mkey_refresh(dns_view_t *view, isc_buffer_t **text) {
isc_result_t result;
char msg[DNS_NAME_FORMATSIZE + 500] = "";
snprintf(msg, sizeof(msg),
"refreshing managed keys for '%s'", view->name);
CHECK(putstr(text, msg));
CHECK(dns_zone_synckeyzone(view->managed_keys));
cleanup:
return (result);
}
static isc_result_t
mkey_dumpzone(dns_view_t *view, isc_buffer_t **text) {
isc_result_t result;
dns_db_t *db = NULL;
dns_dbversion_t *ver = NULL;
dns_rriterator_t rrit;
isc_stdtime_t now;
dns_name_t *prevname = NULL;
isc_stdtime_get(&now);
CHECK(dns_zone_getdb(view->managed_keys, &db));
dns_db_currentversion(db, &ver);
dns_rriterator_init(&rrit, db, ver, 0);
for (result = dns_rriterator_first(&rrit);
result == ISC_R_SUCCESS;
result = dns_rriterator_nextrrset(&rrit))
{
char buf[DNS_NAME_FORMATSIZE + 500];
dns_name_t *name = NULL;
dns_rdataset_t *kdset = NULL;
dns_rdata_t rdata = DNS_RDATA_INIT;
dns_rdata_keydata_t kd;
isc_uint32_t ttl;
dns_rriterator_current(&rrit, &name, &ttl, &kdset, NULL);
if (kdset == NULL || kdset->type != dns_rdatatype_keydata ||
!dns_rdataset_isassociated(kdset))
continue;
if (name != prevname) {
char nbuf[DNS_NAME_FORMATSIZE];
dns_name_format(name, nbuf, sizeof(nbuf));
snprintf(buf, sizeof(buf), "\n\n name: %s", nbuf);
CHECK(putstr(text, buf));
}
for (result = dns_rdataset_first(kdset);
result == ISC_R_SUCCESS;
result = dns_rdataset_next(kdset))
{
char alg[DNS_SECALG_FORMATSIZE];
char tbuf[ISC_FORMATHTTPTIMESTAMP_SIZE];
dns_keytag_t keyid;
isc_region_t r;
isc_time_t t;
isc_boolean_t revoked;
dns_rdata_reset(&rdata);
dns_rdataset_current(kdset, &rdata);
result = dns_rdata_tostruct(&rdata, &kd, NULL);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
dns_rdata_toregion(&rdata, &r);
isc_region_consume(&r, 12);
keyid = dst_region_computeid(&r, kd.algorithm);
snprintf(buf, sizeof(buf), "\n keyid: %u", keyid);
CHECK(putstr(text, buf));
dns_secalg_format(kd.algorithm, alg, sizeof(alg));
snprintf(buf, sizeof(buf), "\n\talgorithm: %s", alg);
CHECK(putstr(text, buf));
revoked = ISC_TF((kd.flags & DNS_KEYFLAG_REVOKE) != 0);
snprintf(buf, sizeof(buf), "\n\tflags:%s%s%s",
revoked ? " REVOKE" : "",
((kd.flags & DNS_KEYFLAG_KSK) != 0)
? " SEP" : "",
(kd.flags == 0) ? " (none)" : "");
CHECK(putstr(text, buf));
isc_time_set(&t, kd.refresh, 0);
isc_time_formathttptimestamp(&t, tbuf, sizeof(tbuf));
snprintf(buf, sizeof(buf),
"\n\tnext refresh: %s", tbuf);
CHECK(putstr(text, buf));
if (kd.removehd != 0) {
isc_time_set(&t, kd.removehd, 0);
isc_time_formathttptimestamp(&t, tbuf,
sizeof(tbuf));
snprintf(buf, sizeof(buf),
"\n\tremove at: %s", tbuf);
CHECK(putstr(text, buf));
}
isc_time_set(&t, kd.addhd, 0);
isc_time_formathttptimestamp(&t, tbuf, sizeof(tbuf));
if (kd.addhd == 0)
snprintf(buf, sizeof(buf), "\n\tno trust");
else if (revoked)
snprintf(buf, sizeof(buf),
"\n\ttrust revoked");
else if (kd.addhd < now)
snprintf(buf, sizeof(buf),
"\n\ttrusted since: %s", tbuf);
else if (kd.addhd >= now)
snprintf(buf, sizeof(buf),
"\n\ttrust pending: %s", tbuf);
CHECK(putstr(text, buf));
}
}
if (result == ISC_R_NOMORE)
result = ISC_R_SUCCESS;
cleanup:
if (ver != NULL) {
dns_rriterator_destroy(&rrit);
dns_db_closeversion(db, &ver, ISC_FALSE);
}
if (db != NULL)
dns_db_detach(&db);
return (result);
}
static isc_result_t
mkey_status(dns_view_t *view, isc_buffer_t **text) {
isc_result_t result;
char msg[ISC_FORMATHTTPTIMESTAMP_SIZE];
isc_time_t t;
CHECK(putstr(text, "view: "));
CHECK(putstr(text, view->name));
CHECK(putstr(text, "\nnext scheduled event: "));
dns_zone_getrefreshkeytime(view->managed_keys, &t);
if (isc_time_isepoch(&t)) {
CHECK(putstr(text, "never"));
} else {
isc_time_formathttptimestamp(&t, msg, sizeof(msg));
CHECK(putstr(text, msg));
}
CHECK(mkey_dumpzone(view, text));
cleanup:
return (result);
}
isc_result_t
ns_server_mkeys(ns_server_t *server, char *args, isc_buffer_t **text) {
char *cmd, *classtxt, *viewtxt = NULL;
isc_result_t result = ISC_R_SUCCESS;
dns_view_t *view = NULL;
dns_rdataclass_t rdclass;
char msg[DNS_NAME_FORMATSIZE + 500] = "";
enum { NONE, STATUS, REFRESH, SYNC } opt = NONE;
isc_boolean_t found = ISC_FALSE;
/* Skip rndc command name */
cmd = next_token(&args, " \t");
if (cmd == NULL)
return (ISC_R_UNEXPECTEDEND);
/* Get managed-keys subcommand */
cmd = next_token(&args, " \t");
if (cmd == NULL)
return (ISC_R_UNEXPECTEDEND);
if (strcasecmp(cmd, "status") == 0)
opt = STATUS;
else if (strcasecmp(cmd, "refresh") == 0)
opt = REFRESH;
else if (strcasecmp(cmd, "sync") == 0)
opt = SYNC;
else {
snprintf(msg, sizeof(msg), "unknown command '%s'", cmd);
(void) putstr(text, msg);
result = ISC_R_UNEXPECTED;
goto cleanup;
}
/* Look for the optional class name. */
classtxt = next_token(&args, " \t");
if (classtxt != NULL) {
/* Look for the optional view name. */
viewtxt = next_token(&args, " \t");
}
if (classtxt == NULL) {
rdclass = dns_rdataclass_in;
} else {
isc_textregion_t r;
r.base = classtxt;
r.length = strlen(classtxt);
result = dns_rdataclass_fromtext(&rdclass, &r);
if (result != ISC_R_SUCCESS) {
if (viewtxt == NULL) {
rdclass = dns_rdataclass_in;
viewtxt = classtxt;
result = ISC_R_SUCCESS;
} else {
snprintf(msg, sizeof(msg),
"unknown class '%s'", classtxt);
(void) putstr(text, msg);
goto cleanup;
}
}
}
for (view = ISC_LIST_HEAD(server->viewlist);
view != NULL;
view = ISC_LIST_NEXT(view, link))
{
isc_boolean_t first = ISC_TRUE;
if (viewtxt != NULL &&
(rdclass != view->rdclass ||
strcmp(view->name, viewtxt) != 0))
continue;
if (view->managed_keys == NULL) {
if (viewtxt != NULL) {
snprintf(msg, sizeof(msg),
"view '%s': no managed keys", viewtxt);
CHECK(putstr(text, msg));
goto cleanup;
} else
continue;
}
found = ISC_TRUE;
switch (opt) {
case REFRESH:
CHECK(mkey_refresh(view, text));
break;
case STATUS:
if (!first)
CHECK(putstr(text, "\n"));
CHECK(mkey_status(view, text));
first = ISC_FALSE;
break;
case SYNC:
CHECK(dns_zone_flush(view->managed_keys));
break;
default:
INSIST(0);
}
if (viewtxt != NULL)
break;
}
if (!found)
CHECK(putstr(text, "no views with managed keys"));
cleanup:
if (isc_buffer_usedlength(*text) > 0)
(void) putnull(text);
return (result);
}
This diff is collapsed.
......@@ -69,8 +69,9 @@ SUBDIRS="acl additional allow_query addzone autosign builtin
@COVERAGE@ database delv dlv dlvauto dlz dlzexternal dname
dns64 dnssec dsdigest dscp ecdsa ednscompliance emptyzones
filter-aaaa formerr forward geoip glue gost ixfr inline
legacy limits logfileconfig lwresd masterfile masterformat
metadata notify nslookup nsupdate pending pipelined @PKCS11_TEST@
legacy limits logfileconfig lwresd
masterfile masterformat metadata mkeys
notify nslookup nsupdate pending pipelined @PKCS11_TEST@
reclimit redirect resolver rndc rpz rrl rrchecker rrsetorder
rsabigexponent runtime sit sfcache smartsign sortlist spf
staticstub statistics stub tcp tkey tsig tsiggss unknown
......
......@@ -16,7 +16,8 @@
# PERFORMANCE OF THIS SOFTWARE.
rm -f */K* */keyset-* */dsset-* */dlvset-* */signedkey-* */*.signed
rm -f */trusted.conf */managed.conf */tmp* */*.jnl */*.bk */*.jbk
rm -f */trusted.conf */managed.conf */revoked.conf
rm -f */tmp* */*.jnl */*.bk */*.jbk
rm -f ns1/root.db ns2/example.db ns3/secure.example.db
rm -f ns3/unsecure.example.db ns3/bogus.example.db ns3/keyless.example.db
rm -f ns3/dynamic.example.db ns3/dynamic.example.db.signed.jnl
......@@ -51,7 +52,7 @@ rm -f signer/*.db
rm -f signer/signer.out.*
rm -f ns2/algroll.db
rm -f ns3/kskonly.example.db
rm -f ns4/named.conf
rm -f ns4/named.conf ns5/named.conf
rm -f ns4/managed-keys.bind*
rm -f ns3/auto-nsec.example.db ns3/auto-nsec3.example.db
rm -f ns3/secure.below-cname.example.db
......@@ -83,3 +84,4 @@ rm -f ns3/dnskey-unknown.example.db
rm -f ns3/dnskey-unknown.example.db.tmp
rm -f ns*/named.lock
rm -f ns*/*.nta
rm -f named.secroots.test*
......@@ -15,8 +15,6 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
# $Id: sign.sh,v 1.43 2011/11/04 05:36:28 each Exp $
SYSTEMTESTTOP=../..
. $SYSTEMTESTTOP/conf.sh
......@@ -520,5 +518,5 @@ zonefile=future.example.db
kskname=`$KEYGEN -q -r $RANDFILE -f KSK $zone`
zskname=`$KEYGEN -q -r $RANDFILE $zone`
cat $infile $kskname.key $zskname.key >$zonefile
$SIGNER -P -s +3600 -r $RANDFILE -o $zone $zonefile # > /dev/null 2>&1
$SIGNER -P -s +3600 -r $RANDFILE -o $zone $zonefile > /dev/null 2>&1
cp -f $kskname.key trusted-future.key
......@@ -15,8 +15,6 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: named.conf,v 1.25 2007/06/18 23:47:28 tbox Exp $ */
// NS5
controls { /* empty */ };
......@@ -35,6 +33,16 @@ options {
dnssec-validation yes;
};
key rndc_key {
secret "1234abcd8765";
algorithm hmac-sha256;
};
controls {
inet 10.53.0.5 port 9953 allow { any; } keys { rndc_key; };
};
zone "." {
type hint;
file "../../common/root.hint";
......
/*
* Copyright (C) 2004, 2006, 2007 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE