toc

package
v0.19.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 25, 2025 License: MIT Imports: 28 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type AdminService added in v0.16.0

type AdminService interface {
	InfoChangeRequest(ctx context.Context, sess *state.Session, frame wire.SNACFrame, body wire.SNAC_0x07_0x04_AdminInfoChangeRequest) (wire.SNACMessage, error)
}

type AuthService

type AuthService interface {
	BUCPChallenge(ctx context.Context, bodyIn wire.SNAC_0x17_0x06_BUCPChallengeRequest, newUUID func() uuid.UUID) (wire.SNACMessage, error)
	BUCPLogin(ctx context.Context, bodyIn wire.SNAC_0x17_0x02_BUCPLoginRequest, newUserFn func(screenName state.DisplayScreenName) (state.User, error), advertisedHost string) (wire.SNACMessage, error)
	CrackCookie(authCookie []byte) (state.ServerCookie, error)
	FLAPLogin(ctx context.Context, frame wire.FLAPSignonFrame, newUserFn func(screenName state.DisplayScreenName) (state.User, error), here string) (wire.TLVRestBlock, error)
	RegisterBOSSession(ctx context.Context, authCookie state.ServerCookie) (*state.Session, error)
	RegisterChatSession(ctx context.Context, authCookie state.ServerCookie) (*state.Session, error)
	RetrieveBOSSession(ctx context.Context, authCookie state.ServerCookie) (*state.Session, error)
	Signout(ctx context.Context, sess *state.Session)
	SignoutChat(ctx context.Context, sess *state.Session)
}

type BuddyListRegistry

type BuddyListRegistry interface {
	RegisterBuddyList(ctx context.Context, user state.IdentScreenName) error
	UnregisterBuddyList(ctx context.Context, user state.IdentScreenName) error
}

BuddyListRegistry is the interface for keeping track of users with active buddy lists. Once registered, a user becomes visible to other users' buddy lists and vice versa.

type BuddyService

type BuddyService interface {
	AddBuddies(ctx context.Context, sess *state.Session, inBody wire.SNAC_0x03_0x04_BuddyAddBuddies) error
	BroadcastBuddyDeparted(ctx context.Context, sess *state.Session) error
	DelBuddies(ctx context.Context, sess *state.Session, inBody wire.SNAC_0x03_0x05_BuddyDelBuddies) error
	RightsQuery(ctx context.Context, inFrame wire.SNACFrame) wire.SNACMessage
}

type ChatNavService

type ChatNavService interface {
	CreateRoom(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, inBody wire.SNAC_0x0E_0x02_ChatRoomInfoUpdate) (wire.SNACMessage, error)
	ExchangeInfo(ctx context.Context, inFrame wire.SNACFrame, inBody wire.SNAC_0x0D_0x03_ChatNavRequestExchangeInfo) (wire.SNACMessage, error)
	RequestChatRights(ctx context.Context, inFrame wire.SNACFrame) wire.SNACMessage
	RequestRoomInfo(ctx context.Context, inFrame wire.SNACFrame, inBody wire.SNAC_0x0D_0x04_ChatNavRequestRoomInfo) (wire.SNACMessage, error)
}

type ChatRegistry

type ChatRegistry struct {
	// contains filtered or unexported fields
}

ChatRegistry manages the chat rooms that a user is connected to during a TOC session. It maintains mappings between chat room identifiers, metadata, and active chat sessions.

This struct provides thread-safe operations for adding, retrieving, and managing chat room metadata and associated sessions.

func NewChatRegistry

func NewChatRegistry() *ChatRegistry

NewChatRegistry creates a new ChatRegistry instances.

func (*ChatRegistry) Add

func (c *ChatRegistry) Add(room wire.ICBMRoomInfo) int

Add registers metadata for a newly joined chat room and returns a unique identifier for it. If the room is already registered, it returns the existing ID.

func (*ChatRegistry) LookupRoom

func (c *ChatRegistry) LookupRoom(chatID int) (wire.ICBMRoomInfo, bool)

LookupRoom retrieves metadata for the chat room registered with chatID. It returns the room metadata and a boolean indicating whether the chat ID was found.

func (*ChatRegistry) RegisterSess

func (c *ChatRegistry) RegisterSess(chatID int, sess *state.Session)

