github.com/jonathaningram/gophish@v0.3.1-0.20170829042651-ac3fe6aeae6c/util/util.go (about) 1 package util 2 3 import ( 4 "crypto/ecdsa" 5 "crypto/elliptic" 6 "crypto/rand" 7 "crypto/x509" 8 "crypto/x509/pkix" 9 "encoding/csv" 10 "encoding/pem" 11 "errors" 12 "fmt" 13 "io" 14 "io/ioutil" 15 "log" 16 "math/big" 17 "net/http" 18 "net/mail" 19 "os" 20 "time" 21 22 "github.com/gophish/gophish/models" 23 "github.com/jordan-wright/email" 24 ) 25 26 // Logger is used to send logging messages to stdout. 27 var Logger = log.New(os.Stdout, " ", log.Ldate|log.Ltime|log.Lshortfile) 28 29 // ParseMail takes in an HTTP Request and returns an Email object 30 // TODO: This function will likely be changed to take in a []byte 31 func ParseMail(r *http.Request) (email.Email, error) { 32 e := email.Email{} 33 m, err := mail.ReadMessage(r.Body) 34 if err != nil { 35 fmt.Println(err) 36 } 37 body, err := ioutil.ReadAll(m.Body) 38 e.HTML = body 39 return e, err 40 } 41 42 // ParseCSV contains the logic to parse the user provided csv file containing Target entries 43 func ParseCSV(r *http.Request) ([]models.Target, error) { 44 mr, err := r.MultipartReader() 45 ts := []models.Target{} 46 if err != nil { 47 return ts, err 48 } 49 for { 50 part, err := mr.NextPart() 51 if err == io.EOF { 52 break 53 } 54 // Skip the "submit" part 55 if part.FileName() == "" { 56 continue 57 } 58 defer part.Close() 59 reader := csv.NewReader(part) 60 reader.TrimLeadingSpace = true 61 record, err := reader.Read() 62 if err == io.EOF { 63 break 64 } 65 fi := -1 66 li := -1 67 ei := -1 68 pi := -1 69 fn := "" 70 ln := "" 71 ea := "" 72 ps := "" 73 for i, v := range record { 74 switch { 75 case v == "First Name": 76 fi = i 77 case v == "Last Name": 78 li = i 79 case v == "Email": 80 ei = i 81 case v == "Position": 82 pi = i 83 } 84 } 85 for { 86 record, err := reader.Read() 87 if err == io.EOF { 88 break 89 } 90 if fi != -1 { 91 fn = record[fi] 92 } 93 if li != -1 { 94 ln = record[li] 95 } 96 if ei != -1 { 97 ea = record[ei] 98 } 99 if pi != -1 { 100 ps = record[pi] 101 } 102 t := models.Target{ 103 FirstName: fn, 104 LastName: ln, 105 Email: ea, 106 Position: ps, 107 } 108 ts = append(ts, t) 109 } 110 } 111 return ts, nil 112 } 113 114 // CheckAndCreateSSL is a helper to setup self-signed certificates for the administrative interface. 115 func CheckAndCreateSSL(cp string, kp string) error { 116 // Check whether there is an existing SSL certificate and/or key, and if so, abort execution of this function 117 if _, err := os.Stat(cp); !os.IsNotExist(err) { 118 return nil 119 } 120 if _, err := os.Stat(kp); !os.IsNotExist(err) { 121 return nil 122 } 123 124 Logger.Printf("Creating new self-signed certificates for administration interface...\n") 125 126 priv, err := ecdsa.GenerateKey(elliptic.P384(), rand.Reader) 127 128 notBefore := time.Now() 129 // Generate a certificate that lasts for 10 years 130 notAfter := notBefore.Add(10 * 365 * 24 * time.Hour) 131 132 serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) 133 serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) 134 135 if err != nil { 136 return errors.New(fmt.Sprintf("TLS Certificate Generation: Failed to generate a random serial number: %s", err)) 137 } 138 139 template := x509.Certificate{ 140 SerialNumber: serialNumber, 141 Subject: pkix.Name{ 142 Organization: []string{"Gophish"}, 143 }, 144 NotBefore: notBefore, 145 NotAfter: notAfter, 146 147 KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, 148 ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, 149 BasicConstraintsValid: true, 150 } 151 152 derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, priv.Public(), priv) 153 if err != nil { 154 return errors.New(fmt.Sprintf("TLS Certificate Generation: Failed to create certificate: %s", err)) 155 } 156 157 certOut, err := os.Create(cp) 158 if err != nil { 159 return errors.New(fmt.Sprintf("TLS Certificate Generation: Failed to open %s for writing: %s", cp, err)) 160 } 161 pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}) 162 certOut.Close() 163 164 keyOut, err := os.OpenFile(kp, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) 165 if err != nil { 166 return errors.New(fmt.Sprintf("TLS Certificate Generation: Failed to open %s for writing", kp)) 167 } 168 169 b, err := x509.MarshalECPrivateKey(priv) 170 if err != nil { 171 return errors.New(fmt.Sprintf("TLS Certificate Generation: Unable to marshal ECDSA private key: %v", err)) 172 } 173 174 pem.Encode(keyOut, &pem.Block{Type: "EC PRIVATE KEY", Bytes: b}) 175 keyOut.Close() 176 177 Logger.Println("TLS Certificate Generation complete") 178 return nil 179 }