register.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. package functions
  2. import (
  3. "crypto/ed25519"
  4. "crypto/rand"
  5. "encoding/json"
  6. "errors"
  7. "net/http"
  8. "os"
  9. "github.com/gravitl/netmaker/logger"
  10. "github.com/gravitl/netmaker/netclient/config"
  11. "github.com/gravitl/netmaker/netclient/ncutils"
  12. "github.com/gravitl/netmaker/tls"
  13. )
  14. // Register - the function responsible for registering with the server and acquiring certs
  15. func Register(cfg *config.ClientConfig) error {
  16. //generate new key if one doesn' exist
  17. var private *ed25519.PrivateKey
  18. var err error
  19. private, err = tls.ReadKeyFromFile(ncutils.GetNetclientPath() + ncutils.GetSeparator() + "client.key")
  20. if err != nil {
  21. _, newKey, err := ed25519.GenerateKey(rand.Reader)
  22. if err != nil {
  23. return err
  24. }
  25. if err := tls.SaveKeyToFile(ncutils.GetNetclientPath(), ncutils.GetSeparator()+"client.key", newKey); err != nil {
  26. return err
  27. }
  28. private = &newKey
  29. }
  30. //check if cert exists
  31. _, err = tls.ReadCertFromFile(ncutils.GetNetclientServerPath(cfg.Server.Server) + ncutils.GetSeparator() + "client.pem")
  32. if errors.Is(err, os.ErrNotExist) {
  33. if err := RegisterWithServer(private, cfg); err != nil {
  34. return err
  35. }
  36. } else if err != nil {
  37. return err
  38. }
  39. return nil
  40. }
  41. // RegisterWithServer calls the register endpoint with privatekey and commonname - api returns ca and client certificate
  42. func RegisterWithServer(private *ed25519.PrivateKey, cfg *config.ClientConfig) error {
  43. data := config.RegisterRequest{
  44. Key: *private,
  45. CommonName: tls.NewCName(cfg.Node.Name),
  46. }
  47. url := "https://" + cfg.Server.API + "/api/server/register"
  48. logger.Log(1, "register at "+url)
  49. token, err := Authenticate(cfg)
  50. if err != nil {
  51. return err
  52. }
  53. response, err := API(data, http.MethodPost, url, token)
  54. if err != nil {
  55. return err
  56. }
  57. if response.StatusCode != http.StatusOK {
  58. return errors.New(response.Status)
  59. }
  60. var resp config.RegisterResponse
  61. if err := json.NewDecoder(response.Body).Decode(&resp); err != nil {
  62. return errors.New("unmarshal cert error " + err.Error())
  63. }
  64. // set broker information on register
  65. var modServer bool
  66. if resp.Broker != "" && resp.Broker != cfg.Server.Server {
  67. cfg.Server.Server = resp.Broker
  68. modServer = true
  69. }
  70. if resp.Port != "" && resp.Port != cfg.Server.MQPort {
  71. cfg.Server.MQPort = resp.Port
  72. modServer = true
  73. }
  74. if modServer {
  75. if err = config.ModServerConfig(&cfg.Server, cfg.Node.Network); err != nil {
  76. logger.Log(0, "error overwriting config with broker information: "+err.Error())
  77. }
  78. }
  79. //x509.Certificate.PublicKey is an interface so json encoding/decoding results in a string rather that []byte
  80. //the pubkeys are included in the response so the values in the certificate can be updated appropriately
  81. resp.CA.PublicKey = resp.CAPubKey
  82. resp.Cert.PublicKey = resp.CertPubKey
  83. if err := tls.SaveCertToFile(ncutils.GetNetclientServerPath(cfg.Server.Server)+ncutils.GetSeparator(), tls.ROOT_PEM_NAME, &resp.CA); err != nil {
  84. return err
  85. }
  86. if err := tls.SaveCertToFile(ncutils.GetNetclientServerPath(cfg.Server.Server)+ncutils.GetSeparator(), "client.pem", &resp.Cert); err != nil {
  87. return err
  88. }
  89. logger.Log(0, "certificates/key saved ")
  90. //join the network defined in the token
  91. return nil
  92. }