From 7e51073400df9cdeefb454ebaaca2ce776162364 Mon Sep 17 00:00:00 2001 From: Jakob Unterwurzacher Date: Sat, 9 May 2020 19:09:09 +0200 Subject: [PATCH] ctlsock: add CtlSock API --- ctlsock/ctlsock.go | 69 ++++++++++++++++++++++++++++++++++----------- ctlsock/json_abi.go | 26 +++++++++++++++++ 2 files changed, 78 insertions(+), 17 deletions(-) create mode 100644 ctlsock/json_abi.go diff --git a/ctlsock/ctlsock.go b/ctlsock/ctlsock.go index 893b3b0..1c440b5 100644 --- a/ctlsock/ctlsock.go +++ b/ctlsock/ctlsock.go @@ -2,25 +2,60 @@ // gocryptfs control socket interface. This interface can be // activated by passing `-ctlsock /tmp/my.sock` to gocryptfs on the // command line. +// See gocryptfs-xray for a usage example. package ctlsock -// RequestStruct is sent by a client -type RequestStruct struct { - EncryptPath string - DecryptPath string +import ( + "encoding/json" + "fmt" + "net" + "time" +) + +func (r *ResponseStruct) Error() string { + return fmt.Sprintf("errno %d: %s", r.ErrNo, r.ErrText) } -// ResponseStruct is sent by the server in response to a request -type ResponseStruct struct { - // Result is the resulting decrypted or encrypted path. Empty on error. - Result string - // ErrNo is the error number as defined in errno.h. - // 0 means success and -1 means that the error number is not known - // (look at ErrText in this case). - ErrNo int32 - // ErrText is a detailed error message. - ErrText string - // WarnText contains warnings that may have been encountered while - // processing the message. - WarnText string +// CtlSock encapsulates a control socket +type CtlSock struct { + Conn net.Conn +} + +// New opens the socket at `socketPath` and stores it in a `CtlSock` object. +func New(socketPath string) (*CtlSock, error) { + conn, err := net.DialTimeout("unix", socketPath, 1*time.Second) + if err != nil { + return nil, err + } + return &CtlSock{Conn: conn}, nil +} + +// Query sends a request to the control socket returns the response. +func (c *CtlSock) Query(req *RequestStruct) (*ResponseStruct, error) { + c.Conn.SetDeadline(time.Now().Add(time.Second)) + msg, err := json.Marshal(req) + if err != nil { + return nil, err + } + _, err = c.Conn.Write(msg) + if err != nil { + return nil, err + } + buf := make([]byte, 5000) + n, err := c.Conn.Read(buf) + if err != nil { + return nil, err + } + buf = buf[:n] + var resp ResponseStruct + json.Unmarshal(buf, &resp) + if resp.ErrNo != 0 { + return nil, &resp + } + return &resp, nil +} + +// Close closes the socket +func (c *CtlSock) Close() { + c.Conn.Close() } diff --git a/ctlsock/json_abi.go b/ctlsock/json_abi.go new file mode 100644 index 0000000..7deff08 --- /dev/null +++ b/ctlsock/json_abi.go @@ -0,0 +1,26 @@ +package ctlsock + +// RequestStruct is sent by a client (encoded as JSON). +// You cannot perform both encryption and decryption in the same request. +type RequestStruct struct { + // EncryptPath is the path that should be encrypted. + EncryptPath string + // DecryptPath is the path that should be decrypted. + DecryptPath string +} + +// ResponseStruct is sent by the server in response to a request +// (encoded as JSON). +type ResponseStruct struct { + // Result is the resulting decrypted or encrypted path. Empty on error. + Result string + // ErrNo is the error number as defined in errno.h. + // 0 means success and -1 means that the error number is not known + // (look at ErrText in this case). + ErrNo int32 + // ErrText is a detailed error message. + ErrText string + // WarnText contains warnings that may have been encountered while + // processing the message. + WarnText string +}