Implement Vebon SecIP encryption types RSA+AES. Needs RSA key with 257 exponent for alphatronics.
Note that the endianness is completely retarded. RSA public key transfer is little endian. Messages are big endian.
This commit is contained in:
parent
3fb1474113
commit
fec14af688
5 changed files with 230 additions and 48 deletions
3
config.c
3
config.c
|
@ -93,6 +93,9 @@ STATUS read_rsa_keys(void) {
|
|||
fclose(file);
|
||||
|
||||
res = rsa_keypair_from_sexp(pub, priv, 0, size, buffer);
|
||||
if (!res) {
|
||||
DEBUG(0, "Error reading the RSA keypair from the SEXP file");
|
||||
}
|
||||
|
||||
conf->public_key = pub;
|
||||
conf->private_key = priv;
|
||||
|
|
30
secip.idl
30
secip.idl
|
@ -41,7 +41,7 @@ interface secip
|
|||
typedef [public,flag(LIBNDR_FLAG_NOALIGN)] struct {
|
||||
[value(0)] uint16 session_id;
|
||||
uint8 rsa_key[128];
|
||||
uint8 padding[75];
|
||||
uint8 padding[74];
|
||||
} secip_ppk_com;
|
||||
|
||||
typedef [public,flag(LIBNDR_FLAG_NOALIGN)] struct {
|
||||
|
@ -51,28 +51,34 @@ interface secip
|
|||
|
||||
typedef [public,flag(LIBNDR_FLAG_NOALIGN)] struct {
|
||||
[value(1)] uint8 protocol_version;
|
||||
uint8 manufacturer[8];
|
||||
uint8 manufacturer[20];
|
||||
uint8 panel_type[12];
|
||||
uint8 panel_version[8];
|
||||
uint8 account_code[6];
|
||||
uint8 crc_mode;
|
||||
uint16 session_id;
|
||||
secip_key_message_block key_block;
|
||||
uint8 padding[137];
|
||||
uint8 padding[136];
|
||||
} secip_ppk_rep;
|
||||
|
||||
typedef [public,flag(LIBNDR_FLAG_NOALIGN)] struct {
|
||||
secip_error error_code;
|
||||
uint16 session_id;
|
||||
uint8 padding[232];
|
||||
uint8 padding[231];
|
||||
} secip_arc_enc;
|
||||
|
||||
typedef [public,flag(LIBNDR_FLAG_NOALIGN)] struct {
|
||||
uint16 path_id;
|
||||
uint32 interval_seconds;
|
||||
uint8 padding[70];
|
||||
} secip_psup_req;
|
||||
|
||||
typedef [nodiscriminant,public,flag(LIBNDR_FLAG_NOALIGN)] union {
|
||||
[case(SECIP_MSG_ATE_ENC)] secip_ate_enc ate_enc;
|
||||
[case(SECIP_MSG_PPK_COM)] secip_ppk_com ppk_com;
|
||||
[case(SECIP_MSG_PPK_REP)] secip_ppk_rep ppk_rep;
|
||||
[case(SECIP_MSG_ARC_ENC)] secip_arc_enc arc_enc;
|
||||
[case(SECIP_MSG_PATH_SUPERVISION_REQUEST)] secip_psup_req psup_req;
|
||||
} secip_msg_union;
|
||||
|
||||
typedef [public,flag(LIBNDR_FLAG_NOALIGN)] struct {
|
||||
|
@ -82,25 +88,17 @@ interface secip
|
|||
uint16 sequence_number;
|
||||
char device_id[16];
|
||||
[switch_is(message_id)] secip_msg_union msg;
|
||||
uint8 padding[30]; /* random */
|
||||
} secip_packet;
|
||||
|
||||
typedef [public,flag(LIBNDR_FLAG_NOALIGN)] struct {
|
||||
uint16 connection_id; /* 0xffff is unassigned */
|
||||
secip_message message_id;
|
||||
uint16 sequence_number;
|
||||
char device_id[16];
|
||||
[switch_is(message_id)] secip_msg_union msg;
|
||||
uint8 padding[30]; /* random */
|
||||
} secip_out_packet;
|
||||
|
||||
typedef [public,flag(LIBNDR_FLAG_NOALIGN)] struct {
|
||||
uint8 raw_packet[256];
|
||||
uint8 raw_packet[226];
|
||||
uint8 padding[30];
|
||||
[value(calculate_crc(raw_packet, 256))] uint16 crc;
|
||||
} secip_setup_packet;
|
||||
|
||||
typedef [public,flag(LIBNDR_FLAG_NOALIGN)] struct {
|
||||
uint8 raw_packet[128];
|
||||
uint8 raw_packet[98];
|
||||
uint8 padding[30];
|
||||
[value(calculate_crc(raw_packet, 128))] uint16 crc;
|
||||
} secip_comm_packet;
|
||||
};
|
||||
|
|
195
secipd.c
195
secipd.c
|
@ -4,7 +4,7 @@
|
|||
|
||||
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
|
||||
the Free Software Foundation; either version 4 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
|
@ -17,56 +17,177 @@
|
|||
*/
|
||||
#include "includes.h"
|
||||
#include "build/ndr_secip.h"
|
||||
#include <nettle/aes.h>
|
||||
|
||||
/* FIXME Does not handle multiple connections.. should be per connection obviously!! */
|
||||
static uint8_t global_aes_key[16];
|
||||
|
||||
|
||||
static STATUS send_ppk_com(TALLOC_CTX *mem_ctx, int sock, struct sockaddr_in from, struct secip_packet *pkt) {
|
||||
struct secip_setup_packet *setup_pkt;
|
||||
struct secip_out_packet *ppk_com;
|
||||
struct secip_packet *ppk_com;
|
||||
DATA_BLOB raw_pkt, raw_setup_pkt;
|
||||
enum ndr_err_code ndr_err;
|
||||
size_t n;
|
||||
size_t n, i;
|
||||
size_t count;
|
||||
const configuration *conf = get_conf();
|
||||
|
||||
|
||||
setup_pkt = talloc_zero(mem_ctx, struct secip_setup_packet);
|
||||
setup_pkt = talloc(mem_ctx, struct secip_setup_packet);
|
||||
|
||||
ppk_com = talloc_zero(setup_pkt, struct secip_out_packet);
|
||||
ppk_com->connection_id = pkt->connection_id;
|
||||
ppk_com = talloc(setup_pkt, struct secip_packet);
|
||||
ppk_com->pad = 0;
|
||||
ppk_com->connection_id = 0x1337;
|
||||
ppk_com->message_id = SECIP_MSG_PPK_COM;
|
||||
ppk_com->sequence_number = 1;
|
||||
memcpy(ppk_com->device_id, "MyFirstAlarm[TM]", strlen("MyFirstAlarm[TM]"));
|
||||
ppk_com->msg.ppk_com.session_id = 0;
|
||||
|
||||
mpz_export(&ppk_com->msg.ppk_com.rsa_key, &count, 1, 4, 1, 0, conf->public_key->n);
|
||||
/* Device ID must not be readable at this stage */
|
||||
for (i = 0; i < 16; i++) {
|
||||
ppk_com->device_id[i] = rand();
|
||||
}
|
||||
for (i = 0; i < 74; i++) {
|
||||
ppk_com->msg.ppk_com.padding[i] = rand();
|
||||
}
|
||||
|
||||
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_out_packet, "ppk_com packet", ppk_com));
|
||||
printf("%s\n", 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_out_packet);
|
||||
ndr_err = ndr_push_struct_blob(&raw_pkt, ppk_com, ppk_com, (ndr_push_flags_fn_t)ndr_push_secip_packet);
|
||||
|
||||
if (ndr_err != NDR_ERR_SUCCESS) {
|
||||
DEBUG(0, "Oh holy shitstorm! That didn't work!\n");
|
||||
DEBUG(0, "Oh holy shitstorm! That didn't work!");
|
||||
return ST_GENERAL_FAILURE;
|
||||
}
|
||||
|
||||
memcpy(setup_pkt->raw_packet, raw_pkt.data, raw_pkt.length);
|
||||
for (i = 0; i < 30; i++) {
|
||||
setup_pkt->padding[i] = rand();
|
||||
}
|
||||
|
||||
|
||||
ndr_err = ndr_push_struct_blob(&raw_setup_pkt, setup_pkt, setup_pkt, (ndr_push_flags_fn_t)ndr_push_secip_setup_packet);
|
||||
|
||||
if (ndr_err != NDR_ERR_SUCCESS) {
|
||||
DEBUG(0, "Oh holy shitstorm! That didn't work!\n");
|
||||
DEBUG(0, "Oh holy shitstorm! That didn't work!");
|
||||
return ST_GENERAL_FAILURE;
|
||||
}
|
||||
|
||||
n = sendto(sock, raw_setup_pkt.data, raw_setup_pkt.length, 0, (struct sockaddr *)&from, sizeof(from));
|
||||
|
||||
|
||||
talloc_free(setup_pkt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static STATUS send_arc_enc(TALLOC_CTX *mem_ctx, int sock, struct sockaddr_in from, struct secip_packet *pkt) {
|
||||
struct secip_setup_packet *setup_pkt;
|
||||
struct secip_packet *arc_enc;
|
||||
DATA_BLOB raw_pkt, raw_setup_pkt, crypted_setup_pkt;
|
||||
size_t n, i;
|
||||
enum ndr_err_code ndr_err;
|
||||
struct aes_ctx aes;
|
||||
|
||||
aes_set_encrypt_key(&aes, 16, pkt->msg.ppk_rep.key_block.aes_key);
|
||||
|
||||
/* FIXME DEATH TO THE GLOBALS! */
|
||||
memcpy(global_aes_key, pkt->msg.ppk_rep.key_block.aes_key, 16);
|
||||
|
||||
setup_pkt = talloc(mem_ctx, struct secip_setup_packet);
|
||||
|
||||
arc_enc = talloc_zero(setup_pkt, struct secip_packet);
|
||||
arc_enc->pad = 0;
|
||||
arc_enc->connection_id = 0x1337;
|
||||
arc_enc->message_id = SECIP_MSG_ARC_ENC;
|
||||
arc_enc->sequence_number = 2;
|
||||
|
||||
arc_enc->msg.arc_enc.error_code = SECIP_ERR_SUCCESS;
|
||||
arc_enc->msg.arc_enc.session_id = pkt->msg.ppk_com.session_id;
|
||||
|
||||
for (i = 0; i < 231; i++) {
|
||||
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));
|
||||
|
||||
ndr_err = ndr_push_struct_blob(&raw_pkt, arc_enc, arc_enc, (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(setup_pkt->raw_packet, raw_pkt.data, raw_pkt.length);
|
||||
for (i = 0; i < 30; i++) {
|
||||
setup_pkt->padding[i] = rand();
|
||||
}
|
||||
|
||||
ndr_err = ndr_push_struct_blob(&raw_setup_pkt, setup_pkt, setup_pkt, (ndr_push_flags_fn_t)ndr_push_secip_setup_packet);
|
||||
|
||||
if (ndr_err != NDR_ERR_SUCCESS) {
|
||||
DEBUG(0, "Oh holy shitstorm! That didn't work!");
|
||||
return ST_GENERAL_FAILURE;
|
||||
}
|
||||
|
||||
crypted_setup_pkt.data = talloc_zero_array(mem_ctx, uint8_t, 258);
|
||||
crypted_setup_pkt.length = 258;
|
||||
memcpy(crypted_setup_pkt.data, raw_setup_pkt.data, 2);
|
||||
|
||||
aes_encrypt(&aes, raw_setup_pkt.length-2, crypted_setup_pkt.data+2, raw_setup_pkt.data+2);
|
||||
|
||||
n = sendto(sock, crypted_setup_pkt.data, crypted_setup_pkt.length, 0, (struct sockaddr *)&from, sizeof(from));
|
||||
|
||||
return ST_OK;
|
||||
}
|
||||
|
||||
DATA_BLOB decrypt_setup_packet(TALLOC_CTX *mem_ctx, DATA_BLOB encrypted_blob) {
|
||||
const configuration *conf = get_conf();
|
||||
mpz_t encrypted_data;
|
||||
mpz_t decrypted_data;
|
||||
DATA_BLOB decrypted_blob;
|
||||
int pos;
|
||||
size_t length = 1;
|
||||
|
||||
decrypted_blob.length = 258;
|
||||
decrypted_blob.data = talloc_zero_array(mem_ctx, uint8_t, 258);
|
||||
memcpy(decrypted_blob.data, encrypted_blob.data, 0x02);
|
||||
|
||||
|
||||
for (pos = 0x02; pos < 258; pos += 128) {
|
||||
/* Initialize the big numbers */
|
||||
mpz_init(encrypted_data);
|
||||
mpz_init(decrypted_data);
|
||||
|
||||
/* Do not decrypt the CRC and the connection ID */
|
||||
mpz_import(encrypted_data, 1, 1, 128, 1, 0, encrypted_blob.data + pos);
|
||||
|
||||
rsa_compute_root(conf->private_key, decrypted_data, encrypted_data);
|
||||
|
||||
mpz_export(decrypted_blob.data + pos, &length, 1, 128, 1, 0, decrypted_data);
|
||||
}
|
||||
|
||||
|
||||
return decrypted_blob;
|
||||
}
|
||||
|
||||
DATA_BLOB decrypt_aes_packet(TALLOC_CTX *mem_ctx, DATA_BLOB encrypted_blob) {
|
||||
static DATA_BLOB ret;
|
||||
struct aes_ctx aes;
|
||||
|
||||
|
||||
ret.length = encrypted_blob.length;
|
||||
ret.data = talloc_zero_array(mem_ctx, uint8_t, ret.length);
|
||||
memcpy(ret.data, encrypted_blob.data, 2);
|
||||
|
||||
aes_set_decrypt_key(&aes, 16, global_aes_key);
|
||||
|
||||
aes_decrypt(&aes, encrypted_blob.length-2, ret.data+2, encrypted_blob.data+2);
|
||||
|
||||
DEBUG(0, "Decrypted this packet maybe!");
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int main (int argc, char **argv) {
|
||||
int sock, n;
|
||||
|
@ -141,13 +262,13 @@ int main (int argc, char **argv) {
|
|||
while (1) {
|
||||
uint16_t src_port;
|
||||
struct secip_setup_packet *setup_pkt;
|
||||
struct secip_comm_packet *comm_pkt;
|
||||
struct secip_packet *pkt;
|
||||
char buf[1024]; /* Purposefully static length */
|
||||
enum ndr_err_code ndr_err;
|
||||
DATA_BLOB data;
|
||||
|
||||
setup_pkt = talloc(mem_ctx, struct secip_setup_packet);
|
||||
pkt = talloc(setup_pkt, struct secip_packet);
|
||||
pkt = talloc(mem_ctx, struct secip_packet);
|
||||
|
||||
n = recvfrom(sock, &buf, sizeof(buf), 0, (struct sockaddr *) &from, &fromlen);
|
||||
if (n < 0) {
|
||||
|
@ -158,22 +279,46 @@ int main (int argc, char **argv) {
|
|||
continue;
|
||||
}
|
||||
src_port = ntohs(from.sin_port);
|
||||
DEBUG(3, "Received packet with len %d from %u", n, src_port);
|
||||
|
||||
/* Copy packet to data blob */
|
||||
data.length = n;
|
||||
data.data = talloc_memdup(setup_pkt, buf, n);
|
||||
data.data = talloc_memdup(pkt, buf, n);
|
||||
|
||||
if (*(uint16_t *)data.data < 0xFF00 && data.length > 256) {
|
||||
data = decrypt_setup_packet(pkt, data);
|
||||
if (data.length == 0) {
|
||||
DEBUG(0, "RSA decryption failed, freeing up memory");
|
||||
talloc_free(pkt);
|
||||
continue;
|
||||
}
|
||||
} else if (*(uint16_t *)data.data < 0xFF00 && data.length > 128) {
|
||||
data = decrypt_aes_packet(pkt, data);
|
||||
if (data.length == 0) {
|
||||
DEBUG(0, "AES decryption failed, freeing up memory");
|
||||
talloc_free(pkt);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Parse the header */
|
||||
ndr_err = ndr_pull_struct_blob_all(&data, setup_pkt, setup_pkt, (ndr_pull_flags_fn_t)ndr_pull_secip_setup_packet);
|
||||
if (data.length > 256) {
|
||||
setup_pkt = talloc(pkt, struct secip_setup_packet);
|
||||
ndr_err = ndr_pull_struct_blob_all(&data, pkt, setup_pkt, (ndr_pull_flags_fn_t)ndr_pull_secip_setup_packet);
|
||||
|
||||
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));
|
||||
} 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);
|
||||
|
||||
/* Copy packet to data blob */
|
||||
data.length = data.length - sizeof(uint16_t);
|
||||
data.data = talloc_memdup(pkt, buf, n);
|
||||
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));
|
||||
}
|
||||
|
||||
ndr_err = ndr_pull_struct_blob_all(&data, pkt, pkt, (ndr_pull_flags_fn_t)ndr_pull_secip_packet);
|
||||
|
||||
|
@ -182,12 +327,16 @@ int main (int argc, char **argv) {
|
|||
}
|
||||
printf("%s\n", ndr_print_struct_string(pkt,(ndr_print_fn_t)ndr_print_secip_packet, "packet", pkt));
|
||||
|
||||
DEBUG(0, "%x %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) {
|
||||
send_ppk_com(pkt, sock, from, pkt);
|
||||
}
|
||||
DEBUG(3, "Received packet with len %d from %u", n, src_port);
|
||||
|
||||
talloc_free(setup_pkt);
|
||||
if (pkt->message_id == SECIP_MSG_PPK_REP) {
|
||||
send_arc_enc(pkt, sock, from, pkt);
|
||||
}
|
||||
|
||||
|
||||
talloc_free(pkt);
|
||||
}
|
||||
}
|
||||
|
|
34
siahs.h
34
siahs.h
|
@ -31,4 +31,36 @@ struct siahs_packet {
|
|||
uint16_t checksum;
|
||||
};
|
||||
|
||||
|
||||
const uint8_t xor_table[] = { 0x51, 0x7a, 0x26, 0x3d, 0x22, 0x21, 0x3b, 0x74,
|
||||
0x31, 0x30, 0x74, 0x27, 0x3b, 0x30, 0x3d, 0x22,
|
||||
0x21, 0x3b, 0x74, 0x27, 0x3b, 0x74, 0x39, 0x31,
|
||||
0x3c, 0x37, 0x3a, 0x31, 0x74, 0x31, 0x27, 0x74,
|
||||
0x39, 0x31, 0x3a, 0x74, 0x78, 0x26, 0x31, 0x22,
|
||||
0x74, 0x31, 0x30, 0x74, 0x39, 0x35, 0x20, 0x26,
|
||||
0x35, 0x32, 0x74, 0x31, 0x27, 0x74, 0x3b, 0xb7,
|
||||
0x3a, 0x74, 0x27, 0x3b, 0x3c, 0x38, 0x3b, 0x74,
|
||||
0x27, 0x3b, 0x6f, 0xc1, 0x26, 0x3d, 0x39, 0x3d,
|
||||
0x26, 0x24, 0x2c, 0x31, 0x74, 0x31, 0x30, 0x3b,
|
||||
0x24, 0x74, 0x27, 0x35, 0x74, 0x39, 0xbd, 0x21,
|
||||
0x33, 0x3a, 0x3d, 0x3a, 0x74, 0x31, 0x21, 0x25,
|
||||
0x74, 0x78, 0x27, 0x3d, 0x35, 0x20, 0x74, 0x27,
|
||||
0x35, 0x26, 0x3d, 0x31, 0x27, 0x3a, 0x35, 0x37,
|
||||
0x74, 0x3b, 0xb7, 0x27, 0x74, 0x27, 0x35, 0x27,
|
||||
0x3d, 0x3b, 0x37, 0x74, 0x27, 0x35, 0x74, 0x27,
|
||||
0x35, 0x30, 0x3b, 0x00, 0xfb, 0x7a, 0x26, 0x31,
|
||||
0x26, 0x26, 0x3b, 0x37, 0x74, 0x35, 0x74, 0x27,
|
||||
0x31, 0x38, 0x31, 0x74, 0x39, 0x35, 0x3a, 0x26,
|
||||
0x3b, 0x20, 0x74, 0xb5, 0x38, 0x74, 0x35, 0x26,
|
||||
0x35, 0x24, 0x74, 0x78, 0x27, 0x3b, 0x3d, 0x26,
|
||||
0x74, 0x27, 0x3b, 0x74, 0x39, 0x31, 0x26, 0x26,
|
||||
0x3b, 0x37, 0x74, 0x31, 0x30, 0x3a, 0x3b, 0x74,
|
||||
0x35, 0x26, 0x35, 0x24, 0x74, 0x26, 0x35, 0x33,
|
||||
0x21, 0x38, 0x74, 0x3b, 0x35, 0x9a, 0x6f, 0x31,
|
||||
0x3c, 0x37, 0x3a, 0x31, 0x74, 0x31, 0x27, 0x74,
|
||||
0x3b, 0xb7, 0x3a, 0x74, 0x26, 0x35, 0x39, 0x74,
|
||||
0x3b, 0x74, 0x31, 0x74, 0x78, 0x26, 0x35, 0x39,
|
||||
0x74, 0x3b, 0x74, 0x35, 0x26, 0x35, 0x24, 0x74,
|
||||
0x39, 0x31, 0x26, 0x26, 0x3b, 0x37, 0x74, 0x27,
|
||||
0x3b, 0x3d, 0x26, 0x74, 0x27, 0x3b, 0x74, 0x27,
|
||||
0x3b, 0x30, 0x3b, 0x00, 0xaa, 0x11, 0x46, 0x54,
|
||||
};
|
||||
|
|
2
wscript
2
wscript
|
@ -84,7 +84,7 @@ def configure(conf):
|
|||
conf.check_cc(lib='gmp', uselib_store='nettle')
|
||||
|
||||
# Purposefully at the bottom because waf configuration tests fail with -Wstrict-prototypes and -Werror
|
||||
conf.env.CFLAGS = ['-O2', '-g', '-ggdb', '-std=c99', '-Wall', '-Wshadow', '-Wpointer-arith', '-Wcast-align', '-Wwrite-strings', '-Wdeclaration-after-statement',
|
||||
conf.env.CFLAGS = ['-O0', '-g', '-ggdb', '-std=c99', '-Wall', '-Wshadow', '-Wpointer-arith', '-Wcast-align', '-Wwrite-strings', '-Wdeclaration-after-statement',
|
||||
'-Werror-implicit-function-declaration', '-Wstrict-prototypes', '-Werror']
|
||||
|
||||
def build(bld):
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue