Skip to content

Commit 9f23302

Browse files
author
Mike
committed
feat: enable cira processing
1 parent 871493c commit 9f23302

File tree

4 files changed

+263
-4
lines changed

4 files changed

+263
-4
lines changed

pkg/apf/processor.go

Lines changed: 248 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,18 @@ func Process(data []byte, session *Session) bytes.Buffer {
2020
var dataToSend interface{}
2121

2222
switch data[0] {
23+
case APF_KEEPALIVE_REQUEST:
24+
log.Debug("received APF_KEEPALIVE_REQUEST")
25+
26+
dataToSend = ProcessKeepAliveRequest(data, session)
27+
case APF_KEEPALIVE_REPLY:
28+
log.Debug("received APF_KEEPALIVE_REPLY")
29+
30+
// dataToSend = ProcessKeepAliveReply(data, session)
31+
case APF_KEEPALIVE_OPTIONS_REPLY:
32+
log.Debug("received APF_KEEPALIVE_OPTIONS_REQUEST")
33+
34+
// dataToSend = ProcessKeepAliveOptionsReply(data, session)
2335
case APF_GLOBAL_REQUEST: // 80
2436
log.Debug("received APF_GLOBAL_REQUEST")
2537

@@ -73,6 +85,9 @@ func Process(data []byte, session *Session) bytes.Buffer {
7385
dataToSend = ProcessProtocolVersion(data)
7486
}
7587
case APF_USERAUTH_REQUEST: // 50
88+
log.Debug("received APF_USERAUTH_REQUEST")
89+
90+
dataToSend = ProcessUserAuthRequest(data, session)
7691
default:
7792
}
7893

@@ -83,9 +98,235 @@ func Process(data []byte, session *Session) bytes.Buffer {
8398
}
8499
}
85100

101+
// fmt.Printf("bin_buf: %x\n", bin_buf.Bytes())
102+
86103
return bin_buf
87104
}
88105

