package main import ( "bytes" "crypto/hmac" "crypto/sha1" "encoding/hex" "encoding/json" "fmt" "io/ioutil" "net/http" "os" ) const ( sharedSecret = "AliceInWonderland" // Replace with your shared secret dendriteURL = "https://chihaya.one" // Replace with your Dendrite server URL ) type NonceResponse struct { Nonce string `json:"nonce"` } type RegistrationRequest struct { Nonce string `json:"nonce"` Username string `json:"username"` Displayname string `json:"displayname,omitempty"` Password string `json:"password"` Admin bool `json:"admin"` Mac string `json:"mac"` } func fetchNonce() (string, error) { resp, err := http.Get(fmt.Sprintf("%s/_synapse/admin/v1/register", dendriteURL)) if err != nil { return "", fmt.Errorf("failed to fetch nonce: %v", err) } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { return "", fmt.Errorf("failed to read response body: %v", err) } var nonceResponse NonceResponse err = json.Unmarshal(body, &nonceResponse) if err != nil { return "", fmt.Errorf("failed to unmarshal nonce response: %v", err) } return nonceResponse.Nonce, nil } func generateMAC(nonce, username, password, admin, sharedSecret string) string { mac := hmac.New(sha1.New, []byte(sharedSecret)) mac.Write([]byte(nonce)) mac.Write([]byte{0}) mac.Write([]byte(username)) mac.Write([]byte{0}) mac.Write([]byte(password)) mac.Write([]byte{0}) mac.Write([]byte(admin)) return hex.EncodeToString(mac.Sum(nil)) } func registerUser(nonce, username, password, displayname string, admin bool) error { adminStr := "notadmin" if admin { adminStr = "admin" } mac := generateMAC(nonce, username, password, adminStr, sharedSecret) reqBody := RegistrationRequest{ Nonce: nonce, Username: username, Displayname: displayname, Password: password, Admin: admin, Mac: mac, } jsonData, err := json.Marshal(reqBody) if err != nil { return fmt.Errorf("failed to marshal request: %v", err) } resp, err := http.Post(fmt.Sprintf("%s/_synapse/admin/v1/register", dendriteURL), "application/json", bytes.NewBuffer(jsonData)) if err != nil { return fmt.Errorf("failed to make request: %v", err) } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { return fmt.Errorf("failed to read response body: %v", err) } fmt.Println("Response Body:", string(body)) if resp.StatusCode != http.StatusOK { return fmt.Errorf("registration failed with status: %s", resp.Status) } fmt.Println("User registered successfully") return nil } func main() { if len(os.Args) != 4 { fmt.Printf("Usage: %s \n", os.Args[0]) return } username := os.Args[1] password := os.Args[2] displayname := os.Args[3] nonce, err := fetchNonce() if err != nil { fmt.Printf("Error fetching nonce: %v\n", err) return } if err := registerUser(nonce, username, password, displayname, false); err != nil { fmt.Printf("Error: %v\n", err) } }