ctlsock: handle non-canonical empty paths
We have to check if the input path is empty AFTER canonicalizing it, too!
This commit is contained in:
parent
8bcae63a5a
commit
0f40afc832
@ -78,6 +78,7 @@ func (ch *ctlSockHandler) acceptLoop() {
|
|||||||
// We abort the connection if the request is bigger than this.
|
// We abort the connection if the request is bigger than this.
|
||||||
const ReadBufSize = 5000
|
const ReadBufSize = 5000
|
||||||
|
|
||||||
|
// handleConnection reads and parses JSON requests from "conn"
|
||||||
func (ch *ctlSockHandler) handleConnection(conn *net.UnixConn) {
|
func (ch *ctlSockHandler) handleConnection(conn *net.UnixConn) {
|
||||||
buf := make([]byte, ReadBufSize)
|
buf := make([]byte, ReadBufSize)
|
||||||
for {
|
for {
|
||||||
@ -100,11 +101,8 @@ func (ch *ctlSockHandler) handleConnection(conn *net.UnixConn) {
|
|||||||
err = json.Unmarshal(buf, &in)
|
err = json.Unmarshal(buf, &in)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tlog.Warn.Printf("ctlsock: JSON Unmarshal error: %#v", err)
|
tlog.Warn.Printf("ctlsock: JSON Unmarshal error: %#v", err)
|
||||||
errorMsg := ResponseStruct{
|
err = errors.New("JSON Unmarshal error: " + err.Error())
|
||||||
ErrNo: int32(syscall.EINVAL),
|
sendResponse(conn, err, "", "")
|
||||||
ErrText: "JSON Unmarshal error: " + err.Error(),
|
|
||||||
}
|
|
||||||
sendResponse(&errorMsg, conn)
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
ch.handleRequest(&in, conn)
|
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) {
|
func (ch *ctlSockHandler) handleRequest(in *RequestStruct, conn *net.UnixConn) {
|
||||||
var err error
|
var err error
|
||||||
var out ResponseStruct
|
var inPath, outPath, clean, warnText string
|
||||||
var inPath, clean string
|
// You cannot perform both decryption and encryption in one request
|
||||||
if in.DecryptPath != "" && in.EncryptPath != "" {
|
if in.DecryptPath != "" && in.EncryptPath != "" {
|
||||||
err = errors.New("Ambigous")
|
err = errors.New("Ambigous")
|
||||||
} else if in.DecryptPath == "" && in.EncryptPath == "" {
|
sendResponse(conn, err, "", "")
|
||||||
err = errors.New("No operation")
|
return
|
||||||
} else if in.DecryptPath != "" {
|
}
|
||||||
inPath = in.DecryptPath
|
// Neither encryption nor encryption has been requested, makes no sense
|
||||||
clean = SanitizePath(inPath)
|
if in.DecryptPath == "" && in.EncryptPath == "" {
|
||||||
out.Result, err = ch.fs.DecryptPath(clean)
|
err = errors.New("Empty input")
|
||||||
} else if in.EncryptPath != "" {
|
sendResponse(conn, err, "", "")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Canonicalize input path
|
||||||
|
if in.EncryptPath != "" {
|
||||||
inPath = in.EncryptPath
|
inPath = in.EncryptPath
|
||||||
|
} else {
|
||||||
|
inPath = in.DecryptPath
|
||||||
|
}
|
||||||
clean = SanitizePath(inPath)
|
clean = SanitizePath(inPath)
|
||||||
out.Result, err = ch.fs.EncryptPath(clean)
|
// 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 {
|
if err != nil {
|
||||||
out.ErrText = err.Error()
|
msg.ErrText = err.Error()
|
||||||
out.ErrNo = -1
|
msg.ErrNo = -1
|
||||||
// Try to extract the actual error number
|
// Try to extract the actual error number
|
||||||
if pe, ok := err.(*os.PathError); ok {
|
if pe, ok := err.(*os.PathError); ok {
|
||||||
if se, ok := pe.Err.(syscall.Errno); 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)
|
jsonMsg, err := json.Marshal(msg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tlog.Warn.Printf("ctlsock: Marshal failed: %v", err)
|
tlog.Warn.Printf("ctlsock: Marshal failed: %v", err)
|
||||||
|
Loading…
Reference in New Issue
Block a user