106+
func ProcessKeepAliveRequest(data []byte, session *Session) any {
107+
if len(data) < 5 {
108+
log.Warn("APF_KEEPALIVE_REQUEST message too short")
109+
110+
return APF_KEEPALIVE_REPLY_MESSAGE{}
111+
}
112+
113+
cookie := binary.BigEndian.Uint32(data[1:5])
114+
log.Debugf("received APF_KEEPALIVE_REQUEST with cookie: %d", cookie)
115+
116+
reply := APF_KEEPALIVE_REPLY_MESSAGE{
117+
MessageType: APF_KEEPALIVE_REPLY,
118+
Cookie: cookie,
119+
}
120+
121+
return reply
122+
}
123+
124+
func ProcessKeepAliveReply(data []byte, session *Session) {
125+
if len(data) < 5 {
126+
log.Warn("APF_KEEPALIVE_REPLY message too short")
127+
128+
return
129+
}
130+
131+
cookie := binary.BigEndian.Uint32(data[1:5])
132+
log.Debugf("received APF_KEEPALIVE_REPLY with cookie: %d", cookie) // TODO: Update session state if necessary
133+
}
134+
135+
func ProcessKeepAliveOptionsReply(data []byte, session *Session) {
136+
if len(data) < 9 {
137+
log.Warn("APF_KEEPALIVE_OPTIONS_REPLY message too short")
138+
139+
return
140+
}
141+
142+
keepaliveInterval := binary.BigEndian.Uint32(data[1:5])
143+
timeout := binary.BigEndian.Uint32(data[5:9])
144+
log.Debugf("KEEPALIVE_OPTIONS_REPLY, Keepalive Interval=%d Timeout=%d", keepaliveInterval, timeout) //TODO: // Update session state or configurations as needed
145+
}
146+
147+
func ProcessUserAuthRequest(data []byte, session *Session) interface{} {
148+
log.Debug("received APF_USERAUTH_REQUEST")
149+
150+
dataBuffer := bytes.NewReader(data)
151+
152+
var messageType byte
153+
154+
err := binary.Read(dataBuffer, binary.BigEndian, &messageType)
155+
if err != nil {
156+
log.Error(err)
157+
158+
return nil
159+
}
160+
161+
// Read username length
162+
var usernameLen uint32
163+
164+
err = binary.Read(dataBuffer, binary.BigEndian, &usernameLen)
165+
if err != nil {
166+
log.Error(err)
167+
168+
return nil
169+
}
170+
171+
if usernameLen > 2048 || uint32(dataBuffer.Len()) < usernameLen {
172+
log.Error("Invalid username length")
173+
174+
return nil
175+
}
176+
177+
usernameBytes := make([]byte, usernameLen)
178+
179+
n, err := dataBuffer.Read(usernameBytes)
180+
if err != nil || n != int(usernameLen) {
181+
log.Error("Failed to read username")
182+
183+
return nil
184+
}
185+
186+
username := string(usernameBytes)
187+
188+
// Read serviceName length
189+
var serviceNameLen uint32
190+
191+
err = binary.Read(dataBuffer, binary.BigEndian, &serviceNameLen)
192+
if err != nil {
193+
log.Error(err)
194+
195+
return nil
196+
}
197+
198+
if serviceNameLen > 2048 || uint32(dataBuffer.Len()) < serviceNameLen {
199+
log.Error("Invalid serviceName length")
200+
201+
return nil
202+
}
203+
204+
serviceNameBytes := make([]byte, serviceNameLen)
205+
206+
n, err = dataBuffer.Read(serviceNameBytes)
207+
if err != nil || n != int(serviceNameLen) {
208+
log.Error("Failed to read serviceName")
209+
210+
return nil
211+
}
212+
213+
serviceName := string(serviceNameBytes)
214+
215+
// Read methodName length
216+
var methodNameLen uint32
217+
218+
err = binary.Read(dataBuffer, binary.BigEndian, &methodNameLen)
219+
if err != nil {
220+
log.Error(err)
221+
222+
return nil
223+
}
224+
225+
if methodNameLen > 2048 || uint32(dataBuffer.Len()) < methodNameLen {
226+
log.Error("Invalid methodName length")
227+
228+
return nil
229+
}
230+
231+
methodNameBytes := make([]byte, methodNameLen)
232+
233+
n, err = dataBuffer.Read(methodNameBytes)
234+
if err != nil || n != int(methodNameLen) {
235+
log.Error("Failed to read methodName")
236+
237+
return nil
238+
}
239+
240+
methodName := string(methodNameBytes)
241+
242+
if methodName == "password" {
243+
if dataBuffer.Len() < 1 {
244+
log.Error("Not enough data for password FALSE byte")
245+
246+
return nil
247+
}
248+
// Read boolean FALSE
249+
var passwordFalse byte
250+
251+
err = binary.Read(dataBuffer, binary.BigEndian, &passwordFalse)
252+
if err != nil {
253+
log.Error(err)
254+
255+
return nil
256+
}
257+
258+
if passwordFalse != 0 {
259+
log.Error("passwordFalse is not zero")
260+
261+
return nil
262+
}
263+
264+
// Read password length
265+
var passwordLen uint32
266+
267+
err = binary.Read(dataBuffer, binary.BigEndian, &passwordLen)
268+
if err != nil {
269+
log.Error(err)
270+
271+
return nil
272+
}
273+
274+
if passwordLen > 2048 || uint32(dataBuffer.Len()) < passwordLen {
275+
log.Error("Invalid password length")
276+
277+
return nil
278+
}
279+
280+
passwordBytes := make([]byte, passwordLen)
281+
282+
n, err = dataBuffer.Read(passwordBytes)
283+
if err != nil || n != int(passwordLen) {
284+
log.Error("Failed to read password")
285+
286+
return nil
287+
}
288+
289+
_ = string(passwordBytes)
290+
} else {
291+
// Unsupported method
292+
log.Warn("Unsupported authentication method: ", methodName)
293+
// Return failure
294+
// failureMessage := &APF_USERAUTH_FAILURE_MESSAGE{
295+
// MessageType: APF_USERAUTH_FAILURE,
296+
// AuthenticationsThatCanContinueLength: uint32(len("password")),
297+
// AuthenticationsThatCanContinue: []byte("password"),
298+
// PartialSuccess: 0,
299+
// }
300+
// return failureMessage
301+
return nil
302+
}
303+
304+
log.Debugf("usernameLen=%d serviceNameLen=%d methodNameLen=%d", usernameLen, serviceNameLen, methodNameLen)
305+
log.Debugf("username=%s serviceName=%s methodName=%s", username, serviceName, methodName)
306+
307+
// Now authenticate the user
308+
authenticated := true // session.AuthenticateUser(username, password)
309+
310+
if authenticated {
311+
// Return success message
312+
message := &APF_USERAUTH_SUCCESS_MESSAGE{
313+
MessageType: APF_USERAUTH_SUCCESS,
314+
}
315+
316+
return message
317+
} else {
318+
// Return failure message
319+
// failureMessage := &APF_USERAUTH_FAILURE_MESSAGE{
320+
// MessageType: APF_USERAUTH_FAILURE,
321+
// AuthenticationsThatCanContinueLength: uint32(len("password")),
322+
// AuthenticationsThatCanContinue: []byte("password"),
323+
// PartialSuccess: 0,
324+
// }
325+
// return failureMessage
326+
return nil
327+
}
328+
}
329+
89330
func ProcessChannelWindowAdjust(data []byte, session *Session) {
90331
adjustMessage := APF_CHANNEL_WINDOW_ADJUST_MESSAGE{}
91332
dataBuffer := bytes.NewBuffer(data)
@@ -170,11 +411,14 @@ func ProcessGlobalRequest(data []byte) interface{} {
170411
log.Tracef("%+v", tcpForwardRequest)
171412

172413
if genericHeader.String == APF_GLOBAL_REQUEST_STR_TCP_FORWARD_REQUEST {
173-
if tcpForwardRequest.Port == 16992 || tcpForwardRequest.Port == 16993 {
174-
reply = TcpForwardReplySuccess(tcpForwardRequest.Port)
175-
} else {
176-
reply = APF_REQUEST_FAILURE
414+
// if tcpForwardRequest.Port == 16992 || tcpForwardRequest.Port == 16993 {
415+
reply = TcpForwardReplySuccess(tcpForwardRequest.Port)
416+
417+
if tcpForwardRequest.Port == 5900 {
177418
}
419+
// } else {
420+
// reply = APF_REQUEST_FAILURE
421+
// }
178422
} else if genericHeader.String == APF_GLOBAL_REQUEST_STR_TCP_FORWARD_CANCEL_REQUEST {
179423
reply = APF_REQUEST_SUCCESS
180424
}

pkg/apf/types.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ const (
3232
APF_CHANNEL_DATA = 94
3333
APF_CHANNEL_CLOSE = 97
3434
APF_PROTOCOLVERSION = 192
35+
APF_KEEPALIVE_REQUEST = 208
36+
APF_KEEPALIVE_REPLY = 209
37+
APF_KEEPALIVE_OPTIONS_REPLY = 211
3538
)
3639

3740
// disconnect reason codes.
@@ -93,6 +96,11 @@ type APF_MESSAGE_HEADER struct {
9396
MessageType byte
9497
}
9598

99+
type APF_KEEPALIVE_REPLY_MESSAGE struct {
100+
MessageType byte
101+
Cookie uint32
102+
}
103+
96104
/**
97105
* APF_GENERIC_HEADER - generic request header (note that its not complete header per protocol (missing WantReply)
98106
*

pkg/wsman/client/types.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package client
22

33
import (
44
"crypto/tls"
5+
"net"
56
"net/http"
67
)
78

@@ -17,6 +18,7 @@ type Parameters struct {
1718
Transport http.RoundTripper
1819
IsRedirection bool
1920
PinnedCert string
21+
Connection net.Conn
2022
TlsConfig *tls.Config
2123
AllowInsecureCipherSuites bool
2224
}

pkg/wsman/client/wsman_tcp.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ func NewWsmanTCP(cp Parameters) *Target {
2626
UseTLS: cp.UseTLS,
2727
InsecureSkipVerify: cp.SelfSignedAllowed,
2828
PinnedCert: cp.PinnedCert,
29+
conn: cp.Connection,
2930
bufferPool: sync.Pool{
3031
New: func() interface{} {
3132
return make([]byte, 4096) // Adjust size according to your needs.
@@ -37,6 +38,10 @@ func NewWsmanTCP(cp Parameters) *Target {
3738
// Connect establishes a TCP connection to the endpoint specified in the Target struct.
3839
func (t *Target) Connect() error {
3940
var err error
41+
// already connected and connection has been provided
42+
if t.conn != nil {
43+
return nil
44+
}
4045

4146
if t.UseTLS {
4247
// check if pinnedCert is not null and not empty

0 commit comments

Comments
 (0)