File: lapi.go

package info (click to toggle)
crowdsec 1.4.6-10
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 18,492 kB
  • sloc: sh: 2,870; makefile: 386; python: 74
file content (174 lines) | stat: -rw-r--r-- 5,561 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
package main

import (
	"context"
	"fmt"
	"net/url"
	"os"
	"strings"

	"github.com/go-openapi/strfmt"
	"github.com/pkg/errors"
	log "github.com/sirupsen/logrus"
	"github.com/spf13/cobra"
	"gopkg.in/yaml.v2"

	"github.com/crowdsecurity/crowdsec/pkg/apiclient"
	"github.com/crowdsecurity/crowdsec/pkg/csconfig"
	"github.com/crowdsecurity/crowdsec/pkg/cwhub"
	"github.com/crowdsecurity/crowdsec/pkg/cwversion"
	"github.com/crowdsecurity/crowdsec/pkg/models"
)

var LAPIURLPrefix string = "v1"
var lapiUser string

func NewLapiCmd() *cobra.Command {
	var cmdLapi = &cobra.Command{
		Use:               "lapi [action]",
		Short:             "Manage interaction with Local API (LAPI)",
		Args:              cobra.MinimumNArgs(1),
		DisableAutoGenTag: true,
		PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
			if err := csConfig.LoadAPIClient(); err != nil {
				return errors.Wrap(err, "loading api client")
			}
			return nil
		},
	}

	var cmdLapiRegister = &cobra.Command{
		Use:   "register",
		Short: "Register a machine to Local API (LAPI)",
		Long: `Register you machine to the Local API (LAPI).
Keep in mind the machine needs to be validated by an administrator on LAPI side to be effective.`,
		Args:              cobra.MinimumNArgs(0),
		DisableAutoGenTag: true,
		Run: func(cmd *cobra.Command, args []string) {
			var err error
			if lapiUser == "" {
				lapiUser, err = generateID("")
				if err != nil {
					log.Fatalf("unable to generate machine id: %s", err)
				}
			}
			password := strfmt.Password(generatePassword(passwordLength))
			if apiURL == "" {
				if csConfig.API.Client != nil && csConfig.API.Client.Credentials != nil && csConfig.API.Client.Credentials.URL != "" {
					apiURL = csConfig.API.Client.Credentials.URL
				} else {
					log.Fatalf("No Local API URL. Please provide it in your configuration or with the -u parameter")
				}
			}
			/*URL needs to end with /, but user doesn't care*/
			if !strings.HasSuffix(apiURL, "/") {
				apiURL += "/"
			}
			/*URL needs to start with http://, but user doesn't care*/
			if !strings.HasPrefix(apiURL, "http://") && !strings.HasPrefix(apiURL, "https://") {
				apiURL = "http://" + apiURL
			}
			apiurl, err := url.Parse(apiURL)
			if err != nil {
				log.Fatalf("parsing api url: %s", err)
			}
			_, err = apiclient.RegisterClient(&apiclient.Config{
				MachineID:     lapiUser,
				Password:      password,
				UserAgent:     fmt.Sprintf("crowdsec/%s", cwversion.VersionStr()),
				URL:           apiurl,
				VersionPrefix: LAPIURLPrefix,
			}, nil)

			if err != nil {
				log.Fatalf("api client register: %s", err)
			}

			log.Printf("Successfully registered to Local API (LAPI)")

			var dumpFile string
			if outputFile != "" {
				dumpFile = outputFile
			} else if csConfig.API.Client.CredentialsFilePath != "" {
				dumpFile = csConfig.API.Client.CredentialsFilePath
			} else {
				dumpFile = ""
			}
			apiCfg := csconfig.ApiCredentialsCfg{
				Login:    lapiUser,
				Password: password.String(),
				URL:      apiURL,
			}
			apiConfigDump, err := yaml.Marshal(apiCfg)
			if err != nil {
				log.Fatalf("unable to marshal api credentials: %s", err)
			}
			if dumpFile != "" {
				err = os.WriteFile(dumpFile, apiConfigDump, 0644)
				if err != nil {
					log.Fatalf("write api credentials in '%s' failed: %s", dumpFile, err)
				}
				log.Printf("Local API credentials dumped to '%s'", dumpFile)
			} else {
				fmt.Printf("%s\n", string(apiConfigDump))
			}
			log.Warning(ReloadMessage())
		},
	}
	cmdLapiRegister.Flags().StringVarP(&apiURL, "url", "u", "", "URL of the API (ie. http://127.0.0.1)")
	cmdLapiRegister.Flags().StringVarP(&outputFile, "file", "f", "", "output file destination")
	cmdLapiRegister.Flags().StringVar(&lapiUser, "machine", "", "Name of the machine to register with")
	cmdLapi.AddCommand(cmdLapiRegister)

	var cmdLapiStatus = &cobra.Command{
		Use:               "status",
		Short:             "Check authentication to Local API (LAPI)",
		Args:              cobra.MinimumNArgs(0),
		DisableAutoGenTag: true,
		Run: func(cmd *cobra.Command, args []string) {
			var err error

			password := strfmt.Password(csConfig.API.Client.Credentials.Password)
			apiurl, err := url.Parse(csConfig.API.Client.Credentials.URL)
			login := csConfig.API.Client.Credentials.Login
			if err != nil {
				log.Fatalf("parsing api url ('%s'): %s", apiurl, err)
			}
			if err := csConfig.LoadHub(); err != nil {
				log.Fatal(err)
			}

			if err := cwhub.GetHubIdx(csConfig.Hub); err != nil {
				log.Info("Run 'sudo cscli hub update' to get the hub index")
				log.Fatalf("Failed to load hub index : %s", err)
			}
			scenarios, err := cwhub.GetInstalledScenariosAsString()
			if err != nil {
				log.Fatalf("failed to get scenarios : %s", err)
			}

			Client, err = apiclient.NewDefaultClient(apiurl,
				LAPIURLPrefix,
				fmt.Sprintf("crowdsec/%s", cwversion.VersionStr()),
				nil)
			if err != nil {
				log.Fatalf("init default client: %s", err)
			}
			t := models.WatcherAuthRequest{
				MachineID: &login,
				Password:  &password,
				Scenarios: scenarios,
			}
			log.Infof("Loaded credentials from %s", csConfig.API.Client.CredentialsFilePath)
			log.Infof("Trying to authenticate with username %s on %s", login, apiurl)
			_, err = Client.Auth.AuthenticateWatcher(context.Background(), t)
			if err != nil {
				log.Fatalf("Failed to authenticate to Local API (LAPI) : %s", err)
			} else {
				log.Infof("You can successfully interact with Local API (LAPI)")
			}
		},
	}
	cmdLapi.AddCommand(cmdLapiStatus)
	return cmdLapi
}