]> git.r.bdr.sh - rbdr/mobius/blobdiff - hotline/transaction_handlers.go
Fix handling of refuse PM flag
[rbdr/mobius] / hotline / transaction_handlers.go
index 85f85a4ddec59feadb0886427fa4517397cf62be..1ef8ad3498582ff83b843d765c700eaeabfae24a 100644 (file)
@@ -337,7 +337,7 @@ func HandleSendInstantMsg(cc *ClientConn, t *Transaction) (res []Transaction, er
 
        // Check if target user has "Refuse private messages" flag
        flagBitmap := big.NewInt(int64(binary.BigEndian.Uint16(otherClient.Flags)))
-       if flagBitmap.Bit(UserFlagRefusePChat) == 1 {
+       if flagBitmap.Bit(UserFlagRefusePM) == 1 {
                res = append(res,
                        *NewTransaction(
                                TranServerMsg,
@@ -385,16 +385,31 @@ func HandleGetFileInfo(cc *ClientConn, t *Transaction) (res []Transaction, err e
                return res, err
        }
 
-       res = append(res, cc.NewReply(t,
-               NewField(FieldFileName, []byte(fw.name)),
+       encodedName, err := txtEncoder.String(fw.name)
+       if err != nil {
+               return res, fmt.Errorf("invalid filepath encoding: %w", err)
+       }
+
+       fields := []Field{
+               NewField(FieldFileName, []byte(encodedName)),
                NewField(FieldFileTypeString, fw.ffo.FlatFileInformationFork.friendlyType()),
                NewField(FieldFileCreatorString, fw.ffo.FlatFileInformationFork.friendlyCreator()),
-               NewField(FieldFileComment, fw.ffo.FlatFileInformationFork.Comment),
                NewField(FieldFileType, fw.ffo.FlatFileInformationFork.TypeSignature),
                NewField(FieldFileCreateDate, fw.ffo.FlatFileInformationFork.CreateDate),
                NewField(FieldFileModifyDate, fw.ffo.FlatFileInformationFork.ModifyDate),
-               NewField(FieldFileSize, fw.totalSize()),
-       ))
+       }
+
+       // Include the optional FileComment field if there is a comment.
+       if len(fw.ffo.FlatFileInformationFork.Comment) != 0 {
+               fields = append(fields, NewField(FieldFileComment, fw.ffo.FlatFileInformationFork.Comment))
+       }
+
+       // Include the FileSize field for files.
+       if !bytes.Equal(fw.ffo.FlatFileInformationFork.TypeSignature, []byte{0x66, 0x6c, 0x64, 0x72}) {
+               fields = append(fields, NewField(FieldFileSize, fw.totalSize()))
+       }
+
+       res = append(res, cc.NewReply(t, fields...))
        return res, err
 }
 
@@ -478,7 +493,11 @@ func HandleSetFileInfo(cc *ClientConn, t *Transaction) (res []Transaction, err e
                        if err != nil {
                                return nil, err
                        }
-                       hlFile.name = string(fileNewName)
+                       hlFile.name, err = txtDecoder.String(string(fileNewName))
+                       if err != nil {
+                               return res, fmt.Errorf("invalid filepath encoding: %w", err)
+                       }
+
                        err = hlFile.move(fileDir)
                        if os.IsNotExist(err) {
                                res = append(res, cc.NewErrReply(t, "Cannot rename file "+string(fileName)+" because it does not exist or cannot be found."))
@@ -566,9 +585,6 @@ func HandleMoveFile(cc *ClientConn, t *Transaction) (res []Transaction, err erro
                res = append(res, cc.NewErrReply(t, "Cannot delete file "+fileName+" because it does not exist or cannot be found."))
                return res, err
        }
-       if err != nil {
-               return res, err
-       }
        switch mode := fi.Mode(); {
        case mode.IsDir():
                if !cc.Authorize(accessMoveFolder) {
@@ -614,6 +630,10 @@ func HandleNewFolder(cc *ClientConn, t *Transaction) (res []Transaction, err err
                }
        }
        newFolderPath := path.Join(cc.Server.Config.FileRoot, subPath, folderName)
+       newFolderPath, err = txtDecoder.String(newFolderPath)
+       if err != nil {
+               return res, fmt.Errorf("invalid filepath encoding: %w", err)
+       }
 
        // TODO: check path and folder name lengths
 
@@ -622,8 +642,6 @@ func HandleNewFolder(cc *ClientConn, t *Transaction) (res []Transaction, err err
                return []Transaction{cc.NewErrReply(t, msg)}, nil
        }
 
-       // TODO: check for disallowed characters to maintain compatibility for original client
-
        if err := cc.Server.FS.Mkdir(newFolderPath, 0777); err != nil {
                msg := fmt.Sprintf("Cannot create folder \"%s\" because an error occurred.", folderName)
                return []Transaction{cc.NewErrReply(t, msg)}, nil
@@ -639,7 +657,7 @@ func HandleSetUser(cc *ClientConn, t *Transaction) (res []Transaction, err error
                return res, err
        }
 
-       login := DecodeUserString(t.GetField(FieldUserLogin).Data)
+       login := decodeString(t.GetField(FieldUserLogin).Data)
        userName := string(t.GetField(FieldUserName).Data)
 
        newAccessLvl := t.GetField(FieldUserAccess).Data
@@ -710,7 +728,7 @@ func HandleGetUser(cc *ClientConn, t *Transaction) (res []Transaction, err error
 
        res = append(res, cc.NewReply(t,
                NewField(FieldUserName, []byte(account.Name)),
-               NewField(FieldUserLogin, negateString(t.GetField(FieldUserLogin).Data)),
+               NewField(FieldUserLogin, encodeString(t.GetField(FieldUserLogin).Data)),
                NewField(FieldUserPassword, []byte(account.Password)),
                NewField(FieldUserAccess, account.Access[:]),
        ))
@@ -755,7 +773,7 @@ func HandleUpdateUser(cc *ClientConn, t *Transaction) (res []Transaction, err er
                }
 
                if len(subFields) == 1 {
-                       login := DecodeUserString(getField(FieldData, &subFields).Data)
+                       login := decodeString(getField(FieldData, &subFields).Data)
                        cc.logger.Infow("DeleteUser", "login", login)
 
                        if !cc.Authorize(accessDeleteUser) {
@@ -769,7 +787,7 @@ func HandleUpdateUser(cc *ClientConn, t *Transaction) (res []Transaction, err er
                        continue
                }
 
-               login := DecodeUserString(getField(FieldUserLogin, &subFields).Data)
+               login := decodeString(getField(FieldUserLogin, &subFields).Data)
 
                // check if the login dataFile; if so, we know we are updating an existing user
                if acc, ok := cc.Server.Accounts[login]; ok {
@@ -793,8 +811,8 @@ func HandleUpdateUser(cc *ClientConn, t *Transaction) (res []Transaction, err er
                        }
 
                        err = cc.Server.UpdateUser(
-                               DecodeUserString(getField(FieldData, &subFields).Data),
-                               DecodeUserString(getField(FieldUserLogin, &subFields).Data),
+                               decodeString(getField(FieldData, &subFields).Data),
+                               decodeString(getField(FieldUserLogin, &subFields).Data),
                                string(getField(FieldUserName, &subFields).Data),
                                acc.Password,
                                acc.Access,
@@ -840,7 +858,7 @@ func HandleNewUser(cc *ClientConn, t *Transaction) (res []Transaction, err error
                return res, err
        }
 
-       login := DecodeUserString(t.GetField(FieldUserLogin).Data)
+       login := decodeString(t.GetField(FieldUserLogin).Data)
 
        // If the account already dataFile, reply with an error
        if _, ok := cc.Server.Accounts[login]; ok {
@@ -876,7 +894,7 @@ func HandleDeleteUser(cc *ClientConn, t *Transaction) (res []Transaction, err er
        }
 
        // TODO: Handle case where account doesn't exist; e.g. delete race condition
-       login := DecodeUserString(t.GetField(FieldUserLogin).Data)
+       login := decodeString(t.GetField(FieldUserLogin).Data)
 
        if err := cc.Server.DeleteUser(login); err != nil {
                return res, err