RegisterSess associates a chat session with a chat room. If a session is already registered for the given chat ID, it will be overwritten.

func (*ChatRegistry) RemoveSess added in v0.15.3

func (c *ChatRegistry) RemoveSess(chatID int)

RemoveSess removes a chat session.

func (*ChatRegistry) RetrieveSess

func (c *ChatRegistry) RetrieveSess(chatID int) *state.Session

RetrieveSess retrieves the chat session associated with the given chat ID. If no session is registered for the chat ID, it returns nil.

func (*ChatRegistry) Sessions added in v0.15.3

func (c *ChatRegistry) Sessions() []*state.Session

Sessions retrieves all the chat sessions.

type ChatService

type ChatService interface {
	ChannelMsgToHost(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, inBody wire.SNAC_0x0E_0x05_ChatChannelMsgToHost) (*wire.SNACMessage, error)
}

type CookieBaker

type CookieBaker interface {
	// Crack verifies and decodes a previously issued authentication token.
	// Returns the original payload if the token is valid.
	Crack(data []byte) ([]byte, error)

	// Issue creates a new authentication token from the given payload.
	// The resulting token can later be verified using Crack.
	Issue(data []byte) ([]byte, error)
}

CookieBaker defines methods for issuing and verifying AIM authentication tokens ("cookies"). These tokens are used for authenticating client sessions with AIM services.

type DirSearchService

type DirSearchService interface {
	InfoQuery(_ context.Context, inFrame wire.SNACFrame, inBody wire.SNAC_0x0F_0x02_InfoQuery) (wire.SNACMessage, error)
}

type ICBMService

type ICBMService interface {
	ChannelMsgToHost(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, inBody wire.SNAC_0x04_0x06_ICBMChannelMsgToHost) (*wire.SNACMessage, error)
	ClientEvent(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, inBody wire.SNAC_0x04_0x14_ICBMClientEvent) error
	EvilRequest(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, inBody wire.SNAC_0x04_0x08_ICBMEvilRequest) (wire.SNACMessage, error)
	ParameterQuery(ctx context.Context, inFrame wire.SNACFrame) wire.SNACMessage
	ClientErr(ctx context.Context, sess *state.Session, frame wire.SNACFrame, body wire.SNAC_0x04_0x0B_ICBMClientErr) error
}

type IPRateLimiter added in v0.17.0

type IPRateLimiter struct {
	// contains filtered or unexported fields
}

IPRateLimiter provides per-IP rate limiting using a token bucket algorithm. It caches individual rate limiters per IP address with automatic TTL expiration.

func NewIPRateLimiter added in v0.17.0

func NewIPRateLimiter(rate rate.Limit, burst int, ttl time.Duration) *IPRateLimiter

NewIPRateLimiter returns a new IPRateLimiter that limits each IP to the specified rate and burst, with limiter state expiring after the given TTL. Entries are retained for up to 2×TTL to reduce churn under frequent lookups.

func (*IPRateLimiter) Allow added in v0.17.0

func (l *IPRateLimiter) Allow(ip string) (allowed bool)

Allow returns true if the request from the given IP is allowed under its rate limit. If no limiter exists for the IP, one is created and tracked in the cache.

type OSCARProxy

type OSCARProxy struct {
	AdminService      AdminService
	AuthService       AuthService
	BuddyListRegistry BuddyListRegistry
	BuddyService      BuddyService
	ChatNavService    ChatNavService
	ChatService       ChatService
	CookieBaker       CookieBaker
	DirSearchService  DirSearchService
	ICBMService       ICBMService
	LocateService     LocateService
	Logger            *slog.Logger
	OServiceService   OServiceService
	PermitDenyService PermitDenyService
	TOCConfigStore    TOCConfigStore
	SNACRateLimits    wire.SNACRateLimits
	HTTPIPRateLimiter *IPRateLimiter
}

OSCARProxy acts as a bridge between TOC clients and the OSCAR server, translating protocol messages between the two.

It performs the following functions:

  • Receives TOC messages from the client, converts them into SNAC messages, and forwards them to the OSCAR server. The SNAC response is then converted back into a TOC response for the client.
  • Receives incoming messages from the OSCAR server and translates them into TOC responses for the client.

