readSOCKSClient reads data from the SOCKS client through the previously accepted connection to the server
(id uuid.UUID)
| 179 | |
| 180 | // readSOCKSClient reads data from the SOCKS client through the previously accepted connection to the server |
| 181 | func readSOCKSClient(id uuid.UUID) { |
| 182 | connection, ok := connections.Load(id) |
| 183 | if !ok { |
| 184 | slog.Error(fmt.Sprintf("%s is not a known SOCKS connection ID", id)) |
| 185 | return |
| 186 | } |
| 187 | |
| 188 | var index int |
| 189 | jobID := core.RandStringBytesMaskImprSrc(10) |
| 190 | token := uuid.New() |
| 191 | for { |
| 192 | // Create SOCKS payload |
| 193 | socks := merlinJob.Socks{ |
| 194 | ID: id, |
| 195 | Index: index, |
| 196 | } |
| 197 | |
| 198 | // Read the connection data |
| 199 | data := make([]byte, 500000) |
| 200 | n, err := connection.(*Connection).Conn.Read(data) |
| 201 | if core.Debug { |
| 202 | slog.Debug(fmt.Sprintf("Read %d bytes from connection ID %s for agent %s with error %s", n, id, connection.(Connection).AgentID, err)) |
| 203 | } |
| 204 | |
| 205 | // If there is data, add it to the message |
| 206 | if n > 0 { |
| 207 | socks.Data = data[:n] |
| 208 | } |
| 209 | |
| 210 | // If there is an error, close the connection |
| 211 | // Errors can occur when the SOCKS client is abruptly closed or the connection is finished |
| 212 | if err != nil { |
| 213 | socks.Close = true |
| 214 | // EOF is not an error it just means the client closed the connection |
| 215 | if err != io.EOF { |
| 216 | slog.Error("there was an error reading from the SOCKS client connection", "ID", id, "Index", socks.Index, "Read Data", n, "Error", err) |
| 217 | } |
| 218 | } |
| 219 | |
| 220 | // Create the jobs.Job |
| 221 | job := merlinJob.Job{ |
| 222 | AgentID: connection.(*Connection).AgentID, |
| 223 | Type: merlinJob.SOCKS, |
| 224 | Payload: socks, |
| 225 | ID: jobID, |
| 226 | Token: token, |
| 227 | } |
| 228 | index++ |
| 229 | // Send the job to the agent |
| 230 | JobsOut <- job |
| 231 | // The connection is closed on the client side, exit the go routine |
| 232 | if socks.Close { |
| 233 | if err == io.EOF { |
| 234 | slog.Debug("received EOF from the SOCKS client, closing the connection", "Agent", job.AgentID, "ID", socks.ID) |
| 235 | } |
| 236 | err = connection.(*Connection).Conn.Close() |
| 237 | if err != nil { |
| 238 | slog.Error("there was an error closing SOCKS client connection", "ID", socks.ID, "Index", socks.Index, "Error", err) |
no test coverage detected