@@ -569,53 +569,19 @@ def self.dump_generic_module(mod, indent = '')
569
569
# @param missing [Boolean] dump only empty required options.
570
570
# @return [String] the string form of the information.
571
571
def self . dump_options ( mod , indent = '' , missing = false )
572
- options = mod . options . map { |_name , option | option }
573
- options_grouped_by_conditions = options . group_by ( &:conditions )
572
+ all_options = mod . options . map { |_name , option | option }
573
+
574
+ # separate mutually exclusive options from conditional options to format them differently
575
+ mutually_exclusive_options , conditional_options = all_options . partition { |option | option . mutual_exclusions . any? }
576
+ options_grouped_by_conditions = conditional_options . group_by ( &:conditions )
577
+ options_grouped_by_mutual_exclusivity = mutually_exclusive_options . group_by ( &:mutual_exclusions )
574
578
575
579
options_with_conditions = '' . dup
576
580
options_without_conditions = '' . dup
581
+ options_with_mutual_exclusivity = '' . dup
577
582
578
583
options_grouped_by_conditions . each do |conditions , options |
579
- tbl = Rex ::Text ::Table . new (
580
- 'Indent' => indent . length ,
581
- 'Columns' =>
582
- [
583
- 'Name' ,
584
- 'Current Setting' ,
585
- 'Required' ,
586
- 'Description'
587
- ] )
588
-
589
- options . sort_by ( &:name ) . each do |opt |
590
- name = opt . name
591
- if mod . datastore . is_a? ( Msf ::DataStoreWithFallbacks )
592
- val = mod . datastore [ name ]
593
- else
594
- val = mod . datastore [ name ] . nil? ? opt . default : mod . datastore [ name ]
595
- end
596
-
597
- next if ( opt . advanced? )
598
- next if ( opt . evasion? )
599
- next if ( missing && opt . valid? ( val ) )
600
-
601
- desc = opt . desc . dup
602
-
603
- # Hint at RPORT proto by regexing mixins
604
- if name == 'RPORT' && opt . kind_of? ( Msf ::OptPort )
605
- mod . class . included_modules . each do |m |
606
- case m . name
607
- when /tcp/i , /HttpClient$/
608
- desc << ' (TCP)'
609
- break
610
- when /udp/i
611
- desc << ' (UDP)'
612
- break
613
- end
614
- end
615
- end
616
-
617
- tbl << [ name , opt . display_value ( val ) , opt . required? ? "yes" : "no" , desc ]
618
- end
584
+ tbl = options_table ( missing , mod , options , indent )
619
585
620
586
next if conditions . any? && tbl . rows . empty?
621
587
@@ -627,10 +593,59 @@ def self.dump_options(mod, indent = '', missing = false)
627
593
end
628
594
end
629
595
630
- result = "#{ options_without_conditions } #{ options_with_conditions } "
596
+ options_grouped_by_mutual_exclusivity . each do |mutual_exclusions , options |
597
+ tbl = options_table ( missing , mod , options , indent )
598
+ options_with_mutual_exclusivity << "\n \n #{ indent } When not using #{ mutual_exclusions . join ( ', ' ) } :\n \n "
599
+ options_with_mutual_exclusivity << tbl . to_s
600
+ end
601
+
602
+ result = "#{ options_without_conditions } #{ options_with_conditions } #{ options_with_mutual_exclusivity } "
631
603
result
632
604
end
633
605
606
+ def self . options_table ( missing , mod , options , indent )
607
+ tbl = Rex ::Text ::Table . new (
608
+ 'Indent' => indent . length ,
609
+ 'Columns' =>
610
+ [
611
+ 'Name' ,
612
+ 'Current Setting' ,
613
+ 'Required' ,
614
+ 'Description'
615
+ ] )
616
+ options . sort_by ( &:name ) . each do |opt |
617
+ # Skip over advanced or evasion options
618
+ next if ( opt . advanced? || opt . evasion? )
619
+
620
+ name = opt . name
621
+ if mod . datastore . is_a? ( Msf ::DataStoreWithFallbacks )
622
+ val = mod . datastore [ name ]
623
+ else
624
+ val = mod . datastore [ name ] . nil? ? opt . default : mod . datastore [ name ]
625
+ end
626
+ next if ( missing && opt . valid? ( val ) )
627
+
628
+ desc = opt . desc . dup
629
+
630
+ # Hint at RPORT proto by regexing mixins
631
+ if name == 'RPORT' && opt . kind_of? ( Msf ::OptPort )
632
+ mod . class . included_modules . each do |m |
633
+ case m . name
634
+ when /tcp/i , /HttpClient$/
635
+ desc << ' (TCP)'
636
+ break
637
+ when /udp/i
638
+ desc << ' (UDP)'
639
+ break
640
+ end
641
+ end
642
+ end
643
+
644
+ tbl << [ name , opt . display_value ( val ) , opt . required? ? "yes" : "no" , desc ]
645
+ end
646
+ tbl
647
+ end
648
+
634
649
# Dumps the advanced options associated with the supplied module.
635
650
#
636
651
# @param mod [Msf::Module] the module.
0 commit comments