From f12af50d4631e4afc65c96c599941f40b4318bc5 Mon Sep 17 00:00:00 2001 From: Jordan Wright Date: Sat, 19 Nov 2016 10:37:22 -0600 Subject: [PATCH] Adding support for Mysql (#442) Thanks, @svigne1! Fixes #53 --- config.json | 3 +- config/config.go | 5 +++- controllers/api_test.go | 3 +- db/db_mysql/dbconf.yml | 5 ++++ .../migrations/20160118194630_init.sql | 28 +++++++++++++++++++ ...20160131153104_0.1.2_add_event_details.sql | 0 ...211211220_0.1.2_add_ignore_cert_errors.sql | 0 ...17211342_0.1.2_create_from_col_results.sql | 0 ...160225173824_0.1.2_capture_credentials.sql | 0 ...160227180335_0.1.2_store-smtp-settings.sql | 22 +++++++++++++++ .../20160317214457_0.2_redirect_url.sql | 0 ...20160605210903_0.2_campaign_scheduling.sql | 9 ++++++ db/{ => db_sqlite3}/dbconf.yml | 2 +- .../migrations/20160118194630_init.sql | 0 ...20160131153104_0.1.2_add_event_details.sql | 8 ++++++ ...211211220_0.1.2_add_ignore_cert_errors.sql | 8 ++++++ ...17211342_0.1.2_create_from_col_results.sql | 8 ++++++ ...160225173824_0.1.2_capture_credentials.sql | 9 ++++++ ...160227180335_0.1.2_store-smtp-settings.sql | 0 .../20160317214457_0.2_redirect_url.sql | 8 ++++++ ...20160605210903_0.2_campaign_scheduling.sql | 0 models/models.go | 27 +++++++++++++----- models/models_test.go | 3 +- 23 files changed, 136 insertions(+), 12 deletions(-) create mode 100644 db/db_mysql/dbconf.yml create mode 100644 db/db_mysql/migrations/20160118194630_init.sql rename db/{ => db_mysql}/migrations/20160131153104_0.1.2_add_event_details.sql (100%) rename db/{ => db_mysql}/migrations/20160211211220_0.1.2_add_ignore_cert_errors.sql (100%) rename db/{ => db_mysql}/migrations/20160217211342_0.1.2_create_from_col_results.sql (100%) rename db/{ => db_mysql}/migrations/20160225173824_0.1.2_capture_credentials.sql (100%) create mode 100644 db/db_mysql/migrations/20160227180335_0.1.2_store-smtp-settings.sql rename db/{ => db_mysql}/migrations/20160317214457_0.2_redirect_url.sql (100%) create mode 100644 db/db_mysql/migrations/20160605210903_0.2_campaign_scheduling.sql rename db/{ => db_sqlite3}/dbconf.yml (65%) rename db/{ => db_sqlite3}/migrations/20160118194630_init.sql (100%) create mode 100644 db/db_sqlite3/migrations/20160131153104_0.1.2_add_event_details.sql create mode 100644 db/db_sqlite3/migrations/20160211211220_0.1.2_add_ignore_cert_errors.sql create mode 100644 db/db_sqlite3/migrations/20160217211342_0.1.2_create_from_col_results.sql create mode 100644 db/db_sqlite3/migrations/20160225173824_0.1.2_capture_credentials.sql rename db/{ => db_sqlite3}/migrations/20160227180335_0.1.2_store-smtp-settings.sql (100%) create mode 100644 db/db_sqlite3/migrations/20160317214457_0.2_redirect_url.sql rename db/{ => db_sqlite3}/migrations/20160605210903_0.2_campaign_scheduling.sql (100%) diff --git a/config.json b/config.json index 893e7834..ec6a41d0 100644 --- a/config.json +++ b/config.json @@ -11,6 +11,7 @@ "cert_path" : "example.crt", "key_path": "example.key" }, + "db_name" : "sqlite3", "db_path" : "gophish.db", - "migrations_path" : "db/migrations/" + "migrations_prefix" : "db/db_" } diff --git a/config/config.go b/config/config.go index 401dcd79..74588b9f 100644 --- a/config/config.go +++ b/config/config.go @@ -26,8 +26,9 @@ type PhishServer struct { type Config struct { AdminConf AdminServer `json:"admin_server"` PhishConf PhishServer `json:"phish_server"` + DBName string `json:"db_name"` DBPath string `json:"db_path"` - MigrationsPath string `json:"migrations_path"` + MigrationsPath string `json:"migrations_prefix"` } // Conf contains the initialized configuration struct @@ -43,4 +44,6 @@ func init() { fmt.Printf("File error: %v\n", err) } json.Unmarshal(config_file, &Conf) + // Choosing the migrations directory based on the database used. + Conf.MigrationsPath = Conf.MigrationsPath + Conf.DBName } diff --git a/controllers/api_test.go b/controllers/api_test.go index 893d1f7c..867963e3 100644 --- a/controllers/api_test.go +++ b/controllers/api_test.go @@ -25,8 +25,9 @@ type ControllersSuite struct { var as *httptest.Server = httptest.NewUnstartedServer(handlers.CombinedLoggingHandler(os.Stdout, CreateAdminRouter())) func (s *ControllersSuite) SetupSuite() { + config.Conf.DBName = "sqlite3" config.Conf.DBPath = ":memory:" - config.Conf.MigrationsPath = "../db/migrations/" + config.Conf.MigrationsPath = "../db/db_sqlite3/migrations/" err := models.Setup() if err != nil { s.T().Fatalf("Failed creating database: %v", err) diff --git a/db/db_mysql/dbconf.yml b/db/db_mysql/dbconf.yml new file mode 100644 index 00000000..198e7e68 --- /dev/null +++ b/db/db_mysql/dbconf.yml @@ -0,0 +1,5 @@ +production: + driver: mysql + open: root:@(:3307)/gophish?charset=utf8&parseTime=True&loc=Local + dialect: mysql + import: github.com/go-sql-driver/mysql \ No newline at end of file diff --git a/db/db_mysql/migrations/20160118194630_init.sql b/db/db_mysql/migrations/20160118194630_init.sql new file mode 100644 index 00000000..f3a78152 --- /dev/null +++ b/db/db_mysql/migrations/20160118194630_init.sql @@ -0,0 +1,28 @@ + +-- +goose Up +-- SQL in section 'Up' is executed when this migration is applied +CREATE TABLE IF NOT EXISTS users (id integer primary key auto_increment,username varchar(255) NOT NULL UNIQUE,hash varchar(255),api_key varchar(255) NOT NULL UNIQUE ); +CREATE TABLE IF NOT EXISTS templates (id integer primary key auto_increment,user_id bigint,name varchar(255),subject varchar(255),text text,html text,modified_date datetime ); +CREATE TABLE IF NOT EXISTS targets (id integer primary key auto_increment,first_name varchar(255),last_name varchar(255),email varchar(255),position varchar(255) ); +CREATE TABLE IF NOT EXISTS smtp (smtp_id integer primary key auto_increment,campaign_id bigint,host varchar(255),username varchar(255),from_address varchar(255) ); +CREATE TABLE IF NOT EXISTS results (id integer primary key auto_increment,campaign_id bigint,user_id bigint,r_id varchar(255),email varchar(255),first_name varchar(255),last_name varchar(255),status varchar(255) NOT NULL ,ip varchar(255),latitude real,longitude real ); +CREATE TABLE IF NOT EXISTS pages (id integer primary key auto_increment,user_id bigint,name varchar(255),html text,modified_date datetime ); +CREATE TABLE IF NOT EXISTS groups (id integer primary key auto_increment,user_id bigint,name varchar(255),modified_date datetime ); +CREATE TABLE IF NOT EXISTS group_targets (group_id bigint,target_id bigint ); +CREATE TABLE IF NOT EXISTS events (id integer primary key auto_increment,campaign_id bigint,email varchar(255),time datetime,message varchar(255) ); +CREATE TABLE IF NOT EXISTS campaigns (id integer primary key auto_increment,user_id bigint,name varchar(255) NOT NULL ,created_date datetime,completed_date datetime,template_id bigint,page_id bigint,status varchar(255),url varchar(255) ); +CREATE TABLE IF NOT EXISTS attachments (id integer primary key auto_increment,template_id bigint,content text,type varchar(255),name varchar(255) ); + +-- +goose Down +-- SQL section 'Down' is executed when this migration is rolled back +DROP TABLE attachments; +DROP TABLE campaigns; +DROP TABLE events; +DROP TABLE group_targets; +DROP TABLE groups; +DROP TABLE pages; +DROP TABLE results; +DROP TABLE smtp; +DROP TABLE targets; +DROP TABLE templates; +DROP TABLE users; diff --git a/db/migrations/20160131153104_0.1.2_add_event_details.sql b/db/db_mysql/migrations/20160131153104_0.1.2_add_event_details.sql similarity index 100% rename from db/migrations/20160131153104_0.1.2_add_event_details.sql rename to db/db_mysql/migrations/20160131153104_0.1.2_add_event_details.sql diff --git a/db/migrations/20160211211220_0.1.2_add_ignore_cert_errors.sql b/db/db_mysql/migrations/20160211211220_0.1.2_add_ignore_cert_errors.sql similarity index 100% rename from db/migrations/20160211211220_0.1.2_add_ignore_cert_errors.sql rename to db/db_mysql/migrations/20160211211220_0.1.2_add_ignore_cert_errors.sql diff --git a/db/migrations/20160217211342_0.1.2_create_from_col_results.sql b/db/db_mysql/migrations/20160217211342_0.1.2_create_from_col_results.sql similarity index 100% rename from db/migrations/20160217211342_0.1.2_create_from_col_results.sql rename to db/db_mysql/migrations/20160217211342_0.1.2_create_from_col_results.sql diff --git a/db/migrations/20160225173824_0.1.2_capture_credentials.sql b/db/db_mysql/migrations/20160225173824_0.1.2_capture_credentials.sql similarity index 100% rename from db/migrations/20160225173824_0.1.2_capture_credentials.sql rename to db/db_mysql/migrations/20160225173824_0.1.2_capture_credentials.sql diff --git a/db/db_mysql/migrations/20160227180335_0.1.2_store-smtp-settings.sql b/db/db_mysql/migrations/20160227180335_0.1.2_store-smtp-settings.sql new file mode 100644 index 00000000..95432fd7 --- /dev/null +++ b/db/db_mysql/migrations/20160227180335_0.1.2_store-smtp-settings.sql @@ -0,0 +1,22 @@ + +-- +goose Up +-- SQL in section 'Up' is executed when this migration is applied +-- Move the relationship between campaigns and smtp to campaigns +ALTER TABLE campaigns ADD COLUMN smtp_id bigint; +-- Create a new table to store smtp records +DROP TABLE smtp; +CREATE TABLE smtp( + id integer primary key auto_increment, + user_id bigint, + interface_type varchar(255), + name varchar(255), + host varchar(255), + username varchar(255), + password varchar(255), + from_address varchar(255), + modified_date datetime, + ignore_cert_errors BOOLEAN +); +-- +goose Down +-- SQL section 'Down' is executed when this migration is rolled back + diff --git a/db/migrations/20160317214457_0.2_redirect_url.sql b/db/db_mysql/migrations/20160317214457_0.2_redirect_url.sql similarity index 100% rename from db/migrations/20160317214457_0.2_redirect_url.sql rename to db/db_mysql/migrations/20160317214457_0.2_redirect_url.sql diff --git a/db/db_mysql/migrations/20160605210903_0.2_campaign_scheduling.sql b/db/db_mysql/migrations/20160605210903_0.2_campaign_scheduling.sql new file mode 100644 index 00000000..47fb5a96 --- /dev/null +++ b/db/db_mysql/migrations/20160605210903_0.2_campaign_scheduling.sql @@ -0,0 +1,9 @@ + +-- +goose Up +-- SQL in section 'Up' is executed when this migration is applied +ALTER TABLE campaigns ADD COLUMN launch_date DATETIME; + +UPDATE campaigns SET launch_date = created_date; +-- +goose Down +-- SQL section 'Down' is executed when this migration is rolled back + diff --git a/db/dbconf.yml b/db/db_sqlite3/dbconf.yml similarity index 65% rename from db/dbconf.yml rename to db/db_sqlite3/dbconf.yml index 819cc99a..ae5350ba 100644 --- a/db/dbconf.yml +++ b/db/db_sqlite3/dbconf.yml @@ -2,4 +2,4 @@ production: driver: sqlite3 open: gophish.db dialect: sqlite3 - import: github.com/mattn/go-sqlite3 + import: github.com/mattn/go-sqlite3 \ No newline at end of file diff --git a/db/migrations/20160118194630_init.sql b/db/db_sqlite3/migrations/20160118194630_init.sql similarity index 100% rename from db/migrations/20160118194630_init.sql rename to db/db_sqlite3/migrations/20160118194630_init.sql diff --git a/db/db_sqlite3/migrations/20160131153104_0.1.2_add_event_details.sql b/db/db_sqlite3/migrations/20160131153104_0.1.2_add_event_details.sql new file mode 100644 index 00000000..e8cc90f1 --- /dev/null +++ b/db/db_sqlite3/migrations/20160131153104_0.1.2_add_event_details.sql @@ -0,0 +1,8 @@ + +-- +goose Up +-- SQL in section 'Up' is executed when this migration is applied +ALTER TABLE events ADD COLUMN details BLOB; + +-- +goose Down +-- SQL section 'Down' is executed when this migration is rolled back + diff --git a/db/db_sqlite3/migrations/20160211211220_0.1.2_add_ignore_cert_errors.sql b/db/db_sqlite3/migrations/20160211211220_0.1.2_add_ignore_cert_errors.sql new file mode 100644 index 00000000..f66183f5 --- /dev/null +++ b/db/db_sqlite3/migrations/20160211211220_0.1.2_add_ignore_cert_errors.sql @@ -0,0 +1,8 @@ + +-- +goose Up +-- SQL in section 'Up' is executed when this migration is applied +ALTER TABLE smtp ADD COLUMN ignore_cert_errors BOOLEAN; + +-- +goose Down +-- SQL section 'Down' is executed when this migration is rolled back + diff --git a/db/db_sqlite3/migrations/20160217211342_0.1.2_create_from_col_results.sql b/db/db_sqlite3/migrations/20160217211342_0.1.2_create_from_col_results.sql new file mode 100644 index 00000000..42f828fe --- /dev/null +++ b/db/db_sqlite3/migrations/20160217211342_0.1.2_create_from_col_results.sql @@ -0,0 +1,8 @@ + +-- +goose Up +-- SQL in section 'Up' is executed when this migration is applied +ALTER TABLE results ADD COLUMN position VARCHAR(255); + +-- +goose Down +-- SQL section 'Down' is executed when this migration is rolled back + diff --git a/db/db_sqlite3/migrations/20160225173824_0.1.2_capture_credentials.sql b/db/db_sqlite3/migrations/20160225173824_0.1.2_capture_credentials.sql new file mode 100644 index 00000000..eff45de5 --- /dev/null +++ b/db/db_sqlite3/migrations/20160225173824_0.1.2_capture_credentials.sql @@ -0,0 +1,9 @@ + +-- +goose Up +-- SQL in section 'Up' is executed when this migration is applied +ALTER TABLE pages ADD COLUMN capture_credentials BOOLEAN; +ALTER TABLE pages ADD COLUMN capture_passwords BOOLEAN; + +-- +goose Down +-- SQL section 'Down' is executed when this migration is rolled back + diff --git a/db/migrations/20160227180335_0.1.2_store-smtp-settings.sql b/db/db_sqlite3/migrations/20160227180335_0.1.2_store-smtp-settings.sql similarity index 100% rename from db/migrations/20160227180335_0.1.2_store-smtp-settings.sql rename to db/db_sqlite3/migrations/20160227180335_0.1.2_store-smtp-settings.sql diff --git a/db/db_sqlite3/migrations/20160317214457_0.2_redirect_url.sql b/db/db_sqlite3/migrations/20160317214457_0.2_redirect_url.sql new file mode 100644 index 00000000..cc016569 --- /dev/null +++ b/db/db_sqlite3/migrations/20160317214457_0.2_redirect_url.sql @@ -0,0 +1,8 @@ + +-- +goose Up +-- SQL in section 'Up' is executed when this migration is applied +ALTER TABLE pages ADD COLUMN redirect_url VARCHAR(255); + +-- +goose Down +-- SQL section 'Down' is executed when this migration is rolled back + diff --git a/db/migrations/20160605210903_0.2_campaign_scheduling.sql b/db/db_sqlite3/migrations/20160605210903_0.2_campaign_scheduling.sql similarity index 100% rename from db/migrations/20160605210903_0.2_campaign_scheduling.sql rename to db/db_sqlite3/migrations/20160605210903_0.2_campaign_scheduling.sql diff --git a/models/models.go b/models/models.go index 580da4d3..08e79e88 100644 --- a/models/models.go +++ b/models/models.go @@ -10,6 +10,7 @@ import ( "bitbucket.org/liamstask/goose/lib/goose" + _ "github.com/go-sql-driver/mysql" "github.com/gophish/gophish/config" "github.com/jinzhu/gorm" _ "github.com/mattn/go-sqlite3" // Blank import needed to import sqlite3 @@ -61,6 +62,23 @@ func generateSecureKey() string { return fmt.Sprintf("%x", k) } +func chooseDBDriver(name, openStr string) goose.DBDriver { + d := goose.DBDriver{Name: name, OpenStr: openStr} + + switch name { + case "mysql": + d.Import = "github.com/go-sql-driver/mysql" + d.Dialect = &goose.MySqlDialect{} + + // Default database is sqlite3 + default: + d.Import = "github.com/mattn/go-sqlite3" + d.Dialect = &goose.Sqlite3Dialect{} + } + + return d +} + // Setup initializes the Conn object // It also populates the Gophish Config object func Setup() error { @@ -72,12 +90,7 @@ func Setup() error { migrateConf := &goose.DBConf{ MigrationsDir: config.Conf.MigrationsPath, Env: "production", - Driver: goose.DBDriver{ - Name: "sqlite3", - OpenStr: config.Conf.DBPath, - Import: "github.com/mattn/go-sqlite3", - Dialect: &goose.Sqlite3Dialect{}, - }, + Driver: chooseDBDriver(config.Conf.DBName, config.Conf.DBPath), } // Get the latest possible migration latest, err := goose.GetMostRecentDBVersion(migrateConf.MigrationsDir) @@ -86,7 +99,7 @@ func Setup() error { return err } // Open our database connection - db, err = gorm.Open("sqlite3", config.Conf.DBPath) + db, err = gorm.Open(config.Conf.DBName, config.Conf.DBPath) db.LogMode(false) db.SetLogger(Logger) db.DB().SetMaxOpenConns(1) diff --git a/models/models_test.go b/models/models_test.go index 3b5dd6c0..13bea6b0 100644 --- a/models/models_test.go +++ b/models/models_test.go @@ -18,8 +18,9 @@ type ModelsSuite struct{} var _ = check.Suite(&ModelsSuite{}) func (s *ModelsSuite) SetUpSuite(c *check.C) { + config.Conf.DBName = "sqlite3" config.Conf.DBPath = ":memory:" - config.Conf.MigrationsPath = "../db/migrations/" + config.Conf.MigrationsPath = "../db/db_sqlite3/migrations/" err := Setup() if err != nil { c.Fatalf("Failed creating database: %v", err)