Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
salcock committed Aug 14, 2024
2 parents 2eae3c4 + e3e019e commit 1e3790a
Show file tree
Hide file tree
Showing 22 changed files with 182 additions and 26 deletions.
3 changes: 3 additions & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ In no particular order, we would like to thank the following people:
* Tyler Marriner for adding support for encrypting inter-component
communications using TLS and adding RabbitMQ support to the collector.
* Neil Tapp for pointing out many bugs and logging inaccuracies.
* Pim van Stam for contributing code to support the "agencycountrycode"
configuration option, as well as handling of certain NL-specific
requirements.

Apologies to anyone that has made a contribution but we've forgotten to
mention you here -- if this has happened to you, please get in touch with the
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
OpenLI -- open source ETSI-compliant Lawful Intercept software

Version: 1.1.7
Version: 1.1.8

---------------------------------------------------------------------------

Expand Down
2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Super primitive configure script

AC_INIT([openli],[1.1.7],[[email protected]])
AC_INIT([openli],[1.1.8],[[email protected]])

AM_INIT_AUTOMAKE([subdir-objects])
AC_CONFIG_SRCDIR(src/collector/collector.c)
Expand Down
19 changes: 19 additions & 0 deletions debian/changelog
Original file line number Diff line number Diff line change
@@ -1,3 +1,22 @@
openli (1.1.8-1) unstable; urgency=medium

* Collector: fix crash in sync_voip thread if an invalid SIP packet
is encountered.
* Collector: add a single zero byte to the list of recognised SIP
keep alives.
* Collector: fix crash that can occur if an IP is mapped to a
RADIUS session more than once.
* Add config option to specify the country where an agency has
jurisdiction, which allows us to support country-specific
requirements for HI1 operations and keep alive messages.
* Keep alive messages for NL agencies now conform to the ETSI-IP.nl
requirements.
* Use '--' instead of 'NA' as the auth and delivery country code for
keep alives when we do not know the country code for the receiving
agency.

-- Shane Alcock <[email protected]> Wed, 14 Aug 2024 10:13:28 +1200

openli (1.1.7-1) unstable; urgency=medium

* Collector: fix file descriptor leak caused by timers in SMS worker
Expand Down
2 changes: 2 additions & 0 deletions doc/ProvisionerDoc.md
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,8 @@ Agencies are expressed as a YAML sequence with a key of `agencies:`. Each
sequence item represents a single agency and must contain the following
key-value elements:
* `agencyid` -- the unique internal identifier for this agency
* `agencycountrycode` -- the 2-letter ISO 3166 country code for the country
where the agency is located.
* `hi2address` -- the address of the HI2 handover on the agency side
* `hi2port` -- the port number for the HI2 handover on the agency side
* `hi3address` -- the address of the HI3 handover on the agency side
Expand Down
4 changes: 4 additions & 0 deletions doc/exampleconfigs/running-intercept-example.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ defaultradiususers:
agencies:

- agencyid: "Police" # id must be unique per agency
agencycountrycode: "NZ" # 2 letter country code (ISO 3166) matching the
# agency's jurisdiction
hi2address: 192.168.200.1 # address of the HI2 service at the agency
hi2port: 35530 # port number of the HI2 service at the agency
hi3address: 192.168.200.1 # address of the HI3 service at the agency
Expand All @@ -71,6 +73,8 @@ agencies:
# 30 seconds to avoid being disconnected

- agencyid: "Spooks" # id must be unique per agency
agencycountrycode: "NZ" # 2 letter country code (ISO 3166) matching the
# agency's jurisdiction
hi2address: 10.10.1.1 # address of the HI2 service at the agency
hi2port: 7001 # port number of the HI2 service at the agency
hi3address: 10.10.1.2 # address of the HI3 service at the agency
Expand Down
5 changes: 4 additions & 1 deletion rpm/openli.spec
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Name: openli
Version: 1.1.7
Version: 1.1.8
Release: 1%{?dist}
Summary: Software for performing ETSI-compliant lawful intercept

Expand Down Expand Up @@ -283,6 +283,9 @@ fi


%changelog
* Thu Jul 25 2024 Shane Alcock <[email protected]> - 1.1.8-1
- Updated for 1.1.8 release

