dun dun dun - warvox - VoIP based wardialing tool, forked from rapid7/warvox.
DIR Log
DIR Files
DIR Refs
DIR README
---
DIR commit e74d9b6a4be8bdbcb582358098f62a3743e772ce
DIR parent d05b856011c786fc8dee983a873228607ff7a9a0
HTML Author: HD Moore <hd_moore@rapid7.com>
Date: Wed, 3 Aug 2011 22:42:01 +0000
dun dun dun
Diffstat:
M Makefile | 13 +++----------
M etc/warvox.conf | 2 +-
M lib/warvox.rb | 2 +-
D src/iaxrecord/Makefile | 4 ----
D src/iaxrecord/iaxrecord.c | 310 -------------------------------
M web/Gemfile | 3 +--
M web/Gemfile.lock | 2 ++
M web/app/controllers/analyze_contro… | 70 +++++++++++++++----------------
M web/config/database.yml | 30 +++++++++---------------------
M web/config/environments/production… | 3 ++-
10 files changed, 53 insertions(+), 386 deletions(-)
---
DIR diff --git a/Makefile b/Makefile
@@ -3,16 +3,12 @@ all: test
test: install
bin/verify_install.rb
-install: bundler iaxrecord dtmf2num ruby-kissfft db
- cp -a src/iaxrecord/iaxrecord bin/
+install: bundler dtmf2num ruby-kissfft db
cp -a src/dtmf2num/dtmf2num bin/
ruby-kissfft-install: ruby-kissfft
cp -a src/ruby-kissfft/kissfft.so lib/
-iaxrecord:
- make -C src/iaxrecord/
-
dtmf2num:
make -C src/dtmf2num/
@@ -20,10 +16,8 @@ ruby-kissfft:
( cd src/ruby-kissfft/; ruby extconf.rb )
make -C src/ruby-kissfft/
-db: web/db/production.sqlite3
+db:
@echo "Checking the database.."
-
-web/db/production.sqlite3: ruby-kissfft-install
(cd web; RAILS_ENV=production rake db:migrate )
bundler:
@@ -39,6 +33,5 @@ bundler:
clean:
( cd src/ruby-kissfft/; ruby extconf.rb )
make -C src/ruby-kissfft/ clean
- make -C src/iaxrecord/ clean
make -C src/dtmf2num/ clean
- rm -f bin/iaxrecord lib/kissfft.so
+ rm -f lib/kissfft.so
DIR diff --git a/etc/warvox.conf b/etc/warvox.conf
@@ -24,7 +24,7 @@ tools:
gnuplot: gnuplot
sox: sox
lame: lame
- iaxrecord: %BASE%/bin/iaxrecord
+ iaxrecord: %BASE%/bin/iaxrecord.rb
dtmf2num: %BASE%/bin/dtmf2num
#
DIR diff --git a/lib/warvox.rb b/lib/warvox.rb
@@ -11,7 +11,7 @@ require 'warvox/db'
# Global configuration
module WarVOX
- VERSION = '1.2.0'
+ VERSION = '1.9.9-dev'
Base = File.expand_path(File.join(File.dirname(__FILE__), '..'))
Conf = File.expand_path(File.join(Base, 'etc', 'warvox.conf'))
JobManager = WarVOX::JobQueue.new
DIR diff --git a/src/iaxrecord/Makefile b/src/iaxrecord/Makefile
@@ -1,4 +0,0 @@
-all:
- gcc -Wall -o iaxrecord iaxrecord.c -liaxclient
-clean:
- rm -f iaxrecord *.o
DIR diff --git a/src/iaxrecord/iaxrecord.c b/src/iaxrecord/iaxrecord.c
@@ -1,310 +0,0 @@
-/*
- * IAXRecord: a utility for recording audio on an outbound IAX call
- *
- * Copyright (C) 2009-2010 Rapid7 LLC - H D Moore <hdm[at]metasploit.com>
- *
- * Based on simpleclient from the IAXClient distribution
- *
- * Copyright (C) 1999, Linux Support Services, Inc.
- *
- * Mark Spencer <markster@linux-support.net>
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License
- */
-
-#define TEST_MODE 1
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <time.h>
-#include <signal.h>
-
-#include <iaxclient.h>
-
-int initialized = 0;
-int debug = 0;
-int audio = 0;
-int busy = 0;
-int fail = 1;
-int done = 0;
-
-float silence_threshold = 0.0f;
-int call_state = 0;
-int call_trace = -1;
-int call_done = 0;
-int call_bytes = 0;
-char *iax_out;
-int reg_id;
-
-#ifdef TEST_MODE
-int call_end = 0;
-unsigned char empty_buf[200];
-#endif
-
-void signal_handler(int signum) {
- if ( signum == SIGTERM || signum == SIGINT ) {
- done = 1;
- }
-}
-
-void usage(char **argv) {
- fprintf(stdout, "Usage: %s -s [server] -u [user] -p <pass> -o [output] -n [number] -c <callerid> -l <seconds> [-D]\n", argv[0]);
- exit(1);
-}
-
-int state_event_callback(struct iaxc_ev_call_state call) {
- if(call.state & IAXC_CALL_STATE_BUSY) busy = 1;
- if(call.state & IAXC_CALL_STATE_COMPLETE) fail = 0;
-
- call_state = call.state;
-
- if(debug) {
- fprintf(stdout, "STATE: ");
- if(call.state & IAXC_CALL_STATE_FREE)
- fprintf(stdout, "F");
-
- if(call.state & IAXC_CALL_STATE_ACTIVE)
- fprintf(stdout, "A");
-
- if(call.state & IAXC_CALL_STATE_OUTGOING)
- fprintf(stdout, "O");
-
- if(call.state & IAXC_CALL_STATE_RINGING)
- fprintf(stdout, "R");
-
- if(call.state & IAXC_CALL_STATE_COMPLETE)
- fprintf(stdout, "C");
-
- if(call.state & IAXC_CALL_STATE_SELECTED)
- fprintf(stdout, "S");
-
- if(call.state & IAXC_CALL_STATE_BUSY)
- fprintf(stdout, "B");
-
- if(call.state & IAXC_CALL_STATE_TRANSFER)
- fprintf(stdout, "T");
-
- fprintf(stdout, "\n");
- fflush(stdout);
- }
-
- return 0;
-}
-
-int audio_event_callback( struct iaxc_ev_audio audio) {
-
- if(call_trace == -1 && !fail) {
- call_trace = open(iax_out, O_CREAT|O_TRUNC|O_WRONLY, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
- }
-
- if(call_trace != -1) {
- if(debug) printf("audio data: format=%d encoded=%d size=%d state=%d\n", audio.format, audio.encoded, audio.size, call_state);
- write(call_trace, audio.data, audio.size);
- call_bytes += audio.size;
- }
- return 0;
-}
-
-int iaxc_callback(iaxc_event e) {
- switch(e.type) {
- case IAXC_EVENT_TEXT:
- // fprintf(stdout, "TEXT: %s\n", e.ev.text.message);
- return ( debug ? 0 : 1 );
- break;
- case IAXC_EVENT_STATE:
- return state_event_callback(e.ev.call);
- break;
- case IAXC_EVENT_AUDIO:
- return audio_event_callback(e.ev.audio);
- break;
- default:
- return 0;
- break;
- }
-}
-
-
-int main(int argc, char **argv) {
-
- char *iax_host = NULL;
- char *iax_user = NULL;
- char *iax_pass = "";
- char *iax_num = NULL;
- char *iax_cid = "15555555555";
- char *iax_name = "";
- int iax_sec = 20;
- int call_id = 0;
- char dest[1024];
- time_t stime, etime;
-
- int c;
- extern char *optarg;
- extern int optind, optopt;
-
- while ((c = getopt(argc, argv, ":hs:u:p:c:o:n:l:N:DA")) != -1) {
- switch(c) {
- case 'h':
- usage(argv);
- break;
- case 's':
- iax_host = optarg;
- break;
- case 'u':
- iax_user = optarg;
- break;
- case 'p':
- iax_pass = optarg;
- break;
- case 'c':
- iax_cid = optarg;
- break;
- case 'o':
- iax_out = optarg;
- break;
- case 'n':
- iax_num = optarg;
- break;
- case 'l':
- iax_sec = atoi(optarg);
- break;
- case 'N':
- iax_name = optarg;
- break;
- case 'D':
- debug = 1;
- break;
- case 'A':
- audio = 1;
- break;
- }
- }
-
-
-/*
- Version 2.2.x of iaxclient has a new function called iaxc_set_test_mode(1), which disables
- audio processing for us. This will not be backported to 2.0.x however...
-*/
-
- if(! (iax_host && iax_user && iax_num && iax_out)) usage(argv);
-
- snprintf(dest, sizeof(dest), "%s:%s@%s/%s", iax_user, iax_pass, iax_host, iax_num);
- iaxc_set_video_prefs(IAXC_VIDEO_PREF_CAPTURE_DISABLE | IAXC_VIDEO_PREF_SEND_DISABLE);
- iaxc_set_audio_prefs(IAXC_AUDIO_PREF_SEND_DISABLE);
-
- if(! debug) {
- fclose(stderr);
- stderr = fopen("/dev/null", "w");
- }
-
- fprintf(stdout, "STARTED %s BYTES=%d FILE=%s\n", iax_num, call_bytes, iax_out);
-
- /* install signal handler to catch CRTL-Cs */
- signal(SIGINT, signal_handler);
- signal(SIGTERM, signal_handler);
-
- /* enable test mode */
-#ifdef TEST_MODE
- iaxc_set_test_mode(1);
-#endif
-
- /* forcible disable pulse audio if the audio flag is not set (-A) */
- // if(! audio) setenv("PULSE_SERVER", "255.255.255.255", 1);
-
- setenv("ALSA_PCM_CARD", "pcm.null", 1);
- setenv("ALSA_CARD", "pcm.null", 1);
- setenv("ALSA_DEVICE", "pcm.null", 1);
-
- if(debug) fprintf(stderr, ">> INITIALIZING\n");
- if ( iaxc_initialize(1) ) {
- fprintf(stdout, "error: Could not initialize iaxclient!\n");
- exit(0);
- }
-
- initialized = 1;
- if(debug) fprintf(stderr, ">> INITIALIZED\n");
-
- iaxc_set_audio_output(audio ? 0 : 1);
- iaxc_set_callerid (iax_name, iax_cid);
- iaxc_set_formats(IAXC_FORMAT_ULAW | IAXC_FORMAT_ALAW, IAXC_FORMAT_ULAW | IAXC_FORMAT_ALAW);
-
- // Causes problems for some asterix servers, not sure why yet
- // iaxc_set_silence_threshold(silence_threshold);
-
- if(debug) fprintf(stderr, ">> STARTING PROCESSING THREAD\n");
- iaxc_set_event_callback(iaxc_callback);
- iaxc_start_processing_thread();
- if(debug) fprintf(stderr, ">> STARTED PROCESSING THREAD\n");
-
- iaxc_set_audio_prefs(IAXC_AUDIO_PREF_RECV_REMOTE_RAW);
-
- if(debug) fprintf(stderr, ">> REGISTERING\n") ;
- reg_id = iaxc_register(iax_user, iax_pass, iax_host);
- if(debug) fprintf(stderr, ">> REGISTERED: %d\n", reg_id);
-
- if(debug) fprintf(stderr, ">> CALLING\n");
- call_id = iaxc_call(dest);
- if(debug) fprintf(stderr, ">> CALLED: %d\n", call_id);
-
- stime = time(NULL);
- etime = 0;
-
- if(debug) fprintf(stderr, ">> WAITING\n");
- if(call_id >= 0) {
- iaxc_select_call(call_id);
- while((unsigned int)(time(NULL))-(unsigned int)stime < iax_sec) {
- if(done) break;
- if(call_state & IAXC_CALL_STATE_COMPLETE && ! etime) etime = time(NULL);
- if(call_state & IAXC_CALL_STATE_BUSY) break;
- if(iaxc_first_free_call() == call_id) break;
- iaxc_millisleep(250);
-
-#ifdef TEST_MODE
- /* we need do send something to receive data... I don't know why... */
- if( !call_end && call_state & IAXC_CALL_STATE_COMPLETE )
- iaxc_push_audio(&empty_buf[0], 200, 200);
-#endif
-
- }
- } else {
- fail = 1;
- }
-
- if(debug) fprintf(stderr, ">> DONE\n");
-
- if(! etime) time(&etime);
-
- fprintf(stdout, "COMPLETED %s BYTES=%d FILE=%s FAIL=%d BUSY=%d RINGTIME=%d\n",
- iax_num,
- call_bytes,
- iax_out,
- fail,
- busy,
- (unsigned int)(etime) - (unsigned int)(stime)
- );
-
-
- iaxc_dump_call();
- iaxc_millisleep(500);
- iaxc_stop_processing_thread();
- iaxc_shutdown();
- return(0);
-}
-
-/*
-
-Note about ring times vs ring counts:
- http://en.wikipedia.org/wiki/Ringtone#Ringing_signal
- The ringing pattern is known as ring cadence. This only applies to POTS fixed phones, where
- the high voltage ring signal is switched on and off to create the ringing pattern. In North
- America, the standard ring cadence is "2-4", or two seconds of ringing followed by four
- seconds of silence. In Australia and the UK, the standard ring cadence is 400 ms on, 200 ms
- off, 400 ms on, 2000 ms off. These patterns may vary from region to region, and other
- patterns are used in different countries around the world.
-
-ring count US = ringtime / 6.0
-ring count UK = ringtime / 3.0
-*/
DIR diff --git a/web/Gemfile b/web/Gemfile
@@ -5,8 +5,7 @@ gem 'rails', '3.0.1'
# Bundle edge Rails instead:
# gem 'rails', :git => 'git://github.com/rails/rails.git'
-gem 'sqlite3-ruby', :require => 'sqlite3'
-
+gem 'pg', '0.11'
# Use unicorn as the web server
# gem 'unicorn'
DIR diff --git a/web/Gemfile.lock b/web/Gemfile.lock
@@ -47,6 +47,7 @@ GEM
mime-types (~> 1.16)
treetop (~> 1.4.8)
mime-types (1.16)
+ pg (0.11.0)
polyglot (0.3.1)
rack (1.2.1)
rack-mount (0.6.13)
@@ -77,6 +78,7 @@ PLATFORMS
ruby
DEPENDENCIES
+ pg (= 0.11)
rails (= 3.0.1)
sqlite3-ruby
will_paginate!
DIR diff --git a/web/app/controllers/analyze_controller.rb b/web/app/controllers/analyze_controller.rb
@@ -1,9 +1,9 @@
class AnalyzeController < ApplicationController
layout 'warvox'
-
+
def index
@jobs = DialJob.paginate(
- :page => params[:page],
+ :page => params[:page],
:order => 'id DESC',
:per_page => 30
)
@@ -13,7 +13,7 @@ class AnalyzeController < ApplicationController
@job_id = params[:id]
@dial_job = DialJob.find(@job_id)
@shown = params[:show]
-
+
@g1 = Ezgraphix::Graphic.new(:c_type => 'col3d', :div_name => 'calls_pie1')
@g1.render_options(:caption => 'Detected Lines by Type', :y_name => 'Lines', :w => 700, :h => 300)
@@ -26,38 +26,38 @@ class AnalyzeController < ApplicationController
:conditions => ['dial_job_id = ? and line_type = ?', @job_id, k]
)
end
-
+
@g1.data = res_types
if(@shown and @shown != 'all')
@results = DialResult.where(:dial_job_id => @job_id).paginate(
- :page => params[:page],
+ :page => params[:page],
:order => 'number ASC',
:per_page => 10,
:conditions => [ 'completed = ? and processed = ? and busy = ? and line_type = ?', true, true, false, @shown ]
- )
+ )
else
@results = DialResult.where(:dial_job_id => @job_id).paginate(
- :page => params[:page],
+ :page => params[:page],
:order => 'number ASC',
:per_page => 10,
:conditions => [ 'completed = ? and processed = ? and busy = ?', true, true, false ]
)
end
-
+
@filters = []
@filters << { :scope => "all", :label => "All" }
res_types.keys.each do |t|
@filters << { :scope => t.to_s.downcase, :label => t.to_s }
end
-
+
end
def show
@job_id = params[:id]
@dial_job = DialJob.find(@job_id)
@shown = params[:show]
-
+
@g1 = Ezgraphix::Graphic.new(:c_type => 'col3d', :div_name => 'calls_pie1')
@g1.render_options(:caption => 'Detected Lines by Type', :y_name => 'Lines', :w => 700, :h => 300)
@@ -70,31 +70,31 @@ class AnalyzeController < ApplicationController
:conditions => ['dial_job_id = ? and line_type = ?', @job_id, k]
)
end
-
+
@g1.data = res_types
if(@shown and @shown != 'all')
@results = DialJob.where(:id => @job_id).paginate(
- :page => params[:page],
+ :page => params[:page],
:order => 'number ASC',
:per_page => 20,
:conditions => [ 'completed = ? and processed = ? and busy = ? and line_type = ?', true, true, false, @shown ]
- )
+ )
else
@results = DialJob.where(:id => @job_id).paginate(
- :page => params[:page],
+ :page => params[:page],
:order => 'number ASC',
:per_page => 20,
:conditions => [ 'completed = ? and processed = ? and busy = ?', true, true, false ]
)
end
-
+
@filters = []
@filters << { :scope => "all", :label => "All" }
res_types.keys.each do |t|
@filters << { :scope => t.to_s.downcase, :label => t.to_s }
end
-
+
end
@@ -102,42 +102,40 @@ class AnalyzeController < ApplicationController
def resource
ctype = 'text/html'
cpath = nil
-
+ cdata = "File not found"
+
res = DialResult.find(params[:result_id])
- if(res and res.processed and res.rawfile)
+
+ if res
case params[:type]
when 'big_sig'
ctype = 'image/png'
- cpath = res.rawfile.gsub(/\..*/, '') + '_big.png'
+ cdata = res.png_sig_freq
when 'big_sig_dots'
ctype = 'image/png'
- cpath = res.rawfile.gsub(/\..*/, '') + '_big_dots.png'
+ cdata = res.png_big_dots
when 'small_sig'
ctype = 'image/png'
- cpath = res.rawfile.gsub(/\..*/, '') + '.png'
+ cdata = res.png_sig
+ when 'big_freq'
+ ctype = 'image/png'
+ cdata = res.png_big_freq
+ when 'small_freq'
+ ctype = 'image/png'
+ cdata = res.png_sig_freq
when 'mp3'
ctype = 'audio/mpeg'
- cpath = res.rawfile.gsub(/\..*/, '') + '.mp3'
+ cdata = res.mp3
when 'sig'
ctype = 'text/plain'
- cpath = res.rawfile.gsub(/\..*/, '') + '.sig'
+ cdata = res.fprint
when 'raw'
ctype = 'octet/binary-stream'
- cpath = res.rawfile
- when 'big_freq'
- ctype = 'image/png'
- cpath = res.rawfile.gsub(/\..*/, '') + '_freq_big.png'
- when 'small_freq'
- ctype = 'image/png'
- cpath = res.rawfile.gsub(/\..*/, '') + '_freq.png'
+ cdata = res.audio
end
end
-
- cdata = "File not found"
- if(cpath and File.readable?(cpath))
- cdata = File.read(cpath, File.size(cpath))
- end
-
+
send_data(cdata, :type => ctype, :disposition => 'inline')
end
end
+
DIR diff --git a/web/config/database.yml b/web/config/database.yml
@@ -1,22 +1,10 @@
-# SQLite version 3.x
-# gem install sqlite3-ruby (not necessary on OS X Leopard)
-development:
- adapter: sqlite3
- database: db/development.sqlite3
- pool: 5
- timeout: 5000
-
-# Warning: The database defined as "test" will be erased and
-# re-generated from your development database when you run "rake".
-# Do not set this db to the same as development or production.
-test:
- adapter: sqlite3
- database: db/test.sqlite3
- pool: 5
- timeout: 5000
-
production:
- adapter: sqlite3
- database: db/production.sqlite3
- pool: 5
- timeout: 5000
+ adapter: postgresql
+ database: warvox
+ username: warvox
+ password: "<yourpass>"
+ host: 127.0.0.1
+ port: 5433
+ pool: 100
+ timeout: 5
+
DIR diff --git a/web/config/environments/production.rb b/web/config/environments/production.rb
@@ -6,7 +6,7 @@ Web::Application.configure do
config.cache_classes = true
# Full error reports are disabled and caching is turned on
- config.consider_all_requests_local = true
+ config.consider_all_requests_local = false
config.action_controller.perform_caching = true
# Specifies the header that your server uses for sending files
@@ -47,3 +47,4 @@ Web::Application.configure do
# Send deprecation notices to registered listeners
config.active_support.deprecation = :notify
end
+