@@ -106,52 +106,25 @@ impl SshdConfigParser {
106106 /// Example criteria node: "user alice,bob" or "address *.*.0.1"
107107 /// Inserts the criterion as a key with an array value into the `criteria_map`.
108108 fn parse_match_criteria ( criteria_node : tree_sitter:: Node , input : & str , input_bytes : & [ u8 ] , criteria_map : & mut Map < String , Value > ) -> Result < ( ) , SshdConfigError > {
109- let mut cursor = criteria_node. walk ( ) ;
110- let mut key: Option < String > = None ;
111- let mut values: Vec < Value > = Vec :: new ( ) ;
112-
113- // Iterate through named children of the criteria node
114- for child in criteria_node. named_children ( & mut cursor) {
115- if child. is_error ( ) {
109+ if let Some ( key_node) = criteria_node. child_by_field_name ( "keyword" ) {
110+ let Ok ( key_text) = key_node. utf8_text ( input_bytes) else {
116111 return Err ( SshdConfigError :: ParserError ( t ! ( "parser.failedToParseNode" , input = input) . to_string ( ) ) ) ;
117- }
112+ } ;
113+ let key = key_text. to_string ( ) ;
118114
119- match child. kind ( ) {
120- "alpha" => {
121- let Ok ( text) = child. utf8_text ( input_bytes) else {
122- return Err ( SshdConfigError :: ParserError ( t ! ( "parser.failedToParseNode" , input = input) . to_string ( ) ) ) ;
123- } ;
124- key = Some ( text. to_string ( ) ) ;
125- }
126- "boolean" | "string" => {
127- let Ok ( arg) = child. utf8_text ( input_bytes) else {
128- return Err ( SshdConfigError :: ParserError ( t ! ( "parser.failedToParseNode" , input = input) . to_string ( ) ) ) ;
129- } ;
130- let arg_str = arg. trim ( ) ;
131- values. push ( Value :: String ( arg_str. to_string ( ) ) ) ;
132- }
133- "number" => {
134- let Ok ( arg) = child. utf8_text ( input_bytes) else {
135- return Err ( SshdConfigError :: ParserError ( t ! ( "parser.failedToParseNode" , input = input) . to_string ( ) ) ) ;
136- } ;
137- values. push ( Value :: Number ( arg. parse :: < u64 > ( ) ?. into ( ) ) ) ;
138- }
139- _ => {
140- return Err ( SshdConfigError :: ParserError ( t ! ( "parser.failedToParseNode" , input = input) . to_string ( ) ) ) ;
141- }
115+ let values: Value ;
116+ if let Some ( value_node) = criteria_node. child_by_field_name ( "argument" ) {
117+ values = parse_arguments_node ( value_node, input, input_bytes, true ) ?;
118+ }
119+ else {
120+ return Err ( SshdConfigError :: ParserError ( t ! ( "parser.missingValueInCriteria" , input = input) . to_string ( ) ) ) ;
142121 }
143- }
144-
145- let Some ( criteria_key) = key else {
146- return Err ( SshdConfigError :: ParserError ( t ! ( "parser.failedToParseNode" , input = input) . to_string ( ) ) ) ;
147- } ;
148122
149- if values. is_empty ( ) {
150- return Err ( SshdConfigError :: ParserError ( t ! ( "parser.noArgumentsFound" , input = input) . to_string ( ) ) ) ;
123+ criteria_map. insert ( key. to_lowercase ( ) , values) ;
124+ Ok ( ( ) )
125+ } else {
126+ Err ( SshdConfigError :: ParserError ( t ! ( "parser.missingKeyInCriteria" , input = input) . to_string ( ) ) )
151127 }
152-
153- criteria_map. insert ( criteria_key. to_lowercase ( ) , Value :: Array ( values) ) ;
154- Ok ( ( ) )
155128 }
156129
157130 /// Parse a keyword node and optionally insert it into a map.
@@ -252,7 +225,7 @@ impl SshdConfigParser {
252225 }
253226 } else if is_repeatable {
254227 // Initialize repeatable keywords as arrays
255- if let Value :: Array ( _ ) = value {
228+ if value . is_array ( ) {
256229 map. insert ( key. to_string ( ) , value) ;
257230 } else {
258231 map. insert ( key. to_string ( ) , Value :: Array ( vec ! [ value] ) ) ;
@@ -276,22 +249,17 @@ fn parse_arguments_node(arg_node: tree_sitter::Node, input: &str, input_bytes: &
276249 if node. is_error ( ) {
277250 return Err ( SshdConfigError :: ParserError ( t ! ( "parser.failedToParseNode" , input = input) . to_string ( ) ) ) ;
278251 }
252+ let arg = node. utf8_text ( input_bytes) ?;
279253 match node. kind ( ) {
280- "boolean" | "string" => {
281- let Ok ( arg) = node. utf8_text ( input_bytes) else {
282- return Err ( SshdConfigError :: ParserError (
283- t ! ( "parser.failedToParseNode" , input = input) . to_string ( )
284- ) ) ;
285- } ;
254+ "boolean" => {
255+ let arg_str = arg. trim ( ) ;
256+ vec. push ( Value :: Bool ( arg_str. eq_ignore_ascii_case ( "yes" ) ) ) ;
257+ }
258+ "string" => {
286259 let arg_str = arg. trim ( ) ;
287260 vec. push ( Value :: String ( arg_str. to_string ( ) ) ) ;
288261 } ,
289262 "number" => {
290- let Ok ( arg) = node. utf8_text ( input_bytes) else {
291- return Err ( SshdConfigError :: ParserError (
292- t ! ( "parser.failedToParseNode" , input = input) . to_string ( )
293- ) ) ;
294- } ;
295263 vec. push ( Value :: Number ( arg. parse :: < u64 > ( ) ?. into ( ) ) ) ;
296264 } ,
297265 _ => return Err ( SshdConfigError :: ParserError ( t ! ( "parser.unknownNode" , kind = node. kind( ) ) . to_string ( ) ) )
@@ -366,7 +334,7 @@ mod tests {
366334 fn bool_keyword ( ) {
367335 let input = "printmotd yes\r \n " ;
368336 let result: Map < String , Value > = parse_text_to_map ( input) . unwrap ( ) ;
369- assert_eq ! ( result. get( "printmotd" ) . unwrap( ) , & Value :: String ( "yes" . to_string ( ) ) ) ;
337+ assert_eq ! ( result. get( "printmotd" ) . unwrap( ) , & Value :: Bool ( true ) ) ;
370338 }
371339
372340 #[ test]
@@ -442,11 +410,12 @@ match user bob
442410 let match_array = result. get ( "match" ) . unwrap ( ) . as_array ( ) . unwrap ( ) ;
443411 assert_eq ! ( match_array. len( ) , 1 ) ;
444412 let match_obj = match_array[ 0 ] . as_object ( ) . unwrap ( ) ;
413+ println ! ( "match_obj: {:?}" , match_obj) ;
445414 let criteria = match_obj. get ( "criteria" ) . unwrap ( ) . as_object ( ) . unwrap ( ) ;
446415 let user_array = criteria. get ( "user" ) . unwrap ( ) . as_array ( ) . unwrap ( ) ;
447416 assert_eq ! ( user_array[ 0 ] , Value :: String ( "bob" . to_string( ) ) ) ;
448- assert_eq ! ( match_obj. get( "gssapiauthentication" ) . unwrap( ) , & Value :: String ( "yes" . to_string ( ) ) ) ;
449- assert_eq ! ( match_obj. get( "allowtcpforwarding" ) . unwrap( ) , & Value :: String ( "yes" . to_string ( ) ) ) ;
417+ assert_eq ! ( match_obj. get( "gssapiauthentication" ) . unwrap( ) , & Value :: Bool ( true ) ) ;
418+ assert_eq ! ( match_obj. get( "allowtcpforwarding" ) . unwrap( ) , & Value :: Bool ( true ) ) ;
450419 }
451420
452421 #[ test]
@@ -464,12 +433,12 @@ match group administrators
464433 let criteria1 = match_obj1. get ( "criteria" ) . unwrap ( ) . as_object ( ) . unwrap ( ) ;
465434 let user_array1 = criteria1. get ( "user" ) . unwrap ( ) . as_array ( ) . unwrap ( ) ;
466435 assert_eq ! ( user_array1[ 0 ] , Value :: String ( "alice" . to_string( ) ) ) ;
467- assert_eq ! ( match_obj1. get( "passwordauthentication" ) . unwrap( ) , & Value :: String ( "yes" . to_string ( ) ) ) ;
436+ assert_eq ! ( match_obj1. get( "passwordauthentication" ) . unwrap( ) , & Value :: Bool ( true ) ) ;
468437 let match_obj2 = match_array[ 1 ] . as_object ( ) . unwrap ( ) ;
469438 let criteria2 = match_obj2. get ( "criteria" ) . unwrap ( ) . as_object ( ) . unwrap ( ) ;
470439 let group_array2 = criteria2. get ( "group" ) . unwrap ( ) . as_array ( ) . unwrap ( ) ;
471440 assert_eq ! ( group_array2[ 0 ] , Value :: String ( "administrators" . to_string( ) ) ) ;
472- assert_eq ! ( match_obj2. get( "permitrootlogin" ) . unwrap( ) , & Value :: String ( "yes" . to_string ( ) ) ) ;
441+ assert_eq ! ( match_obj2. get( "permitrootlogin" ) . unwrap( ) , & Value :: Bool ( true ) ) ;
473442 }
474443
475444 #[ test]
@@ -561,7 +530,7 @@ match user developer
561530 let result: Map < String , Value > = parse_text_to_map ( input) . unwrap ( ) ;
562531 let match_array = result. get ( "match" ) . unwrap ( ) . as_array ( ) . unwrap ( ) ;
563532 let match_obj = match_array[ 0 ] . as_object ( ) . unwrap ( ) ;
564- assert_eq ! ( match_obj. get( "passwordauthentication" ) . unwrap( ) , & Value :: String ( "yes" . to_string ( ) ) ) ;
533+ assert_eq ! ( match_obj. get( "passwordauthentication" ) . unwrap( ) , & Value :: Bool ( true ) ) ;
565534 assert_eq ! ( match_obj. len( ) , 2 ) ;
566535 }
567536
@@ -588,8 +557,8 @@ match user alice,bob address 1.2.3.4/56
588557 assert_eq ! ( address_array. len( ) , 1 ) ;
589558 assert_eq ! ( address_array[ 0 ] , Value :: String ( "1.2.3.4/56" . to_string( ) ) ) ;
590559
591- assert_eq ! ( match_obj. get( "passwordauthentication" ) . unwrap( ) , & Value :: String ( "yes" . to_string ( ) ) ) ;
592- assert_eq ! ( match_obj. get( "allowtcpforwarding" ) . unwrap( ) , & Value :: String ( "no" . to_string ( ) ) ) ;
560+ assert_eq ! ( match_obj. get( "passwordauthentication" ) . unwrap( ) , & Value :: Bool ( true ) ) ;
561+ assert_eq ! ( match_obj. get( "allowtcpforwarding" ) . unwrap( ) , & Value :: Bool ( false ) ) ;
593562 }
594563
595564 #[ test]
0 commit comments