mirror of
https://github.com/gophish/gophish
synced 2024-11-14 00:07:19 +00:00
0558da90fe
This commit allows self-signed certificates to be used in upstream IMAP connections.
154 lines
4.5 KiB
Go
154 lines
4.5 KiB
Go
package models
|
|
|
|
import (
|
|
"errors"
|
|
"net"
|
|
"time"
|
|
|
|
log "github.com/gophish/gophish/logger"
|
|
)
|
|
|
|
const DefaultIMAPFolder = "INBOX"
|
|
const DefaultIMAPFreq = 60 // Every 60 seconds
|
|
|
|
// IMAP contains the attributes needed to handle logging into an IMAP server to check
|
|
// for reported emails
|
|
type IMAP struct {
|
|
UserId int64 `json:"-" gorm:"column:user_id"`
|
|
Enabled bool `json:"enabled"`
|
|
Host string `json:"host"`
|
|
Port uint16 `json:"port,string,omitempty"`
|
|
Username string `json:"username"`
|
|
Password string `json:"password"`
|
|
TLS bool `json:"tls"`
|
|
IgnoreCertErrors bool `json:"ignore_cert_errors"`
|
|
Folder string `json:"folder"`
|
|
RestrictDomain string `json:"restrict_domain"`
|
|
DeleteReportedCampaignEmail bool `json:"delete_reported_campaign_email"`
|
|
LastLogin time.Time `json:"last_login,omitempty"`
|
|
ModifiedDate time.Time `json:"modified_date"`
|
|
IMAPFreq uint32 `json:"imap_freq,string,omitempty"`
|
|
}
|
|
|
|
// ErrIMAPHostNotSpecified is thrown when there is no Host specified
|
|
// in the IMAP configuration
|
|
var ErrIMAPHostNotSpecified = errors.New("No IMAP Host specified")
|
|
|
|
// ErrIMAPPortNotSpecified is thrown when there is no Port specified
|
|
// in the IMAP configuration
|
|
var ErrIMAPPortNotSpecified = errors.New("No IMAP Port specified")
|
|
|
|
// ErrInvalidIMAPHost indicates that the IMAP server string is invalid
|
|
var ErrInvalidIMAPHost = errors.New("Invalid IMAP server address")
|
|
|
|
// ErrInvalidIMAPPort indicates that the IMAP Port is invalid
|
|
var ErrInvalidIMAPPort = errors.New("Invalid IMAP Port")
|
|
|
|
// ErrIMAPUsernameNotSpecified is thrown when there is no Username specified
|
|
// in the IMAP configuration
|
|
var ErrIMAPUsernameNotSpecified = errors.New("No Username specified")
|
|
|
|
// ErrIMAPPasswordNotSpecified is thrown when there is no Password specified
|
|
// in the IMAP configuration
|
|
var ErrIMAPPasswordNotSpecified = errors.New("No Password specified")
|
|
|
|
// ErrInvalidIMAPFreq is thrown when the frequency for polling the
|
|
// IMAP server is invalid
|
|
var ErrInvalidIMAPFreq = errors.New("Invalid polling frequency")
|
|
|
|
// TableName specifies the database tablename for Gorm to use
|
|
func (im IMAP) TableName() string {
|
|
return "imap"
|
|
}
|
|
|
|
// Validate ensures that IMAP configs/connections are valid
|
|
func (im *IMAP) Validate() error {
|
|
switch {
|
|
case im.Host == "":
|
|
return ErrIMAPHostNotSpecified
|
|
case im.Port == 0:
|
|
return ErrIMAPPortNotSpecified
|
|
case im.Username == "":
|
|
return ErrIMAPUsernameNotSpecified
|
|
case im.Password == "":
|
|
return ErrIMAPPasswordNotSpecified
|
|
}
|
|
|
|
// Set the default value for Folder
|
|
if im.Folder == "" {
|
|
im.Folder = DefaultIMAPFolder
|
|
}
|
|
|
|
// Make sure im.Host is an IP or hostname. NB will fail if unable to resolve the hostname.
|
|
ip := net.ParseIP(im.Host)
|
|
_, err := net.LookupHost(im.Host)
|
|
if ip == nil && err != nil {
|
|
return ErrInvalidIMAPHost
|
|
}
|
|
|
|
// Make sure 1 >= port <= 65535
|
|
if im.Port < 1 || im.Port > 65535 {
|
|
return ErrInvalidIMAPPort
|
|
}
|
|
|
|
// Make sure the polling frequency is between every 30 seconds and every year
|
|
// If not set it to the default
|
|
if im.IMAPFreq < 30 || im.IMAPFreq > 31540000 {
|
|
im.IMAPFreq = DefaultIMAPFreq
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// GetIMAP returns the IMAP server owned by the given user.
|
|
func GetIMAP(uid int64) ([]IMAP, error) {
|
|
im := []IMAP{}
|
|
count := 0
|
|
err := db.Where("user_id=?", uid).Find(&im).Count(&count).Error
|
|
|
|
if err != nil {
|
|
log.Error(err)
|
|
return im, err
|
|
}
|
|
return im, nil
|
|
}
|
|
|
|
// PostIMAP updates IMAP settings for a user in the database.
|
|
func PostIMAP(im *IMAP, uid int64) error {
|
|
err := im.Validate()
|
|
if err != nil {
|
|
log.Error(err)
|
|
return err
|
|
}
|
|
|
|
// Delete old entry. TODO: Save settings and if fails to Save below replace with original
|
|
err = DeleteIMAP(uid)
|
|
if err != nil {
|
|
log.Error(err)
|
|
return err
|
|
}
|
|
|
|
// Insert new settings into the DB
|
|
err = db.Save(im).Error
|
|
if err != nil {
|
|
log.Error("Unable to save to database: ", err.Error())
|
|
}
|
|
return err
|
|
}
|
|
|
|
// DeleteIMAP deletes the existing IMAP in the database.
|
|
func DeleteIMAP(uid int64) error {
|
|
err := db.Where("user_id=?", uid).Delete(&IMAP{}).Error
|
|
if err != nil {
|
|
log.Error(err)
|
|
}
|
|
return err
|
|
}
|
|
|
|
func SuccessfulLogin(im *IMAP) error {
|
|
err := db.Model(&im).Where("user_id = ?", im.UserId).Update("last_login", time.Now().UTC()).Error
|
|
if err != nil {
|
|
log.Error("Unable to update database: ", err.Error())
|
|
}
|
|
return err
|
|
}
|