diff --git a/secipd.c b/secipd.c index 19f6c2b..d205bd1 100644 --- a/secipd.c +++ b/secipd.c @@ -15,9 +15,11 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ +#include + #include "includes.h" #include "build/ndr_secip.h" -#include +#include "siahs.h" /* FIXME Does not handle multiple connections.. should be per connection obviously!! */ static uint8_t global_aes_key[16]; @@ -53,7 +55,7 @@ static STATUS send_ppk_com(TALLOC_CTX *mem_ctx, int sock, struct sockaddr_in fro mpz_export(&ppk_com->msg.ppk_com.rsa_key, &count, -1, 1, -1, 0, conf->public_key->n); DEBUG(0, "RSA Words written: %u", count); - printf("%s\n", ndr_print_struct_string(pkt,(ndr_print_fn_t)ndr_print_secip_packet, "ppk_com packet", ppk_com)); + DEBUG(9, "%s", ndr_print_struct_string(pkt,(ndr_print_fn_t)ndr_print_secip_packet, "ppk_com packet", ppk_com)); ndr_err = ndr_push_struct_blob(&raw_pkt, ppk_com, ppk_com, (ndr_push_flags_fn_t)ndr_push_secip_packet); @@ -110,7 +112,7 @@ static STATUS send_arc_enc(TALLOC_CTX *mem_ctx, int sock, struct sockaddr_in fro arc_enc->msg.arc_enc.padding[i] = rand(); } - printf("%s\n", ndr_print_struct_string(mem_ctx, (ndr_print_fn_t)ndr_print_secip_packet, "arc_enc packet", arc_enc)); + DEBUG(9, "%s", ndr_print_struct_string(mem_ctx, (ndr_print_fn_t)ndr_print_secip_packet, "arc_enc packet", arc_enc)); ndr_err = ndr_push_struct_blob(&raw_pkt, arc_enc, arc_enc, (ndr_push_flags_fn_t)ndr_push_secip_packet); @@ -170,7 +172,7 @@ static STATUS send_psup_resp(TALLOC_CTX *mem_ctx, int sock, struct sockaddr_in f psup_resp->msg.psup_resp.padding[i] = rand(); } - printf("%s\n", ndr_print_struct_string(mem_ctx, (ndr_print_fn_t)ndr_print_secip_packet, "psup_resp packet", psup_resp)); + DEBUG(9, "%s", ndr_print_struct_string(mem_ctx, (ndr_print_fn_t)ndr_print_secip_packet, "psup_resp packet", psup_resp)); ndr_err = ndr_push_struct_blob(&raw_pkt, psup_resp, psup_resp, (ndr_push_flags_fn_t)ndr_push_secip_packet); @@ -229,7 +231,7 @@ static STATUS send_pathcheck_resp(TALLOC_CTX *mem_ctx, int sock, struct sockaddr pathcheck_resp->msg.pathcheck_resp.padding[i] = rand(); } - printf("%s\n", ndr_print_struct_string(mem_ctx, (ndr_print_fn_t)ndr_print_secip_packet, "pathcheck_resp packet", pathcheck_resp)); + DEBUG(9, "%s", ndr_print_struct_string(mem_ctx, (ndr_print_fn_t)ndr_print_secip_packet, "pathcheck_resp packet", pathcheck_resp)); ndr_err = ndr_push_struct_blob(&raw_pkt, pathcheck_resp, pathcheck_resp, (ndr_push_flags_fn_t)ndr_push_secip_packet); @@ -268,10 +270,16 @@ static STATUS send_alarm_ack(TALLOC_CTX *mem_ctx, int sock, struct sockaddr_in f enum ndr_err_code ndr_err; struct aes_ctx aes; int i, n; + char *message; /* FIXME DEATH TO THE GLOBALS! */ aes_set_encrypt_key(&aes, 16, global_aes_key); + message = talloc_strndup(pkt, (char *)pkt->msg.alarm.message, pkt->msg.alarm.length); + DEBUG(0, "Got message: %s", message); + + /* FIXME Hardcoded prom */ + parse_siahs_message(pkt, "1337", message); comm_pkt = talloc(mem_ctx, struct secip_comm_packet); @@ -288,7 +296,7 @@ static STATUS send_alarm_ack(TALLOC_CTX *mem_ctx, int sock, struct sockaddr_in f alarm_ack->msg.alarm_ack.padding[i] = rand(); } - printf("%s\n", ndr_print_struct_string(mem_ctx, (ndr_print_fn_t)ndr_print_secip_packet, "alarm_ack packet", alarm_ack)); + DEBUG(9, "%s\n", ndr_print_struct_string(mem_ctx, (ndr_print_fn_t)ndr_print_secip_packet, "alarm_ack packet", alarm_ack)); ndr_err = ndr_push_struct_blob(&raw_pkt, alarm_ack, alarm_ack, (ndr_push_flags_fn_t)ndr_push_secip_packet); @@ -347,7 +355,7 @@ static STATUS send_poll_ack(TALLOC_CTX *mem_ctx, int sock, struct sockaddr_in fr poll_ack->msg.poll_ack.padding[i] = rand(); } - printf("%s\n", ndr_print_struct_string(mem_ctx, (ndr_print_fn_t)ndr_print_secip_packet, "poll_ack packet", poll_ack)); + DEBUG(9, "%s", ndr_print_struct_string(mem_ctx, (ndr_print_fn_t)ndr_print_secip_packet, "poll_ack packet", poll_ack)); ndr_err = ndr_push_struct_blob(&raw_pkt, poll_ack, poll_ack, (ndr_push_flags_fn_t)ndr_push_secip_packet); @@ -547,7 +555,7 @@ int main (int argc, char **argv) { if (ndr_err != NDR_ERR_SUCCESS) { DEBUG(0, "Could not parse this CRC packet"); } - printf("%s\n", ndr_print_struct_string(setup_pkt,(ndr_print_fn_t)ndr_print_secip_setup_packet, "setup packet", setup_pkt)); + DEBUG(10, "%s", ndr_print_struct_string(setup_pkt,(ndr_print_fn_t)ndr_print_secip_setup_packet, "setup packet", setup_pkt)); } else if (data.length > 128) { comm_pkt = talloc(pkt, struct secip_comm_packet); ndr_err = ndr_pull_struct_blob_all(&data, pkt, comm_pkt, (ndr_pull_flags_fn_t)ndr_pull_secip_comm_packet); @@ -555,7 +563,7 @@ int main (int argc, char **argv) { if (ndr_err != NDR_ERR_SUCCESS) { DEBUG(0, "Could not parse this CRC packet"); } - printf("%s\n", ndr_print_struct_string(comm_pkt,(ndr_print_fn_t)ndr_print_secip_comm_packet, "comm packet", comm_pkt)); + DEBUG(10, "%s", ndr_print_struct_string(comm_pkt,(ndr_print_fn_t)ndr_print_secip_comm_packet, "comm packet", comm_pkt)); } ndr_err = ndr_pull_struct_blob_all(&data, pkt, pkt, (ndr_pull_flags_fn_t)ndr_pull_secip_packet); @@ -563,7 +571,7 @@ int main (int argc, char **argv) { if (ndr_err != NDR_ERR_SUCCESS) { DEBUG(0, "Could not parse this packet"); } - printf("%s\n", ndr_print_struct_string(pkt,(ndr_print_fn_t)ndr_print_secip_packet, "packet", pkt)); + DEBUG(9, "%s", ndr_print_struct_string(pkt,(ndr_print_fn_t)ndr_print_secip_packet, "packet", pkt)); DEBUG(0, "%x %x %x", pkt->connection_id, pkt->message_id, pkt->sequence_number); diff --git a/siahs.c b/siahs.c new file mode 100644 index 0000000..e0c6a31 --- /dev/null +++ b/siahs.c @@ -0,0 +1,71 @@ +/* + SIA-HS Alarm Monitoring Service + Copyright (C) Wilco Baan Hofman 2012 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ +#include "includes.h" + +/* + * parse_message parses the string portion of the SIA-HS message + * and writes the event to the database. + * It returns nothing. + */ +STATUS parse_siahs_message(TALLOC_CTX *mem_ctx, const char *pkt_prom, const char *orig_message) { + char *message = talloc_strdup(mem_ctx, orig_message); + char *ptr = message; + char *prom = ptr; + char *code; + const configuration *conf = get_conf(); + uint8_t i; + + NO_MEM_RETURN(message); + + /* Grab the first part, the prom */ + while (*ptr != '\0' && *ptr != 'N') { + ptr++; + } + *ptr++ = '\0'; + + /* Grab the second part, SIA code */ + code = ptr; + while (*ptr != '\0' && *ptr != ',') { + ptr++; + } + if (*ptr != '\0') *ptr++ = '\0'; + + /* The remaining ptr contains the human readable description string */ + + if (strcmp(pkt_prom, prom) != 0) { + return ST_ASSERTION_FAILED; + } + + /* Ignore alive! messages */ + if (strcmp(code, "alive!") == 0) { + DEBUG(2, "Got keepalive packet from prom %s", prom); + /* FIXME We must update some keepalive status somewhere to generate offline messages */ + return ST_OK; + } + + /* Dispatch all configured event handlers */ + for (i = 0; conf->event_handlers[i] != NULL; i++) { + conf->event_handlers[i](message, prom, code, ptr); + } + + talloc_free(message); + + return ST_OK; +} + + diff --git a/siahs.h b/siahs.h index e15f894..7da3f0b 100644 --- a/siahs.h +++ b/siahs.h @@ -64,3 +64,4 @@ const uint8_t xor_table[] = { 0x51, 0x7a, 0x26, 0x3d, 0x22, 0x21, 0x3b, 0x74, 0x3b, 0x3d, 0x26, 0x74, 0x27, 0x3b, 0x74, 0x27, 0x3b, 0x30, 0x3b, 0x00, 0xaa, 0x11, 0x46, 0x54, }; +STATUS parse_siahs_message(TALLOC_CTX *mem_ctx, const char *pkt_prom, const char *message); diff --git a/siahsd.c b/siahsd.c index 8375609..4b64a22 100644 --- a/siahsd.c +++ b/siahsd.c @@ -29,72 +29,13 @@ */ -/* - * parse_message parses the string portion of the SIA-HS message - * and writes the event to the database. - * It returns nothing. - */ -STATUS parse_message(TALLOC_CTX *mem_ctx, struct siahs_packet *pkt) { - char *message = talloc_strdup(mem_ctx, pkt->message + strlen("MESSAGE ")); - char *ptr = message; - char *prom = ptr; - char *pkt_prom; - char *code; - const configuration *conf = get_conf(); - uint8_t i; - - NO_MEM_RETURN(message); - - /* Grab the first part, the prom */ - while (*ptr != '\0' && *ptr != 'N') { - ptr++; - } - *ptr++ = '\0'; - - /* Grab the second part, SIA code */ - code = ptr; - while (*ptr != '\0' && *ptr != ',') { - ptr++; - } - if (*ptr != '\0') *ptr++ = '\0'; - - /* The remaining ptr contains the human readable description string */ - - /* Assert that string prom is identical to hex representation of pkt->prom */ - pkt_prom = talloc_asprintf(message, "%04x", pkt->prom); - - NO_MEM_RETURN(pkt_prom); - - if (strcmp(pkt_prom, prom) != 0) { - return ST_ASSERTION_FAILED; - } - - - /* Ignore alive! messages */ - if (strcmp(code, "alive!") == 0) { - DEBUG(2, "Got keepalive packet from prom %s", prom); - /* FIXME We must update some keepalive status somewhere to generate offline messages */ - return ST_OK; - } - - /* Dispatch all configured event handlers */ - for (i = 0; conf->event_handlers[i] != NULL; i++) { - conf->event_handlers[i](message, prom, code, ptr); - } - - talloc_free(message); - - return ST_OK; -} - - /* * send_reply sends a reply to a SIA-HS transmitter * It requires a memory context, the socket from which to reply, the socket address to reply to, the original packet * and a string with the reply message. * It returns nothing. */ -STATUS send_reply(TALLOC_CTX *mem_ctx, int sock, struct sockaddr_in from, struct siahs_packet *pkt, const char *string) { +static STATUS send_reply(TALLOC_CTX *mem_ctx, int sock, struct sockaddr_in from, struct siahs_packet *pkt, const char *string) { int n; uint8_t *reply; int i; @@ -302,9 +243,11 @@ int main(int argc, char **argv) { } else if (strncmp(pkt->message, "MESSAGE ", strlen("MESSAGE ")) == 0) { + char *pkt_prom; send_reply(pkt, sock, from, pkt, "ACKNOWLEDGE MESSAGE"); - parse_message(pkt, pkt); + pkt_prom = talloc_asprintf(pkt, "%04x", pkt->prom); + parse_siahs_message(pkt, pkt_prom, pkt->message + strlen("MESSAGE ")); } else { DEBUG(0, "Could not parse this message:\n" diff --git a/wscript b/wscript index bf00201..6de21a2 100644 --- a/wscript +++ b/wscript @@ -92,17 +92,18 @@ def build(bld): bld.stlib(source="status.c", target="status", use='glib-2.0') bld.stlib(source="config.c", target="config", use='glib-2.0 database jsonbot') bld.stlib(source="sia.c", target="sia", use='glib-2.0') + bld.stlib(source="siahs.c", target="siahs", use='glib-2.0') bld.stlib(source="jsonbot.c", target="jsonbot", use='glib-2.0') bld.program( source = 'siahsd.c', target = 'siahsd', - use = [ 'database', 'config', 'status', 'sia', 'jsonbot', 'dbi', 'talloc','glib-2.0', 'nettle' ]) + use = [ 'database', 'config', 'status', 'sia', 'siahs', 'jsonbot', 'dbi', 'talloc','glib-2.0', 'nettle' ]) bld.program( source = 'secip.idl secipd.c crc16.c', target = 'secipd', - use = [ 'database', 'config', 'status', 'sia', 'jsonbot', 'dbi', 'talloc','glib-2.0', 'nettle', 'ndr' ]) + use = [ 'database', 'config', 'status', 'sia', 'siahs', 'jsonbot', 'dbi', 'talloc','glib-2.0', 'nettle', 'ndr' ]) pass def clean(ctx):