func (OSCARProxy) AddBuddy

func (s OSCARProxy) AddBuddy(ctx context.Context, me *state.Session, args []byte) string

AddBuddy handles the toc_add_buddy TOC command.

From the TiK documentation:

Add buddies to your buddy list. This does not change your saved config.

Command syntax: toc_add_buddy <Buddy User 1> [<Buddy User2> [<Buddy User 3> [...]]]

func (OSCARProxy) AddDeny

func (s OSCARProxy) AddDeny(ctx context.Context, me *state.Session, args []byte) string

AddDeny handles the toc_add_deny TOC command.

From the TiK documentation:

ADD the following people to your deny mode. If you are in permit mode it
will switch you to deny mode first. With no arguments and in permit mode,
this will switch you to deny none. If already in deny mode, no arguments
does nothing and your deny list remains unchanged.

Command syntax: toc_add_deny [ <User 1> [<User 2> [...]]]

func (OSCARProxy) AddPermit

func (s OSCARProxy) AddPermit(ctx context.Context, me *state.Session, args []byte) string

AddPermit handles the toc_add_permit TOC command.

From the TiK documentation:

ADD the following people to your permit mode. If you are in deny mode it
will switch you to permit mode first. With no arguments and in deny mode
this will switch you to permit none. If already in permit mode, no
arguments does nothing and your permit list remains the same.

Command syntax: toc_add_permit [ <User 1> [<User 2> [...]]]

func (OSCARProxy) AuthMiddleware

func (s OSCARProxy) AuthMiddleware(next http.Handler) http.Handler

AuthMiddleware is an HTTP middleware that enforces authentication using an authorization cookie provided as a query parameter. It validates and decrypts the cookie before allowing the request to proceed.

If the `cookie` query parameter is missing or invalid, the middleware responds with an appropriate HTTP error:

  • 400 Bad Request if the `cookie` parameter is missing.
  • 403 Forbidden if the cookie is invalid or cannot be decrypted.

Requests with a valid cookie are passed to the next handler.

func (OSCARProxy) ChangePassword added in v0.16.0

func (s OSCARProxy) ChangePassword(ctx context.Context, me *state.Session, args []byte) string

ChangePassword handles the toc_change_passwd TOC command.

From the TiK documentation:

Change a user's password. An ADMIN_PASSWD_STATUS or ERROR message will be
sent back to the client.

Command syntax: toc_change_passwd <existing_passwd> <new_passwd>

func (OSCARProxy) ChatAccept

func (s OSCARProxy) ChatAccept(
	ctx context.Context,
	me *state.Session,
	chatRegistry *ChatRegistry,
	args []byte,
) (int, string)

ChatAccept handles the toc_chat_accept TOC command.

From the TiK documentation:

Accept a CHAT_INVITE message from TOC. The server will send a CHAT_JOIN in
response.

Command syntax: toc_chat_accept <Chat Room ID>

func (OSCARProxy) ChatIn

ChatIn handles the CHAT_IN TOC command.

From the TiK documentation:

A chat message was sent in a chat room.

Command syntax: CHAT_IN:<Chat Room Id>:<Source User>:<Whisper? T/F>:<Message>

func (OSCARProxy) ChatInvite

func (s OSCARProxy) ChatInvite(ctx context.Context, me *state.Session, chatRegistry *ChatRegistry, args []byte) string

ChatInvite handles the toc_chat_invite TOC command.

From the TiK documentation:

Once you are inside a chat room you can invite other people into that room.
Remember to quote and encode the invite message.

Command syntax: toc_chat_invite <Chat Room ID> <Invite Msg> <buddy1> [<buddy2> [<buddy3> [...]]]

func (OSCARProxy) ChatJoin

func (s OSCARProxy) ChatJoin(
	ctx context.Context,
	me *state.Session,
	chatRegistry *ChatRegistry,
	args []byte,
) (int, string)

ChatJoin handles the toc_chat_join TOC command.

From the TiK documentation:

Join a chat room in the given exchange. Exchange is an integer that
represents a group of chat rooms. Different exchanges have different
properties. For example some exchanges might have room replication (ie a
room never fills up, there are just multiple instances.) and some exchanges
might have navigational information. Currently, exchange should always be
4, however this may change in the future. You will either receive an ERROR
if the room couldn't be joined or a CHAT_JOIN message. The Chat Room Name
is case-insensitive and consecutive spaces are removed.