* Tue Jul 23 2024 Shane Alcock <[email protected]> - 1.1.7-1
- Updated for 1.1.7 release

Expand Down
3 changes: 3 additions & 0 deletions src/agency.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ void free_liagency(liagency_t *lea) {
if (lea->agencyid) {
free(lea->agencyid);
}
if (lea->agencycc) {
free(lea->agencycc);
}
free(lea);
}

Expand Down
6 changes: 5 additions & 1 deletion src/agency.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ typedef struct liagency {
char *hi3_ipstr;
char *hi3_portstr;
char *agencyid;
char *agencycc;
uint32_t keepalivefreq;
uint32_t keepalivewait;
} liagency_t;
Expand All @@ -48,7 +49,10 @@ typedef struct liagency {
(strcmp(a->hi2_portstr, b->hi2_portstr) == 0) && \
(strcmp(a->hi3_ipstr, b->hi3_ipstr) == 0) && \
(strcmp(a->hi3_portstr, b->hi3_portstr) == 0) && \
(strcmp(a->agencyid, b->agencyid) == 0))
(strcmp(a->agencyid, b->agencyid) == 0) && \
((a->agencycc == NULL && b->agencycc == NULL) || \
(a->agencycc != NULL && b->agencycc != NULL && \
strcmp(a->agencycc, b->agencycc) == 0)))

#endif

