1
- //go:build !windows
2
-
3
1
// pago - a command-line password manager.
4
2
//
5
3
// License: MIT.
6
4
// See the file LICENSE.
7
5
8
- package main
6
+ package agent
9
7
10
8
import (
11
9
"bytes"
@@ -19,136 +17,56 @@ import (
19
17
"syscall"
20
18
21
19
"dbohdan.com/pago"
20
+ "dbohdan.com/pago/crypto"
22
21
23
22
"filippo.io/age"
24
23
"github.com/tidwall/redcon"
25
24
"github.com/valkey-io/valkey-go"
26
25
)
27
26
28
- var defaultSocket = filepath .Join (defaultCacheDir , agentSocketPath )
29
-
30
- func (cmd * RestartCmd ) Run (config * Config ) error {
31
- if config .Verbose {
32
- printRepr (cmd )
33
- }
34
-
35
- if err := pago .LockMemory (); err != nil {
36
- return err
37
- }
38
-
39
- _ , _ = messageAgent (config .Socket , "SHUTDOWN" )
40
-
41
- identitiesText , err := decryptIdentities (config .Identities )
42
- if err != nil {
43
- return err
44
- }
45
-
46
- return startAgentProcess (config .Socket , identitiesText )
47
- }
48
-
49
- func (cmd * RunCmd ) Run (config * Config ) error {
50
- if config .Verbose {
51
- printRepr (cmd )
52
- }
53
-
54
- if err := pago .LockMemory (); err != nil {
55
- return err
56
- }
57
-
58
- return runAgent (config .Socket )
59
- }
60
-
61
- func (cmd * StartCmd ) Run (config * Config ) error {
62
- if config .Verbose {
63
- printRepr (cmd )
64
- }
65
-
66
- if err := pago .LockMemory (); err != nil {
67
- return err
68
- }
69
-
70
- if err := pingAgent (config .Socket ); err == nil {
71
- return fmt .Errorf ("found agent responding on socket" )
72
- }
73
-
74
- identitiesText , err := decryptIdentities (config .Identities )
75
- if err != nil {
76
- return err
77
- }
78
-
79
- return startAgentProcess (config .Socket , identitiesText )
80
- }
81
-
82
- func (cmd * StatusCmd ) Run (config * Config ) error {
83
- if config .Verbose {
84
- printRepr (cmd )
85
- }
86
-
87
- err := pingAgent (config .Socket )
88
- if err == nil {
89
- fmt .Println ("Ping successful" )
90
- os .Exit (0 )
91
- } else {
92
- fmt .Println ("Failed to ping agent" )
93
- os .Exit (1 )
94
- }
95
-
96
- return nil
97
- }
98
-
99
- func (cmd * StopCmd ) Run (config * Config ) error {
100
- if config .Verbose {
101
- printRepr (cmd )
102
- }
103
-
104
- _ , err := messageAgent (config .Socket , "SHUTDOWN" )
105
- return err
106
- }
107
-
108
- func startAgentProcess (agentSocket , identitiesText string ) error {
109
- // The agent is the same executable.
110
- exe , err := os .Executable ()
111
- if err != nil {
112
- return fmt .Errorf ("failed to get executable path: %v" , err )
27
+ func StartProcess (executable string , mlock bool , socket , identitiesText string ) error {
28
+ mlockFlag := "--mlock"
29
+ if ! mlock {
30
+ mlockFlag = "--no-mlock"
113
31
}
114
32
115
- cmd := exec .Command (exe , "agent " , "run" , "--socket" , agentSocket )
33
+ cmd := exec .Command (executable , "run " , mlockFlag , "--socket" , socket )
116
34
117
35
// Start the process in the background.
118
36
if err := cmd .Start (); err != nil {
119
37
return fmt .Errorf ("failed to start agent: %v" , err )
120
38
}
121
39
122
- _ = os .Remove (agentSocket )
40
+ _ = os .Remove (socket )
123
41
// Don't wait for the process to finish.
124
42
go func () {
125
43
_ = cmd .Wait ()
126
44
}()
127
45
128
- if err := waitUntilAvailable ( agentSocket , waitForSocket ); err != nil {
46
+ if err := pago . WaitUntilAvailable ( socket , pago . WaitForSocket ); err != nil {
129
47
return fmt .Errorf ("timed out waiting for agent socket" )
130
48
}
131
49
132
- _ , err = messageAgent ( agentSocket , "IDENTITIES" , identitiesText )
50
+ _ , err := Message ( socket , "IDENTITIES" , identitiesText )
133
51
return err
134
52
}
135
53
136
- func runAgent ( agentSocket string ) error {
137
- if err := pingAgent ( agentSocket ); err == nil {
54
+ func Run ( socket string ) error {
55
+ if err := Ping ( socket ); err == nil {
138
56
return fmt .Errorf ("found agent responding on socket" )
139
57
}
140
58
141
- socketDir := filepath .Dir (agentSocket )
142
- if err := os .MkdirAll (socketDir , dirPerms ); err != nil {
59
+ socketDir := filepath .Dir (socket )
60
+ if err := os .MkdirAll (socketDir , pago . DirPerms ); err != nil {
143
61
return fmt .Errorf ("failed to create socket directory: %v" , err )
144
62
}
145
63
146
- os .Remove (agentSocket )
64
+ os .Remove (socket )
147
65
148
66
identities := []age.Identity {}
149
67
srv := redcon .NewServerNetwork (
150
68
"unix" ,
151
- agentSocket ,
69
+ socket ,
152
70
func (conn redcon.Conn , cmd redcon.Command ) {
153
71
switch strings .ToUpper (string (cmd .Args [0 ])) {
154
72
@@ -162,7 +80,7 @@ func runAgent(agentSocket string) error {
162
80
163
81
// Decrypt the data.
164
82
reader := bytes .NewReader (encryptedData )
165
- decryptedReader , err := wrapDecrypt (reader , identities ... )
83
+ decryptedReader , err := crypto . WrapDecrypt (reader , identities ... )
166
84
if err != nil {
167
85
conn .WriteError ("ERR failed to decrypt: " + err .Error ())
168
86
return
@@ -218,22 +136,22 @@ func runAgent(agentSocket string) error {
218
136
return
219
137
}
220
138
221
- if err := os .Chmod (agentSocket , filePerms ); err != nil {
222
- exitWithError ("failed to set permissions on agent socket: %v" , err )
139
+ if err := os .Chmod (socket , pago . FilePerms ); err != nil {
140
+ pago . ExitWithError ("failed to set permissions on agent socket: %v" , err )
223
141
}
224
142
}()
225
143
226
144
return srv .ListenServeAndSignal (errc )
227
145
}
228
146
229
- func messageAgent ( agentSocket string , args ... string ) (string , error ) {
147
+ func Message ( socket string , args ... string ) (string , error ) {
230
148
// Check socket security.
231
- if err := checkSocketSecurity (agentSocket ); err != nil {
149
+ if err := checkSocketSecurity (socket ); err != nil {
232
150
return "" , fmt .Errorf ("socket security check failed: %v" , err )
233
151
}
234
152
235
153
// Connect to the server.
236
- opts , err := valkey .ParseURL ("unix://" + agentSocket )
154
+ opts , err := valkey .ParseURL ("unix://" + socket )
237
155
if err != nil {
238
156
return "" , fmt .Errorf ("failed to parse socket URL: %v" , err )
239
157
}
@@ -269,23 +187,23 @@ func messageAgent(agentSocket string, args ...string) (string, error) {
269
187
return string (result ), nil
270
188
}
271
189
272
- func pingAgent ( agentSocket string ) error {
273
- _ , err := messageAgent ( agentSocket )
190
+ func Ping ( socket string ) error {
191
+ _ , err := Message ( socket )
274
192
return err
275
193
}
276
194
277
- func decryptWithAgent ( agentSocket string , data []byte ) (string , error ) {
278
- return messageAgent ( agentSocket , "DECRYPT" , valkey .BinaryString (data ))
195
+ func Decrypt ( socket string , data []byte ) (string , error ) {
196
+ return Message ( socket , "DECRYPT" , valkey .BinaryString (data ))
279
197
}
280
198
281
- func checkSocketSecurity (agentSocket string ) error {
282
- info , err := os .Stat (agentSocket )
199
+ func checkSocketSecurity (socket string ) error {
200
+ info , err := os .Stat (socket )
283
201
if err != nil {
284
202
return fmt .Errorf ("failed to stat socket: %v" , err )
285
203
}
286
204
287
205
// Check socket permissions.
288
- if info .Mode ().Perm () != filePerms {
206
+ if info .Mode ().Perm () != pago . FilePerms {
289
207
return fmt .Errorf ("incorrect socket permissions: %v" , info .Mode ().Perm ())
290
208
}
291
209
0 commit comments