Command syntax: toc_chat_join <Exchange> <Chat Room Name>

func (OSCARProxy) ChatLeave

func (s OSCARProxy) ChatLeave(ctx context.Context, chatRegistry *ChatRegistry, args []byte) string

ChatLeave handles the toc_chat_leave TOC command.

From the TiK documentation:

Leave the chat room.

Command syntax: toc_chat_leave <Chat Room ID>

func (OSCARProxy) ChatSend

func (s OSCARProxy) ChatSend(ctx context.Context, chatRegistry *ChatRegistry, args []byte) string

ChatSend handles the toc_chat_send TOC command.

From the TiK documentation:

Send a message in a chat room using the chat room id from CHAT_JOIN. Since
reflection is always on in TOC, you do not need to add the message to your
chat UI, since you will get a CHAT_IN with the message. Remember to quote
and encode the message.

Command syntax: toc_chat_send <Chat Room ID> <Message>

func (OSCARProxy) ChatUpdateBuddyArrived

func (s OSCARProxy) ChatUpdateBuddyArrived(snac wire.SNAC_0x0E_0x03_ChatUsersJoined, chatID int) string

ChatUpdateBuddyArrived handles the CHAT_UPDATE_BUDDY TOC command for chat room arrival events.

From the TiK documentation:

This one command handles arrival/departs from a chat room. The very first
message of this type for each chat room contains the users already in the
room.

Command syntax: CHAT_UPDATE_BUDDY:<Chat Room Id>:<Inside? T/F>:<User 1>:<User 2>...

func (OSCARProxy) ChatUpdateBuddyLeft

func (s OSCARProxy) ChatUpdateBuddyLeft(snac wire.SNAC_0x0E_0x04_ChatUsersLeft, chatID int) string

ChatUpdateBuddyLeft handles the CHAT_UPDATE_BUDDY TOC command for chat room departure events.

From the TiK documentation:

This one command handles arrival/departs from a chat room. The very first
message of this type for each chat room contains the users already in the
room.

Command syntax: CHAT_UPDATE_BUDDY:<Chat Room Id>:<Inside? T/F>:<User 1>:<User 2>...

func (OSCARProxy) ChatWhisper added in v0.16.0

func (s OSCARProxy) ChatWhisper(ctx context.Context, chatRegistry *ChatRegistry, args []byte) string

ChatWhisper handles the toc_chat_send TOC command.

From the TiK documentation:

Send a message in a chat room using the chat room id from CHAT_JOIN.
This message is directed at only one person. (Currently you DO need to add
this to your UI.) Remember to quote and encode the message. Chat whispering
is different from IMs since it is linked to a chat room, and should usually
be displayed in the chat room UI.

Command syntax: toc_chat_whisper <Chat Room ID> <dst_user> <Message>

func (OSCARProxy) DirInfoHandler

func (s OSCARProxy) DirInfoHandler(w http.ResponseWriter, request *http.Request)

DirInfoHandler handles requests to retrieve directory information for a user. It queries the LocateService to fetch directory details associated with the given screen name.

The request must include the following query parameter:

  • `user`: The screen name of the user whose directory info is being requested.

If the `user` parameter is missing, it responds with a 400 Bad Request. If no directory information is found, it responds with a 404 Not Found.

func (OSCARProxy) DirSearchHandler

func (s OSCARProxy) DirSearchHandler(w http.ResponseWriter, r *http.Request)

DirSearchHandler handles requests to perform a directory search based on various criteria. It queries the DirSearchService to find users matching the specified parameters. There are 3 search modes: name, email, keyword.

-Named-based search is toggled by the presence of either `first_name`
and/or `last_name` params. The following search params can be passed:
	-`first_name`
  	-`middle_name`
	-`last_name`
	-`maiden_name`
	-`city`
	-`state`
	-`country`
-Email-based search is triggered by the`email` param.
-Keyword-based search is triggered by the `keyword` param.

If the search is missing required name parameters, it responds with a 400 Bad Request.

func (OSCARProxy) Evil

