| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242 |
- package oscar
- import (
- "bytes"
- "context"
- "encoding/binary"
- "errors"
- "fmt"
- "io"
- "log/slog"
- "github.com/mk6i/open-oscar-server/config"
- "github.com/mk6i/open-oscar-server/server/oscar/middleware"
- "github.com/mk6i/open-oscar-server/state"
- "github.com/mk6i/open-oscar-server/wire"
- )
- var (
- // ErrRouteNotFound is an error that indicates a failure to find a matching
- // route for an OSCAR protocol request.
- ErrRouteNotFound = errors.New("route not found")
- errUnknownICQMetaReqType = errors.New("unknown ICQ request type")
- )
- // ResponseWriter is the interface for sending a SNAC response to the client
- // from the server handlers.
- type ResponseWriter interface {
- SendSNAC(frame wire.SNACFrame, body any) error
- }
- // Handler defines a structure for routing OSCAR protocol requests to
- // appropriate handlers based on group:subGroup identifiers.
- type Handler struct {
- AdminService
- BARTService
- BuddyService
- ChatNavService
- ChatService
- FeedbagService
- ICBMService
- ICQService
- LocateService
- ODirService
- OServiceService
- PermitDenyService
- StatsService
- UserLookupService
- middleware.RouteLogger
- }
- func (rt Handler) AdminConfirmRequest(ctx context.Context, instance *state.SessionInstance, inFrame wire.SNACFrame, _ io.Reader, rw ResponseWriter) error {
- outSNAC, err := rt.ConfirmRequest(ctx, instance, inFrame)
- if err != nil {
- return err
- }
- rt.LogRequestAndResponse(ctx, inFrame, nil, outSNAC.Frame, outSNAC.Body)
- return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
- }
- func (rt Handler) AdminInfoQuery(ctx context.Context, instance *state.SessionInstance, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
- inBody := wire.SNAC_0x07_0x02_AdminInfoQuery{}
- if err := wire.UnmarshalBE(&inBody, r); err != nil {
- return err
- }
- outSNAC, err := rt.AdminService.InfoQuery(ctx, instance, inFrame, inBody)
- if err != nil {
- return err
- }
- rt.LogRequestAndResponse(ctx, inFrame, nil, outSNAC.Frame, outSNAC.Body)
- return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
- }
- func (rt Handler) AdminInfoChangeRequest(ctx context.Context, instance *state.SessionInstance, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
- inBody := wire.SNAC_0x07_0x04_AdminInfoChangeRequest{}
- if err := wire.UnmarshalBE(&inBody, r); err != nil {
- return err
- }
- outSNAC, err := rt.InfoChangeRequest(ctx, instance, inFrame, inBody)
- if err != nil {
- return err
- }
- rt.LogRequestAndResponse(ctx, inFrame, nil, outSNAC.Frame, outSNAC.Body)
- return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
- }
- func (rt Handler) AlertNotifyCapabilities(ctx context.Context, _ *state.SessionInstance, inFrame wire.SNACFrame, _ io.Reader, _ ResponseWriter) error {
- rt.LogRequest(ctx, inFrame, nil)
- return nil
- }
- func (rt Handler) AlertNotifyDisplayCapabilities(ctx context.Context, _ *state.SessionInstance, inFrame wire.SNACFrame, _ io.Reader, _ ResponseWriter) error {
- rt.LogRequest(ctx, inFrame, nil)
- return nil
- }
- func (rt Handler) InviteRequest(ctx context.Context, _ *state.SessionInstance, inFrame wire.SNACFrame, _ io.Reader, _ ResponseWriter) error {
- rt.LogRequest(ctx, inFrame, nil)
- return nil
- }
- func (rt Handler) PluginRequest(ctx context.Context, _ *state.SessionInstance, inFrame wire.SNACFrame, _ io.Reader, _ ResponseWriter) error {
- rt.LogRequest(ctx, inFrame, nil)
- return nil
- }
- func (rt Handler) MDirRequest(ctx context.Context, _ *state.SessionInstance, inFrame wire.SNACFrame, _ io.Reader, _ ResponseWriter) error {
- rt.LogRequest(ctx, inFrame, nil)
- return nil
- }
- func (rt Handler) BARTUploadQuery(ctx context.Context, instance *state.SessionInstance, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
- inBody := wire.SNAC_0x10_0x02_BARTUploadQuery{}
- if err := wire.UnmarshalBE(&inBody, r); err != nil {
- return err
- }
- outSNAC, err := rt.BARTService.UpsertItem(ctx, instance, inFrame, inBody)
- if err != nil {
- return err
- }
- rt.LogRequestAndResponse(ctx, inFrame, outSNAC, outSNAC.Frame, outSNAC.Body)
- return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
- }
- func (rt Handler) BARTDownloadQuery(ctx context.Context, instance *state.SessionInstance, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
- inBody := wire.SNAC_0x10_0x04_BARTDownloadQuery{}
- if err := wire.UnmarshalBE(&inBody, r); err != nil {
- return err
- }
- outSNAC, err := rt.RetrieveItem(ctx, inFrame, inBody)
- if err != nil {
- return err
- }
- rt.LogRequestAndResponse(ctx, inFrame, outSNAC, outSNAC.Frame, outSNAC.Body)
- return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
- }
- func (rt Handler) BARTDownload2Query(ctx context.Context, instance *state.SessionInstance, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
- inBody := wire.SNAC_0x10_0x06_BARTDownload2Query{}
- if err := wire.UnmarshalBE(&inBody, r); err != nil {
- return err
- }
- outSNACS, err := rt.RetrieveItemV2(ctx, inFrame, inBody)
- if err != nil {
- return err
- }
- for _, snac := range outSNACS {
- rt.LogRequestAndResponse(ctx, inFrame, snac, snac.Frame, snac.Body)
- if err := rw.SendSNAC(snac.Frame, snac.Body); err != nil {
- return err
- }
- }
- return nil
- }
- func (rt Handler) BuddyRightsQuery(ctx context.Context, _ *state.SessionInstance, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
- inSNAC := wire.SNAC_0x03_0x02_BuddyRightsQuery{}
- if err := wire.UnmarshalBE(&inSNAC, r); err != nil {
- return err
- }
- outSNAC := rt.BuddyService.RightsQuery(ctx, inFrame)
- rt.LogRequestAndResponse(ctx, inFrame, inSNAC, outSNAC.Frame, outSNAC.Body)
- return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
- }
- func (rt Handler) BuddyAddBuddies(ctx context.Context, instance *state.SessionInstance, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
- inSNAC := wire.SNAC_0x03_0x04_BuddyAddBuddies{}
- if err := wire.UnmarshalBE(&inSNAC, r); err != nil {
- return err
- }
- rejectSNAC, err := rt.AddBuddies(ctx, instance, inFrame, inSNAC)
- if err != nil {
- return err
- }
- if rejectSNAC != nil {
- rt.LogRequestAndResponse(ctx, inFrame, inSNAC, rejectSNAC.Frame, rejectSNAC.Body)
- if sendErr := rw.SendSNAC(rejectSNAC.Frame, rejectSNAC.Body); sendErr != nil {
- return sendErr
- }
- } else {
- rt.LogRequest(ctx, inFrame, inSNAC)
- }
- return nil
- }
- func (rt Handler) BuddyDelBuddies(ctx context.Context, instance *state.SessionInstance, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
- inSNAC := wire.SNAC_0x03_0x05_BuddyDelBuddies{}
- if err := wire.UnmarshalBE(&inSNAC, r); err != nil {
- return err
- }
- rt.LogRequest(ctx, inFrame, inSNAC)
- return rt.DelBuddies(ctx, instance, inSNAC)
- }
- func (rt Handler) BuddyAddTempBuddies(ctx context.Context, instance *state.SessionInstance, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
- inSNAC := wire.SNAC_0x03_0x0F_BuddyAddTempBuddies{}
- if err := wire.UnmarshalBE(&inSNAC, r); err != nil {
- return err
- }
- rejectSNAC, err := rt.AddTempBuddies(ctx, instance, inFrame, inSNAC)
- if err != nil {
- return err
- }
- if rejectSNAC != nil {
- rt.LogRequestAndResponse(ctx, inFrame, inSNAC, rejectSNAC.Frame, rejectSNAC.Body)
- if sendErr := rw.SendSNAC(rejectSNAC.Frame, rejectSNAC.Body); sendErr != nil {
- return sendErr
- }
- } else {
- rt.LogRequest(ctx, inFrame, inSNAC)
- }
- return nil
- }
- func (rt Handler) BuddyDelTempBuddies(ctx context.Context, instance *state.SessionInstance, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
- inSNAC := wire.SNAC_0x03_0x10_BuddyDelTempBuddies{}
- if err := wire.UnmarshalBE(&inSNAC, r); err != nil {
- return err
- }
- rt.LogRequest(ctx, inFrame, inSNAC)
- return rt.DelTempBuddies(ctx, instance, inSNAC)
- }
- func (rt Handler) ChatChannelMsgToHost(ctx context.Context, instance *state.SessionInstance, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
- inBody := wire.SNAC_0x0E_0x05_ChatChannelMsgToHost{}
- if err := wire.UnmarshalBE(&inBody, r); err != nil {
- return err
- }
- outSNAC, err := rt.ChatService.ChannelMsgToHost(ctx, instance, inFrame, inBody)
- if err != nil {
- return err
- }
- if outSNAC == nil {
- return nil
- }
- rt.Logger.InfoContext(ctx, "user sent a chat message")
- rt.LogRequestAndResponse(ctx, inFrame, inBody, outSNAC.Frame, outSNAC.Body)
- return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
- }
- func (rt Handler) ChatNavRequestChatRights(ctx context.Context, _ *state.SessionInstance, inFrame wire.SNACFrame, _ io.Reader, rw ResponseWriter) error {
- outSNAC := rt.RequestChatRights(ctx, inFrame)
- rt.LogRequestAndResponse(ctx, inFrame, nil, outSNAC.Frame, outSNAC.Body)
- return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
- }
- func (rt Handler) ChatNavRequestExchangeInfo(ctx context.Context, _ *state.SessionInstance, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
- inBody := wire.SNAC_0x0D_0x03_ChatNavRequestExchangeInfo{}
- if err := wire.UnmarshalBE(&inBody, r); err != nil {
- return err
- }
- outSNAC, err := rt.ExchangeInfo(ctx, inFrame, inBody)
- if err != nil {
- return err
- }
- rt.LogRequestAndResponse(ctx, inFrame, inBody, outSNAC.Frame, outSNAC.Body)
- return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
- }
- func (rt Handler) ChatNavRequestRoomInfo(ctx context.Context, _ *state.SessionInstance, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
- inBody := wire.SNAC_0x0D_0x04_ChatNavRequestRoomInfo{}
- if err := wire.UnmarshalBE(&inBody, r); err != nil {
- return err
- }
- outSNAC, err := rt.RequestRoomInfo(ctx, inFrame, inBody)
- if err != nil {
- return err
- }
- rt.LogRequestAndResponse(ctx, inFrame, inBody, outSNAC.Frame, outSNAC.Body)
- return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
- }
- func (rt Handler) ChatNavCreateRoom(ctx context.Context, instance *state.SessionInstance, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
- inBody := wire.SNAC_0x0E_0x02_ChatRoomInfoUpdate{}
- if err := wire.UnmarshalBE(&inBody, r); err != nil {
- return err
- }
- outSNAC, err := rt.CreateRoom(ctx, instance, inFrame, inBody)
- if err != nil {
- return err
- }
- roomName, _ := inBody.String(wire.ChatRoomTLVRoomName)
- rt.Logger.InfoContext(ctx, "user started a chat room", slog.String("roomName", roomName))
- rt.LogRequestAndResponse(ctx, inFrame, inBody, outSNAC.Frame, outSNAC.Body)
- return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
- }
- func (rt Handler) FeedbagRightsQuery(ctx context.Context, _ *state.SessionInstance, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
- inBody := wire.SNAC_0x13_0x02_FeedbagRightsQuery{}
- if err := wire.UnmarshalBE(&inBody, r); err != nil {
- return err
- }
- outSNAC := rt.FeedbagService.RightsQuery(ctx, inFrame)
- rt.LogRequestAndResponse(ctx, inFrame, inBody, outSNAC.Frame, outSNAC.Body)
- return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
- }
- func (rt Handler) FeedbagQuery(ctx context.Context, instance *state.SessionInstance, inFrame wire.SNACFrame, _ io.Reader, rw ResponseWriter) error {
- outSNAC, err := rt.Query(ctx, instance, inFrame)
- if err != nil {
- return err
- }
- rt.LogRequest(ctx, inFrame, outSNAC)
- return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
- }
- func (rt Handler) FeedbagQueryIfModified(ctx context.Context, instance *state.SessionInstance, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
- inBody := wire.SNAC_0x13_0x05_FeedbagQueryIfModified{}
- if err := wire.UnmarshalBE(&inBody, r); err != nil {
- return err
- }
- outSNAC, err := rt.QueryIfModified(ctx, instance, inFrame, inBody)
- if err != nil {
- return err
- }
- rt.LogRequestAndResponse(ctx, inFrame, inBody, outSNAC.Frame, outSNAC.Body)
- return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
- }
- func (rt Handler) FeedbagUse(ctx context.Context, instance *state.SessionInstance, inFrame wire.SNACFrame, _ io.Reader, _ ResponseWriter) error {
- rt.LogRequest(ctx, inFrame, nil)
- return rt.Use(ctx, instance)
- }
- func (rt Handler) FeedbagInsertItem(ctx context.Context, instance *state.SessionInstance, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
- inBody := wire.SNAC_0x13_0x08_FeedbagInsertItem{}
- if err := wire.UnmarshalBE(&inBody, r); err != nil {
- return err
- }
- outSNAC, err := rt.FeedbagService.UpsertItem(ctx, instance, inFrame, inBody.Items)
- if err != nil {
- return err
- }
- if outSNAC == nil {
- rt.LogRequest(ctx, inFrame, inBody)
- return nil
- }
- rt.LogRequestAndResponse(ctx, inFrame, inBody, outSNAC.Frame, outSNAC.Body)
- return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
- }
- func (rt Handler) FeedbagUpdateItem(ctx context.Context, instance *state.SessionInstance, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
- inBody := wire.SNAC_0x13_0x09_FeedbagUpdateItem{}
- if err := wire.UnmarshalBE(&inBody, r); err != nil {
- return err
- }
- outSNAC, err := rt.FeedbagService.UpsertItem(ctx, instance, inFrame, inBody.Items)
- if err != nil {
- return err
- }
- if outSNAC == nil {
- rt.LogRequest(ctx, inFrame, inBody)
- return nil
- }
- rt.LogRequestAndResponse(ctx, inFrame, inBody, outSNAC.Frame, outSNAC.Body)
- return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
- }
- func (rt Handler) FeedbagDeleteItem(ctx context.Context, instance *state.SessionInstance, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
- inBody := wire.SNAC_0x13_0x0A_FeedbagDeleteItem{}
- if err := wire.UnmarshalBE(&inBody, r); err != nil {
- return err
- }
- outSNAC, err := rt.DeleteItem(ctx, instance, inFrame, inBody)
- if err != nil {
- return err
- }
- if outSNAC == nil {
- rt.LogRequest(ctx, inFrame, inBody)
- return nil
- }
- rt.LogRequestAndResponse(ctx, inFrame, inBody, outSNAC.Frame, outSNAC.Body)
- return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
- }
- func (rt Handler) FeedbagStartCluster(ctx context.Context, instance *state.SessionInstance, inFrame wire.SNACFrame, r io.Reader, _ ResponseWriter) error {
- inBody := wire.SNAC_0x13_0x11_FeedbagStartCluster{}
- if err := wire.UnmarshalBE(&inBody, r); err != nil {
- return err
- }
- rt.StartCluster(ctx, instance, inFrame, inBody)
- rt.LogRequest(ctx, inFrame, inBody)
- return nil
- }
- func (rt Handler) FeedbagEndCluster(ctx context.Context, instance *state.SessionInstance, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
- if err := rt.EndCluster(ctx, instance, inFrame); err != nil {
- return err
- }
- rt.LogRequest(ctx, inFrame, nil)
- return nil
- }
- func (rt Handler) FeedbagPreAuthorizeBuddy(ctx context.Context, instance *state.SessionInstance, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
- inBody := wire.SNAC_0x13_0x14_FeedbagPreAuthorizeBuddy{}
- if err := wire.UnmarshalBE(&inBody, r); err != nil {
- return err
- }
- outSNAC, err := rt.PreAuthorizeBuddy(ctx, instance, inFrame, inBody)
- if err != nil {
- return err
- }
- if outSNAC != nil {
- rt.LogRequestAndResponse(ctx, inFrame, inBody, outSNAC.Frame, outSNAC.Body)
- return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
- }
- rt.LogRequest(ctx, inFrame, inBody)
- return nil
- }
- func (rt Handler) FeedbagRequestAuthorizeToHost(ctx context.Context, instance *state.SessionInstance, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
- inBody := wire.SNAC_0x13_0x18_FeedbagRequestAuthorizationToHost{}
- if err := wire.UnmarshalBE(&inBody, r); err != nil {
- return err
- }
- if err := rt.RequestAuthorizeToHost(ctx, instance, inFrame, inBody); err != nil {
- return err
- }
- rt.LogRequest(ctx, inFrame, inBody)
- return nil
- }
- func (rt Handler) FeedbagRespondAuthorizeToHost(ctx context.Context, instance *state.SessionInstance, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
- inBody := wire.SNAC_0x13_0x1A_FeedbagRespondAuthorizeToHost{}
- if err := wire.UnmarshalBE(&inBody, r); err != nil {
- return err
- }
- if err := rt.RespondAuthorizeToHost(ctx, instance.IdentScreenName(), inFrame, inBody); err != nil {
- return err
- }
- rt.LogRequest(ctx, inFrame, inBody)
- return nil
- }
- func (rt Handler) ICBMAddParameters(ctx context.Context, _ *state.SessionInstance, inFrame wire.SNACFrame, r io.Reader, _ ResponseWriter) error {
- inBody := wire.SNAC_0x04_0x02_ICBMAddParameters{}
- rt.LogRequest(ctx, inFrame, inBody)
- return wire.UnmarshalBE(&inBody, r)
- }
- func (rt Handler) ICBMParameterQuery(ctx context.Context, _ *state.SessionInstance, inFrame wire.SNACFrame, _ io.Reader, rw ResponseWriter) error {
- outSNAC := rt.ParameterQuery(ctx, inFrame)
- rt.LogRequestAndResponse(ctx, inFrame, outSNAC, outSNAC.Frame, outSNAC.Body)
- return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
- }
- func (rt Handler) ICBMChannelMsgToHost(ctx context.Context, instance *state.SessionInstance, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
- inBody := wire.SNAC_0x04_0x06_ICBMChannelMsgToHost{}
- if err := wire.UnmarshalBE(&inBody, r); err != nil {
- return err
- }
- outSNAC, err := rt.ICBMService.ChannelMsgToHost(ctx, instance, inFrame, inBody)
- if err != nil {
- return err
- }
- if outSNAC == nil {
- rt.LogRequest(ctx, inFrame, inBody)
- return nil
- }
- rt.LogRequestAndResponse(ctx, inFrame, inBody, outSNAC.Frame, outSNAC.Body)
- return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
- }
- func (rt Handler) ICBMEvilRequest(ctx context.Context, instance *state.SessionInstance, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
- inBody := wire.SNAC_0x04_0x08_ICBMEvilRequest{}
- if err := wire.UnmarshalBE(&inBody, r); err != nil {
- return err
- }
- outSNAC, err := rt.EvilRequest(ctx, instance, inFrame, inBody)
- if err != nil {
- return err
- }
- rt.LogRequestAndResponse(ctx, inFrame, inBody, outSNAC.Frame, outSNAC.Body)
- return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
- }
- func (rt Handler) ICBMClientErr(ctx context.Context, instance *state.SessionInstance, inFrame wire.SNACFrame, r io.Reader, _ ResponseWriter) error {
- inBody := wire.SNAC_0x04_0x0B_ICBMClientErr{}
- rt.LogRequest(ctx, inFrame, inBody)
- err := wire.UnmarshalBE(&inBody, r)
- if err != nil {
- return err
- }
- return rt.ClientErr(ctx, instance, inFrame, inBody)
- }
- func (rt Handler) ICBMClientEvent(ctx context.Context, instance *state.SessionInstance, inFrame wire.SNACFrame, r io.Reader, _ ResponseWriter) error {
- inBody := wire.SNAC_0x04_0x14_ICBMClientEvent{}
- if err := wire.UnmarshalBE(&inBody, r); err != nil {
- return err
- }
- rt.LogRequest(ctx, inFrame, inBody)
- return rt.ClientEvent(ctx, instance, inFrame, inBody)
- }
- func (rt Handler) ICBMOfflineRetrieve(ctx context.Context, instance *state.SessionInstance, inFrame wire.SNACFrame, rw ResponseWriter) error {
- outSNAC, err := rt.OfflineRetrieve(ctx, instance, inFrame)
- if err != nil {
- return err
- }
- rt.LogRequestAndResponse(ctx, inFrame, nil, outSNAC.Frame, outSNAC.Body)
- return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
- }
- func (rt Handler) ICQDBQuery(ctx context.Context, instance *state.SessionInstance, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
- inBody := wire.SNAC_0x15_0x02_BQuery{}
- if err := wire.UnmarshalBE(&inBody, r); err != nil {
- return err
- }
- md, ok := inBody.Bytes(wire.ICQTLVTagsMetadata)
- if !ok {
- return errors.New("invalid ICQ frame")
- }
- icqChunk := wire.ICQMessageRequestEnvelope{}
- if err := wire.UnmarshalLE(&icqChunk, bytes.NewBuffer(md)); err != nil {
- return err
- }
- buf := bytes.NewBuffer(icqChunk.Body)
- icqMD := wire.ICQMetadataWithSubType{}
- if err := wire.UnmarshalLE(&icqMD, buf); err != nil {
- return err
- }
- switch icqMD.ReqType {
- case wire.ICQDBQueryOfflineMsgReq:
- return rt.OfflineMsgReq(ctx, inFrame, instance, icqMD.Seq)
- case wire.ICQDBQueryDeleteMsgReq:
- return rt.DeleteMsgReq(ctx, instance, icqMD.Seq)
- case wire.ICQDBQueryMetaReq:
- if icqMD.Optional == nil {
- return errors.New("got req without subtype")
- }
- rt.Logger.Debug("ICQ client request",
- "query_name", wire.ICQDBQueryName(icqMD.ReqType),
- "query_type", wire.ICQDBQueryMetaName(icqMD.Optional.ReqSubType),
- "uin", instance.UIN())
- switch icqMD.Optional.ReqSubType {
- case wire.ICQDBQueryMetaReqShortInfo:
- userInfo := wire.ICQ_0x07D0_0x04BA_DBQueryMetaReqShortInfo{}
- if err := binary.Read(buf, binary.LittleEndian, &userInfo); err != nil {
- return nil
- }
- return rt.ShortUserInfo(ctx, instance, inFrame, userInfo, icqMD.Seq)
- case wire.ICQDBQueryMetaReqFullInfo, wire.ICQDBQueryMetaReqFullInfo2:
- userInfo := wire.ICQ_0x07D0_0x051F_DBQueryMetaReqSearchByUIN{}
- if err := binary.Read(buf, binary.LittleEndian, &userInfo); err != nil {
- return nil
- }
- return rt.FullUserInfo(ctx, instance, inFrame, userInfo, icqMD.Seq)
- case wire.ICQDBQueryMetaReqXMLReq:
- req := wire.ICQ_0x07D0_0x0898_DBQueryMetaReqXMLReq{}
- if err := wire.UnmarshalLE(&req, buf); err != nil {
- return err
- }
- if err := rt.XMLReqData(ctx, instance, inFrame, req, icqMD.Seq); err != nil {
- return err
- }
- case wire.ICQDBQueryMetaReqSetPermissions:
- req := wire.ICQ_0x07D0_0x0424_DBQueryMetaReqSetPermissions{}
- if err := wire.UnmarshalLE(&req, buf); err != nil {
- return err
- }
- if err := rt.SetPermissions(ctx, instance, inFrame, req, icqMD.Seq); err != nil {
- return err
- }
- case wire.ICQDBQueryMetaReqSetICQPhone:
- req := wire.ICQ_0x07D0_0x0654_DBQueryMetaReqSetICQPhone{}
- if err := wire.UnmarshalLE(&req, buf); err != nil {
- return err
- }
- if err := rt.SetICQPhone(ctx, instance, inFrame, req, icqMD.Seq); err != nil {
- return err
- }
- case wire.ICQDBQueryMetaReqSearchByUIN:
- req := wire.ICQ_0x07D0_0x051F_DBQueryMetaReqSearchByUIN{}
- if err := wire.UnmarshalLE(&req, buf); err != nil {
- return err
- }
- if err := rt.FindByUIN(ctx, instance, inFrame, req, icqMD.Seq); err != nil {
- return err
- }
- case wire.ICQDBQueryMetaReqSearchByUIN2:
- req := wire.ICQ_0x07D0_0x0569_DBQueryMetaReqSearchByUIN2{}
- if err := wire.UnmarshalLE(&req, buf); err != nil {
- return err
- }
- if err := rt.FindByUIN2(ctx, instance, inFrame, req, icqMD.Seq); err != nil {
- return err
- }
- case wire.ICQDBQueryMetaReqSearchByEmail:
- req := wire.ICQ_0x07D0_0x0529_DBQueryMetaReqSearchByEmail{}
- if err := wire.UnmarshalLE(&req, buf); err != nil {
- return err
- }
- if err := rt.FindByICQEmail(ctx, instance, inFrame, req, icqMD.Seq); err != nil {
- return err
- }
- case wire.ICQDBQueryMetaReqSearchByEmail3:
- req := wire.ICQ_0x07D0_0x0573_DBQueryMetaReqSearchByEmail3{}
- if err := wire.UnmarshalLE(&req, buf); err != nil {
- return err
- }
- if err := rt.FindByEmail3(ctx, instance, inFrame, req, icqMD.Seq); err != nil {
- return err
- }
- case wire.ICQDBQueryMetaReqSearchByDetails:
- req := wire.ICQ_0x07D0_0x0515_DBQueryMetaReqSearchByDetails{}
- if err := wire.UnmarshalLE(&req, buf); err != nil {
- return err
- }
- if err := rt.FindByICQName(ctx, instance, inFrame, req, icqMD.Seq); err != nil {
- return err
- }
- case wire.ICQDBQueryMetaReqSearchWhitePages:
- req := wire.ICQ_0x07D0_0x0533_DBQueryMetaReqSearchWhitePages{}
- if err := wire.UnmarshalLE(&req, buf); err != nil {
- return err
- }
- if err := rt.FindByICQInterests(ctx, instance, inFrame, req, icqMD.Seq); err != nil {
- return err
- }
- case wire.ICQDBQueryMetaReqSearchWhitePages2:
- req := wire.ICQ_0x07D0_0x055F_DBQueryMetaReqSearchWhitePages2{}
- if err := wire.UnmarshalLE(&req, buf); err != nil {
- return err
- }
- if err := rt.FindByWhitePages2(ctx, instance, inFrame, req, icqMD.Seq); err != nil {
- return err
- }
- case wire.ICQDBQueryMetaReqSetBasicInfo:
- req := wire.ICQ_0x07D0_0x03EA_DBQueryMetaReqSetBasicInfo{}
- if err := wire.UnmarshalLE(&req, buf); err != nil {
- return err
- }
- if err := rt.SetBasicInfo(ctx, instance, inFrame, req, icqMD.Seq); err != nil {
- return err
- }
- case wire.ICQDBQueryMetaReqSetWorkInfo:
- req := wire.ICQ_0x07D0_0x03F3_DBQueryMetaReqSetWorkInfo{}
- if err := wire.UnmarshalLE(&req, buf); err != nil {
- return err
- }
- if err := rt.SetWorkInfo(ctx, instance, inFrame, req, icqMD.Seq); err != nil {
- return err
- }
- case wire.ICQDBQueryMetaReqSetMoreInfo:
- req := wire.ICQ_0x07D0_0x03FD_DBQueryMetaReqSetMoreInfo{}
- if err := wire.UnmarshalLE(&req, buf); err != nil {
- return err
- }
- if err := rt.SetMoreInfo(ctx, instance, inFrame, req, icqMD.Seq); err != nil {
- return err
- }
- case wire.ICQDBQueryMetaReqSetNotes:
- req := wire.ICQ_0x07D0_0x0406_DBQueryMetaReqSetNotes{}
- if err := wire.UnmarshalLE(&req, buf); err != nil {
- return err
- }
- if err := rt.SetUserNotes(ctx, instance, inFrame, req, icqMD.Seq); err != nil {
- return err
- }
- case wire.ICQDBQueryMetaReqSetEmails:
- req := wire.ICQ_0x07D0_0x040B_DBQueryMetaReqSetEmails{}
- if err := wire.UnmarshalLE(&req, buf); err != nil {
- return err
- }
- if err := rt.SetEmails(ctx, instance, inFrame, req, icqMD.Seq); err != nil {
- return err
- }
- case wire.ICQDBQueryMetaReqSetInterests:
- req := wire.ICQ_0x07D0_0x0410_DBQueryMetaReqSetInterests{}
- if err := wire.UnmarshalLE(&req, buf); err != nil {
- return err
- }
- if err := rt.SetInterests(ctx, instance, inFrame, req, icqMD.Seq); err != nil {
- return err
- }
- case wire.ICQDBQueryMetaReqSetAffiliations:
- req := wire.ICQ_0x07D0_0x041A_DBQueryMetaReqSetAffiliations{}
- if err := wire.UnmarshalLE(&req, buf); err != nil {
- return err
- }
- if err := rt.SetAffiliations(ctx, instance, inFrame, req, icqMD.Seq); err != nil {
- return err
- }
- case wire.ICQDBQueryMetaReqSetFullInfo:
- req := wire.ICQ_0x07D0_0x0C3A_DBQueryMetaReqSetFullInfo{}
- if err := wire.UnmarshalLE(&req, buf); err != nil {
- return err
- }
- if err := rt.SetICQInfo(ctx, instance, inFrame, req, icqMD.Seq); err != nil {
- return err
- }
- default:
- rt.Logger.Debug("unsupported ICQDBQueryMetaReqType", "type", icqMD.Optional.ReqSubType)
- return nil
- }
- default:
- return fmt.Errorf("%w: %X", errUnknownICQMetaReqType, icqMD.ReqType)
- }
- return nil
- }
- func (rt Handler) LocateRightsQuery(ctx context.Context, _ *state.SessionInstance, inFrame wire.SNACFrame, _ io.Reader, rw ResponseWriter) error {
- outSNAC := rt.LocateService.RightsQuery(ctx, inFrame)
- rt.LogRequestAndResponse(ctx, inFrame, nil, outSNAC.Frame, outSNAC.Body)
- return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
- }
- func (rt Handler) LocateSetInfo(ctx context.Context, instance *state.SessionInstance, inFrame wire.SNACFrame, r io.Reader, _ ResponseWriter) error {
- inBody := wire.SNAC_0x02_0x04_LocateSetInfo{}
- if err := wire.UnmarshalBE(&inBody, r); err != nil {
- return err
- }
- rt.LogRequest(ctx, inFrame, inBody)
- return rt.SetInfo(ctx, instance, inBody)
- }
- func (rt Handler) LocateSetDirInfo(ctx context.Context, instance *state.SessionInstance, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
- inBody := wire.SNAC_0x02_0x09_LocateSetDirInfo{}
- if err := wire.UnmarshalBE(&inBody, r); err != nil {
- return err
- }
- outSNAC, err := rt.SetDirInfo(ctx, instance, inFrame, inBody)
- if err != nil {
- return err
- }
- rt.LogRequestAndResponse(ctx, inFrame, inBody, outSNAC.Frame, outSNAC.Body)
- return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
- }
- func (rt Handler) LocateGetDirInfo(ctx context.Context, _ *state.SessionInstance, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
- inBody := wire.SNAC_0x02_0x0B_LocateGetDirInfo{}
- if err := wire.UnmarshalBE(&inBody, r); err != nil {
- return err
- }
- outSNAC, err := rt.DirInfo(ctx, inFrame, inBody)
- if err != nil {
- return err
- }
- rt.LogRequestAndResponse(ctx, inFrame, inBody, outSNAC.Frame, outSNAC.Body)
- return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
- }
- func (rt Handler) LocateSetKeywordInfo(ctx context.Context, instance *state.SessionInstance, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
- inBody := wire.SNAC_0x02_0x0F_LocateSetKeywordInfo{}
- if err := wire.UnmarshalBE(&inBody, r); err != nil {
- return err
- }
- outSNAC, err := rt.SetKeywordInfo(ctx, instance, inFrame, inBody)
- if err != nil {
- return err
- }
- rt.LogRequestAndResponse(ctx, inFrame, inBody, outSNAC.Frame, outSNAC.Body)
- return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
- }
- func (rt Handler) LocateUserInfoQuery(ctx context.Context, instance *state.SessionInstance, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
- inBody := wire.SNAC_0x02_0x05_LocateUserInfoQuery{}
- if err := wire.UnmarshalBE(&inBody, r); err != nil {
- return err
- }
- outSNAC, err := rt.LocateService.UserInfoQuery(ctx, instance, inFrame, inBody)
- if err != nil {
- return err
- }
- rt.LogRequestAndResponse(ctx, inFrame, inBody, outSNAC.Frame, outSNAC.Body)
- return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
- }
- func (rt Handler) LocateUserInfoQuery2(ctx context.Context, instance *state.SessionInstance, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
- inBody := wire.SNAC_0x02_0x15_LocateUserInfoQuery2{}
- if err := wire.UnmarshalBE(&inBody, r); err != nil {
- return err
- }
- // SNAC functionality for LocateUserInfoQuery and LocateUserInfoQuery2 is
- // identical except for the Type field data type (uint16 vs uint32).
- wrappedBody := wire.SNAC_0x02_0x05_LocateUserInfoQuery{
- Type: uint16(inBody.Type2),
- ScreenName: inBody.ScreenName,
- }
- outSNAC, err := rt.LocateService.UserInfoQuery(ctx, instance, inFrame, wrappedBody)
- if err != nil {
- return err
- }
- rt.LogRequestAndResponse(ctx, inFrame, inBody, outSNAC.Frame, outSNAC.Body)
- return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
- }
- func (rt Handler) ODirInfoQuery(ctx context.Context, instance *state.SessionInstance, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
- inBody := wire.SNAC_0x0F_0x02_InfoQuery{}
- if err := wire.UnmarshalBE(&inBody, r); err != nil {
- return err
- }
- outSNAC, err := rt.ODirService.InfoQuery(ctx, inFrame, inBody)
- if err != nil {
- return err
- }
- rt.LogRequestAndResponse(ctx, inFrame, outSNAC, outSNAC.Frame, outSNAC.Body)
- return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
- }
- func (rt Handler) ODirKeywordListQuery(ctx context.Context, instance *state.SessionInstance, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
- outSNAC, err := rt.KeywordListQuery(ctx, inFrame)
- if err != nil {
- return err
- }
- rt.LogRequestAndResponse(ctx, inFrame, nil, outSNAC.Frame, outSNAC.Body)
- return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
- }
- func (rt Handler) OServiceRateParamsQuery(ctx context.Context, instance *state.SessionInstance, inFrame wire.SNACFrame, _ io.Reader, rw ResponseWriter) error {
- outSNAC := rt.RateParamsQuery(ctx, instance, inFrame)
- rt.LogRequestAndResponse(ctx, inFrame, nil, outSNAC.Frame, outSNAC.Body)
- return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
- }
- func (rt Handler) OServiceRateParamsSubAdd(ctx context.Context, instance *state.SessionInstance, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
- inBody := wire.SNAC_0x01_0x08_OServiceRateParamsSubAdd{}
- if err := wire.UnmarshalBE(&inBody, r); err != nil {
- return err
- }
- rt.RateParamsSubAdd(ctx, instance, inBody)
- rt.LogRequest(ctx, inFrame, inBody)
- return nil
- }
- func (rt Handler) OServiceUserInfoQuery(ctx context.Context, instance *state.SessionInstance, inFrame wire.SNACFrame, _ io.Reader, rw ResponseWriter) error {
- outSNAC := rt.OServiceService.UserInfoQuery(ctx, instance, inFrame)
- rt.LogRequestAndResponse(ctx, inFrame, nil, outSNAC.Frame, outSNAC.Body)
- return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
- }
- func (rt Handler) OServiceProbeReq(ctx context.Context, instance *state.SessionInstance, inFrame wire.SNACFrame, _ io.Reader, rw ResponseWriter) error {
- outSNAC := rt.ProbeReq(ctx, inFrame)
- rt.LogRequestAndResponse(ctx, inFrame, nil, outSNAC.Frame, outSNAC.Body)
- return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
- }
- func (rt Handler) OServiceIdleNotification(ctx context.Context, instance *state.SessionInstance, inFrame wire.SNACFrame, r io.Reader, _ ResponseWriter) error {
- inBody := wire.SNAC_0x01_0x11_OServiceIdleNotification{}
- if err := wire.UnmarshalBE(&inBody, r); err != nil {
- return err
- }
- rt.LogRequest(ctx, inFrame, inBody)
- return rt.IdleNotification(ctx, instance, inBody)
- }
- func (rt Handler) OServiceClientVersions(ctx context.Context, instance *state.SessionInstance, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
- inBody := wire.SNAC_0x01_0x17_OServiceClientVersions{}
- if err := wire.UnmarshalBE(&inBody, r); err != nil {
- return err
- }
- outSNACs := rt.ClientVersions(ctx, instance, inFrame, inBody)
- for _, snac := range outSNACs {
- rt.LogRequestAndResponse(ctx, inFrame, inBody, snac.Frame, snac.Body)
- if err := rw.SendSNAC(snac.Frame, snac.Body); err != nil {
- return err
- }
- }
- return nil
- }
- func (rt Handler) OServiceSetUserInfoFields(ctx context.Context, instance *state.SessionInstance, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
- inBody := wire.SNAC_0x01_0x1E_OServiceSetUserInfoFields{}
- if err := wire.UnmarshalBE(&inBody, r); err != nil {
- return err
- }
- outSNAC, err := rt.SetUserInfoFields(ctx, instance, inFrame, inBody)
- if err != nil {
- return err
- }
- rt.LogRequestAndResponse(ctx, inFrame, inBody, outSNAC.Frame, outSNAC.Body)
- return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
- }
- func (rt Handler) OServiceNoop(ctx context.Context, instance *state.SessionInstance, inFrame wire.SNACFrame, _ io.Reader, rw ResponseWriter) error {
- // no-op keep-alive
- rt.LogRequest(ctx, inFrame, nil)
- return nil
- }
- func (rt Handler) OServiceSetPrivacyFlags(ctx context.Context, instance *state.SessionInstance, inFrame wire.SNACFrame, r io.Reader, _ ResponseWriter) error {
- inBody := wire.SNAC_0x01_0x14_OServiceSetPrivacyFlags{}
- if err := wire.UnmarshalBE(&inBody, r); err != nil {
- return err
- }
- rt.SetPrivacyFlags(ctx, inBody)
- rt.LogRequest(ctx, inFrame, inBody)
- return nil
- }
- func (rt Handler) OServiceServiceRequest(ctx context.Context, service uint16, instance *state.SessionInstance, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter, listener config.Listener) error {
- inBody := wire.SNAC_0x01_0x04_OServiceServiceRequest{}
- if err := wire.UnmarshalBE(&inBody, r); err != nil {
- return err
- }
- outSNAC, err := rt.ServiceRequest(ctx, service, instance, inFrame, inBody, listener)
- if err != nil {
- return err
- }
- rt.LogRequestAndResponse(ctx, inFrame, inBody, outSNAC.Frame, outSNAC.Body)
- return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
- }
- func (rt Handler) OServiceClientOnline(ctx context.Context, service uint16, instance *state.SessionInstance, inFrame wire.SNACFrame, r io.Reader, _ ResponseWriter) error {
- inBody := wire.SNAC_0x01_0x02_OServiceClientOnline{}
- if err := wire.UnmarshalBE(&inBody, r); err != nil {
- return err
- }
- rt.Logger.InfoContext(ctx, "user signed on")
- rt.LogRequest(ctx, inFrame, inBody)
- return rt.ClientOnline(ctx, service, inBody, instance)
- }
- func (rt Handler) PermitDenyRightsQuery(ctx context.Context, _ *state.SessionInstance, inFrame wire.SNACFrame, _ io.Reader, rw ResponseWriter) error {
- outSNAC := rt.PermitDenyService.RightsQuery(ctx, inFrame)
- rt.LogRequestAndResponse(ctx, inFrame, nil, outSNAC.Frame, outSNAC.Body)
- return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
- }
- func (rt Handler) PermitDenyAddDenyListEntries(ctx context.Context, instance *state.SessionInstance, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
- inBody := wire.SNAC_0x09_0x07_PermitDenyAddDenyListEntries{}
- if err := wire.UnmarshalBE(&inBody, r); err != nil {
- return err
- }
- rt.LogRequest(ctx, inFrame, inBody)
- return rt.AddDenyListEntries(ctx, instance, inBody)
- }
- func (rt Handler) PermitDenyDelDenyListEntries(ctx context.Context, instance *state.SessionInstance, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
- inBody := wire.SNAC_0x09_0x08_PermitDenyDelDenyListEntries{}
- if err := wire.UnmarshalBE(&inBody, r); err != nil {
- return err
- }
- rt.LogRequest(ctx, inFrame, inBody)
- return rt.DelDenyListEntries(ctx, instance, inBody)
- }
- func (rt Handler) PermitDenyAddPermListEntries(ctx context.Context, instance *state.SessionInstance, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
- inBody := wire.SNAC_0x09_0x05_PermitDenyAddPermListEntries{}
- if err := wire.UnmarshalBE(&inBody, r); err != nil {
- return err
- }
- rt.LogRequest(ctx, inFrame, inBody)
- return rt.AddPermListEntries(ctx, instance, inBody)
- }
- func (rt Handler) PermitDenyDelPermListEntries(ctx context.Context, instance *state.SessionInstance, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
- inBody := wire.SNAC_0x09_0x06_PermitDenyDelPermListEntries{}
- if err := wire.UnmarshalBE(&inBody, r); err != nil {
- return err
- }
- rt.LogRequest(ctx, inFrame, inBody)
- return rt.DelPermListEntries(ctx, instance, inBody)
- }
- // PermitDenySetGroupPermitMask sets the classes of users I can interact with. We don't
- // apply any of these settings to the privacy mechanism, so just log them for
- // now.
- func (rt Handler) PermitDenySetGroupPermitMask(ctx context.Context, instance *state.SessionInstance, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
- inBody := wire.SNAC_0x09_0x04_PermitDenySetGroupPermitMask{}
- if err := wire.UnmarshalBE(&inBody, r); err != nil {
- return err
- }
- var flags []string
- if inBody.IsFlagSet(wire.OServiceUserFlagUnconfirmed) {
- flags = append(flags, "wire.OServiceUserFlagUnconfirmed")
- }
- if inBody.IsFlagSet(wire.OServiceUserFlagAdministrator) {
- flags = append(flags, "wire.OServiceUserFlagAdministrator")
- }
- if inBody.IsFlagSet(wire.OServiceUserFlagAOL) {
- flags = append(flags, "wire.OServiceUserFlagAOL")
- }
- if inBody.IsFlagSet(wire.OServiceUserFlagOSCARPay) {
- flags = append(flags, "wire.OServiceUserFlagOSCARPay")
- }
- if inBody.IsFlagSet(wire.OServiceUserFlagOSCARFree) {
- flags = append(flags, "wire.OServiceUserFlagOSCARFree")
- }
- if inBody.IsFlagSet(wire.OServiceUserFlagUnavailable) {
- flags = append(flags, "wire.OServiceUserFlagUnavailable")
- }
- if inBody.IsFlagSet(wire.OServiceUserFlagICQ) {
- flags = append(flags, "wire.OServiceUserFlagICQ")
- }
- if inBody.IsFlagSet(wire.OServiceUserFlagWireless) {
- flags = append(flags, "wire.OServiceUserFlagWireless")
- }
- if inBody.IsFlagSet(wire.OServiceUserFlagInternal) {
- flags = append(flags, "wire.OServiceUserFlagInternal")
- }
- if inBody.IsFlagSet(wire.OServiceUserFlagFish) {
- flags = append(flags, "wire.OServiceUserFlagFish")
- }
- if inBody.IsFlagSet(wire.OServiceUserFlagBot) {
- flags = append(flags, "wire.OServiceUserFlagBot")
- }
- if inBody.IsFlagSet(wire.OServiceUserFlagBeast) {
- flags = append(flags, "wire.OServiceUserFlagBeast")
- }
- if inBody.IsFlagSet(wire.OServiceUserFlagOneWayWireless) {
- flags = append(flags, "wire.OServiceUserFlagOneWayWireless")
- }
- if inBody.IsFlagSet(wire.OServiceUserFlagOfficial) {
- flags = append(flags, "wire.OServiceUserFlagOfficial")
- }
- rt.Logger.Info("set pd group mask", "flags", flags)
- rt.LogRequest(ctx, inFrame, inBody)
- return nil
- }
- func (rt Handler) StatsReportEvents(ctx context.Context, _ *state.SessionInstance, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
- inBody := wire.SNAC_0x0B_0x03_StatsReportEvents{}
- if err := wire.UnmarshalBE(&inBody, r); err != nil {
- return err
- }
- outSNAC := rt.ReportEvents(ctx, inFrame, inBody)
- rt.LogRequestAndResponse(ctx, inFrame, inBody, outSNAC.Frame, outSNAC.Body)
- return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
- }
- func (rt Handler) UserLookupFindByEmail(ctx context.Context, _ *state.SessionInstance, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
- inBody := wire.SNAC_0x0A_0x02_UserLookupFindByEmail{}
- if err := wire.UnmarshalBE(&inBody, r); err != nil {
- return err
- }
- outSNAC, err := rt.FindByEmail(ctx, inFrame, inBody)
- if err != nil {
- return err
- }
- rt.LogRequestAndResponse(ctx, inFrame, inBody, outSNAC.Frame, outSNAC.Body)
- return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
- }
- // Handle directs an incoming OSCAR request to the appropriate handler based on
- // its group and subGroup identifiers found in the SNAC frame. It returns an
- // ErrRouteNotFound error if no matching handler is found for the group:subGroup
- // pair in the request.
- func (rt Handler) Handle(ctx context.Context, server uint16, instance *state.SessionInstance, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter, listener config.Listener) error {
- switch inFrame.FoodGroup {
- case wire.Admin:
- switch inFrame.SubGroup {
- case wire.AdminAcctConfirmRequest:
- return rt.AdminConfirmRequest(ctx, instance, inFrame, r, rw)
- case wire.AdminInfoChangeRequest:
- return rt.AdminInfoChangeRequest(ctx, instance, inFrame, r, rw)
- case wire.AdminInfoQuery:
- return rt.AdminInfoQuery(ctx, instance, inFrame, r, rw)
- }
- case wire.Alert:
- switch inFrame.SubGroup {
- case wire.AlertNotifyCapabilities:
- return rt.AlertNotifyCapabilities(ctx, instance, inFrame, r, rw)
- case wire.AlertNotifyDisplayCapabilities:
- return rt.AlertNotifyDisplayCapabilities(ctx, instance, inFrame, r, rw)
- }
- case wire.BART:
- switch inFrame.SubGroup {
- case wire.BARTDownloadQuery:
- return rt.BARTDownloadQuery(ctx, instance, inFrame, r, rw)
- case wire.BARTDownload2Query:
- return rt.BARTDownload2Query(ctx, instance, inFrame, r, rw)
- case wire.BARTUploadQuery:
- return rt.BARTUploadQuery(ctx, instance, inFrame, r, rw)
- }
- case wire.Buddy:
- switch inFrame.SubGroup {
- case wire.BuddyAddBuddies:
- return rt.BuddyAddBuddies(ctx, instance, inFrame, r, rw)
- case wire.BuddyDelBuddies:
- return rt.BuddyDelBuddies(ctx, instance, inFrame, r, rw)
- case wire.BuddyRightsQuery:
- return rt.BuddyRightsQuery(ctx, instance, inFrame, r, rw)
- case wire.BuddyAddTempBuddies:
- return rt.BuddyAddTempBuddies(ctx, instance, inFrame, r, rw)
- case wire.BuddyDelTempBuddies:
- return rt.BuddyDelTempBuddies(ctx, instance, inFrame, r, rw)
- }
- case wire.Chat:
- switch inFrame.SubGroup {
- case wire.ChatChannelMsgToHost:
- return rt.ChatChannelMsgToHost(ctx, instance, inFrame, r, rw)
- }
- case wire.ChatNav:
- switch inFrame.SubGroup {
- case wire.ChatNavCreateRoom:
- return rt.ChatNavCreateRoom(ctx, instance, inFrame, r, rw)
- case wire.ChatNavRequestChatRights:
- return rt.ChatNavRequestChatRights(ctx, instance, inFrame, r, rw)
- case wire.ChatNavRequestExchangeInfo:
- return rt.ChatNavRequestExchangeInfo(ctx, instance, inFrame, r, rw)
- case wire.ChatNavRequestRoomInfo:
- return rt.ChatNavRequestRoomInfo(ctx, instance, inFrame, r, rw)
- }
- case wire.Feedbag:
- switch inFrame.SubGroup {
- case wire.FeedbagDeleteItem:
- return rt.FeedbagDeleteItem(ctx, instance, inFrame, r, rw)
- case wire.FeedbagEndCluster:
- return rt.FeedbagEndCluster(ctx, instance, inFrame, r, rw)
- case wire.FeedbagInsertItem:
- return rt.FeedbagInsertItem(ctx, instance, inFrame, r, rw)
- case wire.FeedbagQuery:
- return rt.FeedbagQuery(ctx, instance, inFrame, r, rw)
- case wire.FeedbagQueryIfModified:
- return rt.FeedbagQueryIfModified(ctx, instance, inFrame, r, rw)
- case wire.FeedbagPreAuthorizeBuddy:
- return rt.FeedbagPreAuthorizeBuddy(ctx, instance, inFrame, r, rw)
- case wire.FeedbagRequestAuthorizeToHost:
- return rt.FeedbagRequestAuthorizeToHost(ctx, instance, inFrame, r, rw)
- case wire.FeedbagRespondAuthorizeToHost:
- return rt.FeedbagRespondAuthorizeToHost(ctx, instance, inFrame, r, rw)
- case wire.FeedbagRightsQuery:
- return rt.FeedbagRightsQuery(ctx, instance, inFrame, r, rw)
- case wire.FeedbagStartCluster:
- return rt.FeedbagStartCluster(ctx, instance, inFrame, r, rw)
- case wire.FeedbagUpdateItem:
- return rt.FeedbagUpdateItem(ctx, instance, inFrame, r, rw)
- case wire.FeedbagUse:
- return rt.FeedbagUse(ctx, instance, inFrame, r, rw)
- }
- case wire.Invite:
- switch inFrame.SubGroup {
- case wire.InviteRequestQuery, wire.InviteRequestReply:
- return rt.InviteRequest(ctx, instance, inFrame, r, rw)
- }
- case wire.ICQ:
- switch inFrame.SubGroup {
- case wire.ICQDBQuery:
- return rt.ICQDBQuery(ctx, instance, inFrame, r, rw)
- }
- case wire.ICBM:
- switch inFrame.SubGroup {
- case wire.ICBMAddParameters:
- return rt.ICBMAddParameters(ctx, instance, inFrame, r, rw)
- case wire.ICBMChannelMsgToHost:
- return rt.ICBMChannelMsgToHost(ctx, instance, inFrame, r, rw)
- case wire.ICBMClientErr:
- return rt.ICBMClientErr(ctx, instance, inFrame, r, rw)
- case wire.ICBMClientEvent:
- return rt.ICBMClientEvent(ctx, instance, inFrame, r, rw)
- case wire.ICBMEvilRequest:
- return rt.ICBMEvilRequest(ctx, instance, inFrame, r, rw)
- case wire.ICBMParameterQuery:
- return rt.ICBMParameterQuery(ctx, instance, inFrame, r, rw)
- case wire.ICBMOfflineRetrieve:
- return rt.ICBMOfflineRetrieve(ctx, instance, inFrame, rw)
- }
- case wire.Locate:
- switch inFrame.SubGroup {
- case wire.LocateGetDirInfo:
- return rt.LocateGetDirInfo(ctx, instance, inFrame, r, rw)
- case wire.LocateRightsQuery:
- return rt.LocateRightsQuery(ctx, instance, inFrame, r, rw)
- case wire.LocateSetDirInfo:
- return rt.LocateSetDirInfo(ctx, instance, inFrame, r, rw)
- case wire.LocateSetInfo:
- return rt.LocateSetInfo(ctx, instance, inFrame, r, rw)
- case wire.LocateSetKeywordInfo:
- return rt.LocateSetKeywordInfo(ctx, instance, inFrame, r, rw)
- case wire.LocateUserInfoQuery:
- return rt.LocateUserInfoQuery(ctx, instance, inFrame, r, rw)
- case wire.LocateUserInfoQuery2:
- return rt.LocateUserInfoQuery2(ctx, instance, inFrame, r, rw)
- }
- case wire.MDir:
- return rt.MDirRequest(ctx, instance, inFrame, r, rw)
- case wire.ODir:
- switch inFrame.SubGroup {
- case wire.ODirInfoQuery:
- return rt.ODirInfoQuery(ctx, instance, inFrame, r, rw)
- case wire.ODirKeywordListQuery:
- return rt.ODirKeywordListQuery(ctx, instance, inFrame, r, rw)
- }
- case wire.OService:
- switch inFrame.SubGroup {
- case wire.OServiceClientOnline:
- return rt.OServiceClientOnline(ctx, server, instance, inFrame, r, rw)
- case wire.OServiceClientVersions:
- return rt.OServiceClientVersions(ctx, instance, inFrame, r, rw)
- case wire.OServiceIdleNotification:
- return rt.OServiceIdleNotification(ctx, instance, inFrame, r, rw)
- case wire.OServiceNoop:
- return rt.OServiceNoop(ctx, instance, inFrame, r, rw)
- case wire.OServiceRateParamsQuery:
- return rt.OServiceRateParamsQuery(ctx, instance, inFrame, r, rw)
- case wire.OServiceRateParamsSubAdd:
- return rt.OServiceRateParamsSubAdd(ctx, instance, inFrame, r, rw)
- case wire.OServiceServiceRequest:
- return rt.OServiceServiceRequest(ctx, server, instance, inFrame, r, rw, listener)
- case wire.OServiceSetPrivacyFlags:
- return rt.OServiceSetPrivacyFlags(ctx, instance, inFrame, r, rw)
- case wire.OServiceSetUserInfoFields:
- return rt.OServiceSetUserInfoFields(ctx, instance, inFrame, r, rw)
- case wire.OServiceUserInfoQuery:
- return rt.OServiceUserInfoQuery(ctx, instance, inFrame, r, rw)
- case wire.OServiceProbeReq:
- return rt.OServiceProbeReq(ctx, instance, inFrame, r, rw)
- }
- case wire.PermitDeny:
- switch inFrame.SubGroup {
- case wire.PermitDenyAddDenyListEntries:
- return rt.PermitDenyAddDenyListEntries(ctx, instance, inFrame, r, rw)
- case wire.PermitDenyAddPermListEntries:
- return rt.PermitDenyAddPermListEntries(ctx, instance, inFrame, r, rw)
- case wire.PermitDenyDelDenyListEntries:
- return rt.PermitDenyDelDenyListEntries(ctx, instance, inFrame, r, rw)
- case wire.PermitDenyDelPermListEntries:
- return rt.PermitDenyDelPermListEntries(ctx, instance, inFrame, r, rw)
- case wire.PermitDenyRightsQuery:
- return rt.PermitDenyRightsQuery(ctx, instance, inFrame, r, rw)
- case wire.PermitDenySetGroupPermitMask:
- return rt.PermitDenySetGroupPermitMask(ctx, instance, inFrame, r, rw)
- }
- case wire.Plugin:
- return rt.PluginRequest(ctx, instance, inFrame, r, rw)
- case wire.Stats:
- switch inFrame.SubGroup {
- case wire.StatsReportEvents:
- return rt.StatsReportEvents(ctx, instance, inFrame, r, rw)
- }
- case wire.UserLookup:
- switch inFrame.SubGroup {
- case wire.UserLookupFindByEmail:
- return rt.UserLookupFindByEmail(ctx, instance, inFrame, r, rw)
- }
- }
- return ErrRouteNotFound
- }
|