Hector 172971a055 fix command writing code
Fix the code writing commands to the fail2ban socket to correctly encode
the command terminator string. The terminator string should be encoded as
a simple byte array, not using the pickle format. Using the pickle format
allowed the first command to succeed, but would "break" the socket in the
sense that all following commands would fail with an underflow exception.
2021-08-29 12:03:44 +01:00

54 lines
1.1 KiB
Go

package socket
import (
"bytes"
"fmt"
"github.com/nlpodyssey/gopickle/pickle"
)
const (
commandTerminator = "<F2B_END_COMMAND>"
pingCommand = "ping"
socketReadBufferSize = 10000
)
func (s *Fail2BanSocket) sendCommand(command []string) (interface{}, error) {
err := s.write(command)
if err != nil {
return nil, err
}
return s.read()
}
func (s *Fail2BanSocket) write(command []string) error {
err := s.encoder.Encode(command)
if err != nil {
return err
}
_, err = s.socket.Write([]byte(commandTerminator))
if err != nil {
return err
}
return nil
}
func (s *Fail2BanSocket) read() (interface{}, error) {
buf := make([]byte, socketReadBufferSize)
_, err := s.socket.Read(buf)
if err != nil {
return nil, err
}
bufReader := bytes.NewReader(buf)
unpickler := pickle.NewUnpickler(bufReader)
unpickler.FindClass = func(module, name string) (interface{}, error) {
if module == "builtins" && name == "str" {
return &Py_builtins_str{}, nil
}
return nil, fmt.Errorf("class not found: " + module + " : " + name)
}
return unpickler.Load()
}