130 lines
3.0 KiB
Go
130 lines
3.0 KiB
Go
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 <username> <password> <displayname>\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)
|
|
}
|
|
}
|