Skip to content

Commit

Permalink
isisd: fix #10505 using base64 encoding
Browse files Browse the repository at this point in the history
Using base64 instead of the raw string to encode
the binary data.

Signed-off-by: whichbug <whichbug@github.com>
  • Loading branch information
whichbug committed Feb 22, 2022
1 parent 6142a17 commit 4eb2b34
Show file tree
Hide file tree
Showing 6 changed files with 315 additions and 8 deletions.
16 changes: 8 additions & 8 deletions isisd/isis_nb_notifications.c
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ void isis_notif_max_area_addr_mismatch(const struct isis_circuit *circuit,
data = yang_data_new_uint8(xpath_arg, max_area_addrs);
listnode_add(arguments, data);
snprintf(xpath_arg, sizeof(xpath_arg), "%s/raw-pdu", xpath);
data = yang_data_new(xpath_arg, raw_pdu);
data = yang_data_new_binary(xpath_arg, raw_pdu, raw_pdu_len);
listnode_add(arguments, data);

hook_call(isis_hook_max_area_addr_mismatch, circuit, max_area_addrs,
Expand All @@ -270,7 +270,7 @@ void isis_notif_authentication_type_failure(const struct isis_circuit *circuit,
notif_prep_instance_hdr(xpath, area, "default", arguments);
notif_prepr_iface_hdr(xpath, circuit, arguments);
snprintf(xpath_arg, sizeof(xpath_arg), "%s/raw-pdu", xpath);
data = yang_data_new(xpath_arg, raw_pdu);
data = yang_data_new_binary(xpath_arg, raw_pdu, raw_pdu_len);
listnode_add(arguments, data);

hook_call(isis_hook_authentication_type_failure, circuit, raw_pdu,
Expand All @@ -294,7 +294,7 @@ void isis_notif_authentication_failure(const struct isis_circuit *circuit,
notif_prep_instance_hdr(xpath, area, "default", arguments);
notif_prepr_iface_hdr(xpath, circuit, arguments);
snprintf(xpath_arg, sizeof(xpath_arg), "%s/raw-pdu", xpath);
data = yang_data_new(xpath_arg, raw_pdu);
data = yang_data_new_binary(xpath_arg, raw_pdu, raw_pdu_len);
listnode_add(arguments, data);

hook_call(isis_hook_authentication_failure, circuit, raw_pdu,
Expand Down Expand Up @@ -361,7 +361,7 @@ void isis_notif_reject_adjacency(const struct isis_circuit *circuit,
data = yang_data_new_string(xpath_arg, reason);
listnode_add(arguments, data);
snprintf(xpath_arg, sizeof(xpath_arg), "%s/raw-pdu", xpath);
data = yang_data_new(xpath_arg, raw_pdu);
data = yang_data_new_binary(xpath_arg, raw_pdu, raw_pdu_len);
listnode_add(arguments, data);

hook_call(isis_hook_reject_adjacency, circuit, raw_pdu, raw_pdu_len);
Expand All @@ -384,7 +384,7 @@ void isis_notif_area_mismatch(const struct isis_circuit *circuit,
notif_prep_instance_hdr(xpath, area, "default", arguments);
notif_prepr_iface_hdr(xpath, circuit, arguments);
snprintf(xpath_arg, sizeof(xpath_arg), "%s/raw-pdu", xpath);
data = yang_data_new(xpath_arg, raw_pdu);
data = yang_data_new_binary(xpath_arg, raw_pdu, raw_pdu_len);
listnode_add(arguments, data);

hook_call(isis_hook_area_mismatch, circuit, raw_pdu, raw_pdu_len);
Expand Down Expand Up @@ -467,7 +467,7 @@ void isis_notif_id_len_mismatch(const struct isis_circuit *circuit,
data = yang_data_new_uint8(xpath_arg, rcv_id_len);
listnode_add(arguments, data);
snprintf(xpath_arg, sizeof(xpath_arg), "%s/raw-pdu", xpath);
data = yang_data_new(xpath_arg, raw_pdu);
data = yang_data_new_binary(xpath_arg, raw_pdu, raw_pdu_len);
listnode_add(arguments, data);

hook_call(isis_hook_id_len_mismatch, circuit, rcv_id_len, raw_pdu,
Expand Down Expand Up @@ -495,7 +495,7 @@ void isis_notif_version_skew(const struct isis_circuit *circuit,
data = yang_data_new_uint8(xpath_arg, version);
listnode_add(arguments, data);
snprintf(xpath_arg, sizeof(xpath_arg), "%s/raw-pdu", xpath);
data = yang_data_new(xpath_arg, raw_pdu);
data = yang_data_new_binary(xpath_arg, raw_pdu, raw_pdu_len);
listnode_add(arguments, data);

hook_call(isis_hook_version_skew, circuit, version, raw_pdu,
Expand Down Expand Up @@ -525,7 +525,7 @@ void isis_notif_lsp_error(const struct isis_circuit *circuit,
data = yang_data_new_string(xpath_arg, rawlspid_print(lsp_id));
listnode_add(arguments, data);
snprintf(xpath_arg, sizeof(xpath_arg), "%s/raw-pdu", xpath);
data = yang_data_new(xpath_arg, raw_pdu);
data = yang_data_new_binary(xpath_arg, raw_pdu, raw_pdu_len);
listnode_add(arguments, data);
/* ignore offset and tlv_type which cannot be set properly */

Expand Down
195 changes: 195 additions & 0 deletions lib/base64.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
/*
* This is part of the libb64 project, and has been placed in the public domain.
* For details, see http://sourceforge.net/projects/libb64
*/

#include "base64.h"

const int CHARS_PER_LINE = 72;

void base64_init_encodestate(struct base64_encodestate *state_in)
{
state_in->step = step_A;
state_in->result = 0;
state_in->stepcount = 0;
}

char base64_encode_value(char value_in)
{
static const char *encoding =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
if (value_in > 63)
return '=';
return encoding[(int)value_in];
}

int base64_encode_block(const char *plaintext_in, int length_in, char *code_out,
struct base64_encodestate *state_in)
{
const char *plainchar = plaintext_in;
const char *const plaintextend = plaintext_in + length_in;
char *codechar = code_out;
char result;
char fragment;

result = state_in->result;

switch (state_in->step) {
while (1) {
case step_A:
if (plainchar == plaintextend) {
state_in->result = result;
state_in->step = step_A;
return codechar - code_out;
}
fragment = *plainchar++;
result = (fragment & 0x0fc) >> 2;
*codechar++ = base64_encode_value(result);
result = (fragment & 0x003) << 4;
/* fall through */
case step_B:
if (plainchar == plaintextend) {
state_in->result = result;
state_in->step = step_B;
return codechar - code_out;
}
fragment = *plainchar++;
result |= (fragment & 0x0f0) >> 4;
*codechar++ = base64_encode_value(result);
result = (fragment & 0x00f) << 2;
/* fall through */
case step_C:
if (plainchar == plaintextend) {
state_in->result = result;
state_in->step = step_C;
return codechar - code_out;
}
fragment = *plainchar++;
result |= (fragment & 0x0c0) >> 6;
*codechar++ = base64_encode_value(result);
result = (fragment & 0x03f) >> 0;
*codechar++ = base64_encode_value(result);

++(state_in->stepcount);
if (state_in->stepcount == CHARS_PER_LINE/4) {
*codechar++ = '\n';
state_in->stepcount = 0;
}
}
}
/* control should not reach here */
return codechar - code_out;
}

int base64_encode_blockend(char *code_out, struct base64_encodestate *state_in)
{
char *codechar = code_out;

switch (state_in->step) {
case step_B:
*codechar++ = base64_encode_value(state_in->result);
*codechar++ = '=';
*codechar++ = '=';
break;
case step_C:
*codechar++ = base64_encode_value(state_in->result);
*codechar++ = '=';
break;
case step_A:
break;
}
*codechar++ = '\n';

return codechar - code_out;
}


signed char base64_decode_value(signed char value_in)
{
static const signed char decoding[] = {
62, -1, -1, -1, 63, 52, 53, 54,
55, 56, 57, 58, 59, 60, 61, -1,
-1, -1, -2, -1, -1, -1, 0, 1,
2, 3, 4, 5, 6, 7, 8, 9,
10, 11, 12, 13, 14, 15, 16, 17,
18, 19, 20, 21, 22, 23, 24, 25,
-1, -1, -1, -1, -1, -1, 26, 27,
28, 29, 30, 31, 32, 33, 34, 35,
36, 37, 38, 39, 40, 41, 42, 43,
44, 45, 46, 47, 48, 49, 50, 51
};
value_in -= 43;
if (value_in < 0 || value_in >= 80)
return -1;
return decoding[(int)value_in];
}

void base64_init_decodestate(struct base64_decodestate *state_in)
{
state_in->step = step_a;
state_in->plainchar = 0;
}

int base64_decode_block(const char *code_in, int length_in, char *plaintext_out,
struct base64_decodestate *state_in)
{
const char *codechar = code_in;
char *plainchar = plaintext_out;
signed char fragment;

*plainchar = state_in->plainchar;

switch (state_in->step) {
while (1) {
case step_a:
do {
if (codechar == code_in+length_in) {
state_in->step = step_a;
state_in->plainchar = *plainchar;
return plainchar - plaintext_out;
}
fragment = base64_decode_value(*codechar++);
} while (fragment < 0);
*plainchar = (fragment & 0x03f) << 2;
/* fall through */
case step_b:
do {
if (codechar == code_in+length_in) {
state_in->step = step_b;
state_in->plainchar = *plainchar;
return plainchar - plaintext_out;
}
fragment = base64_decode_value(*codechar++);
} while (fragment < 0);
*plainchar++ |= (fragment & 0x030) >> 4;
*plainchar = (fragment & 0x00f) << 4;
/* fall through */
case step_c:
do {
if (codechar == code_in+length_in) {
state_in->step = step_c;
state_in->plainchar = *plainchar;
return plainchar - plaintext_out;
}
fragment = base64_decode_value(*codechar++);
} while (fragment < 0);
*plainchar++ |= (fragment & 0x03c) >> 2;
*plainchar = (fragment & 0x003) << 6;
/* fall through */
case step_d:
do {
if (codechar == code_in+length_in) {
state_in->step = step_d;
state_in->plainchar = *plainchar;
return plainchar - plaintext_out;
}
fragment = base64_decode_value(*codechar++);
} while (fragment < 0);
*plainchar++ |= (fragment & 0x03f);
}
}
/* control should not reach here */
return plainchar - plaintext_out;
}
45 changes: 45 additions & 0 deletions lib/base64.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* This is part of the libb64 project, and has been placed in the public domain.
* For details, see http://sourceforge.net/projects/libb64
*/

#ifndef _BASE64_H_
#define _BASE64_H_

enum base64_encodestep {
step_A, step_B, step_C
};

struct base64_encodestate {
enum base64_encodestep step;
char result;
int stepcount;
};

void base64_init_encodestate(struct base64_encodestate *state_in);

char base64_encode_value(char value_in);

int base64_encode_block(const char *plaintext_in, int length_in, char *code_out,
struct base64_encodestate *state_in);

int base64_encode_blockend(char *code_out, struct base64_encodestate *state_in);


enum base64_decodestep {
step_a, step_b, step_c, step_d
};

struct base64_decodestate {
enum base64_decodestep step;
char plainchar;
};

void base64_init_decodestate(struct base64_decodestate *state_in);

signed char base64_decode_value(signed char value_in);

int base64_decode_block(const char *code_in, int length_in, char *plaintext_out,
struct base64_decodestate *state_in);

#endif /* _BASE64_H_ */
2 changes: 2 additions & 0 deletions lib/subdir.am
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ lib_libfrr_la_LIBADD = $(LIBCAP) $(UNWIND_LIBS) $(LIBYANG_LIBS) $(LUA_LIB) $(UST
lib_libfrr_la_SOURCES = \
lib/agg_table.c \
lib/atomlist.c \
lib/base64.c \
lib/bfd.c \
lib/buffer.c \
lib/checksum.c \
Expand Down Expand Up @@ -177,6 +178,7 @@ clippy_scan += \
pkginclude_HEADERS += \
lib/agg_table.h \
lib/atomlist.h \
lib/base64.h \
lib/bfd.h \
lib/bitfield.h \
lib/buffer.h \
Expand Down
Loading

0 comments on commit 4eb2b34

Please sign in to comment.