@@ -314,17 +314,28 @@ def workspace
314
314
end
315
315
316
316
317
+ # @note Does nothing unless {#migrated} is +true+ and {#modules_caching} is
318
+ # +false+.
319
+ #
320
+ # Destroys all Mdm::ModuleDetails in the database.
321
+ #
322
+ # @return [void]
317
323
def purge_all_module_details
318
324
return if not self . migrated
319
325
return if self . modules_caching
320
326
321
327
::ActiveRecord ::Base . connection_pool . with_connection do
322
328
Mdm ::ModuleDetail . destroy_all
323
329
end
324
-
325
- true
326
330
end
327
331
332
+ # Destroys the old Mdm::ModuleDetail and creates a new Mdm::ModuleDetail for
333
+ # any module with an Mdm::ModuleDetail where the modification time of the
334
+ # Mdm::ModuleDetail#file differs from the Mdm::ModuleDetail#mtime. If the
335
+ # Mdm::ModuleDetail#file no only exists on disk, then the Mdm::ModuleDetail
336
+ # is just destroyed without a new one being created.
337
+ #
338
+ # @return [void]
328
339
def update_all_module_details
329
340
return if not self . migrated
330
341
return if self . modules_caching
@@ -334,106 +345,110 @@ def update_all_module_details
334
345
self . modules_cached = false
335
346
self . modules_caching = true
336
347
337
- :: ActiveRecord ::Base . connection_pool . with_connection {
348
+ ActiveRecord ::Base . connection_pool . with_connection do
338
349
339
- refresh = [ ]
340
- skipped = [ ]
350
+ refresh = [ ]
351
+ skipped = [ ]
341
352
342
- Mdm ::ModuleDetail . find_each do |md |
353
+ Mdm ::ModuleDetail . find_each do |md |
343
354
344
- unless md . ready
345
- refresh << md
346
- next
347
- end
355
+ unless md . ready
356
+ refresh << md
357
+ next
358
+ end
348
359
349
- unless md . file and ::File . exists? ( md . file )
350
- refresh << md
351
- next
352
- end
360
+ unless md . file and ::File . exists? ( md . file )
361
+ refresh << md
362
+ next
363
+ end
353
364
354
- if ::File . mtime ( md . file ) . to_i != md . mtime . to_i
355
- refresh << md
356
- next
357
- end
365
+ if ::File . mtime ( md . file ) . to_i != md . mtime . to_i
366
+ refresh << md
367
+ next
368
+ end
358
369
359
- skipped << [ md . mtype , md . refname ]
360
- end
370
+ skipped << [ md . mtype , md . refname ]
371
+ end
361
372
362
- refresh . each { |md | md . destroy }
363
- refresh = nil
364
-
365
- [
366
- [ 'exploit ', framework . exploits ] ,
367
- [ 'auxiliary ', framework . auxiliary ] ,
368
- [ 'post ', framework . post ] ,
369
- [ 'payload ', framework . payloads ] ,
370
- [ 'encoder ', framework . encoders ] ,
371
- [ 'nop' , framework . nops ]
372
- ] . each do |mt |
373
- mt [ 1 ] . keys . sort . each do | mn |
374
- next if skipped . include? ( [ mt [ 0 ] , mn ] )
375
- obj = mt [ 1 ] . create ( mn )
376
- next if not obj
377
- begin
378
- update_module_details ( obj )
379
- rescue :: Exception
380
- elog ( "Error updating module details for #{ obj . fullname } : #{ $! . class } #{ $! } " )
373
+ refresh . each { |md | md . destroy }
374
+
375
+ [
376
+ [ 'exploit' , framework . exploits ] ,
377
+ [ 'auxiliary ', framework . auxiliary ] ,
378
+ [ 'post ', framework . post ] ,
379
+ [ 'payload ', framework . payloads ] ,
380
+ [ 'encoder ', framework . encoders ] ,
381
+ [ 'nop ', framework . nops ]
382
+ ] . each do | mt |
383
+ mt [ 1 ] . keys . sort . each do |mn |
384
+ next if skipped . include? ( [ mt [ 0 ] , mn ] )
385
+ obj = mt [ 1 ] . create ( mn )
386
+ next if not obj
387
+ begin
388
+ update_module_details ( obj )
389
+ rescue :: Exception
390
+ elog ( "Error updating module details for #{ obj . fullname } : #{ $! . class } #{ $! } " )
391
+ end
381
392
end
382
393
end
383
- end
384
394
385
- self . framework . cache_initialized = true
386
- self . framework . cache_thread = nil
395
+ self . framework . cache_initialized = true
396
+ end
387
397
388
- self . modules_cached = true
398
+ # in reverse order of section before with_connection block
389
399
self . modules_caching = false
390
-
391
- nil
392
-
393
- }
400
+ self . modules_cached = true
401
+ self . framework . cache_thread = nil
394
402
end
395
403
396
- def update_module_details ( obj )
404
+ # Creates an Mdm::ModuleDetail from a module instance.
405
+ #
406
+ # @param module_instance [Msf::Module] a metasploit module instance.
407
+ # @return [void]
408
+ def update_module_details ( module_instance )
397
409
return if not self . migrated
398
410
399
- :: ActiveRecord ::Base . connection_pool . with_connection {
400
- info = module_to_details_hash ( obj )
401
- bits = info . delete ( :bits ) || [ ]
402
-
403
- md = Mdm :: ModuleDetail . create ( info )
404
- bits . each do |args |
405
- otype , vals = args
406
- case otype
407
- when :author
408
- md . add_author ( vals [ :name ] , vals [ :email ] )
409
- when :action
410
- md . add_action ( vals [ :name ] )
411
- when :arch
412
- md . add_arch ( vals [ :name ] )
413
- when :platform
414
- md . add_platform ( vals [ :name ] )
415
- when :target
416
- md . add_target ( vals [ :index ] , vals [ :name ] )
417
- when :ref
418
- md . add_ref ( vals [ :name ] )
419
- when :mixin
420
- # md.add_mixin(vals[:name])
411
+ ActiveRecord ::Base . connection_pool . with_connection do
412
+ info = module_to_details_hash ( module_instance )
413
+ bits = info . delete ( :bits ) || [ ]
414
+ module_detail = Mdm :: ModuleDetail . create ( info )
415
+
416
+ bits . each do |args |
417
+ otype , vals = args
418
+
419
+ case otype
420
+ when :action
421
+ module_detail . add_action ( vals [ :name ] )
422
+ when :arch
423
+ module_detail . add_arch ( vals [ :name ] )
424
+ when :author
425
+ module_detail . add_author ( vals [ :name ] , vals [ :email ] )
426
+ when :platform
427
+ module_detail . add_platform ( vals [ :name ] )
428
+ when :ref
429
+ module_detail . add_ref ( vals [ :name ] )
430
+ when :target
431
+ module_detail . add_target ( vals [ :index ] , vals [ :name ] )
432
+ end
421
433
end
422
- end
423
-
424
- md . ready = true
425
- md . save
426
- md . id
427
434
428
- }
435
+ module_detail . ready = true
436
+ module_detail . save
437
+ end
429
438
end
430
439
440
+ # Destroys Mdm::ModuleDetail if one exists for the given
441
+ # Mdm::ModuleDetail#mtype and Mdm::ModuleDetail#refname.
442
+ #
443
+ # @param mtype [String] module type.
444
+ # @param refname [String] module reference name.
445
+ # @return [void]
431
446
def remove_module_details ( mtype , refname )
432
447
return if not self . migrated
433
- :: ActiveRecord :: Base . connection_pool . with_connection {
434
- md = Mdm :: ModuleDetail . find ( :conditions => [ 'mtype = ? and refname = ?' , mtype , refname ] )
435
- md . destroy if md
436
- }
448
+
449
+ ActiveRecord :: Base . connection_pool . with_connection do
450
+ Mdm :: ModuleDetail . where ( :mtype => mtype , :refname => refname ) . destroy_all
451
+ end
437
452
end
438
453
439
454
def module_to_details_hash ( m )
@@ -525,17 +540,31 @@ def module_to_details_hash(m)
525
540
526
541
527
542
528
- #
529
543
# This provides a standard set of search filters for every module.
530
- # The search terms are in the form of:
531
- # {
532
- # "text" => [ [ "include_term1", "include_term2", ...], [ "exclude_term1", "exclude_term2"], ... ],
533
- # "cve" => [ [ "include_term1", "include_term2", ...], [ "exclude_term1", "exclude_term2"], ... ]
534
- # }
535
544
#
536
- # Returns true on no match, false on match
545
+ # Supported keywords with the format <keyword>:<search_value>:
546
+ # +app+:: If +client+ then matches +'passive'+ stance modules, otherwise matches +'active' stance modules.
547
+ # +author+:: Matches modules with the given author email or name.
548
+ # +bid+:: Matches modules with the given Bugtraq ID.
549
+ # +cve+:: Matches modules with the given CVE ID.
550
+ # +edb+:: Matches modules with the given Exploit-DB ID.
551
+ # +name+:: Matches modules with the given full name or name.
552
+ # +os+, +platform+:: Matches modules with the given platform or target name.
553
+ # +osvdb+:: Matches modules with the given OSVDB ID.
554
+ # +ref+:: Matches modules with the given reference ID.
555
+ # +type+:: Matches modules with the given type.
556
+ #
557
+ # Any text not associated with a keyword is matched against the description,
558
+ # the full name, and the name of the module; the name of the module actions;
559
+ # the name of the module archs; the name of the module authors; the name of
560
+ # module platform; the module refs; or the module target.
537
561
#
538
- def search_modules ( search_string , inclusive = false )
562
+ # @param search_string [String] a string of space separated keyword pairs or
563
+ # free form text.
564
+ # @return [false] if search_string is +nil+
565
+ # @return [Array<Mdm::ModuleDetail>] module details that matched
566
+ # +search_string+
567
+ def search_modules ( search_string )
539
568
return false if not search_string
540
569
541
570
search_string += " "
@@ -589,8 +618,6 @@ def search_modules(search_string, inclusive=false)
589
618
xv = "%#{ kv } %"
590
619
where_q << ' ( module_platforms.name ILIKE ? OR module_targets.name ILIKE ? ) '
591
620
where_v << [ xv , xv ]
592
- when 'port'
593
- # TODO
594
621
when 'type'
595
622
where_q << ' ( module_details.mtype = ? ) '
596
623
where_v << [ kv ]
@@ -617,7 +644,7 @@ def search_modules(search_string, inclusive=false)
617
644
"LEFT OUTER JOIN module_targets ON module_details.id = module_targets.module_detail_id " +
618
645
"LEFT OUTER JOIN module_platforms ON module_details.id = module_platforms.module_detail_id "
619
646
) .
620
- where ( where_q . join ( inclusive ? " OR " : " AND " ) , *( where_v . flatten ) ) .
647
+ where ( where_q . join ( " AND " ) , *( where_v . flatten ) ) .
621
648
# Compatibility for Postgres installations prior to 9.1 - doesn't have support for wildcard group by clauses
622
649
group ( "module_details.id, module_details.mtime, module_details.file, module_details.mtype, module_details.refname, module_details.fullname, module_details.name, module_details.rank, module_details.description, module_details.license, module_details.privileged, module_details.disclosure_date, module_details.default_target, module_details.default_action, module_details.stance, module_details.ready" )
623
650
0 commit comments