Expand Down
18 changes: 17 additions & 1 deletion src/collector/collector_sync.c
Original file line number Diff line number Diff line change
Expand Up @@ -2000,6 +2000,7 @@ static inline int report_silent_logoffs(collector_sync_t *sync,
if (remove_session_ip(prev->session[i], &(prev->ip)) == 1) {
HASH_DELETE(hh, prev->owner[i]->sessions, prev->session[i]);
free_single_session(prev->session[i]);
prev->session[i] = NULL;
}
}
HASH_DELETE(hh, sync->activeips, prev);
Expand All @@ -2012,7 +2013,7 @@ static inline int report_silent_logoffs(collector_sync_t *sync,
static int add_ip_to_session_mapping(collector_sync_t *sync,
access_session_t *sess, internet_user_t *iuser) {

int i, replaced = 0;
int i, j, replaced = 0;
ip_to_session_t *prev;

prev = NULL;
Expand All @@ -2028,6 +2029,21 @@ static int add_ip_to_session_mapping(collector_sync_t *sync,
sizeof(internetaccess_ip_t), prev);

if (prev && prev->cin == sess->cin) {
int already = 0;
for (j = 0; j < prev->sessioncount; j++) {
if (prev->session[j] == sess) {
already = 1;
break;
}
}

/* This IP->session mapping is already known (somehow?),
* don't insert it twice because that can cause issues
* if we have to do a silent-logoff later on */
if (already) {
continue;
}

prev->session = realloc(prev->session,
(prev->sessioncount + 1) * sizeof(access_session_t *));
prev->owner = realloc(prev->owner,
Expand Down
4 changes: 0 additions & 4 deletions src/collector/collector_sync_voip.c
Original file line number Diff line number Diff line change
Expand Up @@ -1953,18 +1953,15 @@ static void sip_update_fast_path(collector_sync_voip_t *sync,
&(baseirimsg.data.ipmmiri.ipfamily)) != 0) {
handle_bad_sip_update(sync, &recvdpkt, 1,
SIP_PROCESSING_EXTRACTING_IPS);
trace_destroy_packet(recvdpkt);
return;
}

ret = parse_next_sip_message(sync->sipparser, NULL, NULL);
if (ret == 0) {
trace_destroy_packet(recvdpkt);
return;
}
if (ret < 0) {
handle_bad_sip_update(sync, &recvdpkt, 1, SIP_PROCESSING_PARSING);
trace_destroy_packet(recvdpkt);
return;

}
Expand Down Expand Up @@ -1997,7 +1994,6 @@ static void sip_update_slow_path(collector_sync_voip_t *sync,
&(baseirimsg.data.ipmmiri.ipfamily)) != 0) {
handle_bad_sip_update(sync, &recvdpkt, 1,
SIP_PROCESSING_EXTRACTING_IPS);
trace_destroy_packet(recvdpkt);
return;
}

Expand Down
10 changes: 10 additions & 0 deletions src/collector/sipparsing.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ static int parse_tcp_sip_packet(openli_sip_parser_t *p, libtrace_packet_t *pkt,
return -1;
}

/* Yet another keep alive pattern */
if (tcprem == 1 && memcmp(payload, "\x00", 1) == 0) {
return -1;
}

ret = update_tcp_reassemble_stream(stream, (uint8_t *)payload, tcprem,
ntohl(tcp->seq), pkt);

Expand Down Expand Up @@ -98,6 +103,11 @@ static int parse_udp_sip_packet(libtrace_udp_t *udp, uint32_t udprem) {
return -1;
}

/* Yet another keep alive pattern */
if (udprem == 1 && memcmp(payload, "\x00", 1) == 0) {
return -1;
}

/* eXosip keep alive */
if (udprem >= 4 && memcmp(payload, "\x6a\x61\x4b\x00", 4) == 0) {
return -1;
Expand Down
19 changes: 18 additions & 1 deletion src/configparser.c
Original file line number Diff line number Diff line change
Expand Up @@ -595,8 +595,9 @@ static int parse_agency_list(prov_intercept_conf_t *state, yaml_document_t *doc,
newag->hi3_ipstr = NULL;
newag->hi3_portstr = NULL;
newag->agencyid = NULL;
newag->agencycc = NULL;
newag->keepalivefreq = DEFAULT_AGENCY_KEEPALIVE_FREQ;
newag->keepalivewait = DEFAULT_AGENCY_KEEPALIVE_WAIT;
newag->keepalivewait = 0;

for (pair = node->data.mapping.pairs.start;
pair < node->data.mapping.pairs.top; pair ++) {
Expand Down Expand Up @@ -640,6 +641,13 @@ static int parse_agency_list(prov_intercept_conf_t *state, yaml_document_t *doc,
SET_CONFIG_STRING_OPTION(newag->agencyid, value);
}

if (key->type == YAML_SCALAR_NODE &&
value->type == YAML_SCALAR_NODE &&
strcmp((char *)key->data.scalar.value,
"agencycountrycode") == 0) {
SET_CONFIG_STRING_OPTION(newag->agencycc, value);
}

if (key->type == YAML_SCALAR_NODE &&
value->type == YAML_SCALAR_NODE &&
strcmp((char *)key->data.scalar.value,
Expand All @@ -664,6 +672,9 @@ static int parse_agency_list(prov_intercept_conf_t *state, yaml_document_t *doc,
logger(LOG_INFO,
"OpenLI: 'pcapdisk' is a reserved agencyid, please rename to something else.");
free(newag->agencyid);
if (newag->agencycc) {
free(newag->agencycc);
}
newag->agencyid = NULL;
}

Expand All @@ -684,6 +695,12 @@ static int parse_agency_list(prov_intercept_conf_t *state, yaml_document_t *doc,
strlen(prov_ag->ag->agencyid), prov_ag);

} else {
if (newag->agencyid) {
free(newag->agencyid);
}
if (newag->agencycc) {
free(newag->agencycc);
}
free(newag);
logger(LOG_INFO, "OpenLI: LEA configuration was incomplete -- skipping.");
}
Expand Down
35 changes: 26 additions & 9 deletions src/mediator/handover.c
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ void trigger_handover_ka_failure(handover_t *ho) {
* @return -1 if an error occurs, 0 otherwise
*/
int trigger_handover_keepalive(handover_t *ho, uint32_t mediator_id,
char *operator_id) {
char *operator_id, char *agency_cc) {

wandder_encoded_result_t *kamsg;
wandder_etsipshdr_data_t hdrdata;
Expand Down Expand Up @@ -237,17 +237,30 @@ int trigger_handover_keepalive(handover_t *ho, uint32_t mediator_id,
/* Include the OpenLI version in the LIID field, so the LEAs can
* identify which version of the software is being used by the
* sender.
*
* PACKAGE_NAME and PACKAGE_VERSION come from config.h
*/
/* PACKAGE_NAME and PACKAGE_VERSION come from config.h */
snprintf(liidstring, 24, "%s-%s", PACKAGE_NAME, PACKAGE_VERSION);
if (agency_cc && strlen(agency_cc) == 2) {
hdrdata.delivcc = agency_cc;
hdrdata.authcc = agency_cc;
} else {
hdrdata.delivcc = "--";
hdrdata.authcc = "--";
}
hdrdata.delivcc_len = strlen(hdrdata.delivcc);
hdrdata.authcc_len = strlen(hdrdata.authcc);

/* Netherlands has a specific rule regarding the content of the
* LIID within keepalives
*/
if (agency_cc && strcmp(agency_cc, "NL")==0) {
snprintf(liidstring, 2, "-");
} else {
snprintf(liidstring, 24, "%s-%s", PACKAGE_NAME, PACKAGE_VERSION);
}
hdrdata.liid = liidstring;
hdrdata.liid_len = strlen(hdrdata.liid);

hdrdata.authcc = "NA";
hdrdata.authcc_len = strlen(hdrdata.authcc);
hdrdata.delivcc = "NA";
hdrdata.delivcc_len = strlen(hdrdata.delivcc);

if (operator_id) {
hdrdata.operatorid = operator_id;
} else {
Expand All @@ -256,7 +269,11 @@ int trigger_handover_keepalive(handover_t *ho, uint32_t mediator_id,
hdrdata.operatorid_len = strlen(hdrdata.operatorid);

/* Stupid 16 character limit... */
snprintf(elemstring, 16, "med-%u", mediator_id);
if (agency_cc && strcmp(agency_cc, "NL")==0) {
snprintf(elemstring, 16, "%u", mediator_id);
} else {
snprintf(elemstring, 16, "med-%u", mediator_id);
}
hdrdata.networkelemid = elemstring;
hdrdata.networkelemid_len = strlen(hdrdata.networkelemid);

Expand Down
3 changes: 2 additions & 1 deletion src/mediator/handover.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ typedef struct handover {

typedef struct mediator_agency {
char *agencyid;
char *agencycc;
int awaitingconfirm;
int disabled;
int disabled_msg;
Expand Down Expand Up @@ -135,7 +136,7 @@ void trigger_handover_ka_failure(handover_t *ho);
* @return -1 if an error occurs, 0 otherwise
*/
int trigger_handover_keepalive(handover_t *ho, uint32_t mediator_id,
char *operator_id);
char *operator_id, char *agency_cc);

/** Disconnects a single mediator handover connection to an LEA.
*
Expand Down
14 changes: 13 additions & 1 deletion src/mediator/lea_send_thread.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,11 @@ static void init_mediator_agency(mediator_agency_t *agency,

agency->awaitingconfirm = 0;
agency->agencyid = strdup(fromprov->agencyid);
if (fromprov->agencycc) {
agency->agencycc = strdup(fromprov->agencycc);
} else {
agency->agencycc = NULL;
}
agency->disabled = 0;
agency->disabled_msg = 0;
agency->hi2 = create_new_handover(epollfd, fromprov->hi2_ipstr,
Expand Down Expand Up @@ -207,6 +212,12 @@ static void update_agency_handovers(mediator_agency_t *currag,

}

if (currag->agencycc) {
free(currag->agencycc);
}
currag->agencycc = newag->agencycc;
newag->agencycc = NULL;

if (currag->hi3 == NULL || currag->hi3->ipstr == NULL ||
currag->hi3->portstr == NULL) {
currag->hi3 = create_new_handover(epollfd, newag->hi3_ipstr,
Expand Down Expand Up @@ -494,7 +505,7 @@ static int agency_thread_epoll_event(lea_thread_state_t *state,
/* we are due to send a keep alive */
ho = (handover_t *)(mev->state);
trigger_handover_keepalive(ho, state->mediator_id,
state->operator_id);
state->operator_id, state->agency.agencycc);
ret = 0;
break;
case MED_EPOLL_KA_RESPONSE_TIMER:
Expand Down Expand Up @@ -1111,6 +1122,7 @@ void destroy_agency_thread_state(lea_thread_state_t *state) {
}
purge_liid_map(&(state->active_liids));
free(state->agencyid);

close(state->epoll_fd);
}

Expand Down
Loading

0 comments on commit 1e3790a

Please sign in to comment.