github.com/benoitkugler/goacve@v0.0.0-20201217100549-151ce6e55dc8/logs/def.go (about) 1 // Ce package définit les paramètres de connexion 2 // nécessaire aux différents services (mail, serveur, base de données, etc) 3 package logs 4 5 import ( 6 "crypto/aes" 7 "crypto/cipher" 8 "crypto/md5" 9 "crypto/rand" 10 "encoding/hex" 11 "errors" 12 "fmt" 13 "io" 14 "log" 15 mrd "math/rand" 16 "net/smtp" 17 "strconv" 18 "strings" 19 ) 20 21 var debugEmails = [4]string{ 22 "x.ben.x@free.fr", "bench26@gmail.com", "benoit.kugler@ens-lyon.fr", "benoit.kugler@inria.fr", 23 } 24 25 // SMTP enregistre les informations de connection 26 type SMTP struct { 27 Host, Password string 28 29 // Should be a valid adress mail 30 User string 31 Port int 32 33 // Adresse à laquelle répondre 34 ReplyTo string 35 36 // Si false, envoie tous les mails sur une même adresse. 37 Prod bool 38 } 39 40 func (creds SMTP) GetFromAuth() (string, smtp.Auth) { 41 from := fmt.Sprintf("%s:%d", creds.Host, creds.Port) 42 auth := smtp.PlainAuth("", creds.User, creds.Password, creds.Host) 43 return from, auth 44 } 45 46 func (creds SMTP) GetTo(to string) string { 47 if !creds.Prod { // sécurité 48 oldTo := to 49 to = debugEmails[mrd.Intn(4)] 50 log.Printf("Dev mode : changement de destinataire : %s ---> %s", oldTo, to) 51 } 52 return strings.TrimSpace(to) 53 } 54 55 type DB struct { 56 Host, Name, User, Password string 57 Port int 58 } 59 60 type Joomeo struct { 61 Apikey, Login, Password string 62 } 63 64 type CredencesHelloAsso struct { 65 Id string 66 Key string 67 } 68 69 type offuscateur struct { 70 m, a, b int64 // m * b > a 71 } 72 73 func (o offuscateur) crypte(id int64) int64 { 74 return (id+o.b)*o.m - o.a 75 } 76 77 func (o offuscateur) parse(entry int) (id int64, ok bool) { 78 a := int64(entry) + o.a 79 if a%o.m != 0 { 80 return 0, false 81 } 82 return a/o.m - o.b, true 83 } 84 85 type OffuscLabelVirement struct { 86 offuscateur 87 } 88 89 func (o OffuscLabelVirement) Offusc(id int64) string { 90 return fmt.Sprintf("ACVE: %d", o.crypte(id)) 91 } 92 93 func (o OffuscLabelVirement) Parse(entry int) (id int64, err error) { 94 out, ok := o.parse(entry) 95 if !ok { 96 return 0, fmt.Errorf("label de virement invalide : %d", entry) 97 } 98 return out, nil 99 } 100 101 type OffuscIdVote struct { 102 offuscateur 103 } 104 105 func (o OffuscIdVote) Offusc(id int64) string { 106 return fmt.Sprintf("%d", o.crypte(id)) 107 } 108 109 func (o OffuscIdVote) Parse(entryS string) (id int64, err error) { 110 entry, err := strconv.Atoi(entryS) 111 if err != nil { 112 return 0, fmt.Errorf("lien de vote non décodable : %s", err) 113 } 114 out, ok := o.parse(entry) 115 if !ok { 116 return 0, fmt.Errorf("lien de vote invalide : %d", entry) 117 } 118 return out, nil 119 } 120 121 type OffuscIdDirecteur struct { 122 offuscateur 123 } 124 125 // Password renvoie un mot de passe constant en fonction de 'id' 126 func (o OffuscIdDirecteur) Password(id int64) string { 127 lenWord, L := 4, len(offuscPasswordDir) 128 index := int(uint(id)) % L 129 if index > L-lenWord { 130 index -= lenWord 131 } 132 133 nb := o.crypte(id) 134 return offuscPasswordDir[index:index+lenWord] + fmt.Sprintf("%d", nb) 135 } 136 137 type Encrypteur []byte 138 139 func NewEncrypteur(key string) Encrypteur { 140 hasher := md5.New() 141 if _, err := hasher.Write([]byte(key)); err != nil { 142 log.Fatal(err) 143 } 144 return []byte(hex.EncodeToString(hasher.Sum(nil))) 145 } 146 147 func (pass Encrypteur) Encrypt(data []byte) ([]byte, error) { 148 block, _ := aes.NewCipher(pass) 149 gcm, err := cipher.NewGCM(block) 150 if err != nil { 151 return nil, err 152 } 153 nonce := make([]byte, gcm.NonceSize()) 154 if _, err = io.ReadFull(rand.Reader, nonce); err != nil { 155 return nil, err 156 } 157 ciphertext := gcm.Seal(nonce, nonce, data, nil) 158 return ciphertext, nil 159 } 160 161 func (pass Encrypteur) Decrypt(data []byte) ([]byte, error) { 162 block, err := aes.NewCipher(pass) 163 if err != nil { 164 return nil, err 165 } 166 gcm, err := cipher.NewGCM(block) 167 if err != nil { 168 return nil, err 169 } 170 nonceSize := gcm.NonceSize() 171 if len(data) <= nonceSize { 172 return nil, errors.New("data too short") 173 } 174 nonce, ciphertext := data[:nonceSize], data[nonceSize:] 175 plaintext, err := gcm.Open(nil, nonce, ciphertext, nil) 176 return plaintext, err 177 }