Fix rest of SecIP protocol. Protocol is now fully implemented.

Note that there is no monitoring implemented yet, just the protocol basics.
This commit is contained in:
Wilco Baan Hofman 2012-10-07 20:46:44 +02:00
parent fec14af688
commit 24c1286e5f
2 changed files with 310 additions and 8 deletions

View file

@ -29,10 +29,21 @@ interface secip
SECIP_MSG_PPK_REP = 0x82, SECIP_MSG_PPK_REP = 0x82,
SECIP_MSG_PATH_SUPERVISION_REQUEST = 0x10, SECIP_MSG_PATH_SUPERVISION_REQUEST = 0x10,
SECIP_MSG_PATH_SUPERVISION_RESPONSE = 0x90, SECIP_MSG_PATH_SUPERVISION_RESPONSE = 0x90,
SECIP_MSG_PATH_CHECK_REQUEST = 0x20,
SECIP_MSG_PATH_CHECK_RESPONSE = 0xA0,
SECIP_MSG_POLL_MESSAGE = 0x11, SECIP_MSG_POLL_MESSAGE = 0x11,
SECIP_MSG_POLL_ACKNOWLEDGE = 0x91 SECIP_MSG_POLL_ACKNOWLEDGE = 0x91,
SECIP_MSG_ALARM = 0x30,
SECIP_MSG_ALARM_ACKNOWLEDGE = 0xB0
} secip_message; } secip_message;
typedef [public,enum8bit] enum {
SECIP_PROTO_SIA = 0x01,
SECIP_PROTO_CONTACTID = 0x02,
SECIP_PROTO_SCANCOM = 0x03,
SECIP_PROTO_SIAHS = 0x04
} secip_protocol;
typedef [public,flag(LIBNDR_FLAG_NOALIGN)] struct { typedef [public,flag(LIBNDR_FLAG_NOALIGN)] struct {
[value(0)] uint16 session_id; [value(0)] uint16 session_id;
uint8 padding[202]; uint8 padding[202];
@ -73,12 +84,58 @@ interface secip
uint8 padding[70]; uint8 padding[70];
} secip_psup_req; } secip_psup_req;
typedef [public,flag(LIBNDR_FLAG_NOALIGN)] struct {
secip_error error_code;
uint16 path_id;
uint32 interval_seconds;
uint8 padding[69];
} secip_psup_resp;
typedef [public,flag(LIBNDR_FLAG_NOALIGN)] struct {
uint8 padding[76];
} secip_pathcheck_req;
typedef [public,flag(LIBNDR_FLAG_NOALIGN)] struct {
secip_error error_code;
uint8 path_check_id;
uint8 padding[74];
} secip_pathcheck_resp;
typedef [public,flag(LIBNDR_FLAG_NOALIGN)] struct {
secip_protocol protocol_identifier;
[range(0,97)] uint8 length;
int8 message[length];
} secip_alarm;
typedef [public,flag(LIBNDR_FLAG_NOALIGN)] struct {
secip_error error_code;
uint8 padding[75];
} secip_alarm_ack;
typedef [public,flag(LIBNDR_FLAG_NOALIGN)] struct {
uint16 path_check_id;
uint8 padding[74];
} secip_poll_message;
typedef [public,flag(LIBNDR_FLAG_NOALIGN)] struct {
secip_error error_code;
uint16 path_check_id;
uint8 padding[73];
} secip_poll_ack;
typedef [nodiscriminant,public,flag(LIBNDR_FLAG_NOALIGN)] union { typedef [nodiscriminant,public,flag(LIBNDR_FLAG_NOALIGN)] union {
[case(SECIP_MSG_ATE_ENC)] secip_ate_enc ate_enc; [case(SECIP_MSG_ATE_ENC)] secip_ate_enc ate_enc;
[case(SECIP_MSG_PPK_COM)] secip_ppk_com ppk_com; [case(SECIP_MSG_PPK_COM)] secip_ppk_com ppk_com;
[case(SECIP_MSG_PPK_REP)] secip_ppk_rep ppk_rep; [case(SECIP_MSG_PPK_REP)] secip_ppk_rep ppk_rep;
[case(SECIP_MSG_ARC_ENC)] secip_arc_enc arc_enc; [case(SECIP_MSG_ARC_ENC)] secip_arc_enc arc_enc;
[case(SECIP_MSG_PATH_SUPERVISION_REQUEST)] secip_psup_req psup_req; [case(SECIP_MSG_PATH_SUPERVISION_REQUEST)] secip_psup_req psup_req;
[case(SECIP_MSG_PATH_SUPERVISION_RESPONSE)] secip_psup_resp psup_resp;
[case(SECIP_MSG_PATH_CHECK_REQUEST)] secip_pathcheck_req pathcheck_req;
[case(SECIP_MSG_PATH_CHECK_RESPONSE)] secip_pathcheck_resp pathcheck_resp;
[case(SECIP_MSG_ALARM)] secip_alarm alarm;
[case(SECIP_MSG_ALARM_ACKNOWLEDGE)] secip_alarm_ack alarm_ack;
[case(SECIP_MSG_POLL_MESSAGE)] secip_poll_message poll_message;
[case(SECIP_MSG_POLL_ACKNOWLEDGE)] secip_poll_ack poll_ack;
} secip_msg_union; } secip_msg_union;
typedef [public,flag(LIBNDR_FLAG_NOALIGN)] struct { typedef [public,flag(LIBNDR_FLAG_NOALIGN)] struct {

259
secipd.c
View file

@ -37,7 +37,7 @@ static STATUS send_ppk_com(TALLOC_CTX *mem_ctx, int sock, struct sockaddr_in fro
ppk_com = talloc(setup_pkt, struct secip_packet); ppk_com = talloc(setup_pkt, struct secip_packet);
ppk_com->pad = 0; ppk_com->pad = 0;
ppk_com->connection_id = 0x1337; ppk_com->connection_id = 0x1337; /* FIXME */
ppk_com->message_id = SECIP_MSG_PPK_COM; ppk_com->message_id = SECIP_MSG_PPK_COM;
ppk_com->sequence_number = 1; ppk_com->sequence_number = 1;
ppk_com->msg.ppk_com.session_id = 0; ppk_com->msg.ppk_com.session_id = 0;
@ -98,7 +98,8 @@ static STATUS send_arc_enc(TALLOC_CTX *mem_ctx, int sock, struct sockaddr_in fro
arc_enc = talloc_zero(setup_pkt, struct secip_packet); arc_enc = talloc_zero(setup_pkt, struct secip_packet);
arc_enc->pad = 0; arc_enc->pad = 0;
arc_enc->connection_id = 0x1337; arc_enc->connection_id = 0x1337; /* FIXME */
memcpy(arc_enc->device_id, "Bitlair SecIPd!", 16);
arc_enc->message_id = SECIP_MSG_ARC_ENC; arc_enc->message_id = SECIP_MSG_ARC_ENC;
arc_enc->sequence_number = 2; arc_enc->sequence_number = 2;
@ -141,7 +142,244 @@ static STATUS send_arc_enc(TALLOC_CTX *mem_ctx, int sock, struct sockaddr_in fro
return ST_OK; return ST_OK;
} }
DATA_BLOB decrypt_setup_packet(TALLOC_CTX *mem_ctx, DATA_BLOB encrypted_blob) { static STATUS send_psup_resp(TALLOC_CTX *mem_ctx, int sock, struct sockaddr_in from, struct secip_packet *pkt) {
DATA_BLOB raw_pkt, raw_comm_pkt, crypted_comm_pkt;
struct secip_comm_packet *comm_pkt;
struct secip_packet *psup_resp;
enum ndr_err_code ndr_err;
struct aes_ctx aes;
int i, n;
/* FIXME DEATH TO THE GLOBALS! */
aes_set_encrypt_key(&aes, 16, global_aes_key);
comm_pkt = talloc(mem_ctx, struct secip_comm_packet);
psup_resp = talloc_zero(comm_pkt, struct secip_packet);
psup_resp->pad = 0;
psup_resp->connection_id = 0x1337; /* FIXME */
memcpy(psup_resp->device_id, "Bitlair SecIPd!", 16);
psup_resp->message_id = SECIP_MSG_PATH_SUPERVISION_RESPONSE;
psup_resp->sequence_number = pkt->sequence_number;
psup_resp->msg.psup_resp.error_code = SECIP_ERR_SUCCESS; /* FIXME: Make sure we actually supervise */
psup_resp->msg.psup_resp.path_id = pkt->msg.psup_req.path_id;
psup_resp->msg.psup_resp.interval_seconds = pkt->msg.psup_req.interval_seconds;
for (i = 0; i < 69; i++) {
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));
ndr_err = ndr_push_struct_blob(&raw_pkt, psup_resp, psup_resp, (ndr_push_flags_fn_t)ndr_push_secip_packet);
if (ndr_err != NDR_ERR_SUCCESS) {
DEBUG(0, "Oh holy shitstorm! That didn't work!");
return ST_GENERAL_FAILURE;
}
memcpy(comm_pkt->raw_packet, raw_pkt.data, raw_pkt.length);
for (i = 0; i < 30; i++) {
comm_pkt->padding[i] = rand();
}
ndr_err = ndr_push_struct_blob(&raw_comm_pkt, comm_pkt, comm_pkt, (ndr_push_flags_fn_t)ndr_push_secip_comm_packet);
if (ndr_err != NDR_ERR_SUCCESS) {
DEBUG(0, "Oh holy shitstorm! That didn't work!");
return ST_GENERAL_FAILURE;
}
crypted_comm_pkt.data = talloc_zero_array(mem_ctx, uint8_t, 258);
crypted_comm_pkt.length = 130;
memcpy(crypted_comm_pkt.data, raw_comm_pkt.data, 2);
aes_encrypt(&aes, raw_comm_pkt.length-2, crypted_comm_pkt.data+2, raw_comm_pkt.data+2);
n = sendto(sock, crypted_comm_pkt.data, crypted_comm_pkt.length, 0, (struct sockaddr *)&from, sizeof(from));
return ST_OK;
}
static STATUS send_pathcheck_resp(TALLOC_CTX *mem_ctx, int sock, struct sockaddr_in from, struct secip_packet *pkt) {
DATA_BLOB raw_pkt, raw_comm_pkt, crypted_comm_pkt;
struct secip_comm_packet *comm_pkt;
struct secip_packet *pathcheck_resp;
enum ndr_err_code ndr_err;
struct aes_ctx aes;
int i, n;
/* FIXME DEATH TO THE GLOBALS! */
aes_set_encrypt_key(&aes, 16, global_aes_key);
comm_pkt = talloc(mem_ctx, struct secip_comm_packet);
pathcheck_resp = talloc_zero(comm_pkt, struct secip_packet);
pathcheck_resp->pad = 0;
pathcheck_resp->connection_id = 0x1337; /* FIXME */
memcpy(pathcheck_resp->device_id, "Bitlair SecIPd!", 16);
pathcheck_resp->message_id = SECIP_MSG_PATH_SUPERVISION_RESPONSE;
pathcheck_resp->sequence_number = pkt->sequence_number;
pathcheck_resp->msg.pathcheck_resp.error_code = SECIP_ERR_PATHCHECK_NOT_SUPPORTED; /* FIXME */
for (i = 0; i < 74; i++) {
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));
ndr_err = ndr_push_struct_blob(&raw_pkt, pathcheck_resp, pathcheck_resp, (ndr_push_flags_fn_t)ndr_push_secip_packet);
if (ndr_err != NDR_ERR_SUCCESS) {
DEBUG(0, "Oh holy shitstorm! That didn't work!");
return ST_GENERAL_FAILURE;
}
memcpy(comm_pkt->raw_packet, raw_pkt.data, raw_pkt.length);
for (i = 0; i < 30; i++) {
comm_pkt->padding[i] = rand();
}
ndr_err = ndr_push_struct_blob(&raw_comm_pkt, comm_pkt, comm_pkt, (ndr_push_flags_fn_t)ndr_push_secip_comm_packet);
if (ndr_err != NDR_ERR_SUCCESS) {
DEBUG(0, "Oh holy shitstorm! That didn't work!");
return ST_GENERAL_FAILURE;
}
crypted_comm_pkt.data = talloc_zero_array(mem_ctx, uint8_t, 258);
crypted_comm_pkt.length = 130;
memcpy(crypted_comm_pkt.data, raw_comm_pkt.data, 2);
aes_encrypt(&aes, raw_comm_pkt.length-2, crypted_comm_pkt.data+2, raw_comm_pkt.data+2);
n = sendto(sock, crypted_comm_pkt.data, crypted_comm_pkt.length, 0, (struct sockaddr *)&from, sizeof(from));
return ST_OK;
}
static STATUS send_alarm_ack(TALLOC_CTX *mem_ctx, int sock, struct sockaddr_in from, struct secip_packet *pkt) {
DATA_BLOB raw_pkt, raw_comm_pkt, crypted_comm_pkt;
struct secip_comm_packet *comm_pkt;
struct secip_packet *alarm_ack;
enum ndr_err_code ndr_err;
struct aes_ctx aes;
int i, n;
/* FIXME DEATH TO THE GLOBALS! */
aes_set_encrypt_key(&aes, 16, global_aes_key);
comm_pkt = talloc(mem_ctx, struct secip_comm_packet);
alarm_ack = talloc_zero(comm_pkt, struct secip_packet);
alarm_ack->pad = 0;
alarm_ack->connection_id = 0x1337; /* FIXME */
memcpy(alarm_ack->device_id, "Bitlair SecIPd!", 16);
alarm_ack->message_id = SECIP_MSG_ALARM_ACKNOWLEDGE;
alarm_ack->sequence_number = pkt->sequence_number;
alarm_ack->msg.alarm_ack.error_code = SECIP_ERR_ACKNOWLEDGE;
for (i = 0; i < 75; i++) {
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));
ndr_err = ndr_push_struct_blob(&raw_pkt, alarm_ack, alarm_ack, (ndr_push_flags_fn_t)ndr_push_secip_packet);
if (ndr_err != NDR_ERR_SUCCESS) {
DEBUG(0, "Oh holy shitstorm! That didn't work!");
return ST_GENERAL_FAILURE;
}
memcpy(comm_pkt->raw_packet, raw_pkt.data, raw_pkt.length);
for (i = 0; i < 30; i++) {
comm_pkt->padding[i] = rand();
}
ndr_err = ndr_push_struct_blob(&raw_comm_pkt, comm_pkt, comm_pkt, (ndr_push_flags_fn_t)ndr_push_secip_comm_packet);
if (ndr_err != NDR_ERR_SUCCESS) {
DEBUG(0, "Oh holy shitstorm! That didn't work!");
return ST_GENERAL_FAILURE;
}
crypted_comm_pkt.data = talloc_zero_array(mem_ctx, uint8_t, 258);
crypted_comm_pkt.length = 130;
memcpy(crypted_comm_pkt.data, raw_comm_pkt.data, 2);
aes_encrypt(&aes, raw_comm_pkt.length-2, crypted_comm_pkt.data+2, raw_comm_pkt.data+2);
n = sendto(sock, crypted_comm_pkt.data, crypted_comm_pkt.length, 0, (struct sockaddr *)&from, sizeof(from));
return ST_OK;
}
static STATUS send_poll_ack(TALLOC_CTX *mem_ctx, int sock, struct sockaddr_in from, struct secip_packet *pkt) {
DATA_BLOB raw_pkt, raw_comm_pkt, crypted_comm_pkt;
struct secip_comm_packet *comm_pkt;
struct secip_packet *poll_ack;
enum ndr_err_code ndr_err;
struct aes_ctx aes;
int i, n;
/* FIXME DEATH TO THE GLOBALS! */
aes_set_encrypt_key(&aes, 16, global_aes_key);
comm_pkt = talloc(mem_ctx, struct secip_comm_packet);
poll_ack = talloc_zero(comm_pkt, struct secip_packet);
poll_ack->pad = 0;
poll_ack->connection_id = 0x1337; /* FIXME */
memcpy(poll_ack->device_id, "Bitlair SecIPd!", 16);
poll_ack->message_id = SECIP_MSG_PATH_SUPERVISION_RESPONSE;
poll_ack->sequence_number = pkt->sequence_number;
poll_ack->msg.pathcheck_resp.error_code = SECIP_ERR_SUCCESS; /* FIXME */
for (i = 0; i < 73; i++) {
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));
ndr_err = ndr_push_struct_blob(&raw_pkt, poll_ack, poll_ack, (ndr_push_flags_fn_t)ndr_push_secip_packet);
if (ndr_err != NDR_ERR_SUCCESS) {
DEBUG(0, "Oh holy shitstorm! That didn't work!");
return ST_GENERAL_FAILURE;
}
memcpy(comm_pkt->raw_packet, raw_pkt.data, raw_pkt.length);
for (i = 0; i < 30; i++) {
comm_pkt->padding[i] = rand();
}
ndr_err = ndr_push_struct_blob(&raw_comm_pkt, comm_pkt, comm_pkt, (ndr_push_flags_fn_t)ndr_push_secip_comm_packet);
if (ndr_err != NDR_ERR_SUCCESS) {
DEBUG(0, "Oh holy shitstorm! That didn't work!");
return ST_GENERAL_FAILURE;
}
crypted_comm_pkt.data = talloc_zero_array(mem_ctx, uint8_t, 258);
crypted_comm_pkt.length = 130;
memcpy(crypted_comm_pkt.data, raw_comm_pkt.data, 2);
aes_encrypt(&aes, raw_comm_pkt.length-2, crypted_comm_pkt.data+2, raw_comm_pkt.data+2);
n = sendto(sock, crypted_comm_pkt.data, crypted_comm_pkt.length, 0, (struct sockaddr *)&from, sizeof(from));
return ST_OK;
}
static DATA_BLOB decrypt_setup_packet(TALLOC_CTX *mem_ctx, DATA_BLOB encrypted_blob) {
const configuration *conf = get_conf(); const configuration *conf = get_conf();
mpz_t encrypted_data; mpz_t encrypted_data;
mpz_t decrypted_data; mpz_t decrypted_data;
@ -171,7 +409,7 @@ DATA_BLOB decrypt_setup_packet(TALLOC_CTX *mem_ctx, DATA_BLOB encrypted_blob) {
return decrypted_blob; return decrypted_blob;
} }
DATA_BLOB decrypt_aes_packet(TALLOC_CTX *mem_ctx, DATA_BLOB encrypted_blob) { static DATA_BLOB decrypt_aes_packet(TALLOC_CTX *mem_ctx, DATA_BLOB encrypted_blob) {
static DATA_BLOB ret; static DATA_BLOB ret;
struct aes_ctx aes; struct aes_ctx aes;
@ -328,12 +566,19 @@ int main (int argc, char **argv) {
printf("%s\n", ndr_print_struct_string(pkt,(ndr_print_fn_t)ndr_print_secip_packet, "packet", pkt)); printf("%s\n", 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); DEBUG(0, "%x %x %x", pkt->connection_id, pkt->message_id, pkt->sequence_number);
if (pkt->message_id == SECIP_MSG_ATE_ENC && pkt->msg.ate_enc.session_id == 0x0000) { if (pkt->message_id == SECIP_MSG_ATE_ENC && pkt->msg.ate_enc.session_id == 0x0000) {
send_ppk_com(pkt, sock, from, pkt); send_ppk_com(pkt, sock, from, pkt);
} } else if (pkt->message_id == SECIP_MSG_PPK_REP) {
if (pkt->message_id == SECIP_MSG_PPK_REP) {
send_arc_enc(pkt, sock, from, pkt); send_arc_enc(pkt, sock, from, pkt);
} else if (pkt->message_id == SECIP_MSG_PATH_SUPERVISION_REQUEST) {
send_psup_resp(pkt, sock, from, pkt);
} else if (pkt->message_id == SECIP_MSG_PATH_CHECK_REQUEST) {
send_pathcheck_resp(pkt, sock, from, pkt);
} else if (pkt->message_id == SECIP_MSG_ALARM) {
send_alarm_ack(pkt, sock, from, pkt);
} else if (pkt->message_id == SECIP_MSG_POLL_MESSAGE) {
send_poll_ack(pkt, sock, from, pkt);
} }