Class: Msf::MCP::Config::Validator

Inherits:
Object
  • Object
show all
Defined in:
lib/msf/core/mcp/config/validator.rb

Constant Summary collapse

VALID_API_TYPES =
%w[messagepack json-rpc].freeze
VALID_TRANSPORTS =
%w[stdio http].freeze

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.validate!(config) ⇒ true

Validate configuration hash (class method)

Parameters:

  • config (Hash)

    Configuration hash to validate

Returns:

  • (true)

    If validation passes

Raises:



14
15
16
# File 'lib/msf/core/mcp/config/validator.rb', line 14

def self.validate!(config)
  new.validate!(config)
end

Instance Method Details

#validate!(config) ⇒ true

Validate configuration hash (instance method)

Parameters:

  • config (Hash)

    Configuration hash to validate

Returns:

  • (true)

    If validation passes

Raises:



23
24
25
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/msf/core/mcp/config/validator.rb', line 23

def validate!(config)
  errors = {}

  # Check msf_api section exists
  unless config[:msf_api].is_a?(Hash)
    errors[:msf_api] = "configuration section is required"
    raise ValidationError.new(errors)
  end

  # Validate API type
  if config[:msf_api][:type] && !VALID_API_TYPES.include?(config[:msf_api][:type])
    errors[:'msf_api.type'] = "must be one of the valid API types: #{VALID_API_TYPES.join(', ')}"
  end

  # Validate API type
  if config[:msf_api][:host] && config[:msf_api][:host].to_s.strip.empty?
    errors[:'msf_api.host'] = "must be a non-empty string"
  end

  # Validate mcp section type
  if config.key?(:mcp) && !config[:mcp].is_a?(Hash)
    errors[:mcp] = "must be a configuration hash"
  end

  # Validate transport
  if config[:mcp].is_a?(Hash) && config[:mcp][:transport] && !VALID_TRANSPORTS.include?(config[:mcp][:transport])
    errors[:'mcp.transport'] = "must be one of the valid transport: #{VALID_TRANSPORTS.join(', ')}"
  end

  # Validate port
  if config[:msf_api][:port]
    port = config[:msf_api][:port].to_i
    unless port.between?(1, 65535)
      errors[:'msf_api.port'] = "must be between 1 and 65535"
    end
  end

  # Validate SSL option
  if config[:msf_api].key?(:ssl) && ![true, false].include?(config[:msf_api][:ssl])
    errors[:'msf_api.ssl'] = "must be boolean (true or false)"
  end

  # Validate auto_start_rpc option
  if config[:msf_api].key?(:auto_start_rpc) && ![true, false].include?(config[:msf_api][:auto_start_rpc])
    errors[:'msf_api.auto_start_rpc'] = "must be boolean (true or false)"
  end

  # Validate MCP port
  if config[:mcp].is_a?(Hash) && config[:mcp][:port]
    port = config[:mcp][:port].to_i
    unless port.between?(1, 65535)
      errors[:'mcp.port'] = "must be between 1 and 65535"
    end
  end

  # Validate MCP Puma thread/worker settings
  if config[:mcp].is_a?(Hash)
    if config[:mcp].key?(:min_threads)
      unless config[:mcp][:min_threads].is_a?(Integer) && config[:mcp][:min_threads] >= 0
        errors[:'mcp.min_threads'] = "must be an integer >= 0"
      end
    end

    if config[:mcp].key?(:max_threads)
      unless config[:mcp][:max_threads].is_a?(Integer) && config[:mcp][:max_threads] >= 1
        errors[:'mcp.max_threads'] = "must be an integer >= 1"
      end
    end

    if config[:mcp].key?(:workers)
      unless config[:mcp][:workers].is_a?(Integer) && config[:mcp][:workers] >= 0
        errors[:'mcp.workers'] = "must be an integer >= 0"
      end
    end

    if config[:mcp].key?(:min_threads) && config[:mcp].key?(:max_threads)
      if config[:mcp][:min_threads].is_a?(Integer) && config[:mcp][:max_threads].is_a?(Integer) &&
         config[:mcp][:min_threads] > config[:mcp][:max_threads]
        errors[:'mcp.min_threads'] = "must be less than or equal to mcp.max_threads"
      end
    end
  end

  # Validate conditional requirements based on API type
  if config[:msf_api][:type] == 'messagepack'
    validate_messagepack_auth(config, errors)
  elsif config[:msf_api][:type] == 'json-rpc'
    validate_jsonrpc_auth(config, errors)
  end

  # Validate rate_limit section
  if config.key?(:rate_limit)
    if config[:rate_limit].is_a?(Hash)
      validate_rate_limit(config, errors)
    else
      errors[:rate_limit] = "must be a configuration hash"
    end
  end

  # Validate logging section
  if config.key?(:logging)
    if config[:logging].is_a?(Hash)
      validate_logging(config, errors)
    else
      errors[:logging] = "must be a configuration hash"
    end
  end

  # Raise error if any validation failed
  unless errors.empty?
    raise ValidationError.new(errors)
  end

  true
end