package main import ( "crypto/aes" "crypto/cipher" "crypto/md5" "crypto/rand" "crypto/sha512" "encoding/base64" "errors" "fmt" "io" "log" "net/http" "os" "strings" ) const ( UserFile = "loop_users" ) var ( EnvironmentVariables = map[string]string{ "LOOP_URL": "localhost:6006", "LOOP_SALT": "whatyoutalkingaboutwillus", "LOOP_DATA": ".", } ) func ConfigureEnvironment() { for key, value := range EnvironmentVariables { env := os.Getenv(key) if env == "" && value != "" { os.Setenv(key, value) } } } func main() { log.Print("Configuring environment...") ConfigureEnvironment() //http.HandleFunc("/", DefaultHandler) log.Fatal(http.ListenAndServe(address(), nil)) } // General stuff type Account struct { Username string `json:username` Passphrase string `json:passphrase` } func address() string { return os.Getenv("LOOP_URL") } // Security stuff func encodeBase64(data []byte) string { return base64.StdEncoding.EncodeToString(data) } func decodeBase64(data []byte) []byte { b, _ := base64.StdEncoding.DecodeString(string(data)) return b } func salt() string { return os.Getenv("LOOP_SALT") } func getSizedKey(key string) string { // Get the correct key length l := len(key) if l < 16 { for i := 0; i < 16-l; i++ { key += "." } } else if l < 24 { for i := 0; i < 24-l; i++ { key += "." } } else if l < 32 { for i := 0; i < 32-l; i++ { key += "." } } else { key = key[:32] } return key } func encrypt(text, passphrase string) ([]byte, error) { key := []byte(getSizedKey(passphrase)) block, err := aes.NewCipher(key) if err != nil { return nil, err } cipherText := make([]byte, aes.BlockSize+len(text)) iv := cipherText[:aes.BlockSize] if _, err := io.ReadFull(rand.Reader, iv); err != nil { return nil, err } encrypter := cipher.NewCFBEncrypter(block, iv) encrypter.XORKeyStream(cipherText[aes.BlockSize:], []byte(text)) return cipherText, nil } func decrypt(text []byte, passphrase string) ([]byte, error) { key := []byte(getSizedKey(passphrase)) block, err := aes.NewCipher(key) if err != nil { return nil, err } if len(text) < aes.BlockSize { return nil, errors.New("Cipher text too short") } iv := text[:aes.BlockSize] data := text[aes.BlockSize:] decrypter := cipher.NewCFBDecrypter(block, iv) decrypter.XORKeyStream(data, data) return data, nil } func hash(clearText, salt string) []byte { h := md5.New() h.Write([]byte(clearText)) return h.Sum(nil) } func hashCredentials(username, passphrase, salt string) []byte { clearText := fmt.Sprintf( "%s%s-%s", salt, strings.ToLower(username), strings.ToLower(passphrase)) sha := sha512.New() sha.Write([]byte(clearText)) return sha.Sum(nil) } func generatePassphrase(username, passphrase string) string { return encodeBase64(hashCredentials(username, passphrase, salt())) }