func (s OSCARProxy) Evil(ctx context.Context, me *state.Session, args []byte) string

Evil handles the toc_evil TOC command.

From the TiK documentation:

Evil/Warn someone else. The 2nd argument is either the string "norm" for a
normal warning, or "anon" for an anonymous warning. You can only evil
people who have recently sent you ims. The higher someones evil level, the
slower they can send message.

Command syntax: toc_evil <User> <norm|anon>

func (OSCARProxy) Eviled

Eviled handles the EVILED TOC command.

From the TiK documentation:

The user was just eviled.

Command syntax: EVILED:<new evil>:<name of eviler, blank if anonymous>

func (OSCARProxy) FormatNickname added in v0.16.0

func (s OSCARProxy) FormatNickname(ctx context.Context, me *state.Session, args []byte) string

FormatNickname handles the toc_format_nickname TOC command.

From the TiK documentation:

Reformat a user's nickname. An ADMIN_NICK_STATUS or ERROR message will be
sent back to the client.

Command syntax: toc_format_nickname <new_format>

func (OSCARProxy) GetDirSearchURL

func (s OSCARProxy) GetDirSearchURL(ctx context.Context, me *state.Session, args []byte) string

GetDirSearchURL handles the toc_dir_search TOC command.

From the TiK documentation:

Perform a search of the Oscar Directory, using colon separated fields as in:

	"first name":"middle name":"last name":"maiden name":"city":"state":"country":"email"

You can search by keyword by setting search terms in the 11th position (this feature is not in the TiK docs but is present in the code):

::::::::::"search kw"

Returns either a GOTO_URL or ERROR msg.

Command syntax: toc_dir_search <info information>

func (OSCARProxy) GetDirURL

func (s OSCARProxy) GetDirURL(ctx context.Context, me *state.Session, args []byte) string

GetDirURL handles the toc_get_dir TOC command.

From the TiK documentation:

Gets a user's dir info a GOTO_URL or ERROR message will be sent back to the client.

Command syntax: toc_get_dir <username>

func (OSCARProxy) GetInfoURL

func (s OSCARProxy) GetInfoURL(ctx context.Context, me *state.Session, args []byte) string

GetInfoURL handles the toc_get_info TOC command.

From the TiK documentation:

Gets a user's info a GOTO_URL or ERROR message will be sent back to the client.

Command syntax: toc_get_info <username>

func (OSCARProxy) GetStatus added in v0.16.0

func (s OSCARProxy) GetStatus(ctx context.Context, me *state.Session, args []byte) string

GetStatus handles the toc_get_status TOC command.

From the TOC2 documentation:

This useful command wasn't ever really documented. It returns either an
UPDATE_BUDDY message or an ERROR message depending on whether or not the
guy appears to be online.

Command syntax: toc_get_status <screenname>

func (OSCARProxy) IMIn

IMIn handles the IM_IN TOC command.

From the TiK documentation:

Receive an IM from someone. Everything after the third colon is the
incoming message, including other colons.

Command syntax: IM_IN:<Source User>:<Auto Response T/F?>:<Message>

func (OSCARProxy) InitDone

func (s OSCARProxy) InitDone(ctx context.Context, sess *state.Session) string

InitDone handles the toc_init_done TOC command.

From the TiK documentation:

Tells TOC that we are ready to go online. TOC clients should first send TOC
the buddy list and any permit/deny lists. However, toc_init_done must be
called within 30 seconds after toc_signon, or the connection will be
dropped. Remember, it can't be called until after the SIGN_ON message is
received. Calling this before or multiple times after a SIGN_ON will cause
the connection to be dropped.

Note: The business logic described in the last 3 sentences are not yet implemented.

Command syntax: toc_init_done

func (OSCARProxy) NewServeMux

func (s OSCARProxy) NewServeMux() http.Handler

NewServeMux creates and returns an HTTP mux that serves all TOC routes.

func (OSCARProxy) ProfileHandler

func (s OSCARProxy) ProfileHandler(w http.ResponseWriter, r *http.Request)

ProfileHandler handles requests to retrieve a user's profile information. It queries the LocateService to fetch profile data for the specified user.

The request must include the following query parameters:

  • `from`: The screen name of the user making the request.
  • `user`: The screen name of the user whose profile is being requested.

