X-Git-Url: https://git.r.bdr.sh/rbdr/mobius/blobdiff_plain/003a743e6767b3041c3a8321566c3586d73b399a..2161a64281bcf0a33649ec6b33d78453747d94ca:/hotline/transaction_handlers.go diff --git a/hotline/transaction_handlers.go b/hotline/transaction_handlers.go index 270f73e..ba2512e 100644 --- a/hotline/transaction_handlers.go +++ b/hotline/transaction_handlers.go @@ -45,10 +45,13 @@ var TransactionHandlers = map[uint16]TransactionType{ Name: "tranNotifyDeleteUser", }, tranAgreed: { + Access: accessAlwaysAllow, Name: "tranAgreed", Handler: HandleTranAgreed, }, tranChatSend: { + Access: accessSendChat, + DenyMsg: "You are not allowed to participate in chat.", Handler: HandleChatSend, Name: "tranChatSend", RequiredFields: []requiredField{ @@ -65,16 +68,20 @@ var TransactionHandlers = map[uint16]TransactionType{ Handler: HandleDelNewsArt, }, tranDelNewsItem: { + Access: accessAlwaysAllow, // Granular access enforced inside the handler // Has multiple access flags: News Delete Folder (37) or News Delete Category (35) // TODO: Implement inside the handler Name: "tranDelNewsItem", Handler: HandleDelNewsItem, }, tranDeleteFile: { + Access: accessAlwaysAllow, // Granular access enforced inside the handler Name: "tranDeleteFile", Handler: HandleDeleteFile, }, tranDeleteUser: { + Access: accessDeleteUser, + DenyMsg: "You are not allowed to delete accounts.", Name: "tranDeleteUser", Handler: HandleDeleteUser, }, @@ -103,10 +110,12 @@ var TransactionHandlers = map[uint16]TransactionType{ Handler: HandleGetClientConnInfoText, }, tranGetFileInfo: { + Access: accessAlwaysAllow, Name: "tranGetFileInfo", Handler: HandleGetFileInfo, }, tranGetFileNameList: { + Access: accessAlwaysAllow, Name: "tranGetFileNameList", Handler: HandleGetFileNameList, }, @@ -135,11 +144,13 @@ var TransactionHandlers = map[uint16]TransactionType{ Handler: HandleGetNewsCatNameList, }, tranGetUser: { + Access: accessOpenUser, DenyMsg: "You are not allowed to view accounts.", Name: "tranGetUser", Handler: HandleGetUser, }, tranGetUserNameList: { + Access: accessAlwaysAllow, Name: "tranHandleGetUserNameList", Handler: HandleGetUserNameList, }, @@ -156,14 +167,17 @@ var TransactionHandlers = map[uint16]TransactionType{ Handler: HandleInviteToChat, }, tranJoinChat: { + Access: accessAlwaysAllow, Name: "tranJoinChat", Handler: HandleJoinChat, }, tranKeepAlive: { + Access: accessAlwaysAllow, Name: "tranKeepAlive", Handler: HandleKeepAlive, }, tranLeaveChat: { + Access: accessAlwaysAllow, Name: "tranJoinChat", Handler: HandleLeaveChat, }, @@ -217,6 +231,7 @@ var TransactionHandlers = map[uint16]TransactionType{ Handler: HandlePostNewsArt, }, tranRejectChatInvite: { + Access: accessAlwaysAllow, Name: "tranRejectChatInvite", Handler: HandleRejectChatInvite, }, @@ -237,10 +252,12 @@ var TransactionHandlers = map[uint16]TransactionType{ }, }, tranSetChatSubject: { + Access: accessAlwaysAllow, Name: "tranSetChatSubject", Handler: HandleSetChatSubject, }, tranMakeFileAlias: { + Access: accessAlwaysAllow, Name: "tranMakeFileAlias", Handler: HandleMakeAlias, RequiredFields: []requiredField{ @@ -250,10 +267,12 @@ var TransactionHandlers = map[uint16]TransactionType{ }, }, tranSetClientUserInfo: { + Access: accessAlwaysAllow, Name: "tranSetClientUserInfo", Handler: HandleSetClientUserInfo, }, tranSetFileInfo: { + Access: accessAlwaysAllow, Name: "tranSetFileInfo", Handler: HandleSetFileInfo, }, @@ -264,10 +283,12 @@ var TransactionHandlers = map[uint16]TransactionType{ Handler: HandleSetUser, }, tranUploadFile: { + Access: accessAlwaysAllow, Name: "tranUploadFile", Handler: HandleUploadFile, }, tranUploadFldr: { + Access: accessAlwaysAllow, Name: "tranUploadFldr", Handler: HandleUploadFolder, }, @@ -401,7 +422,7 @@ func HandleGetFileInfo(cc *ClientConn, t *Transaction) (res []Transaction, err e NewField(fieldFileType, ffo.FlatFileInformationFork.TypeSignature), NewField(fieldFileCreateDate, ffo.FlatFileInformationFork.CreateDate), NewField(fieldFileModifyDate, ffo.FlatFileInformationFork.ModifyDate), - NewField(fieldFileSize, ffo.FlatFileDataForkHeader.DataSize), + NewField(fieldFileSize, ffo.FlatFileDataForkHeader.DataSize[:]), )) return res, err } @@ -1066,8 +1087,8 @@ func HandleDelNewsItem(cc *ClientConn, t *Transaction) (res []Transaction, err e delName := pathStrs[len(pathStrs)-1] if len(pathStrs) > 1 { - for _, path := range pathStrs[0 : len(pathStrs)-1] { - cats = cats[path].SubCats + for _, fp := range pathStrs[0 : len(pathStrs)-1] { + cats = cats[fp].SubCats } } @@ -1213,7 +1234,7 @@ func HandleDownloadFile(cc *ClientConn, t *Transaction) (res []Transaction, err NewField(fieldRefNum, transactionRef), NewField(fieldWaitingCount, []byte{0x00, 0x00}), // TODO: Implement waiting count NewField(fieldTransferSize, ffo.TransferSize()), - NewField(fieldFileSize, ffo.FlatFileDataForkHeader.DataSize), + NewField(fieldFileSize, ffo.FlatFileDataForkHeader.DataSize[:]), )) return res, err @@ -1295,6 +1316,21 @@ func HandleUploadFolder(cc *ClientConn, t *Transaction) (res []Transaction, err transactionRef := cc.Server.NewTransactionRef() data := binary.BigEndian.Uint32(transactionRef) + var fp FilePath + if t.GetField(fieldFilePath).Data != nil { + if err = fp.UnmarshalBinary(t.GetField(fieldFilePath).Data); err != nil { + return res, err + } + } + + // Handle special cases for Upload and Drop Box folders + if !authorize(cc.Account.Access, accessUploadAnywhere) { + if !fp.IsUploadDir() && !fp.IsDropbox() { + res = append(res, cc.NewErrReply(t, fmt.Sprintf("Cannot accept upload of the folder \"%v\" because you are only allowed to upload to the \"Uploads\" folder.", string(t.GetField(fieldFileName).Data)))) + return res, err + } + } + fileTransfer := &FileTransfer{ FileName: t.GetField(fieldFileName).Data, FilePath: t.GetField(fieldFilePath).Data, @@ -1309,8 +1345,10 @@ func HandleUploadFolder(cc *ClientConn, t *Transaction) (res []Transaction, err return res, err } +// HandleUploadFile +// Special cases: +// * If the target directory contains "uploads" (case insensitive) func HandleUploadFile(cc *ClientConn, t *Transaction) (res []Transaction, err error) { - // TODO: add permission handing for upload folders and drop boxes if !authorize(cc.Account.Access, accessUploadFile) { res = append(res, cc.NewErrReply(t, "You are not allowed to upload files.")) return res, err @@ -1319,6 +1357,21 @@ func HandleUploadFile(cc *ClientConn, t *Transaction) (res []Transaction, err er fileName := t.GetField(fieldFileName).Data filePath := t.GetField(fieldFilePath).Data + var fp FilePath + if filePath != nil { + if err = fp.UnmarshalBinary(filePath); err != nil { + return res, err + } + } + + // Handle special cases for Upload and Drop Box folders + if !authorize(cc.Account.Access, accessUploadAnywhere) { + if !fp.IsUploadDir() && !fp.IsDropbox() { + res = append(res, cc.NewErrReply(t, fmt.Sprintf("Cannot accept upload of the file \"%v\" because you are only allowed to upload to the \"Uploads\" folder.", string(fileName)))) + return res, err + } + } + transactionRef := cc.Server.NewTransactionRef() data := binary.BigEndian.Uint32(transactionRef) @@ -1395,6 +1448,19 @@ func HandleGetFileNameList(cc *ClientConn, t *Transaction) (res []Transaction, e return res, err } + var fp FilePath + if t.GetField(fieldFilePath).Data != nil { + if err = fp.UnmarshalBinary(t.GetField(fieldFilePath).Data); err != nil { + return res, err + } + } + + // Handle special case for drop box folders + if fp.IsDropbox() && !authorize(cc.Account.Access, accessViewDropBoxes) { + res = append(res, cc.NewReply(t)) + return res, err + } + fileNames, err := getFileNameList(fullPath) if err != nil { return res, err