Files
fleet/cmd/android-amapi-mock/seed_android.go
T

96 lines
3.2 KiB
Go

//go:build ignore
// Usage: go run seed_android.go <private_key_32bytes> <enterprise_id> <pubsub_token>
//
// Generates SQL to seed android_enterprises and mdm_config_assets with
// values encrypted using the given Fleet server private key.
//
// Example:
// go run seed_android.go 'TwmSR]%_$x7$rt[VveeRjjc$3c18ln:2' LC03k6enk8 my-pubsub-token
// # Pipe output to mysql to import
package main
import (
"crypto/aes"
"crypto/cipher"
"crypto/md5" //nolint:gosec
"crypto/rand"
"encoding/hex"
"fmt"
"io"
"os"
)
func main() {
if len(os.Args) != 4 {
fmt.Fprintf(os.Stderr, "usage: %s <private_key> <enterprise_id> <pubsub_token>\n", os.Args[0])
os.Exit(1)
}
key := os.Args[1]
if len(key) < 32 {
fmt.Fprintf(os.Stderr, "private key must be at least 32 bytes, got %d\n", len(key))
os.Exit(1)
}
key = key[:32]
enterpriseID := os.Args[2]
pubsubToken := os.Args[3]
// Encrypt the pubsub token
encToken, err := encrypt([]byte(pubsubToken), key)
if err != nil {
fmt.Fprintf(os.Stderr, "encrypt pubsub token: %v\n", err)
os.Exit(1)
}
// Encrypt a fleet server secret (can be any value, mock doesn't validate it)
fleetSecret := "mock-fleet-server-secret-for-loadtest"
encSecret, err := encrypt([]byte(fleetSecret), key)
if err != nil {
fmt.Fprintf(os.Stderr, "encrypt fleet secret: %v\n", err)
os.Exit(1)
}
hexToken := hex.EncodeToString(encToken)
hexSecret := hex.EncodeToString(encSecret)
md5Token := md5Hex(encToken)
md5Secret := md5Hex(encSecret)
fmt.Println("-- Seed Android MDM for load testing")
fmt.Println("-- Generated by seed_android.go")
fmt.Println()
fmt.Println("-- Clean up any existing android data")
fmt.Println("DELETE FROM android_devices;")
fmt.Println("DELETE FROM hosts WHERE platform = 'android';")
fmt.Println("DELETE FROM android_enterprises;")
fmt.Println("DELETE FROM mdm_config_assets WHERE name IN ('android_pubsub_token', 'android_fleet_server_secret');")
fmt.Println()
fmt.Printf("INSERT INTO android_enterprises (signup_name, enterprise_id, signup_token, pubsub_topic_id, user_id) VALUES ('loadtest-signup', '%s', 'loadtest-token', 'loadtest-topic', 1);\n", enterpriseID)
fmt.Println()
fmt.Printf("INSERT INTO mdm_config_assets (name, value, md5_checksum) VALUES ('android_pubsub_token', 0x%s, 0x%s);\n", hexToken, md5Token)
fmt.Printf("INSERT INTO mdm_config_assets (name, value, md5_checksum) VALUES ('android_fleet_server_secret', 0x%s, 0x%s);\n", hexSecret, md5Secret)
fmt.Println()
fmt.Println("-- Enable Android MDM")
fmt.Println("UPDATE app_config_json SET json_value = JSON_SET(json_value, '$.mdm.android_enabled_and_configured', true) WHERE id = 1;")
}
func encrypt(plainText []byte, privateKey string) ([]byte, error) {
block, err := aes.NewCipher([]byte(privateKey))
if err != nil {
return nil, fmt.Errorf("create cipher: %w", err)
}
aesGCM, err := cipher.NewGCM(block)
if err != nil {
return nil, fmt.Errorf("create gcm: %w", err)
}
nonce := make([]byte, aesGCM.NonceSize())
if _, err = io.ReadFull(rand.Reader, nonce); err != nil {
return nil, fmt.Errorf("generate nonce: %w", err)
}
return aesGCM.Seal(nonce, nonce, plainText, nil), nil
}
func md5Hex(data []byte) string {
h := md5.Sum(data) //nolint:gosec
return hex.EncodeToString(h[:])
}