Skip to content
This repository was archived by the owner on Apr 13, 2025. It is now read-only.

Commit 2b5dd81

Browse files
committed
create default profiles on server initialistion
1 parent 4cbb6f2 commit 2b5dd81

4 files changed

Lines changed: 116 additions & 27 deletions

File tree

pkg/commands/build.go

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ import (
3131
var (
3232
l log.Logger
3333
internals = []string{"id", "ca_cert"}
34-
ValidTypes = []string{"bool", "int", "string", "float"}
34+
ValidTypes = []string{consts.OpTypeBool, consts.OpTypeInt, consts.OpTypeString, consts.OpTypeFloat}
3535
builderConfig *BuilderConfig
3636
)
3737

@@ -82,59 +82,60 @@ func defaultOptions() []*builderpb.Option {
8282
Name: "id",
8383
Description: "[internal] the agent ID assigned to the build (immutable)",
8484
Default: builderConfig.ID,
85-
Type: "string",
85+
Type: consts.OpTypeString,
8686
Required: true,
8787
}
8888
name := &builderpb.Option{
8989
Name: "name",
9090
Description: "name of this particular agent instance",
9191
Default: builderConfig.ID,
92-
Type: "string",
92+
Type: consts.OpTypeString,
9393
Required: false,
9494
}
9595
OS := &builderpb.Option{
9696
Name: "os",
9797
Description: "the OS that the build targets",
9898
Default: runtime.GOOS,
99+
Type: consts.OpTypeString,
99100
Required: false,
100101
}
101102
arch := &builderpb.Option{
102103
Name: "arch",
103104
Description: "the platform architecture that the build targets",
104105
Default: "amd64",
105-
Type: "string",
106+
Type: consts.OpTypeString,
106107
Required: false,
107108
}
108109
def := config.MainConfig.Interface
109110
if def == "" {
110111
def = config.ClientConfig.RHost
111112
}
112113
host := &builderpb.Option{
113-
Name: "host",
114+
Name: "lhost",
114115
Description: "the host that the agent calls back to",
115116
Default: def,
116-
Type: "string",
117+
Type: consts.OpTypeString,
117118
Required: false,
118119
}
119120
port := &builderpb.Option{
120-
Name: "port",
121+
Name: consts.OpLPort,
121122
Description: "the port on which to connect to the host on callback",
122-
Default: "8000",
123-
Type: "int",
123+
Default: "",
124+
Type: consts.OpTypeInt,
124125
Required: false,
125126
}
126127
out := &builderpb.Option{
127128
Name: "outfile",
128129
Description: "the name of the resulting binary",
129130
Default: "",
130-
Type: "string",
131+
Type: consts.OpTypeString,
131132
Required: false,
132133
}
133134
caCert := &builderpb.Option{
134135
Name: "ca_cert",
135136
Description: "[internal] the certificate authority used to sign server certificates (immutable)",
136137
Default: "***",
137-
Type: "string",
138+
Type: consts.OpTypeString,
138139
Required: true,
139140
}
140141
options = append(options, ID, name, OS, arch, host, port, caCert, out)
@@ -221,17 +222,17 @@ func setCmd(name, value string) {
221222

222223
func TypeVerify(t, value string) error {
223224
switch t {
224-
case "int":
225+
case consts.OpTypeInt:
225226
if _, err := strconv.Atoi(value); err != nil {
226227
return fmt.Errorf("not a valid integer")
227228
}
228229

229-
case "bool":
230+
case consts.OpTypeBool:
230231
if _, err := strconv.ParseBool(value); err != nil {
231232
return fmt.Errorf("not a valid boolean")
232233
}
233234

234-
case "float":
235+
case consts.OpTypeFloat:
235236
if _, err := strconv.ParseFloat(value, 64); err != nil {
236237
return fmt.Errorf("not a valid float")
237238
}
@@ -355,6 +356,8 @@ func build() {
355356
return
356357
}
357358
l.Success("build complete. saved to %s", out.Name())
359+
// regen in case they want the convenience of building agents in succession
360+
builderConfig.ID = agentID()
358361
}
359362

360363
// agentID generates an ID for an agent.
@@ -385,11 +388,11 @@ func gatherOptions() string {
385388

386389
func allOptions() []string {
387390
var options []string
388-
for k := range builderConfig.request.Options {
389-
if slices.Contains(internals, k) {
391+
for _, k := range builderConfig.options {
392+
if slices.Contains(internals, k.Name) {
390393
continue
391394
}
392-
options = append(options, k)
395+
options = append(options, k.Name)
393396
}
394397
return options
395398
}

pkg/consts/consts.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,16 @@ const (
1717
AgentIDSize = 8
1818
RequestIDLength = 36
1919
OpcodeLength = 4 // uint32
20+
21+
ProfileTCP = "tcp"
22+
ProfileHTTP = "http"
23+
ProfileHTTPS = "https"
24+
TypeInternalProfile = "internal"
25+
26+
OpTypeBool = "bool"
27+
OpTypeInt = "int"
28+
OpTypeFloat = "float"
29+
OpTypeString = "string"
30+
31+
OpLPort = "lport"
2032
)

pkg/db/db.go

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"gorm.io/driver/mysql"
1212
"gorm.io/gorm"
1313
"gorm.io/gorm/logger"
14+
"strconv"
1415
)
1516

1617
var (
@@ -36,9 +37,66 @@ func Initialize() string {
3637
if err = db.AutoMigrate(&Builder{}, &Agent{}, &Player{}, &Profile{}, &ProfileRecord{}); err != nil {
3738
l.Fatal("failed to migrate schema: %v. Monarch cannot continue to operate", err)
3839
}
40+
return initServerUser(&conf)
41+
}
42+
43+
// initialize profiles for default handlers - HTTP, HTTPS, TCP
44+
func initDefaultProfiles(c *config.MonarchConfig) {
45+
httpProfile := &Profile{
46+
Name: consts.ProfileHTTP,
47+
BuilderID: consts.TypeInternalProfile,
48+
CreatedBy: consts.ServerUser,
49+
}
50+
httpR1 := &ProfileRecord{
51+
Profile: consts.ProfileHTTP,
52+
Name: consts.OpLPort,
53+
Value: strconv.Itoa(c.HttpPort),
54+
}
55+
if tx := db.Create(httpProfile); tx.Error != nil {
56+
l.Warn(tx.Error.Error())
57+
}
58+
if tx := db.Create(httpR1); tx.Error != nil {
59+
l.Warn(tx.Error.Error())
60+
}
61+
httpsProfile := &Profile{
62+
Name: consts.ProfileHTTPS,
63+
BuilderID: consts.TypeInternalProfile,
64+
CreatedBy: consts.ServerUser,
65+
}
66+
httpsR1 := &ProfileRecord{
67+
Profile: consts.ProfileHTTPS,
68+
Name: consts.OpLPort,
69+
Value: strconv.Itoa(c.HttpsPort),
70+
}
71+
if tx := db.Create(httpsProfile); tx.Error != nil {
72+
l.Warn(tx.Error.Error())
73+
}
74+
if tx := db.Create(httpsR1); tx.Error != nil {
75+
l.Warn(tx.Error.Error())
76+
}
77+
tcpProfile := &Profile{
78+
Name: consts.ProfileTCP,
79+
BuilderID: consts.TypeInternalProfile,
80+
CreatedBy: consts.ServerUser,
81+
}
82+
tcpR1 := &ProfileRecord{
83+
Profile: consts.ProfileTCP,
84+
Name: consts.OpLPort,
85+
Value: strconv.Itoa(c.TcpPort),
86+
}
87+
if tx := db.Create(tcpProfile); tx.Error != nil {
88+
l.Warn(tx.Error.Error())
89+
}
90+
if tx := db.Create(tcpR1); tx.Error != nil {
91+
l.Warn(tx.Error.Error())
92+
}
93+
}
94+
95+
func initServerUser(c *config.MonarchConfig) string {
3996
uid := uuid.New().String()
4097
serverPlayer := &Player{}
4198
if db.Where("username = ?", consts.ServerUser).First(serverPlayer); len(serverPlayer.UUID) == 0 {
99+
// we can do first-time-run steps here
42100
serverPlayer = &Player{
43101
UUID: uid,
44102
Username: consts.ServerUser,
@@ -48,6 +106,9 @@ func Initialize() string {
48106
l.Fatal("could not create default server user: %v", result.Error)
49107
}
50108
config.ClientConfig.UUID = uid
109+
110+
// create default profiles (for now it just loads port numbers for each endpoint type)
111+
initDefaultProfiles(c)
51112
} else {
52113
config.ClientConfig.Name = consts.ServerUser
53114
config.ClientConfig.UUID = serverPlayer.UUID

pkg/teamserver/teamserver.go

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"encoding/json"
99
"errors"
1010
"fmt"
11+
"github.com/pygrum/monarch/pkg/consts"
1112
"github.com/pygrum/monarch/pkg/handler/tcp"
1213
"github.com/pygrum/monarch/pkg/teamserver/roles"
1314
"github.com/pygrum/monarch/pkg/types"
@@ -211,15 +212,20 @@ func (s *MonarchServer) Builders(_ context.Context, req *clientpb.BuilderRequest
211212

212213
func (s *MonarchServer) Profiles(_ context.Context, req *clientpb.ProfileRequest) (*clientpb.Profiles, error) {
213214
var profiles []db.Profile
215+
builderIDs := append(req.Name, consts.TypeInternalProfile)
216+
214217
pbProfiles := &clientpb.Profiles{}
215-
if len(req.Name) > 0 {
216-
if err := db.Where("name IN ? AND builder_id = ?", req.Name, req.BuilderId).Find(&profiles); err != nil {
217-
return nil, fmt.Errorf("failed to find profiles(s): %v", err)
218-
}
219-
} else {
220-
if err := db.Where("builder_id = ?", req.BuilderId).Find(&profiles).Error; err != nil {
221-
return nil, fmt.Errorf("failed to find profiles(s): %v", err)
222-
}
218+
//if len(req.Name) > 0 {
219+
// if err := db.Where("name IN ? AND builder_id IN ?", req.Name, builderIDs).Find(&profiles); err != nil {
220+
// return nil, fmt.Errorf("failed to find profiles(s): %v", err)
221+
// }
222+
//} else {
223+
// if err := db.Where("builder_id IN ?", builderIDs).Find(&profiles).Error; err != nil {
224+
// return nil, fmt.Errorf("failed to find profiles(s): %v", err)
225+
// }
226+
//}
227+
if err := db.Where("builder_id IN ?", builderIDs).Find(&profiles).Error; err != nil {
228+
return nil, fmt.Errorf("failed to find profiles(s): %v", err)
223229
}
224230
for _, p := range profiles {
225231
pbProfiles.Profiles = append(pbProfiles.Profiles, &clientpb.Profile{
@@ -239,7 +245,9 @@ func (s *MonarchServer) SaveProfile(ctx context.Context, req *clientpb.SaveProfi
239245
return nil, ErrNoMetadata
240246
}
241247
player := md["uid"]
242-
if db.Where("name = ? AND builder_id = ?", req.Name, req.BuilderId).Find(&profile); len(profile.Name) != 0 {
248+
// include internal profile in duplicate check to prevent load conflicts
249+
builderIDs := []string{req.BuilderId, consts.TypeInternalProfile}
250+
if db.Where("name = ? AND builder_id IN ?", req.Name, builderIDs).Find(&profile); len(profile.Name) != 0 {
243251
return nil, fmt.Errorf("a profile for this build named '%s' already exists", req.Name)
244252
}
245253
profile = &db.Profile{
@@ -268,7 +276,10 @@ func (s *MonarchServer) SaveProfile(ctx context.Context, req *clientpb.SaveProfi
268276
func (s *MonarchServer) LoadProfile(_ context.Context, req *clientpb.SaveProfileRequest) (*clientpb.ProfileData, error) {
269277
profile := &db.Profile{}
270278
profileData := &clientpb.ProfileData{}
271-
if err := db.Where("name = ? AND builder_id = ?", req.Name, req.BuilderId).Find(profile).Error; err != nil {
279+
280+
// include internal builder ID to allow for loading of internal profiles
281+
builderIDs := []string{req.BuilderId, consts.TypeInternalProfile}
282+
if err := db.Where("name = ? AND builder_id IN ?", req.Name, builderIDs).Find(profile).Error; err != nil {
272283
return nil, fmt.Errorf("failed to find %s: %v", req.Name, err)
273284
}
274285
var records []db.ProfileRecord
@@ -306,6 +317,8 @@ func (s *MonarchServer) RmProfiles(ctx context.Context, req *clientpb.ProfileReq
306317
role := md["role"][0]
307318

308319
var profiles []db.Profile
320+
// rightly only allow deletion from current loaded profile and not internal
321+
// if they somehow managed to change the builder_id to internal, they would only be able to remove if admin
309322
if err := db.Where("name IN ? AND builder_id = ? ", req.Name, req.BuilderId).Find(&profiles).Error; err != nil {
310323
return nil, fmt.Errorf("couldn't get profiles: %v", err)
311324
}

0 commit comments

Comments
 (0)