From: Jeff Halter Date: Sat, 25 Jun 2022 02:23:44 +0000 (-0700) Subject: Prevent user with accessAnyName from change name X-Git-Url: https://git.r.bdr.sh/rbdr/mobius/commitdiff_plain/264b7c27c7a46e2d0eb699812c8e38cf771fcf00?ds=inline;hp=-c Prevent user with accessAnyName from change name --- 264b7c27c7a46e2d0eb699812c8e38cf771fcf00 diff --git a/hotline/transaction_handlers.go b/hotline/transaction_handlers.go index aa994b9..2a81768 100644 --- a/hotline/transaction_handlers.go +++ b/hotline/transaction_handlers.go @@ -1593,18 +1593,17 @@ func HandleUploadFile(cc *ClientConn, t *Transaction) (res []Transaction, err er } func HandleSetClientUserInfo(cc *ClientConn, t *Transaction) (res []Transaction, err error) { - var icon []byte if len(t.GetField(fieldUserIconID).Data) == 4 { - icon = t.GetField(fieldUserIconID).Data[2:] + cc.Icon = t.GetField(fieldUserIconID).Data[2:] } else { - icon = t.GetField(fieldUserIconID).Data + cc.Icon = t.GetField(fieldUserIconID).Data + } + if cc.Authorize(accessAnyName) { + cc.UserName = t.GetField(fieldUserName).Data } - cc.Icon = icon - cc.UserName = t.GetField(fieldUserName).Data // the options field is only passed by the client versions > 1.2.3. options := t.GetField(fieldOptions).Data - if options != nil { optBitmap := big.NewInt(int64(binary.BigEndian.Uint16(options))) flagBitmap := big.NewInt(int64(binary.BigEndian.Uint16(cc.Flags))) @@ -1623,14 +1622,16 @@ func HandleSetClientUserInfo(cc *ClientConn, t *Transaction) (res []Transaction, } } - // Notify all clients of updated user info - cc.sendAll( - tranNotifyChangeUser, - NewField(fieldUserID, *cc.ID), - NewField(fieldUserIconID, cc.Icon), - NewField(fieldUserFlags, cc.Flags), - NewField(fieldUserName, cc.UserName), - ) + for _, c := range sortedClients(cc.Server.Clients) { + res = append(res, *NewTransaction( + tranNotifyChangeUser, + c.ID, + NewField(fieldUserID, *cc.ID), + NewField(fieldUserIconID, cc.Icon), + NewField(fieldUserFlags, cc.Flags), + NewField(fieldUserName, cc.UserName), + )) + } return res, err } diff --git a/hotline/transaction_handlers_test.go b/hotline/transaction_handlers_test.go index f283112..f43d45f 100644 --- a/hotline/transaction_handlers_test.go +++ b/hotline/transaction_handlers_test.go @@ -2887,3 +2887,72 @@ func TestHandleTranAgreed(t *testing.T) { }) } } + +func TestHandleSetClientUserInfo(t *testing.T) { + type args struct { + cc *ClientConn + t *Transaction + } + tests := []struct { + name string + args args + wantRes []Transaction + wantErr assert.ErrorAssertionFunc + }{ + { + name: "when client does not have accessAnyName", + args: args{ + cc: &ClientConn{ + Account: &Account{ + Access: func() *[]byte { + var bits accessBitmap + access := bits[:] + return &access + }(), + }, + ID: &[]byte{0, 1}, + UserName: []byte("Guest"), + Flags: []byte{0, 1}, + Server: &Server{ + Clients: map[uint16]*ClientConn{ + uint16(1): { + ID: &[]byte{0, 1}, + }, + }, + }, + }, + t: NewTransaction( + tranSetClientUserInfo, nil, + NewField(fieldUserIconID, []byte{0, 1}), + NewField(fieldUserName, []byte("NOPE")), + ), + }, + wantRes: []Transaction{ + { + clientID: &[]byte{0, 1}, + Flags: 0x00, + IsReply: 0x00, + Type: []byte{0x01, 0x2d}, + ID: []byte{0, 0, 0, 0}, + ErrorCode: []byte{0, 0, 0, 0}, + Fields: []Field{ + NewField(fieldUserID, []byte{0, 1}), + NewField(fieldUserIconID, []byte{0, 1}), + NewField(fieldUserFlags, []byte{0, 1}), + NewField(fieldUserName, []byte("Guest"))}, + }, + }, + wantErr: assert.NoError, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + gotRes, err := HandleSetClientUserInfo(tt.args.cc, tt.args.t) + if !tt.wantErr(t, err, fmt.Sprintf("HandleSetClientUserInfo(%v, %v)", tt.args.cc, tt.args.t)) { + return + } + + tranAssertEqual(t, tt.wantRes, gotRes) + }) + } +}