If any required parameter is missing, it responds with a 400 Bad Request. If the requested user is unavailable, it responds with a 404 Not Found.

func (OSCARProxy) RateLimiterMiddleware added in v0.17.0

func (s OSCARProxy) RateLimiterMiddleware(next http.Handler) http.Handler

func (OSCARProxy) RecvBOS

func (s OSCARProxy) RecvBOS(ctx context.Context, me *state.Session, chatRegistry *ChatRegistry, ch chan<- []byte) error

RecvBOS routes incoming SNAC messages from the BOS server to their corresponding TOC handlers. It ignores any SNAC messages for which there is no TOC response.

func (OSCARProxy) RecvChat

func (s OSCARProxy) RecvChat(ctx context.Context, me *state.Session, chatID int, ch chan<- []byte)

RecvChat routes incoming SNAC messages from the chat server to their corresponding TOC handlers. It ignores any SNAC messages for which there is no TOC response.

func (OSCARProxy) RecvClientCmd

func (s OSCARProxy) RecvClientCmd(
	ctx context.Context,
	sessBOS *state.Session,
	chatRegistry *ChatRegistry,
	payload []byte,
	toCh chan<- []byte,
	doAsync func(f func() error),
) (reply string)

RecvClientCmd processes a client TOC command and returns a server reply.

* sessBOS is the current user's session. * chatRegistry manages the current user's chat sessions * payload is the command + arguments * toCh is the channel that transports messages to client * doAsync performs async tasks, is auto-cleaned up by caller

It returns true if the server can continue processing commands.

func (OSCARProxy) RemoveBuddy

func (s OSCARProxy) RemoveBuddy(ctx context.Context, me *state.Session, args []byte) string

RemoveBuddy handles the toc_remove_buddy TOC command.

From the TiK documentation:

Remove buddies from your buddy list. This does not change your saved config.

Command syntax: toc_remove_buddy <Buddy User 1> [<Buddy User2> [<Buddy User 3> [...]]]

func (OSCARProxy) RvousAccept added in v0.16.0

func (s OSCARProxy) RvousAccept(ctx context.Context, me *state.Session, args []byte) string

RvousAccept handles the toc_rvous_accept TOC command.

From the TiK documentation:

Accept a rendezvous proposal from the user <nick>. <cookie> is the cookie
from the RVOUS_PROPOSE message. <service> is the UUID the proposal was for.
<tlvlist> contains a list of tlv tags followed by base64 encoded values.

Note: This method does not actually process the TLV list param, as it's not passed in the TiK client, the reference implementation.

Command syntax: toc_rvous_accept <nick> <cookie> <service>

func (OSCARProxy) RvousCancel added in v0.16.0

func (s OSCARProxy) RvousCancel(ctx context.Context, me *state.Session, args []byte) string

RvousCancel handles the toc_rvous_cancel TOC command.

From the TiK documentation:

Cancel a rendezvous proposal from the user <nick>. <cookie> is the cookie
from the RVOUS_PROPOSE message. <service> is the UUID the proposal was for.
<tlvlist> contains a list of tlv tags followed by base64 encoded values.

Note: This method does not actually process the TLV list param, as it's not passed in the TiK client, the reference implementation.

Command syntax: toc_rvous_cancel <nick> <cookie> <service>

func (OSCARProxy) SendIM

func (s OSCARProxy) SendIM(ctx context.Context, sender *state.Session, args []byte) string

SendIM handles the toc_send_im TOC command.

From the TiK documentation:

Send a message to a remote user. Remember to quote and encode the message.
If the optional string "auto" is the last argument, then the auto response
flag will be turned on for the IM.

Command syntax: toc_send_im <Destination User> <Message> [auto]

func (OSCARProxy) SetAway

func (s OSCARProxy) SetAway(ctx context.Context, me *state.Session, args []byte) string

SetAway handles the toc_chat_join TOC command.

From the TiK documentation:

If the away message is present, then the unavailable status flag is set for
the user. If the away message is not present, then the unavailable status
flag is unset. The away message is basic HTML, remember to encode the
information.

Command syntax: toc_set_away [<away message>]

func (OSCARProxy) SetCaps

func (s OSCARProxy) SetCaps(ctx context.Context, me *state.Session, args []byte) string

