package common import ( "bufio" "crypto/rand" "encoding/base32" "encoding/binary" "fmt" "io" "math/big" "strings" ) func AddStringSliceItem(item string, slice *[]string) { for _, i := range *slice { if i == item { return } } *slice = append(*slice, item) } func RemoveStringSliceItem(item string, slice *[]string) { for i, listItem := range *slice { if item == listItem { (*slice)[i] = (*slice)[len(*slice)-1] *slice = (*slice)[:len(*slice)-1] } } } func ResponseContainsSubstring(reader io.ReadCloser, target string) (bool, error) { scanner := bufio.NewScanner(reader) for scanner.Scan() { if strings.Contains(scanner.Text(), target) { return true, nil } } if err := scanner.Err(); err != nil { return false, err } return false, nil } var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789") // RandomID returns a random string of the given length. func RandomID(length int) string { b := make([]rune, length) for i := range b { randInt, _ := rand.Int(rand.Reader, big.NewInt(int64(len(letters)))) b[i] = letters[randInt.Int64()] } return string(b) } func GetAccountNumFromAWSID(AWSID string) (string, error) { // Function to get the account number from an AWS ID (no verification required) // Source: https://medium.com/@TalBeerySec/a-short-note-on-aws-key-id-f88cc4317489 if len(AWSID) < 4 { return "", fmt.Errorf("AWSID is too short") } if AWSID[4] == 'I' || AWSID[4] == 'J' { return "", fmt.Errorf("Can't get account number from AKIAJ/ASIAJ or AKIAI/ASIAI keys") } trimmedAWSID := AWSID[4:] decodedBytes, err := base32.StdEncoding.WithPadding(base32.NoPadding).DecodeString(strings.ToUpper(trimmedAWSID)) if err != nil { return "", err } if len(decodedBytes) < 6 { return "", fmt.Errorf("Decoded AWSID is too short") } data := make([]byte, 8) copy(data[2:], decodedBytes[0:6]) z := binary.BigEndian.Uint64(data) const mask uint64 = 0x7fffffffff80 accountNum := (z & mask) >> 7 return fmt.Sprintf("%012d", accountNum), nil }