diff --git a/.gitignore b/.gitignore index 00268614..dab6c659 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,4 @@ _cgo_export.* _testmain.go *.exe +*.db diff --git a/api.go b/api.go index 6938ce6c..4c27681d 100644 --- a/api.go +++ b/api.go @@ -2,24 +2,36 @@ package main import ( "fmt" - "github.com/gorilla/mux" "net/http" + + "github.com/gorilla/mux" ) func API(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello api") } +//API_Campaigns returns a list of campaigns if requested via GET. +//If requested via POST, API_Campaigns creates a new campaign and returns a reference to it. func API_Campaigns(w http.ResponseWriter, r *http.Request) { + switch { + case r.Method == "GET": + + case r.Method == "POST": + fmt.Fprintf(w, "Hello POST!") + } fmt.Fprintf(w, "Hello api") } +//API_Campaigns_Id returns details about the requested campaign. If the campaign is not +//valid, API_Campaigns_Id returns null. func API_Campaigns_Id(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") vars := mux.Vars(r) fmt.Fprintf(w, "{\"method\" : \""+r.Method+"\", \"id\" : "+vars["id"]+"}") } +//API_Doc renders a template describing the API documentation. func API_Doc(w http.ResponseWriter, r *http.Request) { renderTemplate(w, "api_doc") } diff --git a/config.json b/config.json index 2ccf0715..a9be3f72 100644 --- a/config.json +++ b/config.json @@ -4,5 +4,6 @@ "host" : "smtp.example.com:25", "user" : "username", "pass" : "password" - } + }, + "dbpath" : "db/gophish.db" } \ No newline at end of file diff --git a/gophish.go b/gophish.go index da110080..d98b584a 100644 --- a/gophish.go +++ b/gophish.go @@ -26,7 +26,10 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ import ( + "database/sql" + "encoding/gob" "encoding/json" + "flag" "fmt" "io/ioutil" "net/http" @@ -34,15 +37,27 @@ import ( ) var config Config +var db sql.DB +var setupFlag = flag.Bool("setup", false, "Starts the initial setup process for Gophish") + +//init registers the necessary models to be saved in the session later +func init() { + gob.Register(&User{}) +} func main() { // Get the config file - config_file, e := ioutil.ReadFile("./config.json") - if e != nil { - fmt.Printf("File error: %v\n", e) + config_file, err := ioutil.ReadFile("./config.json") + defer db.Close() + if err != nil { + fmt.Printf("File error: %v\n", err) os.Exit(1) } json.Unmarshal(config_file, &config) + _, err = Setup() + if err != nil { + fmt.Println(err) + } fmt.Printf("Gophish server started at http://%s\n", config.URL) http.Handle("/", createRouter()) http.ListenAndServe(config.URL, nil) diff --git a/models.go b/models.go index 3b4f495b..e9ff21e2 100644 --- a/models.go +++ b/models.go @@ -6,22 +6,14 @@ type SMTPServer struct { Password string `json:"password"` } -type Email struct { - Subject string - Body string - To []string - Bcc []string - Cc []string - From string -} - type Config struct { - URL string `json:"url"` - SMTP SMTPServer `json:"smtp"` + URL string `json:"url"` + SMTP SMTPServer `json:"smtp"` + DBPath string `json:"dbpath"` } type User struct { - Id string + Id int Username string Hash string APIKey string diff --git a/route.go b/route.go index f156bb8d..5fa45de9 100644 --- a/route.go +++ b/route.go @@ -27,11 +27,12 @@ THE SOFTWARE. */ import ( + "html/template" + "net/http" + "github.com/gorilla/mux" "github.com/gorilla/securecookie" "github.com/gorilla/sessions" - "html/template" - "net/http" ) var store = sessions.NewCookieStore([]byte(securecookie.GenerateRandomKey(64))) @@ -66,7 +67,7 @@ func Register(w http.ResponseWriter, r *http.Request) { func Base(w http.ResponseWriter, r *http.Request) { session, _ := store.Get(r, "gophish") - // Example of saving session - will be removed. + // Example of using session - will be removed. session.Save(r, w) renderTemplate(w, "dashboard") } @@ -85,10 +86,27 @@ func Base_Campaigns(w http.ResponseWriter, r *http.Request) { } func Login(w http.ResponseWriter, r *http.Request) { - renderTemplate(w, "login") + switch { + case r.Method == "GET": + renderTemplate(w, "login") + case r.Method == "POST": + //Attempt to login + if login(r) { + session, _ := store.Get(r, "gophish") + session.Save(r, w) + http.Redirect(w, r, "/", 302) + } + } } func renderTemplate(w http.ResponseWriter, tmpl string) { t := template.Must(template.New("template").ParseFiles("templates/base.html", "templates/nav.html", "templates/"+tmpl+".html")) t.ExecuteTemplate(w, "base", "T") } + +func login(r *http.Request) bool { + //session, _ := store.Get(r, "gophish") + //session.Values["user"] = User{1, "jordan", "hash", "key"} + //user := session.Values["user"].(*User) + return true +} diff --git a/setup.go b/setup.go new file mode 100644 index 00000000..2d60e0c6 --- /dev/null +++ b/setup.go @@ -0,0 +1,39 @@ +package main + +import ( + "database/sql" + "fmt" + "os" + + _ "github.com/mattn/go-sqlite3" +) + +//Setup creates and returns the database needed by Gophish +func Setup() (*sql.DB, error) { + //If the file already exists, delete it and recreate it + if _, err := os.Stat(config.DBPath); err == nil { + os.Remove(config.DBPath) + } + fmt.Println("Creating db at " + config.DBPath) + db, err := sql.Open("sqlite3", config.DBPath) + if err != nil { + return nil, err + } + //Create the tables needed + _, err = db.Exec( + `CREATE TABLE Users (id INTEGER PRIMARY KEY AUTOINCREMENT, username TEXT, hash VARCHAR(32), apikey VARCHAR(32));`) + if err != nil { + return nil, err + } + //Create the default user + stmt, err := db.Prepare(`INSERT INTO Users (username, hash, apikey) VALUES (?, ?, ?);`) + defer stmt.Close() + if err != nil { + return nil, err + } + _, err = stmt.Exec("jordan", "12345678901234567890123456789012", "12345678901234567890123456789012") + if err != nil { + return nil, err + } + return db, nil +} diff --git a/templates/login.html b/templates/login.html index c51374f1..c80cf5de 100644 --- a/templates/login.html +++ b/templates/login.html @@ -1,6 +1,6 @@ {{define "content"}}