SetCaps handles the toc_set_caps TOC command.

From the TiK documentation:

Set my capabilities. All capabilities that we support need to be sent at
the same time. Capabilities are represented by UUIDs.

This method automatically adds the "chat" capability since it doesn't seem to be sent explicitly by the official clients, even though they support chat.

Command syntax: toc_set_caps [ <Capability 1> [<Capability 2> [...]]]

func (OSCARProxy) SetConfig

func (s OSCARProxy) SetConfig(ctx context.Context, me *state.Session, args []byte) string

SetConfig handles the toc_set_config TOC command.

From the TiK documentation:

Set the config information for this user. The config information is line
oriented with the first character being the item type, followed by a space,
with the rest of the line being the item value. Only letters, numbers, and
spaces should be used. Remember you will have to enclose the entire config
in quotes.

Item Types:
	- g - Buddy Group (All Buddies until the next g or the end of config are in this group.)
	- b - A Buddy
	- p - Person on permit list
	- d - Person on deny list
	- m - Permit/Deny Mode. Possible values are
	- 1 - Permit All
	- 2 - Deny All
	- 3 - Permit Some
	- 4 - Deny Some

This method doesn't attempt to validate any of the configuration--it saves the config as received from the client.

Command syntax: toc_set_config <Config Info>

func (OSCARProxy) SetDir

func (s OSCARProxy) SetDir(ctx context.Context, me *state.Session, args []byte) string

SetDir handles the toc_set_dir TOC command.

From the TiK documentation:

Set the DIR user information. This is a colon separated fields as in:

	"first name":"middle name":"last name":"maiden name":"city":"state":"country":"email":"allow web searches".

Should return a DIR_STATUS msg. Having anything in the "allow web searches"
field allows people to use web-searches to find your directory info.
Otherwise, they'd have to use the client.

The fields "email" and "allow web searches" are ignored by this method.

Command syntax: toc_set_dir <info information>

func (OSCARProxy) SetIdle

func (s OSCARProxy) SetIdle(ctx context.Context, me *state.Session, args []byte) string

SetIdle handles the toc_set_idle TOC command.

From the TiK documentation:

Set idle information. If <idle secs> is 0 then the user isn't idle at all.
If <idle secs> is greater than 0 then the user has already been idle for
<idle secs> number of seconds. The server will automatically keep
incrementing this number, so do not repeatedly call with new idle times.

Command syntax: toc_set_idle <idle secs>

func (OSCARProxy) SetInfo

func (s OSCARProxy) SetInfo(ctx context.Context, me *state.Session, args []byte) string

SetInfo handles the toc_set_info TOC command.

From the TiK documentation:

Set the LOCATE user information. This is basic HTML. Remember to encode the info.

Command syntax: toc_set_info <info information>

func (OSCARProxy) Signon

func (s OSCARProxy) Signon(ctx context.Context, args []byte) (*state.Session, []string)

Signon handles the toc_signon TOC command.

From the TiK documentation:

The password needs to be roasted with the Roasting String if coming over a
FLAP connection, CP connections don't use roasted passwords. The language
specified will be used when generating web pages, such as the get info
pages. Currently, the only supported language is "english". If the language
sent isn't found, the default "english" language will be used. The version
string will be used for the client identity, and must be less than 50
characters.

Passwords are roasted when sent to the host. This is done so they aren't
sent in "clear text" over the wire, although they are still trivial to
decode. Roasting is performed by first xoring each byte in the password
with the equivalent modulo byte in the roasting string. The result is then
converted to ascii hex, and prepended with "0x". So for example the
password "password" roasts to "0x2408105c23001130".

The Roasting String is Tic/Toc.

Command syntax: toc_signon <authorizer host> <authorizer port> <User Name> <Password> <language> <version>

func (OSCARProxy) Signout

func (s OSCARProxy) Signout(ctx context.Context, me *state.Session, chatRegistry *ChatRegistry)

Signout terminates a TOC session. It sends departure notifications to buddies, de-registers buddy list and session.

func (OSCARProxy) UpdateBuddyArrival

func (s OSCARProxy) UpdateBuddyArrival(snac wire.SNAC_0x03_0x0B_BuddyArrived) string

