package models import ( "errors" "net/mail" "strconv" "strings" "time" "github.com/gophish/gophish/translations" ) // SMTP contains the attributes needed to handle the sending of campaign emails type SMTP struct { Id int64 `json:"id" gorm:"column:id; primary_key:yes"` UserId int64 `json:"-" gorm:"column:user_id"` Interface string `json:"interface_type" gorm:"column:interface_type"` Name string `json:"name"` Host string `json:"host"` Username string `json:"username,omitempty"` Password string `json:"password,omitempty"` FromAddress string `json:"from_address"` IgnoreCertErrors bool `json:"ignore_cert_errors"` ModifiedDate time.Time `json:"modified_date"` } // ErrFromAddressNotSpecified is thrown when there is no "From" address // specified in the SMTP configuration var ErrFromAddressNotSpecified = errors.New(translations.T("No From Address specified")) // ErrHostNotSpecified is thrown when there is no Host specified // in the SMTP configuration var ErrHostNotSpecified = errors.New(translations.T("No SMTP Host specified")) // ErrInvalidHost indicates that the SMTP server string is invalid var ErrInvalidHost = errors.New(translations.T("Invalid SMTP server address")) // TableName specifies the database tablename for Gorm to use func (s SMTP) TableName() string { return "smtp" } // Validate ensures that SMTP configs/connections are valid func (s *SMTP) Validate() error { switch { case s.FromAddress == "": return ErrFromAddressNotSpecified case s.Host == "": return ErrHostNotSpecified } _, err := mail.ParseAddress(s.FromAddress) if err != nil { return err } // Make sure addr is in host:port format hp := strings.Split(s.Host, ":") if len(hp) > 2 { return ErrInvalidHost } else if len(hp) < 2 { hp = append(hp, "25") } _, err = strconv.Atoi(hp[1]) if err != nil { return ErrInvalidHost } return err } // GetSMTPs returns the SMTPs owned by the given user. func GetSMTPs(uid int64) ([]SMTP, error) { ss := []SMTP{} err := db.Where("user_id=?", uid).Find(&ss).Error if err != nil { Logger.Println(err) } return ss, err } // GetSMTP returns the SMTP, if it exists, specified by the given id and user_id. func GetSMTP(id int64, uid int64) (SMTP, error) { s := SMTP{} err := db.Where("user_id=? and id=?", uid, id).Find(&s).Error if err != nil { Logger.Println(err) } return s, err } // GetSMTPByName returns the SMTP, if it exists, specified by the given name and user_id. func GetSMTPByName(n string, uid int64) (SMTP, error) { s := SMTP{} err := db.Where("user_id=? and name=?", uid, n).Find(&s).Error if err != nil { Logger.Println(err) } return s, err } // PostSMTP creates a new SMTP in the database. func PostSMTP(s *SMTP) error { err := s.Validate() if err != nil { Logger.Println(err) return err } // Insert into the DB err = db.Save(s).Error if err != nil { Logger.Println(err) } return err } // PutSMTP edits an existing SMTP in the database. // Per the PUT Method RFC, it presumes all data for a SMTP is provided. func PutSMTP(s *SMTP) error { err := s.Validate() if err != nil { Logger.Println(err) return err } err = db.Where("id=?", s.Id).Save(s).Error if err != nil { Logger.Println(err) } return err } // DeleteSMTP deletes an existing SMTP in the database. // An error is returned if a SMTP with the given user id and SMTP id is not found. func DeleteSMTP(id int64, uid int64) error { err = db.Where("user_id=?", uid).Delete(SMTP{Id: id}).Error if err != nil { Logger.Println(err) } return err }