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  }