UpdateBuddyArrival handles the UPDATE_BUDDY TOC command for buddy arrival events.

From the TiK documentation:

This one command handles arrival/depart/updates. Evil Amount is a percentage, Signon Time is UNIX epoc, idle time is in minutes, UC (User Class) is a two/three character string.
	- uc[0]
		- ' ' - Ignore
		- 'A' - On AOL
	- uc[1]
		- ' ' - Ignore
		- 'A' - Oscar Admin
		- 'U' - Oscar Unconfirmed
		- 'O' - Oscar Normal
	- uc[2]
		- '\0' - Ignore
		- ' ' - Ignore
		- 'U' - The user has set their unavailable flag.

Command syntax: UPDATE_BUDDY:<Buddy User>:<Online? T/F>:<Evil Amount>:<Signon Time>:<IdleTime>:<UC>

func (OSCARProxy) UpdateBuddyDeparted

func (s OSCARProxy) UpdateBuddyDeparted(snac wire.SNAC_0x03_0x0C_BuddyDeparted) string

UpdateBuddyDeparted handles the UPDATE_BUDDY TOC command for buddy departure events.

From the TiK documentation:

This one command handles arrival/depart/updates. Evil Amount is a
percentage, Signon Time is UNIX epoc, idle time is in minutes, UC (User
Class) is a two/three character string.
	- uc[0]
		- ' ' - Ignore
		- 'A' - On AOL
	- uc[1]
		- ' ' - Ignore
		- 'A' - Oscar Admin
		- 'U' - Oscar Unconfirmed
		- 'O' - Oscar Normal
	- uc[2]
		- '\0' - Ignore
		- ' ' - Ignore
		- 'U' - The user has set their unavailable flag.

Command syntax: UPDATE_BUDDY:<Buddy User>:<Online? T/F>:<Evil Amount>:<Signon Time>:<IdleTime>:<UC>

type OServiceService

type OServiceService interface {
	ClientOnline(ctx context.Context, service uint16, bodyIn wire.SNAC_0x01_0x02_OServiceClientOnline, sess *state.Session) error
	IdleNotification(ctx context.Context, sess *state.Session, bodyIn wire.SNAC_0x01_0x11_OServiceIdleNotification) error
	ServiceRequest(ctx context.Context, service uint16, sess *state.Session, frame wire.SNACFrame, bodyIn wire.SNAC_0x01_0x04_OServiceServiceRequest, listener config.Listener) (wire.SNACMessage, error)
}

type PermitDenyService

type PermitDenyService interface {
	AddDenyListEntries(ctx context.Context, sess *state.Session, body wire.SNAC_0x09_0x07_PermitDenyAddDenyListEntries) error
	AddPermListEntries(ctx context.Context, sess *state.Session, body wire.SNAC_0x09_0x05_PermitDenyAddPermListEntries) error
	DelDenyListEntries(ctx context.Context, sess *state.Session, body wire.SNAC_0x09_0x08_PermitDenyDelDenyListEntries) error
	DelPermListEntries(ctx context.Context, sess *state.Session, body wire.SNAC_0x09_0x06_PermitDenyDelPermListEntries) error
	RightsQuery(_ context.Context, frame wire.SNACFrame) wire.SNACMessage
}

type Server

type Server struct {
	// contains filtered or unexported fields
}

Server implements a TOC protocol server that multiplexes TOC/HTTP and TOC/FLAP requests. It acts as a gateway, forwarding all TOC requests to the OSCAR server for processing.

func NewServer added in v0.19.0

func NewServer(listenerCfg []string, logger *slog.Logger, BOSProxy OSCARProxy, ipRateLimiter *IPRateLimiter) *Server

func (*Server) ListenAndServe added in v0.19.0

func (s *Server) ListenAndServe() error

func (*Server) Shutdown added in v0.19.0

func (s *Server) Shutdown(ctx context.Context) error

type TOCConfigStore

type TOCConfigStore interface {
	// SetTOCConfig sets the user's TOC config. The TOC config is the server-side
	// buddy list functionality for TOC. This configuration is not available to
	// OSCAR clients.
	SetTOCConfig(ctx context.Context, user state.IdentScreenName, config string) error
	User(ctx context.Context, screenName state.IdentScreenName) (*state.User, error)
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL