diff --git a/src/protocols/der/base.c b/src/protocols/der/base.c index 95369fa6d7126..0416758b487b2 100644 --- a/src/protocols/der/base.c +++ b/src/protocols/der/base.c @@ -361,12 +361,28 @@ static int dict_flag_max(fr_dict_attr_t **da_p, char const *value, UNUSED fr_dic return 0; } -static int dict_flag_option(fr_dict_attr_t **da_p, UNUSED char const *value, UNUSED fr_dict_flag_parser_rule_t const *rules) +static int dict_flag_option(fr_dict_attr_t **da_p, char const *value, UNUSED fr_dict_flag_parser_rule_t const *rules) { fr_der_attr_flags_t *flags = fr_dict_attr_ext(*da_p, FR_DICT_ATTR_EXT_PROTOCOL_SPECIFIC); unsigned long num; char *end = NULL; + /* + * In the interest of laziness, allow a bare 'option', so + * that we don't have to give an attribute number, and + * then also duplicate that numbr in 'option='. + */ + if (!value) { + if (!(*da_p)->state.attr_set || (*da_p)->attr > 0x1f) { + fr_strerror_printf("Missing value for 'option='"); + return -1; + } + + flags->class = FR_DER_CLASS_CONTEXT; + flags->option = (*da_p)->attr; + return 0; + } + /* * We limit the allowed options (tag numbers) to ones * which fit into the 5 bits of the first byte. We don't @@ -378,9 +394,8 @@ static int dict_flag_option(fr_dict_attr_t **da_p, UNUSED char const *value, UNU return -1; } - /* - * Don't over-ride 'class==foo,option=bar' - */ + fr_assert(!(*da_p)->state.attr_set); + flags->class = FR_DER_CLASS_CONTEXT; flags->option = num; @@ -397,7 +412,7 @@ static const fr_dict_flag_parser_t der_flags[] = { { L("is_pair"), { .func = dict_flag_is_pair } }, { L("is_pairs"), { .func = dict_flag_is_pairs } }, { L("max"), { .func = dict_flag_max, .needs_value = true } }, - { L("option"), { .func = dict_flag_option, .needs_value = true } }, + { L("option"), { .func = dict_flag_option} }, { L("sequence_of"), { .func = dict_flag_sequence_of, .needs_value = true } }, { L("set_of"), { .func = dict_flag_set_of, .needs_value = true } }, };