handler.go 41 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084
  1. package oscar
  2. import (
  3. "bytes"
  4. "context"
  5. "encoding/binary"
  6. "errors"
  7. "fmt"
  8. "io"
  9. "log/slog"
  10. "github.com/mk6i/retro-aim-server/config"
  11. "github.com/mk6i/retro-aim-server/server/oscar/middleware"
  12. "github.com/mk6i/retro-aim-server/state"
  13. "github.com/mk6i/retro-aim-server/wire"
  14. )
  15. var (
  16. // ErrRouteNotFound is an error that indicates a failure to find a matching
  17. // route for an OSCAR protocol request.
  18. ErrRouteNotFound = errors.New("route not found")
  19. errUnknownICQMetaReqType = errors.New("unknown ICQ request type")
  20. errUnknownICQMetaReqSubType = errors.New("unknown ICQ metadata request subtype")
  21. )
  22. // ResponseWriter is the interface for sending a SNAC response to the client
  23. // from the server handlers.
  24. type ResponseWriter interface {
  25. SendSNAC(frame wire.SNACFrame, body any) error
  26. }
  27. // Handler defines a structure for routing OSCAR protocol requests to
  28. // appropriate handlers based on group:subGroup identifiers.
  29. type Handler struct {
  30. AdminService
  31. BARTService
  32. BuddyService
  33. ChatNavService
  34. ChatService
  35. FeedbagService
  36. ICBMService
  37. ICQService
  38. LocateService
  39. ODirService
  40. OServiceService
  41. PermitDenyService
  42. StatsService
  43. UserLookupService
  44. middleware.RouteLogger
  45. }
  46. func (rt Handler) AdminConfirmRequest(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, _ io.Reader, rw ResponseWriter) error {
  47. outSNAC, err := rt.AdminService.ConfirmRequest(ctx, sess, inFrame)
  48. if err != nil {
  49. return err
  50. }
  51. rt.LogRequestAndResponse(ctx, inFrame, nil, outSNAC.Frame, outSNAC.Body)
  52. return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
  53. }
  54. func (rt Handler) AdminInfoQuery(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
  55. inBody := wire.SNAC_0x07_0x02_AdminInfoQuery{}
  56. if err := wire.UnmarshalBE(&inBody, r); err != nil {
  57. return err
  58. }
  59. outSNAC, err := rt.AdminService.InfoQuery(ctx, sess, inFrame, inBody)
  60. if err != nil {
  61. return err
  62. }
  63. rt.LogRequestAndResponse(ctx, inFrame, nil, outSNAC.Frame, outSNAC.Body)
  64. return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
  65. }
  66. func (rt Handler) AdminInfoChangeRequest(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
  67. inBody := wire.SNAC_0x07_0x04_AdminInfoChangeRequest{}
  68. if err := wire.UnmarshalBE(&inBody, r); err != nil {
  69. return err
  70. }
  71. outSNAC, err := rt.AdminService.InfoChangeRequest(ctx, sess, inFrame, inBody)
  72. if err != nil {
  73. return err
  74. }
  75. rt.LogRequestAndResponse(ctx, inFrame, nil, outSNAC.Frame, outSNAC.Body)
  76. return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
  77. }
  78. func (rt Handler) AlertNotifyCapabilities(ctx context.Context, _ *state.Session, inFrame wire.SNACFrame, _ io.Reader, _ ResponseWriter) error {
  79. rt.LogRequest(ctx, inFrame, nil)
  80. return nil
  81. }
  82. func (rt Handler) AlertNotifyDisplayCapabilities(ctx context.Context, _ *state.Session, inFrame wire.SNACFrame, _ io.Reader, _ ResponseWriter) error {
  83. rt.LogRequest(ctx, inFrame, nil)
  84. return nil
  85. }
  86. func (rt Handler) BARTUploadQuery(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
  87. inBody := wire.SNAC_0x10_0x02_BARTUploadQuery{}
  88. if err := wire.UnmarshalBE(&inBody, r); err != nil {
  89. return err
  90. }
  91. outSNAC, err := rt.BARTService.UpsertItem(ctx, sess, inFrame, inBody)
  92. if err != nil {
  93. return err
  94. }
  95. rt.LogRequestAndResponse(ctx, inFrame, outSNAC, outSNAC.Frame, outSNAC.Body)
  96. return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
  97. }
  98. func (rt Handler) BARTDownloadQuery(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
  99. inBody := wire.SNAC_0x10_0x04_BARTDownloadQuery{}
  100. if err := wire.UnmarshalBE(&inBody, r); err != nil {
  101. return err
  102. }
  103. outSNAC, err := rt.BARTService.RetrieveItem(ctx, sess, inFrame, inBody)
  104. if err != nil {
  105. return err
  106. }
  107. rt.LogRequestAndResponse(ctx, inFrame, outSNAC, outSNAC.Frame, outSNAC.Body)
  108. return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
  109. }
  110. func (rt Handler) BuddyRightsQuery(ctx context.Context, _ *state.Session, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
  111. inSNAC := wire.SNAC_0x03_0x02_BuddyRightsQuery{}
  112. if err := wire.UnmarshalBE(&inSNAC, r); err != nil {
  113. return err
  114. }
  115. outSNAC := rt.BuddyService.RightsQuery(ctx, inFrame)
  116. rt.LogRequestAndResponse(ctx, inFrame, inSNAC, outSNAC.Frame, outSNAC.Body)
  117. return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
  118. }
  119. func (rt Handler) BuddyAddBuddies(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
  120. inSNAC := wire.SNAC_0x03_0x04_BuddyAddBuddies{}
  121. if err := wire.UnmarshalBE(&inSNAC, r); err != nil {
  122. return err
  123. }
  124. rt.LogRequest(ctx, inFrame, inSNAC)
  125. return rt.BuddyService.AddBuddies(ctx, sess, inSNAC)
  126. }
  127. func (rt Handler) BuddyDelBuddies(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
  128. inSNAC := wire.SNAC_0x03_0x05_BuddyDelBuddies{}
  129. if err := wire.UnmarshalBE(&inSNAC, r); err != nil {
  130. return err
  131. }
  132. rt.LogRequest(ctx, inFrame, inSNAC)
  133. return rt.BuddyService.DelBuddies(ctx, sess, inSNAC)
  134. }
  135. func (rt Handler) ChatChannelMsgToHost(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
  136. inBody := wire.SNAC_0x0E_0x05_ChatChannelMsgToHost{}
  137. if err := wire.UnmarshalBE(&inBody, r); err != nil {
  138. return err
  139. }
  140. outSNAC, err := rt.ChatService.ChannelMsgToHost(ctx, sess, inFrame, inBody)
  141. if err != nil {
  142. return err
  143. }
  144. if outSNAC == nil {
  145. return nil
  146. }
  147. rt.Logger.InfoContext(ctx, "user sent a chat message")
  148. rt.LogRequestAndResponse(ctx, inFrame, inBody, outSNAC.Frame, outSNAC.Body)
  149. return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
  150. }
  151. func (rt Handler) ChatNavRequestChatRights(ctx context.Context, _ *state.Session, inFrame wire.SNACFrame, _ io.Reader, rw ResponseWriter) error {
  152. outSNAC := rt.ChatNavService.RequestChatRights(ctx, inFrame)
  153. rt.LogRequestAndResponse(ctx, inFrame, nil, outSNAC.Frame, outSNAC.Body)
  154. return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
  155. }
  156. func (rt Handler) ChatNavRequestExchangeInfo(ctx context.Context, _ *state.Session, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
  157. inBody := wire.SNAC_0x0D_0x03_ChatNavRequestExchangeInfo{}
  158. if err := wire.UnmarshalBE(&inBody, r); err != nil {
  159. return err
  160. }
  161. outSNAC, err := rt.ChatNavService.ExchangeInfo(ctx, inFrame, inBody)
  162. if err != nil {
  163. return err
  164. }
  165. rt.LogRequestAndResponse(ctx, inFrame, inBody, outSNAC.Frame, outSNAC.Body)
  166. return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
  167. }
  168. func (rt Handler) ChatNavRequestRoomInfo(ctx context.Context, _ *state.Session, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
  169. inBody := wire.SNAC_0x0D_0x04_ChatNavRequestRoomInfo{}
  170. if err := wire.UnmarshalBE(&inBody, r); err != nil {
  171. return err
  172. }
  173. outSNAC, err := rt.ChatNavService.RequestRoomInfo(ctx, inFrame, inBody)
  174. if err != nil {
  175. return err
  176. }
  177. rt.LogRequestAndResponse(ctx, inFrame, inBody, outSNAC.Frame, outSNAC.Body)
  178. return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
  179. }
  180. func (rt Handler) ChatNavCreateRoom(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
  181. inBody := wire.SNAC_0x0E_0x02_ChatRoomInfoUpdate{}
  182. if err := wire.UnmarshalBE(&inBody, r); err != nil {
  183. return err
  184. }
  185. outSNAC, err := rt.ChatNavService.CreateRoom(ctx, sess, inFrame, inBody)
  186. if err != nil {
  187. return err
  188. }
  189. roomName, _ := inBody.String(wire.ChatRoomTLVRoomName)
  190. rt.Logger.InfoContext(ctx, "user started a chat room", slog.String("roomName", roomName))
  191. rt.LogRequestAndResponse(ctx, inFrame, inBody, outSNAC.Frame, outSNAC.Body)
  192. return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
  193. }
  194. func (rt Handler) FeedbagRightsQuery(ctx context.Context, _ *state.Session, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
  195. inBody := wire.SNAC_0x13_0x02_FeedbagRightsQuery{}
  196. if err := wire.UnmarshalBE(&inBody, r); err != nil {
  197. return err
  198. }
  199. outSNAC := rt.FeedbagService.RightsQuery(ctx, inFrame)
  200. rt.LogRequestAndResponse(ctx, inFrame, inBody, outSNAC.Frame, outSNAC.Body)
  201. return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
  202. }
  203. func (rt Handler) FeedbagQuery(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, _ io.Reader, rw ResponseWriter) error {
  204. outSNAC, err := rt.FeedbagService.Query(ctx, sess, inFrame)
  205. if err != nil {
  206. return err
  207. }
  208. rt.LogRequest(ctx, inFrame, outSNAC)
  209. return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
  210. }
  211. func (rt Handler) FeedbagQueryIfModified(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
  212. inBody := wire.SNAC_0x13_0x05_FeedbagQueryIfModified{}
  213. if err := wire.UnmarshalBE(&inBody, r); err != nil {
  214. return err
  215. }
  216. outSNAC, err := rt.FeedbagService.QueryIfModified(ctx, sess, inFrame, inBody)
  217. if err != nil {
  218. return err
  219. }
  220. rt.LogRequestAndResponse(ctx, inFrame, inBody, outSNAC.Frame, outSNAC.Body)
  221. return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
  222. }
  223. func (rt Handler) FeedbagUse(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, _ io.Reader, _ ResponseWriter) error {
  224. rt.LogRequest(ctx, inFrame, nil)
  225. return rt.FeedbagService.Use(ctx, sess)
  226. }
  227. func (rt Handler) FeedbagInsertItem(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
  228. inBody := wire.SNAC_0x13_0x08_FeedbagInsertItem{}
  229. if err := wire.UnmarshalBE(&inBody, r); err != nil {
  230. return err
  231. }
  232. outSNAC, err := rt.FeedbagService.UpsertItem(ctx, sess, inFrame, inBody.Items)
  233. if err != nil {
  234. return err
  235. }
  236. rt.LogRequestAndResponse(ctx, inFrame, inBody, outSNAC.Frame, outSNAC.Body)
  237. return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
  238. }
  239. func (rt Handler) FeedbagUpdateItem(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
  240. inBody := wire.SNAC_0x13_0x09_FeedbagUpdateItem{}
  241. if err := wire.UnmarshalBE(&inBody, r); err != nil {
  242. return err
  243. }
  244. outSNAC, err := rt.FeedbagService.UpsertItem(ctx, sess, inFrame, inBody.Items)
  245. if err != nil {
  246. return err
  247. }
  248. rt.LogRequestAndResponse(ctx, inFrame, inBody, outSNAC.Frame, outSNAC.Body)
  249. return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
  250. }
  251. func (rt Handler) FeedbagDeleteItem(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
  252. inBody := wire.SNAC_0x13_0x0A_FeedbagDeleteItem{}
  253. if err := wire.UnmarshalBE(&inBody, r); err != nil {
  254. return err
  255. }
  256. outSNAC, err := rt.FeedbagService.DeleteItem(ctx, sess, inFrame, inBody)
  257. if err != nil {
  258. return err
  259. }
  260. rt.LogRequestAndResponse(ctx, inFrame, inBody, outSNAC.Frame, outSNAC.Body)
  261. return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
  262. }
  263. func (rt Handler) FeedbagStartCluster(ctx context.Context, _ *state.Session, inFrame wire.SNACFrame, r io.Reader, _ ResponseWriter) error {
  264. inBody := wire.SNAC_0x13_0x11_FeedbagStartCluster{}
  265. if err := wire.UnmarshalBE(&inBody, r); err != nil {
  266. return err
  267. }
  268. rt.FeedbagService.StartCluster(ctx, inFrame, inBody)
  269. rt.LogRequest(ctx, inFrame, inBody)
  270. return nil
  271. }
  272. func (rt Handler) FeedbagEndCluster(ctx context.Context, _ *state.Session, inFrame wire.SNACFrame, _ io.Reader, _ ResponseWriter) error {
  273. rt.LogRequest(ctx, inFrame, nil)
  274. return nil
  275. }
  276. func (rt Handler) FeedbagRespondAuthorizeToHost(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
  277. inBody := wire.SNAC_0x13_0x1A_FeedbagRespondAuthorizeToHost{}
  278. if err := wire.UnmarshalBE(&inBody, r); err != nil {
  279. return err
  280. }
  281. if err := rt.FeedbagService.RespondAuthorizeToHost(ctx, sess, inFrame, inBody); err != nil {
  282. return err
  283. }
  284. rt.LogRequest(ctx, inFrame, inBody)
  285. return nil
  286. }
  287. func (rt Handler) ICBMAddParameters(ctx context.Context, _ *state.Session, inFrame wire.SNACFrame, r io.Reader, _ ResponseWriter) error {
  288. inBody := wire.SNAC_0x04_0x02_ICBMAddParameters{}
  289. rt.LogRequest(ctx, inFrame, inBody)
  290. return wire.UnmarshalBE(&inBody, r)
  291. }
  292. func (rt Handler) ICBMParameterQuery(ctx context.Context, _ *state.Session, inFrame wire.SNACFrame, _ io.Reader, rw ResponseWriter) error {
  293. outSNAC := rt.ICBMService.ParameterQuery(ctx, inFrame)
  294. rt.LogRequestAndResponse(ctx, inFrame, outSNAC, outSNAC.Frame, outSNAC.Body)
  295. return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
  296. }
  297. func (rt Handler) ICBMChannelMsgToHost(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
  298. inBody := wire.SNAC_0x04_0x06_ICBMChannelMsgToHost{}
  299. if err := wire.UnmarshalBE(&inBody, r); err != nil {
  300. return err
  301. }
  302. outSNAC, err := rt.ICBMService.ChannelMsgToHost(ctx, sess, inFrame, inBody)
  303. if err != nil {
  304. return err
  305. }
  306. rt.Logger.InfoContext(ctx, "user sent an IM", slog.String("recipient", inBody.ScreenName))
  307. if outSNAC == nil {
  308. return nil
  309. }
  310. rt.LogRequestAndResponse(ctx, inFrame, inBody, outSNAC.Frame, outSNAC.Body)
  311. return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
  312. }
  313. func (rt Handler) ICBMEvilRequest(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
  314. inBody := wire.SNAC_0x04_0x08_ICBMEvilRequest{}
  315. if err := wire.UnmarshalBE(&inBody, r); err != nil {
  316. return err
  317. }
  318. outSNAC, err := rt.ICBMService.EvilRequest(ctx, sess, inFrame, inBody)
  319. if err != nil {
  320. return err
  321. }
  322. rt.LogRequestAndResponse(ctx, inFrame, inBody, outSNAC.Frame, outSNAC.Body)
  323. return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
  324. }
  325. func (rt Handler) ICBMClientErr(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, r io.Reader, _ ResponseWriter) error {
  326. inBody := wire.SNAC_0x04_0x0B_ICBMClientErr{}
  327. rt.LogRequest(ctx, inFrame, inBody)
  328. err := wire.UnmarshalBE(&inBody, r)
  329. if err != nil {
  330. return err
  331. }
  332. return rt.ICBMService.ClientErr(ctx, sess, inFrame, inBody)
  333. }
  334. func (rt Handler) ICBMClientEvent(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, r io.Reader, _ ResponseWriter) error {
  335. inBody := wire.SNAC_0x04_0x14_ICBMClientEvent{}
  336. if err := wire.UnmarshalBE(&inBody, r); err != nil {
  337. return err
  338. }
  339. rt.LogRequest(ctx, inFrame, inBody)
  340. return rt.ICBMService.ClientEvent(ctx, sess, inFrame, inBody)
  341. }
  342. func (rt Handler) ICQDBQuery(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
  343. inBody := wire.SNAC_0x15_0x02_BQuery{}
  344. if err := wire.UnmarshalBE(&inBody, r); err != nil {
  345. return err
  346. }
  347. md, ok := inBody.Bytes(wire.ICQTLVTagsMetadata)
  348. if !ok {
  349. return errors.New("invalid ICQ frame")
  350. }
  351. icqChunk := wire.ICQMessageRequestEnvelope{}
  352. if err := wire.UnmarshalLE(&icqChunk, bytes.NewBuffer(md)); err != nil {
  353. return err
  354. }
  355. buf := bytes.NewBuffer(icqChunk.Body)
  356. icqMD := wire.ICQMetadataWithSubType{}
  357. if err := wire.UnmarshalLE(&icqMD, buf); err != nil {
  358. return err
  359. }
  360. switch icqMD.ReqType {
  361. case wire.ICQDBQueryOfflineMsgReq:
  362. return rt.ICQService.OfflineMsgReq(ctx, sess, icqMD.Seq)
  363. case wire.ICQDBQueryDeleteMsgReq:
  364. return rt.ICQService.DeleteMsgReq(ctx, sess, icqMD.Seq)
  365. case wire.ICQDBQueryMetaReq:
  366. if icqMD.Optional == nil {
  367. return errors.New("got req without subtype")
  368. }
  369. rt.Logger.Debug("ICQ client request",
  370. "query_name", wire.ICQDBQueryName(icqMD.ReqType),
  371. "query_type", wire.ICQDBQueryMetaName(icqMD.Optional.ReqSubType),
  372. "uin", sess.UIN())
  373. switch icqMD.Optional.ReqSubType {
  374. case wire.ICQDBQueryMetaReqShortInfo:
  375. userInfo := wire.ICQ_0x07D0_0x04BA_DBQueryMetaReqShortInfo{}
  376. if err := binary.Read(buf, binary.LittleEndian, &userInfo); err != nil {
  377. return nil
  378. }
  379. return rt.ICQService.ShortUserInfo(ctx, sess, userInfo, icqMD.Seq)
  380. case wire.ICQDBQueryMetaReqFullInfo, wire.ICQDBQueryMetaReqFullInfo2:
  381. userInfo := wire.ICQ_0x07D0_0x051F_DBQueryMetaReqSearchByUIN{}
  382. if err := binary.Read(buf, binary.LittleEndian, &userInfo); err != nil {
  383. return nil
  384. }
  385. return rt.ICQService.FullUserInfo(ctx, sess, userInfo, icqMD.Seq)
  386. case wire.ICQDBQueryMetaReqXMLReq:
  387. req := wire.ICQ_0x07D0_0x0898_DBQueryMetaReqXMLReq{}
  388. if err := wire.UnmarshalLE(&req, buf); err != nil {
  389. return err
  390. }
  391. if err := rt.ICQService.XMLReqData(ctx, sess, req, icqMD.Seq); err != nil {
  392. return err
  393. }
  394. case wire.ICQDBQueryMetaReqSetPermissions:
  395. req := wire.ICQ_0x07D0_0x0424_DBQueryMetaReqSetPermissions{}
  396. if err := wire.UnmarshalLE(&req, buf); err != nil {
  397. return err
  398. }
  399. if err := rt.ICQService.SetPermissions(ctx, sess, req, icqMD.Seq); err != nil {
  400. return err
  401. }
  402. case wire.ICQDBQueryMetaReqSearchByUIN:
  403. req := wire.ICQ_0x07D0_0x051F_DBQueryMetaReqSearchByUIN{}
  404. if err := wire.UnmarshalLE(&req, buf); err != nil {
  405. return err
  406. }
  407. if err := rt.ICQService.FindByUIN(ctx, sess, req, icqMD.Seq); err != nil {
  408. return err
  409. }
  410. case wire.ICQDBQueryMetaReqSearchByUIN2:
  411. rest := buf.Bytes()
  412. if bytes.HasPrefix(rest, []byte{0x36, 0x01, 0x06, 0x00}) && len(rest) == 8 {
  413. // fix incorrect TLV len set by QIP 2005. it specifies len=6
  414. // for a 4-byte value, causing the unmarshaler to return EOF.
  415. rest[2] = 4
  416. }
  417. req := wire.ICQ_0x07D0_0x0569_DBQueryMetaReqSearchByUIN2{}
  418. if err := wire.UnmarshalLE(&req, bytes.NewReader(rest)); err != nil {
  419. return err
  420. }
  421. if err := rt.ICQService.FindByUIN2(ctx, sess, req, icqMD.Seq); err != nil {
  422. return err
  423. }
  424. case wire.ICQDBQueryMetaReqSearchByEmail:
  425. req := wire.ICQ_0x07D0_0x0529_DBQueryMetaReqSearchByEmail{}
  426. if err := wire.UnmarshalLE(&req, buf); err != nil {
  427. return err
  428. }
  429. if err := rt.ICQService.FindByICQEmail(ctx, sess, req, icqMD.Seq); err != nil {
  430. return err
  431. }
  432. case wire.ICQDBQueryMetaReqSearchByEmail3:
  433. req := wire.ICQ_0x07D0_0x0573_DBQueryMetaReqSearchByEmail3{}
  434. if err := wire.UnmarshalLE(&req, buf); err != nil {
  435. return err
  436. }
  437. if err := rt.ICQService.FindByEmail3(ctx, sess, req, icqMD.Seq); err != nil {
  438. return err
  439. }
  440. case wire.ICQDBQueryMetaReqSearchByDetails:
  441. req := wire.ICQ_0x07D0_0x0515_DBQueryMetaReqSearchByDetails{}
  442. if err := wire.UnmarshalLE(&req, buf); err != nil {
  443. return err
  444. }
  445. if err := rt.ICQService.FindByICQName(ctx, sess, req, icqMD.Seq); err != nil {
  446. return err
  447. }
  448. case wire.ICQDBQueryMetaReqSearchWhitePages:
  449. req := wire.ICQ_0x07D0_0x0533_DBQueryMetaReqSearchWhitePages{}
  450. if err := wire.UnmarshalLE(&req, buf); err != nil {
  451. return err
  452. }
  453. if err := rt.ICQService.FindByICQInterests(ctx, sess, req, icqMD.Seq); err != nil {
  454. return err
  455. }
  456. case wire.ICQDBQueryMetaReqSearchWhitePages2:
  457. req := wire.ICQ_0x07D0_0x055F_DBQueryMetaReqSearchWhitePages2{}
  458. if err := wire.UnmarshalLE(&req, buf); err != nil {
  459. return err
  460. }
  461. if err := rt.ICQService.FindByWhitePages2(ctx, sess, req, icqMD.Seq); err != nil {
  462. return err
  463. }
  464. case wire.ICQDBQueryMetaReqSetBasicInfo:
  465. req := wire.ICQ_0x07D0_0x03EA_DBQueryMetaReqSetBasicInfo{}
  466. if err := wire.UnmarshalLE(&req, buf); err != nil {
  467. return err
  468. }
  469. if err := rt.ICQService.SetBasicInfo(ctx, sess, req, icqMD.Seq); err != nil {
  470. return err
  471. }
  472. case wire.ICQDBQueryMetaReqSetWorkInfo:
  473. req := wire.ICQ_0x07D0_0x03F3_DBQueryMetaReqSetWorkInfo{}
  474. if err := wire.UnmarshalLE(&req, buf); err != nil {
  475. return err
  476. }
  477. if err := rt.ICQService.SetWorkInfo(ctx, sess, req, icqMD.Seq); err != nil {
  478. return err
  479. }
  480. case wire.ICQDBQueryMetaReqSetMoreInfo:
  481. req := wire.ICQ_0x07D0_0x03FD_DBQueryMetaReqSetMoreInfo{}
  482. if err := wire.UnmarshalLE(&req, buf); err != nil {
  483. return err
  484. }
  485. if err := rt.ICQService.SetMoreInfo(ctx, sess, req, icqMD.Seq); err != nil {
  486. return err
  487. }
  488. case wire.ICQDBQueryMetaReqSetNotes:
  489. req := wire.ICQ_0x07D0_0x0406_DBQueryMetaReqSetNotes{}
  490. if err := wire.UnmarshalLE(&req, buf); err != nil {
  491. return err
  492. }
  493. if err := rt.ICQService.SetUserNotes(ctx, sess, req, icqMD.Seq); err != nil {
  494. return err
  495. }
  496. case wire.ICQDBQueryMetaReqSetEmails:
  497. req := wire.ICQ_0x07D0_0x040B_DBQueryMetaReqSetEmails{}
  498. if err := wire.UnmarshalLE(&req, buf); err != nil {
  499. return err
  500. }
  501. if err := rt.ICQService.SetEmails(ctx, sess, req, icqMD.Seq); err != nil {
  502. return err
  503. }
  504. case wire.ICQDBQueryMetaReqSetInterests:
  505. req := wire.ICQ_0x07D0_0x0410_DBQueryMetaReqSetInterests{}
  506. if err := wire.UnmarshalLE(&req, buf); err != nil {
  507. return err
  508. }
  509. if err := rt.ICQService.SetInterests(ctx, sess, req, icqMD.Seq); err != nil {
  510. return err
  511. }
  512. case wire.ICQDBQueryMetaReqSetAffiliations:
  513. req := wire.ICQ_0x07D0_0x041A_DBQueryMetaReqSetAffiliations{}
  514. if err := wire.UnmarshalLE(&req, buf); err != nil {
  515. return err
  516. }
  517. if err := rt.ICQService.SetAffiliations(ctx, sess, req, icqMD.Seq); err != nil {
  518. return err
  519. }
  520. case wire.ICQDBQueryMetaReqStat0a8c,
  521. wire.ICQDBQueryMetaReqStat0a96,
  522. wire.ICQDBQueryMetaReqStat0aaa,
  523. wire.ICQDBQueryMetaReqStat0ab4,
  524. wire.ICQDBQueryMetaReqStat0ab9,
  525. wire.ICQDBQueryMetaReqStat0abe,
  526. wire.ICQDBQueryMetaReqStat0ac8,
  527. wire.ICQDBQueryMetaReqStat0acd,
  528. wire.ICQDBQueryMetaReqStat0ad2,
  529. wire.ICQDBQueryMetaReqStat0ad7,
  530. wire.ICQDBQueryMetaReqStat0758:
  531. rt.Logger.Debug("got a request for stats, not doing anything right now")
  532. default:
  533. return fmt.Errorf("%w: %X", errUnknownICQMetaReqSubType, icqMD.Optional.ReqSubType)
  534. }
  535. default:
  536. return fmt.Errorf("%w: %X", errUnknownICQMetaReqType, icqMD.ReqType)
  537. }
  538. return nil
  539. }
  540. func (rt Handler) LocateRightsQuery(ctx context.Context, _ *state.Session, inFrame wire.SNACFrame, _ io.Reader, rw ResponseWriter) error {
  541. outSNAC := rt.LocateService.RightsQuery(ctx, inFrame)
  542. rt.LogRequestAndResponse(ctx, inFrame, nil, outSNAC.Frame, outSNAC.Body)
  543. return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
  544. }
  545. func (rt Handler) LocateSetInfo(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, r io.Reader, _ ResponseWriter) error {
  546. inBody := wire.SNAC_0x02_0x04_LocateSetInfo{}
  547. if err := wire.UnmarshalBE(&inBody, r); err != nil {
  548. return err
  549. }
  550. rt.LogRequest(ctx, inFrame, inBody)
  551. return rt.LocateService.SetInfo(ctx, sess, inBody)
  552. }
  553. func (rt Handler) LocateSetDirInfo(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
  554. inBody := wire.SNAC_0x02_0x09_LocateSetDirInfo{}
  555. if err := wire.UnmarshalBE(&inBody, r); err != nil {
  556. return err
  557. }
  558. outSNAC, err := rt.LocateService.SetDirInfo(ctx, sess, inFrame, inBody)
  559. if err != nil {
  560. return err
  561. }
  562. rt.LogRequestAndResponse(ctx, inFrame, inBody, outSNAC.Frame, outSNAC.Body)
  563. return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
  564. }
  565. func (rt Handler) LocateGetDirInfo(ctx context.Context, _ *state.Session, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
  566. inBody := wire.SNAC_0x02_0x0B_LocateGetDirInfo{}
  567. if err := wire.UnmarshalBE(&inBody, r); err != nil {
  568. return err
  569. }
  570. outSNAC, err := rt.LocateService.DirInfo(ctx, inFrame, inBody)
  571. if err != nil {
  572. return err
  573. }
  574. rt.LogRequestAndResponse(ctx, inFrame, inBody, outSNAC.Frame, outSNAC.Body)
  575. return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
  576. }
  577. func (rt Handler) LocateSetKeywordInfo(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
  578. inBody := wire.SNAC_0x02_0x0F_LocateSetKeywordInfo{}
  579. if err := wire.UnmarshalBE(&inBody, r); err != nil {
  580. return err
  581. }
  582. outSNAC, err := rt.LocateService.SetKeywordInfo(ctx, sess, inFrame, inBody)
  583. if err != nil {
  584. return err
  585. }
  586. rt.LogRequestAndResponse(ctx, inFrame, inBody, outSNAC.Frame, outSNAC.Body)
  587. return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
  588. }
  589. func (rt Handler) LocateUserInfoQuery(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
  590. inBody := wire.SNAC_0x02_0x05_LocateUserInfoQuery{}
  591. if err := wire.UnmarshalBE(&inBody, r); err != nil {
  592. return err
  593. }
  594. outSNAC, err := rt.LocateService.UserInfoQuery(ctx, sess, inFrame, inBody)
  595. if err != nil {
  596. return err
  597. }
  598. rt.LogRequestAndResponse(ctx, inFrame, inBody, outSNAC.Frame, outSNAC.Body)
  599. return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
  600. }
  601. func (rt Handler) LocateUserInfoQuery2(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
  602. inBody := wire.SNAC_0x02_0x15_LocateUserInfoQuery2{}
  603. if err := wire.UnmarshalBE(&inBody, r); err != nil {
  604. return err
  605. }
  606. // SNAC functionality for LocateUserInfoQuery and LocateUserInfoQuery2 is
  607. // identical except for the Type field data type (uint16 vs uint32).
  608. wrappedBody := wire.SNAC_0x02_0x05_LocateUserInfoQuery{
  609. Type: uint16(inBody.Type2),
  610. ScreenName: inBody.ScreenName,
  611. }
  612. outSNAC, err := rt.LocateService.UserInfoQuery(ctx, sess, inFrame, wrappedBody)
  613. if err != nil {
  614. return err
  615. }
  616. rt.LogRequestAndResponse(ctx, inFrame, inBody, outSNAC.Frame, outSNAC.Body)
  617. return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
  618. }
  619. func (rt Handler) ODirInfoQuery(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
  620. inBody := wire.SNAC_0x0F_0x02_InfoQuery{}
  621. if err := wire.UnmarshalBE(&inBody, r); err != nil {
  622. return err
  623. }
  624. outSNAC, err := rt.ODirService.InfoQuery(ctx, inFrame, inBody)
  625. if err != nil {
  626. return err
  627. }
  628. rt.LogRequestAndResponse(ctx, inFrame, outSNAC, outSNAC.Frame, outSNAC.Body)
  629. return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
  630. }
  631. func (rt Handler) ODirKeywordListQuery(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
  632. outSNAC, err := rt.ODirService.KeywordListQuery(ctx, inFrame)
  633. if err != nil {
  634. return err
  635. }
  636. rt.LogRequestAndResponse(ctx, inFrame, nil, outSNAC.Frame, outSNAC.Body)
  637. return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
  638. }
  639. func (rt Handler) OServiceRateParamsQuery(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, _ io.Reader, rw ResponseWriter) error {
  640. outSNAC := rt.OServiceService.RateParamsQuery(ctx, sess, inFrame)
  641. rt.LogRequestAndResponse(ctx, inFrame, nil, outSNAC.Frame, outSNAC.Body)
  642. return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
  643. }
  644. func (rt Handler) OServiceRateParamsSubAdd(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
  645. inBody := wire.SNAC_0x01_0x08_OServiceRateParamsSubAdd{}
  646. if err := wire.UnmarshalBE(&inBody, r); err != nil {
  647. return err
  648. }
  649. rt.OServiceService.RateParamsSubAdd(ctx, sess, inBody)
  650. rt.LogRequest(ctx, inFrame, inBody)
  651. return nil
  652. }
  653. func (rt Handler) OServiceUserInfoQuery(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, _ io.Reader, rw ResponseWriter) error {
  654. outSNAC := rt.OServiceService.UserInfoQuery(ctx, sess, inFrame)
  655. rt.LogRequestAndResponse(ctx, inFrame, nil, outSNAC.Frame, outSNAC.Body)
  656. return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
  657. }
  658. func (rt Handler) OServiceIdleNotification(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, r io.Reader, _ ResponseWriter) error {
  659. inBody := wire.SNAC_0x01_0x11_OServiceIdleNotification{}
  660. if err := wire.UnmarshalBE(&inBody, r); err != nil {
  661. return err
  662. }
  663. rt.LogRequest(ctx, inFrame, inBody)
  664. return rt.OServiceService.IdleNotification(ctx, sess, inBody)
  665. }
  666. func (rt Handler) OServiceClientVersions(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
  667. inBody := wire.SNAC_0x01_0x17_OServiceClientVersions{}
  668. if err := wire.UnmarshalBE(&inBody, r); err != nil {
  669. return err
  670. }
  671. outSNAC := rt.OServiceService.ClientVersions(ctx, sess, inFrame, inBody)
  672. rt.LogRequestAndResponse(ctx, inFrame, inBody, outSNAC.Frame, outSNAC.Body)
  673. return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
  674. }
  675. func (rt Handler) OServiceSetUserInfoFields(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
  676. inBody := wire.SNAC_0x01_0x1E_OServiceSetUserInfoFields{}
  677. if err := wire.UnmarshalBE(&inBody, r); err != nil {
  678. return err
  679. }
  680. outSNAC, err := rt.OServiceService.SetUserInfoFields(ctx, sess, inFrame, inBody)
  681. if err != nil {
  682. return err
  683. }
  684. rt.LogRequestAndResponse(ctx, inFrame, inBody, outSNAC.Frame, outSNAC.Body)
  685. return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
  686. }
  687. func (rt Handler) OServiceNoop(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, _ io.Reader, rw ResponseWriter) error {
  688. // no-op keep-alive
  689. rt.LogRequest(ctx, inFrame, nil)
  690. return nil
  691. }
  692. func (rt Handler) OServiceSetPrivacyFlags(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, r io.Reader, _ ResponseWriter) error {
  693. inBody := wire.SNAC_0x01_0x14_OServiceSetPrivacyFlags{}
  694. if err := wire.UnmarshalBE(&inBody, r); err != nil {
  695. return err
  696. }
  697. rt.OServiceService.SetPrivacyFlags(ctx, inBody)
  698. rt.LogRequest(ctx, inFrame, inBody)
  699. return nil
  700. }
  701. func (rt Handler) OServiceServiceRequest(ctx context.Context, service uint16, sess *state.Session, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter, listener config.Listener) error {
  702. inBody := wire.SNAC_0x01_0x04_OServiceServiceRequest{}
  703. if err := wire.UnmarshalBE(&inBody, r); err != nil {
  704. return err
  705. }
  706. outSNAC, err := rt.OServiceService.ServiceRequest(ctx, service, sess, inFrame, inBody, listener)
  707. if err != nil {
  708. return err
  709. }
  710. rt.LogRequestAndResponse(ctx, inFrame, inBody, outSNAC.Frame, outSNAC.Body)
  711. return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
  712. }
  713. func (rt Handler) OServiceClientOnline(ctx context.Context, service uint16, sess *state.Session, inFrame wire.SNACFrame, r io.Reader, _ ResponseWriter) error {
  714. inBody := wire.SNAC_0x01_0x02_OServiceClientOnline{}
  715. if err := wire.UnmarshalBE(&inBody, r); err != nil {
  716. return err
  717. }
  718. rt.Logger.InfoContext(ctx, "user signed on")
  719. rt.LogRequest(ctx, inFrame, inBody)
  720. return rt.OServiceService.ClientOnline(ctx, service, inBody, sess)
  721. }
  722. func (rt Handler) PermitDenyRightsQuery(ctx context.Context, _ *state.Session, inFrame wire.SNACFrame, _ io.Reader, rw ResponseWriter) error {
  723. outSNAC := rt.PermitDenyService.RightsQuery(ctx, inFrame)
  724. rt.LogRequestAndResponse(ctx, inFrame, nil, outSNAC.Frame, outSNAC.Body)
  725. return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
  726. }
  727. func (rt Handler) PermitDenyAddDenyListEntries(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
  728. inBody := wire.SNAC_0x09_0x07_PermitDenyAddDenyListEntries{}
  729. if err := wire.UnmarshalBE(&inBody, r); err != nil {
  730. return err
  731. }
  732. rt.LogRequest(ctx, inFrame, inBody)
  733. return rt.PermitDenyService.AddDenyListEntries(ctx, sess, inBody)
  734. }
  735. func (rt Handler) PermitDenyDelDenyListEntries(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
  736. inBody := wire.SNAC_0x09_0x08_PermitDenyDelDenyListEntries{}
  737. if err := wire.UnmarshalBE(&inBody, r); err != nil {
  738. return err
  739. }
  740. rt.LogRequest(ctx, inFrame, inBody)
  741. return rt.PermitDenyService.DelDenyListEntries(ctx, sess, inBody)
  742. }
  743. func (rt Handler) PermitDenyAddPermListEntries(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
  744. inBody := wire.SNAC_0x09_0x05_PermitDenyAddPermListEntries{}
  745. if err := wire.UnmarshalBE(&inBody, r); err != nil {
  746. return err
  747. }
  748. rt.LogRequest(ctx, inFrame, inBody)
  749. return rt.PermitDenyService.AddPermListEntries(ctx, sess, inBody)
  750. }
  751. func (rt Handler) PermitDenyDelPermListEntries(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
  752. inBody := wire.SNAC_0x09_0x06_PermitDenyDelPermListEntries{}
  753. if err := wire.UnmarshalBE(&inBody, r); err != nil {
  754. return err
  755. }
  756. rt.LogRequest(ctx, inFrame, inBody)
  757. return rt.PermitDenyService.DelPermListEntries(ctx, sess, inBody)
  758. }
  759. // PermitDenySetGroupPermitMask sets the classes of users I can interact with. We don't
  760. // apply any of these settings to the privacy mechanism, so just log them for
  761. // now.
  762. func (rt Handler) PermitDenySetGroupPermitMask(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
  763. inBody := wire.SNAC_0x09_0x04_PermitDenySetGroupPermitMask{}
  764. if err := wire.UnmarshalBE(&inBody, r); err != nil {
  765. return err
  766. }
  767. var flags []string
  768. if inBody.IsFlagSet(wire.OServiceUserFlagUnconfirmed) {
  769. flags = append(flags, "wire.OServiceUserFlagUnconfirmed")
  770. }
  771. if inBody.IsFlagSet(wire.OServiceUserFlagAdministrator) {
  772. flags = append(flags, "wire.OServiceUserFlagAdministrator")
  773. }
  774. if inBody.IsFlagSet(wire.OServiceUserFlagAOL) {
  775. flags = append(flags, "wire.OServiceUserFlagAOL")
  776. }
  777. if inBody.IsFlagSet(wire.OServiceUserFlagOSCARPay) {
  778. flags = append(flags, "wire.OServiceUserFlagOSCARPay")
  779. }
  780. if inBody.IsFlagSet(wire.OServiceUserFlagOSCARFree) {
  781. flags = append(flags, "wire.OServiceUserFlagOSCARFree")
  782. }
  783. if inBody.IsFlagSet(wire.OServiceUserFlagUnavailable) {
  784. flags = append(flags, "wire.OServiceUserFlagUnavailable")
  785. }
  786. if inBody.IsFlagSet(wire.OServiceUserFlagICQ) {
  787. flags = append(flags, "wire.OServiceUserFlagICQ")
  788. }
  789. if inBody.IsFlagSet(wire.OServiceUserFlagWireless) {
  790. flags = append(flags, "wire.OServiceUserFlagWireless")
  791. }
  792. if inBody.IsFlagSet(wire.OServiceUserFlagInternal) {
  793. flags = append(flags, "wire.OServiceUserFlagInternal")
  794. }
  795. if inBody.IsFlagSet(wire.OServiceUserFlagFish) {
  796. flags = append(flags, "wire.OServiceUserFlagFish")
  797. }
  798. if inBody.IsFlagSet(wire.OServiceUserFlagBot) {
  799. flags = append(flags, "wire.OServiceUserFlagBot")
  800. }
  801. if inBody.IsFlagSet(wire.OServiceUserFlagBeast) {
  802. flags = append(flags, "wire.OServiceUserFlagBeast")
  803. }
  804. if inBody.IsFlagSet(wire.OServiceUserFlagOneWayWireless) {
  805. flags = append(flags, "wire.OServiceUserFlagOneWayWireless")
  806. }
  807. if inBody.IsFlagSet(wire.OServiceUserFlagOfficial) {
  808. flags = append(flags, "wire.OServiceUserFlagOfficial")
  809. }
  810. rt.Logger.Info("set pd group mask", "flags", flags)
  811. rt.LogRequest(ctx, inFrame, inBody)
  812. return nil
  813. }
  814. func (rt Handler) StatsReportEvents(ctx context.Context, _ *state.Session, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
  815. inBody := wire.SNAC_0x0B_0x03_StatsReportEvents{}
  816. if err := wire.UnmarshalBE(&inBody, r); err != nil {
  817. return err
  818. }
  819. outSNAC := rt.StatsService.ReportEvents(ctx, inFrame, inBody)
  820. rt.LogRequestAndResponse(ctx, inFrame, inBody, outSNAC.Frame, outSNAC.Body)
  821. return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
  822. }
  823. func (rt Handler) UserLookupFindByEmail(ctx context.Context, _ *state.Session, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
  824. inBody := wire.SNAC_0x0A_0x02_UserLookupFindByEmail{}
  825. if err := wire.UnmarshalBE(&inBody, r); err != nil {
  826. return err
  827. }
  828. outSNAC, err := rt.UserLookupService.FindByEmail(ctx, inFrame, inBody)
  829. if err != nil {
  830. return err
  831. }
  832. rt.LogRequestAndResponse(ctx, inFrame, inBody, outSNAC.Frame, outSNAC.Body)
  833. return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
  834. }
  835. // Handle directs an incoming OSCAR request to the appropriate handler based on
  836. // its group and subGroup identifiers found in the SNAC frame. It returns an
  837. // ErrRouteNotFound error if no matching handler is found for the group:subGroup
  838. // pair in the request.
  839. func (rt Handler) Handle(ctx context.Context, server uint16, sess *state.Session, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter, listener config.Listener) error {
  840. switch inFrame.FoodGroup {
  841. case wire.Admin:
  842. switch inFrame.SubGroup {
  843. case wire.AdminAcctConfirmRequest:
  844. return rt.AdminConfirmRequest(ctx, sess, inFrame, r, rw)
  845. case wire.AdminInfoChangeRequest:
  846. return rt.AdminInfoChangeRequest(ctx, sess, inFrame, r, rw)
  847. case wire.AdminInfoQuery:
  848. return rt.AdminInfoQuery(ctx, sess, inFrame, r, rw)
  849. }
  850. case wire.Alert:
  851. switch inFrame.SubGroup {
  852. case wire.AlertNotifyCapabilities:
  853. return rt.AlertNotifyCapabilities(ctx, sess, inFrame, r, rw)
  854. case wire.AlertNotifyDisplayCapabilities:
  855. return rt.AlertNotifyDisplayCapabilities(ctx, sess, inFrame, r, rw)
  856. }
  857. case wire.BART:
  858. switch inFrame.SubGroup {
  859. case wire.BARTDownloadQuery:
  860. return rt.BARTDownloadQuery(ctx, sess, inFrame, r, rw)
  861. case wire.BARTUploadQuery:
  862. return rt.BARTUploadQuery(ctx, sess, inFrame, r, rw)
  863. }
  864. case wire.Buddy:
  865. switch inFrame.SubGroup {
  866. case wire.BuddyAddBuddies:
  867. return rt.BuddyAddBuddies(ctx, sess, inFrame, r, rw)
  868. case wire.BuddyDelBuddies:
  869. return rt.BuddyDelBuddies(ctx, sess, inFrame, r, rw)
  870. case wire.BuddyRightsQuery:
  871. return rt.BuddyRightsQuery(ctx, sess, inFrame, r, rw)
  872. }
  873. case wire.Chat:
  874. switch inFrame.SubGroup {
  875. case wire.ChatChannelMsgToHost:
  876. return rt.ChatChannelMsgToHost(ctx, sess, inFrame, r, rw)
  877. }
  878. case wire.ChatNav:
  879. switch inFrame.SubGroup {
  880. case wire.ChatNavCreateRoom:
  881. return rt.ChatNavCreateRoom(ctx, sess, inFrame, r, rw)
  882. case wire.ChatNavRequestChatRights:
  883. return rt.ChatNavRequestChatRights(ctx, sess, inFrame, r, rw)
  884. case wire.ChatNavRequestExchangeInfo:
  885. return rt.ChatNavRequestExchangeInfo(ctx, sess, inFrame, r, rw)
  886. case wire.ChatNavRequestRoomInfo:
  887. return rt.ChatNavRequestRoomInfo(ctx, sess, inFrame, r, rw)
  888. }
  889. case wire.Feedbag:
  890. switch inFrame.SubGroup {
  891. case wire.FeedbagDeleteItem:
  892. return rt.FeedbagDeleteItem(ctx, sess, inFrame, r, rw)
  893. case wire.FeedbagEndCluster:
  894. return rt.FeedbagEndCluster(ctx, sess, inFrame, r, rw)
  895. case wire.FeedbagInsertItem:
  896. return rt.FeedbagInsertItem(ctx, sess, inFrame, r, rw)
  897. case wire.FeedbagQuery:
  898. return rt.FeedbagQuery(ctx, sess, inFrame, r, rw)
  899. case wire.FeedbagQueryIfModified:
  900. return rt.FeedbagQueryIfModified(ctx, sess, inFrame, r, rw)
  901. case wire.FeedbagRespondAuthorizeToHost:
  902. return rt.FeedbagRespondAuthorizeToHost(ctx, sess, inFrame, r, rw)
  903. case wire.FeedbagRightsQuery:
  904. return rt.FeedbagRightsQuery(ctx, sess, inFrame, r, rw)
  905. case wire.FeedbagStartCluster:
  906. return rt.FeedbagStartCluster(ctx, sess, inFrame, r, rw)
  907. case wire.FeedbagUpdateItem:
  908. return rt.FeedbagUpdateItem(ctx, sess, inFrame, r, rw)
  909. case wire.FeedbagUse:
  910. return rt.FeedbagUse(ctx, sess, inFrame, r, rw)
  911. }
  912. case wire.ICQ:
  913. switch inFrame.SubGroup {
  914. case wire.ICQDBQuery:
  915. return rt.ICQDBQuery(ctx, sess, inFrame, r, rw)
  916. }
  917. case wire.ICBM:
  918. switch inFrame.SubGroup {
  919. case wire.ICBMAddParameters:
  920. return rt.ICBMAddParameters(ctx, sess, inFrame, r, rw)
  921. case wire.ICBMChannelMsgToHost:
  922. return rt.ICBMChannelMsgToHost(ctx, sess, inFrame, r, rw)
  923. case wire.ICBMClientErr:
  924. return rt.ICBMClientErr(ctx, sess, inFrame, r, rw)
  925. case wire.ICBMClientEvent:
  926. return rt.ICBMClientEvent(ctx, sess, inFrame, r, rw)
  927. case wire.ICBMEvilRequest:
  928. return rt.ICBMEvilRequest(ctx, sess, inFrame, r, rw)
  929. case wire.ICBMParameterQuery:
  930. return rt.ICBMParameterQuery(ctx, sess, inFrame, r, rw)
  931. }
  932. case wire.Locate:
  933. switch inFrame.SubGroup {
  934. case wire.LocateGetDirInfo:
  935. return rt.LocateGetDirInfo(ctx, sess, inFrame, r, rw)
  936. case wire.LocateRightsQuery:
  937. return rt.LocateRightsQuery(ctx, sess, inFrame, r, rw)
  938. case wire.LocateSetDirInfo:
  939. return rt.LocateSetDirInfo(ctx, sess, inFrame, r, rw)
  940. case wire.LocateSetInfo:
  941. return rt.LocateSetInfo(ctx, sess, inFrame, r, rw)
  942. case wire.LocateSetKeywordInfo:
  943. return rt.LocateSetKeywordInfo(ctx, sess, inFrame, r, rw)
  944. case wire.LocateUserInfoQuery:
  945. return rt.LocateUserInfoQuery(ctx, sess, inFrame, r, rw)
  946. case wire.LocateUserInfoQuery2:
  947. return rt.LocateUserInfoQuery2(ctx, sess, inFrame, r, rw)
  948. }
  949. case wire.ODir:
  950. switch inFrame.SubGroup {
  951. case wire.ODirInfoQuery:
  952. return rt.ODirInfoQuery(ctx, sess, inFrame, r, rw)
  953. case wire.ODirKeywordListQuery:
  954. return rt.ODirKeywordListQuery(ctx, sess, inFrame, r, rw)
  955. }
  956. case wire.OService:
  957. switch inFrame.SubGroup {
  958. case wire.OServiceClientOnline:
  959. return rt.OServiceClientOnline(ctx, server, sess, inFrame, r, rw)
  960. case wire.OServiceClientVersions:
  961. return rt.OServiceClientVersions(ctx, sess, inFrame, r, rw)
  962. case wire.OServiceIdleNotification:
  963. return rt.OServiceIdleNotification(ctx, sess, inFrame, r, rw)
  964. case wire.OServiceNoop:
  965. return rt.OServiceNoop(ctx, sess, inFrame, r, rw)
  966. case wire.OServiceRateParamsQuery:
  967. return rt.OServiceRateParamsQuery(ctx, sess, inFrame, r, rw)
  968. case wire.OServiceRateParamsSubAdd:
  969. return rt.OServiceRateParamsSubAdd(ctx, sess, inFrame, r, rw)
  970. case wire.OServiceServiceRequest:
  971. return rt.OServiceServiceRequest(ctx, server, sess, inFrame, r, rw, listener)
  972. case wire.OServiceSetPrivacyFlags:
  973. return rt.OServiceSetPrivacyFlags(ctx, sess, inFrame, r, rw)
  974. case wire.OServiceSetUserInfoFields:
  975. return rt.OServiceSetUserInfoFields(ctx, sess, inFrame, r, rw)
  976. case wire.OServiceUserInfoQuery:
  977. return rt.OServiceUserInfoQuery(ctx, sess, inFrame, r, rw)
  978. }
  979. case wire.PermitDeny:
  980. switch inFrame.SubGroup {
  981. case wire.PermitDenyAddDenyListEntries:
  982. return rt.PermitDenyAddDenyListEntries(ctx, sess, inFrame, r, rw)
  983. case wire.PermitDenyAddPermListEntries:
  984. return rt.PermitDenyAddPermListEntries(ctx, sess, inFrame, r, rw)
  985. case wire.PermitDenyDelDenyListEntries:
  986. return rt.PermitDenyDelDenyListEntries(ctx, sess, inFrame, r, rw)
  987. case wire.PermitDenyDelPermListEntries:
  988. return rt.PermitDenyDelPermListEntries(ctx, sess, inFrame, r, rw)
  989. case wire.PermitDenyRightsQuery:
  990. return rt.PermitDenyRightsQuery(ctx, sess, inFrame, r, rw)
  991. case wire.PermitDenySetGroupPermitMask:
  992. return rt.PermitDenySetGroupPermitMask(ctx, sess, inFrame, r, rw)
  993. }
  994. case wire.Stats:
  995. switch inFrame.SubGroup {
  996. case wire.StatsReportEvents:
  997. return rt.StatsReportEvents(ctx, sess, inFrame, r, rw)
  998. }
  999. case wire.UserLookup:
  1000. switch inFrame.SubGroup {
  1001. case wire.UserLookupFindByEmail:
  1002. return rt.UserLookupFindByEmail(ctx, sess, inFrame, r, rw)
  1003. }
  1004. }
  1005. return ErrRouteNotFound
  1006. }