aboutsummaryrefslogtreecommitdiff
path: root/internal/ctlsock/ctlsock_serve.go
diff options
context:
space:
mode:
authorJakob Unterwurzacher2017-02-05 18:07:14 +0100
committerJakob Unterwurzacher2017-02-05 18:17:30 +0100
commit0f40afc8321746ebd0ba0131b3296dd160f84ccc (patch)
tree6939927beb9a7d1325eb1014f7a162dd9cbb913e /internal/ctlsock/ctlsock_serve.go
parent8bcae63a5a375d918aad9f2c18804867730378e1 (diff)
ctlsock: handle non-canonical empty paths
We have to check if the input path is empty AFTER canonicalizing it, too!
Diffstat (limited to 'internal/ctlsock/ctlsock_serve.go')
-rw-r--r--internal/ctlsock/ctlsock_serve.go74
1 files changed, 48 insertions, 26 deletions
diff --git a/internal/ctlsock/ctlsock_serve.go b/internal/ctlsock/ctlsock_serve.go
index d1c0090..d09f981 100644
--- a/internal/ctlsock/ctlsock_serve.go
+++ b/internal/ctlsock/ctlsock_serve.go
@@ -78,6 +78,7 @@ func (ch *ctlSockHandler) acceptLoop() {
// We abort the connection if the request is bigger than this.
const ReadBufSize = 5000
+// handleConnection reads and parses JSON requests from "conn"
func (ch *ctlSockHandler) handleConnection(conn *net.UnixConn) {
buf := make([]byte, ReadBufSize)
for {
@@ -100,11 +101,8 @@ func (ch *ctlSockHandler) handleConnection(conn *net.UnixConn) {
err = json.Unmarshal(buf, &in)
if err != nil {
tlog.Warn.Printf("ctlsock: JSON Unmarshal error: %#v", err)
- errorMsg := ResponseStruct{
- ErrNo: int32(syscall.EINVAL),
- ErrText: "JSON Unmarshal error: " + err.Error(),
- }
- sendResponse(&errorMsg, conn)
+ err = errors.New("JSON Unmarshal error: " + err.Error())
+ sendResponse(conn, err, "", "")
continue
}
ch.handleRequest(&in, conn)
@@ -113,40 +111,64 @@ func (ch *ctlSockHandler) handleConnection(conn *net.UnixConn) {
}
}
+// handleRequest handles an already-unmarshaled JSON request
func (ch *ctlSockHandler) handleRequest(in *RequestStruct, conn *net.UnixConn) {
var err error
- var out ResponseStruct
- var inPath, clean string
+ var inPath, outPath, clean, warnText string
+ // You cannot perform both decryption and encryption in one request
if in.DecryptPath != "" && in.EncryptPath != "" {
err = errors.New("Ambigous")
- } else if in.DecryptPath == "" && in.EncryptPath == "" {
- err = errors.New("No operation")
- } else if in.DecryptPath != "" {
- inPath = in.DecryptPath
- clean = SanitizePath(inPath)
- out.Result, err = ch.fs.DecryptPath(clean)
- } else if in.EncryptPath != "" {
+ sendResponse(conn, err, "", "")
+ return
+ }
+ // Neither encryption nor encryption has been requested, makes no sense
+ if in.DecryptPath == "" && in.EncryptPath == "" {
+ err = errors.New("Empty input")
+ sendResponse(conn, err, "", "")
+ return
+ }
+ // Canonicalize input path
+ if in.EncryptPath != "" {
inPath = in.EncryptPath
- clean = SanitizePath(inPath)
- out.Result, err = ch.fs.EncryptPath(clean)
+ } else {
+ inPath = in.DecryptPath
+ }
+ clean = SanitizePath(inPath)
+ // Warn if a non-canonical path was passed
+ if inPath != clean {
+ warnText = fmt.Sprintf("Non-canonical input path '%s' has been interpreted as '%s'.", inPath, clean)
+ }
+ // Error out if the canonical path is now empty
+ if clean == "" {
+ err = errors.New("Empty input after canonicalization")
+ sendResponse(conn, err, "", warnText)
+ return
+ }
+ // Actual encrypt or decrypt operation
+ if in.EncryptPath != "" {
+ outPath, err = ch.fs.EncryptPath(clean)
+ } else {
+ outPath, err = ch.fs.DecryptPath(clean)
+ }
+ sendResponse(conn, err, outPath, warnText)
+}
+
+// sendResponse sends a JSON response message
+func sendResponse(conn *net.UnixConn, err error, result string, warnText string) {
+ msg := ResponseStruct{
+ Result: result,
+ WarnText: warnText,
}
if err != nil {
- out.ErrText = err.Error()
- out.ErrNo = -1
+ msg.ErrText = err.Error()
+ msg.ErrNo = -1
// Try to extract the actual error number
if pe, ok := err.(*os.PathError); ok {
if se, ok := pe.Err.(syscall.Errno); ok {
- out.ErrNo = int32(se)
+ msg.ErrNo = int32(se)
}
}
}
- if inPath != clean {
- out.WarnText = fmt.Sprintf("Non-canonical input path '%s' has been interpreted as '%s'.", inPath, clean)
- }
- sendResponse(&out, conn)
-}
-
-func sendResponse(msg *ResponseStruct, conn *net.UnixConn) {
jsonMsg, err := json.Marshal(msg)
if err != nil {
tlog.Warn.Printf("ctlsock: Marshal failed: %v", err)