irc

package
v0.5.0 Latest Latest
Warning

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

Go to latest
Published: Dec 10, 2016 License: MIT Imports: 35 Imported by: 0

Documentation

Index

Constants

View Source
const (
	IDLE_TIMEOUT        = time.Minute + time.Second*30 // how long before a client is considered idle
	QUIT_TIMEOUT        = time.Minute                  // how long after idle before a client is kicked
	IdentTimeoutSeconds = 5
)
View Source
const (
	RPL_WELCOME                     = "001"
	RPL_YOURHOST                    = "002"
	RPL_CREATED                     = "003"
	RPL_MYINFO                      = "004"
	RPL_ISUPPORT                    = "005"
	RPL_BOUNCE                      = "010"
	RPL_TRACELINK                   = "200"
	RPL_TRACECONNECTING             = "201"
	RPL_TRACEHANDSHAKE              = "202"
	RPL_TRACEUNKNOWN                = "203"
	RPL_TRACEOPERATOR               = "204"
	RPL_TRACEUSER                   = "205"
	RPL_TRACESERVER                 = "206"
	RPL_TRACESERVICE                = "207"
	RPL_TRACENEWTYPE                = "208"
	RPL_TRACECLASS                  = "209"
	RPL_TRACERECONNECT              = "210"
	RPL_STATSLINKINFO               = "211"
	RPL_STATSCOMMANDS               = "212"
	RPL_ENDOFSTATS                  = "219"
	RPL_UMODEIS                     = "221"
	RPL_SERVLIST                    = "234"
	RPL_SERVLISTEND                 = "235"
	RPL_STATSUPTIME                 = "242"
	RPL_STATSOLINE                  = "243"
	RPL_LUSERCLIENT                 = "251"
	RPL_LUSEROP                     = "252"
	RPL_LUSERUNKNOWN                = "253"
	RPL_LUSERCHANNELS               = "254"
	RPL_LUSERME                     = "255"
	RPL_ADMINME                     = "256"
	RPL_ADMINLOC1                   = "257"
	RPL_ADMINLOC2                   = "258"
	RPL_ADMINEMAIL                  = "259"
	RPL_TRACELOG                    = "261"
	RPL_TRACEEND                    = "262"
	RPL_TRYAGAIN                    = "263"
	RPL_WHOISCERTFP                 = "276"
	RPL_AWAY                        = "301"
	RPL_USERHOST                    = "302"
	RPL_ISON                        = "303"
	RPL_UNAWAY                      = "305"
	RPL_NOWAWAY                     = "306"
	RPL_WHOISUSER                   = "311"
	RPL_WHOISSERVER                 = "312"
	RPL_WHOISOPERATOR               = "313"
	RPL_WHOWASUSER                  = "314"
	RPL_ENDOFWHO                    = "315"
	RPL_WHOISIDLE                   = "317"
	RPL_ENDOFWHOIS                  = "318"
	RPL_WHOISCHANNELS               = "319"
	RPL_LIST                        = "322"
	RPL_LISTEND                     = "323"
	RPL_CHANNELMODEIS               = "324"
	RPL_UNIQOPIS                    = "325"
	RPL_CHANNELCREATED              = "329"
	RPL_NOTOPIC                     = "331"
	RPL_TOPIC                       = "332"
	RPL_TOPICTIME                   = "333"
	RPL_INVITING                    = "341"
	RPL_SUMMONING                   = "342"
	RPL_INVITELIST                  = "346"
	RPL_ENDOFINVITELIST             = "347"
	RPL_EXCEPTLIST                  = "348"
	RPL_ENDOFEXCEPTLIST             = "349"
	RPL_VERSION                     = "351"
	RPL_WHOREPLY                    = "352"
	RPL_NAMREPLY                    = "353"
	RPL_LINKS                       = "364"
	RPL_ENDOFLINKS                  = "365"
	RPL_ENDOFNAMES                  = "366"
	RPL_BANLIST                     = "367"
	RPL_ENDOFBANLIST                = "368"
	RPL_ENDOFWHOWAS                 = "369"
	RPL_INFO                        = "371"
	RPL_MOTD                        = "372"
	RPL_ENDOFINFO                   = "374"
	RPL_MOTDSTART                   = "375"
	RPL_ENDOFMOTD                   = "376"
	RPL_YOUREOPER                   = "381"
	RPL_REHASHING                   = "382"
	RPL_YOURESERVICE                = "383"
	RPL_TIME                        = "391"
	RPL_USERSSTART                  = "392"
	RPL_USERS                       = "393"
	RPL_ENDOFUSERS                  = "394"
	RPL_NOUSERS                     = "395"
	ERR_UNKNOWNERROR                = "400"
	ERR_NOSUCHNICK                  = "401"
	ERR_NOSUCHSERVER                = "402"
	ERR_NOSUCHCHANNEL               = "403"
	ERR_CANNOTSENDTOCHAN            = "404"
	ERR_TOOMANYCHANNELS             = "405"
	ERR_WASNOSUCHNICK               = "406"
	ERR_TOOMANYTARGETS              = "407"
	ERR_NOSUCHSERVICE               = "408"
	ERR_NOORIGIN                    = "409"
	ERR_INVALIDCAPCMD               = "410"
	ERR_NORECIPIENT                 = "411"
	ERR_NOTEXTTOSEND                = "412"
	ERR_NOTOPLEVEL                  = "413"
	ERR_WILDTOPLEVEL                = "414"
	ERR_BADMASK                     = "415"
	ERR_UNKNOWNCOMMAND              = "421"
	ERR_NOMOTD                      = "422"
	ERR_NOADMININFO                 = "423"
	ERR_FILEERROR                   = "424"
	ERR_NONICKNAMEGIVEN             = "431"
	ERR_ERRONEUSNICKNAME            = "432"
	ERR_NICKNAMEINUSE               = "433"
	ERR_NICKCOLLISION               = "436"
	ERR_UNAVAILRESOURCE             = "437"
	ERR_REG_UNAVAILABLE             = "440"
	ERR_USERNOTINCHANNEL            = "441"
	ERR_NOTONCHANNEL                = "442"
	ERR_USERONCHANNEL               = "443"
	ERR_NOLOGIN                     = "444"
	ERR_SUMMONDISABLED              = "445"
	ERR_USERSDISABLED               = "446"
	ERR_NOTREGISTERED               = "451"
	ERR_NEEDMOREPARAMS              = "461"
	ERR_ALREADYREGISTRED            = "462"
	ERR_NOPERMFORHOST               = "463"
	ERR_PASSWDMISMATCH              = "464"
	ERR_YOUREBANNEDCREEP            = "465"
	ERR_YOUWILLBEBANNED             = "466"
	ERR_KEYSET                      = "467"
	ERR_CHANNELISFULL               = "471"
	ERR_UNKNOWNMODE                 = "472"
	ERR_INVITEONLYCHAN              = "473"
	ERR_BANNEDFROMCHAN              = "474"
	ERR_BADCHANNELKEY               = "475"
	ERR_BADCHANMASK                 = "476"
	ERR_NOCHANMODES                 = "477"
	ERR_BANLISTFULL                 = "478"
	ERR_NOPRIVILEGES                = "481"
	ERR_CHANOPRIVSNEEDED            = "482"
	ERR_CANTKILLSERVER              = "483"
	ERR_RESTRICTED                  = "484"
	ERR_UNIQOPPRIVSNEEDED           = "485"
	ERR_NOOPERHOST                  = "491"
	ERR_UMODEUNKNOWNFLAG            = "501"
	ERR_USERSDONTMATCH              = "502"
	ERR_HELPNOTFOUND                = "524"
	ERR_CANNOTSENDRP                = "573"
	RPL_HELPSTART                   = "704"
	RPL_HELPTXT                     = "705"
	RPL_ENDOFHELP                   = "706"
	ERR_NOPRIVS                     = "723"
	RPL_MONONLINE                   = "730"
	RPL_MONOFFLINE                  = "731"
	RPL_MONLIST                     = "732"
	RPL_ENDOFMONLIST                = "733"
	ERR_MONLISTFULL                 = "734"
	RPL_LOGGEDIN                    = "900"
	RPL_LOGGEDOUT                   = "901"
	ERR_NICKLOCKED                  = "902"
	RPL_SASLSUCCESS                 = "903"
	ERR_SASLFAIL                    = "904"
	ERR_SASLTOOLONG                 = "905"
	ERR_SASLABORTED                 = "906"
	ERR_SASLALREADY                 = "907"
	RPL_SASLMECHS                   = "908"
	RPL_REGISTRATION_SUCCESS        = "920"
	ERR_ACCOUNT_ALREADY_EXISTS      = "921"
	ERR_REG_UNSPECIFIED_ERROR       = "922"
	RPL_VERIFYSUCCESS               = "923"
	ERR_ACCOUNT_ALREADY_VERIFIED    = "924"
	ERR_ACCOUNT_INVALID_VERIFY_CODE = "925"
	RPL_REG_VERIFICATION_REQUIRED   = "927"
	ERR_REG_INVALID_CRED_TYPE       = "928"
	ERR_REG_INVALID_CALLBACK        = "929"
)
View Source
const (
	// SemVer is the semantic version of Oragono.
	SemVer = "0.5.0"
)

Variables

View Source
var (
	// EnabledSaslMechanisms contains the SASL mechanisms that exist and that we support.
	// This can be moved to some other data structure/place if we need to load/unload mechs later.
	EnabledSaslMechanisms = map[string]func(*Server, *Client, string, []byte) bool{
		"PLAIN":    authPlainHandler,
		"EXTERNAL": authExternalHandler,
	}

	// NoAccount is a placeholder which means that the user is not logged into an account.
	NoAccount = ClientAccount{
		Name: "*",
	}
)
View Source
var (
	TIMEOUT_STATED_SECONDS = strconv.Itoa(int((IDLE_TIMEOUT + QUIT_TIMEOUT).Seconds()))
	ErrNickAlreadySet      = errors.New("Nickname is already set")
)
View Source
var (
	ErrNickMissing      = errors.New("nick missing")
	ErrNicknameInUse    = errors.New("nickname in use")
	ErrNicknameMismatch = errors.New("nickname mismatch")
)
View Source
var (
	ChannelFounder  ChannelMode = 'q' // arg
	ChannelAdmin    ChannelMode = 'a' // arg
	ChannelOperator ChannelMode = 'o' // arg
	Halfop          ChannelMode = 'h' // arg
	Voice           ChannelMode = 'v' // arg

	SupportedChannelModes = ChannelModes{
		BanMask, ExceptMask, InviteMask, InviteOnly, Key, NoOutside,
		OpOnlyTopic, Secret, UserLimit, ChanRoleplaying,
	}

	DefaultChannelModes = ChannelModes{
		NoOutside, OpOnlyTopic,
	}

	// ChannelPrivModes holds the list of modes that are privileged, ie founder/op/halfop, in order.
	// voice is not in this list because it cannot perform channel operator actions.
	ChannelPrivModes = ChannelModes{
		ChannelFounder, ChannelAdmin, ChannelOperator, Halfop,
	}

	ChannelModePrefixes = map[ChannelMode]string{
		ChannelFounder:  "~",
		ChannelAdmin:    "&",
		ChannelOperator: "@",
		Halfop:          "%",
		Voice:           "+",
	}
)
View Source
var Commands = map[string]Command{
	"AMBIANCE": {
		// contains filtered or unexported fields
	},
	"AUTHENTICATE": {
		// contains filtered or unexported fields
	},
	"AWAY": {
		// contains filtered or unexported fields
	},
	"CAP": {
		// contains filtered or unexported fields
	},
	"DEBUG": {
		// contains filtered or unexported fields
	},
	"DLINE": {
		// contains filtered or unexported fields
	},
	"HELP": {
		// contains filtered or unexported fields
	},
	"INVITE": {
		// contains filtered or unexported fields
	},
	"ISON": {
		// contains filtered or unexported fields
	},
	"JOIN": {
		// contains filtered or unexported fields
	},
	"KICK": {
		// contains filtered or unexported fields
	},
	"KILL": {
		// contains filtered or unexported fields
	},
	"LIST": {
		// contains filtered or unexported fields
	},
	"MODE": {
		// contains filtered or unexported fields
	},
	"MONITOR": {
		// contains filtered or unexported fields
	},
	"MOTD": {
		// contains filtered or unexported fields
	},
	"NAMES": {
		// contains filtered or unexported fields
	},
	"NICK": {
		// contains filtered or unexported fields
	},
	"NOTICE": {
		// contains filtered or unexported fields
	},
	"NPC": {
		// contains filtered or unexported fields
	},
	"NPCA": {
		// contains filtered or unexported fields
	},
	"OPER": {
		// contains filtered or unexported fields
	},
	"PART": {
		// contains filtered or unexported fields
	},
	"PASS": {
		// contains filtered or unexported fields
	},
	"PING": {
		// contains filtered or unexported fields
	},
	"PONG": {
		// contains filtered or unexported fields
	},
	"PRIVMSG": {
		// contains filtered or unexported fields
	},
	"SANICK": {
		// contains filtered or unexported fields
	},
	"SCENE": {
		// contains filtered or unexported fields
	},
	"QUIT": {
		// contains filtered or unexported fields
	},
	"REG": {
		// contains filtered or unexported fields
	},
	"REHASH": {
		// contains filtered or unexported fields
	},
	"TIME": {
		// contains filtered or unexported fields
	},
	"TOPIC": {
		// contains filtered or unexported fields
	},
	"UNDLINE": {
		// contains filtered or unexported fields
	},
	"USER": {
		// contains filtered or unexported fields
	},
	"VERSION": {
		// contains filtered or unexported fields
	},
	"WHO": {
		// contains filtered or unexported fields
	},
	"WHOIS": {
		// contains filtered or unexported fields
	},
	"WHOWAS": {
		// contains filtered or unexported fields
	},
}

Commands holds all commands executable by a client connected to us.

View Source
var (
	// ErrEmptyPassword means that an empty password was given.
	ErrEmptyPassword = errors.New("empty password")
)
View Source
var Help = map[string]HelpEntry{

	"ambiance": {
		// contains filtered or unexported fields
	},
	"authenticate": {
		// contains filtered or unexported fields
	},
	"away": {
		// contains filtered or unexported fields
	},
	"cap": {
		// contains filtered or unexported fields
	},
	"debug": {
		// contains filtered or unexported fields
	},
	"dline": {
		// contains filtered or unexported fields
	},
	"help": {
		// contains filtered or unexported fields
	},
	"invite": {
		// contains filtered or unexported fields
	},
	"ison": {
		// contains filtered or unexported fields
	},
	"join": {
		// contains filtered or unexported fields
	},
	"kick": {
		// contains filtered or unexported fields
	},
	"kill": {
		// contains filtered or unexported fields
	},
	"list": {
		// contains filtered or unexported fields
	},
	"mode": {
		// contains filtered or unexported fields
	},
	"monitor": {
		// contains filtered or unexported fields
	},
	"motd": {
		// contains filtered or unexported fields
	},
	"names": {
		// contains filtered or unexported fields
	},
	"nick": {
		// contains filtered or unexported fields
	},
	"notice": {
		// contains filtered or unexported fields
	},
	"npc": {
		// contains filtered or unexported fields
	},
	"npca": {
		// contains filtered or unexported fields
	},
	"oper": {
		// contains filtered or unexported fields
	},
	"part": {
		// contains filtered or unexported fields
	},
	"pass": {
		// contains filtered or unexported fields
	},
	"ping": {
		// contains filtered or unexported fields
	},
	"pong": {
		// contains filtered or unexported fields
	},
	"privmsg": {
		// contains filtered or unexported fields
	},
	"sanick": {
		// contains filtered or unexported fields
	},
	"scene": {
		// contains filtered or unexported fields
	},
	"quit": {
		// contains filtered or unexported fields
	},
	"reg": {
		// contains filtered or unexported fields
	},
	"rehash": {
		// contains filtered or unexported fields
	},
	"time": {
		// contains filtered or unexported fields
	},
	"topic": {
		// contains filtered or unexported fields
	},
	"undline": {
		// contains filtered or unexported fields
	},
	"user": {
		// contains filtered or unexported fields
	},
	"version": {
		// contains filtered or unexported fields
	},
	"who": {
		// contains filtered or unexported fields
	},
	"whois": {
		// contains filtered or unexported fields
	},
	"whowas": {
		// contains filtered or unexported fields
	},

	"cmode": {
		// contains filtered or unexported fields
	},
	"cmodes": {
		// contains filtered or unexported fields
	},
	"umode": {
		// contains filtered or unexported fields
	},
	"umodes": {
		// contains filtered or unexported fields
	},

	"casemapping": {
		// contains filtered or unexported fields
	},
	"prefix": {
		// contains filtered or unexported fields
	},
}

Help contains the help strings distributed with the IRCd.

View Source
var (
	// Log is the default logger.
	Log = NewLogging("warn")
)
View Source
var (
	// ServerExitSignals are the signals the server will exit on.
	ServerExitSignals = []os.Signal{
		syscall.SIGINT,
		syscall.SIGTERM,
		syscall.SIGQUIT,
	}
)
View Source
var (
	SupportedUserModes = UserModes{
		Away, Invisible, Operator, UserRoleplaying,
	}
)
View Source
var (
	// Ver is the full version of Oragono, used in responses to clients.
	Ver = fmt.Sprintf("oragono-%s", SemVer)
)

Functions

func AddrLookupHostname

func AddrLookupHostname(addr net.Addr) string

AddrLookupHostname returns the hostname (if possible) or address for the given `net.Addr`.

func Casefold added in v0.2.0

func Casefold(str string) (string, error)

Casefold returns a casefolded string, without doing any name or channel character checks.

func CasefoldChannel added in v0.2.0

func CasefoldChannel(name string) (string, error)

CasefoldChannel returns a casefolded version of a channel name.

func CasefoldName added in v0.2.0

func CasefoldName(name string) (string, error)

CasefoldName returns a casefolded version of a nick/user name.

func ComparePassword

func ComparePassword(hash, password []byte) error

ComparePassword compares a given password with the given hash.

func DecodePasswordHash added in v0.2.0

func DecodePasswordHash(encoded string) (decoded []byte, err error)

DecodePasswordHash takes a base64-encoded password hash and returns the appropriate bytes.

func ExpandUserHost

func ExpandUserHost(userhost string) (expanded string)

func GenerateEncodedPassword

func GenerateEncodedPassword(passwd string) (encoded string, err error)

GenerateEncodedPassword returns an encrypted password, encoded into a string with base64.

func GetClientOnlyTags added in v0.2.0

func GetClientOnlyTags(tags map[string]ircmsg.TagValue) *map[string]ircmsg.TagValue

GetClientOnlyTags tags a tag map, and returns a map containing just the client-only tags from it.

func IPString

func IPString(addr net.Addr) string

func InitDB

func InitDB(path string)

InitDB creates the database.

func IsHostname

func IsHostname(name string) bool

IsHostname returns whether we consider `name` a valid hostname.

func LookupHostname

func LookupHostname(addr string) string

LookupHostname returns the hostname for `addr` if it has one. Otherwise, just returns `addr`.

func NewLogger

func NewLogger(on bool) *log.Logger

func NewSalt

func NewSalt() ([]byte, error)

NewSalt returns a salt for crypto uses.

func SplitChannelMembershipPrefixes added in v0.3.0

func SplitChannelMembershipPrefixes(target string) (prefixes string, name string)

SplitChannelMembershipPrefixes takes a target and returns the prefixes on it, then the name.

func UpgradeDB

func UpgradeDB(path string)

UpgradeDB upgrades the datastore to the latest schema.

Types

type AccountCredentials

type AccountCredentials struct {
	PassphraseSalt []byte
	PassphraseHash []byte
	Certificate    string // fingerprint
}

AccountCredentials stores the various methods for verifying accounts.

type AccountRegistration

type AccountRegistration struct {
	Enabled                bool
	EnabledCallbacks       []string
	EnabledCredentialTypes []string
}

AccountRegistration manages the registration of accounts.

func NewAccountRegistration

func NewAccountRegistration(config AccountRegistrationConfig) (accountReg AccountRegistration)

NewAccountRegistration returns a new AccountRegistration, configured correctly.

type AccountRegistrationConfig

type AccountRegistrationConfig struct {
	Enabled          bool
	EnabledCallbacks []string `yaml:"enabled-callbacks"`
	Callbacks        struct {
		Mailto struct {
			Server string
			Port   int
			TLS    struct {
				Enabled            bool
				InsecureSkipVerify bool   `yaml:"insecure_skip_verify"`
				ServerName         string `yaml:"servername"`
			}
			Username             string
			Password             string
			Sender               string
			VerifyMessageSubject string `yaml:"verify-message-subject"`
			VerifyMessage        string `yaml:"verify-message"`
		}
	}
}

type CapModifier

type CapModifier rune

CapModifiers are indicators showing the state of a capability after a REQ or ACK.

const (
	Ack     CapModifier = '~'
	Disable CapModifier = '-'
	Sticky  CapModifier = '='
)

func (CapModifier) String

func (mod CapModifier) String() string

type CapState

type CapState uint
const (
	CapNone        CapState = iota
	CapNegotiating CapState = iota
	CapNegotiated  CapState = iota
)

type CapVersion added in v0.2.0

type CapVersion uint

CapVersion is used to select which max version of CAP the client supports.

const (
	// Cap301 refers to the base CAP spec.
	Cap301 CapVersion = 301
	// Cap302 refers to the IRCv3.2 CAP spec.
	Cap302 CapVersion = 302
)

type Capability

type Capability string

Capabilities are optional features a client may request from a server.

const (
	AccountTag      Capability = "account-tag"
	AccountNotify   Capability = "account-notify"
	AwayNotify      Capability = "away-notify"
	CapNotify       Capability = "cap-notify"
	ChgHost         Capability = "chghost"
	EchoMessage     Capability = "echo-message"
	ExtendedJoin    Capability = "extended-join"
	InviteNotify    Capability = "invite-notify"
	MessageTags     Capability = "draft/message-tags"
	MultiPrefix     Capability = "multi-prefix"
	SASL            Capability = "sasl"
	ServerTime      Capability = "server-time"
	UserhostInNames Capability = "userhost-in-names"
)

func (Capability) String

func (capability Capability) String() string

type CapabilitySet

type CapabilitySet map[Capability]bool

CapabilitySet is used to track supported, enabled, and existing caps.

func (CapabilitySet) DisableString

func (set CapabilitySet) DisableString() string

func (CapabilitySet) String

func (set CapabilitySet) String(version CapVersion) string

type Channel

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

func NewChannel

func NewChannel(s *Server, name string, addDefaultModes bool) *Channel

NewChannel creates a new channel from a `Server` and a `name` string, which must be unique on the server.

func (*Channel) CanSpeak

func (channel *Channel) CanSpeak(client *Client) bool

func (*Channel) CheckKey

func (channel *Channel) CheckKey(key string) bool

func (*Channel) ClientIsAtLeast added in v0.3.0

func (channel *Channel) ClientIsAtLeast(client *Client, permission ChannelMode) bool

ClientIsAtLeast returns whether the client has at least the given channel privilege.

func (*Channel) GetTopic

func (channel *Channel) GetTopic(client *Client)

func (*Channel) Id

func (channel *Channel) Id() string

func (*Channel) Invite

func (channel *Channel) Invite(invitee *Client, inviter *Client)

func (*Channel) IsEmpty

func (channel *Channel) IsEmpty() bool

func (*Channel) IsFull

func (channel *Channel) IsFull() bool

func (*Channel) Join

func (channel *Channel) Join(client *Client, key string)

func (*Channel) Kick

func (channel *Channel) Kick(client *Client, target *Client, comment string)

func (*Channel) ModeString

func (channel *Channel) ModeString(client *Client) (str string)

<mode> <mode params>

func (*Channel) Names

func (channel *Channel) Names(client *Client)

func (*Channel) Nick

func (channel *Channel) Nick() string

func (*Channel) Nicks

func (channel *Channel) Nicks(target *Client) []string

func (*Channel) Notice

func (channel *Channel) Notice(minPrefix *ChannelMode, clientOnlyTags *map[string]ircmsg.TagValue, client *Client, message string)

Notice sends a private message to everyone in this channel.

func (*Channel) Part

func (channel *Channel) Part(client *Client, message string)

func (*Channel) PrivMsg

func (channel *Channel) PrivMsg(minPrefix *ChannelMode, clientOnlyTags *map[string]ircmsg.TagValue, client *Client, message string)

PrivMsg sends a private message to everyone in this channel.

func (*Channel) Quit

func (channel *Channel) Quit(client *Client)

func (*Channel) SetTopic

func (channel *Channel) SetTopic(client *Client, topic string)

func (*Channel) ShowMaskList

func (channel *Channel) ShowMaskList(client *Client, mode ChannelMode)

type ChannelMode

type ChannelMode rune

channel mode flags

const (
	BanMask         ChannelMode = 'b' // arg
	ChanRoleplaying ChannelMode = 'E' // flag
	ExceptMask      ChannelMode = 'e' // arg
	InviteMask      ChannelMode = 'I' // arg
	InviteOnly      ChannelMode = 'i' // flag
	Key             ChannelMode = 'k' // flag arg
	Moderated       ChannelMode = 'm' // flag
	NoOutside       ChannelMode = 'n' // flag
	OpOnlyTopic     ChannelMode = 't' // flag
	Secret          ChannelMode = 's' // flag
	UserLimit       ChannelMode = 'l' // flag arg
)

func GetLowestChannelModePrefix added in v0.3.0

func GetLowestChannelModePrefix(prefixes string) *ChannelMode

GetLowestChannelModePrefix returns the lowest channel prefix mode out of the given prefixes.

func (ChannelMode) String

func (mode ChannelMode) String() string

type ChannelModeChange

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

func (*ChannelModeChange) String

func (change *ChannelModeChange) String() (str string)

type ChannelModeChanges

type ChannelModeChanges []*ChannelModeChange

func (ChannelModeChanges) String

func (changes ChannelModeChanges) String() string

type ChannelModeCommand

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

type ChannelModeSet

type ChannelModeSet map[ChannelMode]bool

func (ChannelModeSet) Prefixes

func (modes ChannelModeSet) Prefixes(isMultiPrefix bool) string

Prefixes returns a list of prefixes for the given set of channel modes.

func (ChannelModeSet) String

func (set ChannelModeSet) String() string

type ChannelModes

type ChannelModes []ChannelMode

func (ChannelModes) String

func (modes ChannelModes) String() string

type ChannelNameMap

type ChannelNameMap map[string]*Channel

func (ChannelNameMap) Add

func (channels ChannelNameMap) Add(channel *Channel) error

func (ChannelNameMap) Get

func (channels ChannelNameMap) Get(name string) *Channel

func (ChannelNameMap) Remove

func (channels ChannelNameMap) Remove(channel *Channel) error

type ChannelSet

type ChannelSet map[*Channel]bool

func (ChannelSet) Add

func (channels ChannelSet) Add(channel *Channel)

func (ChannelSet) First

func (channels ChannelSet) First() *Channel

func (ChannelSet) Remove

func (channels ChannelSet) Remove(channel *Channel)

type Client

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

Client is an IRC client.

func NewClient

func NewClient(server *Server, conn net.Conn, isTLS bool) *Client

NewClient returns a client with all the appropriate info setup.

func (*Client) Active

func (client *Client) Active()

Active marks the client as 'active' (i.e. the user should be there).

func (*Client) ChangeNickname

func (client *Client) ChangeNickname(nickname string) error

ChangeNickname changes the existing nickname of the client.

func (*Client) Friends

func (client *Client) Friends(Capabilities ...Capability) ClientSet

Friends refers to clients that share a channel with this client.

func (*Client) HasCapabs added in v0.4.0

func (client *Client) HasCapabs(capabs ...string) bool

HasCapabs returns true if client has the given (role) capabilities.

func (*Client) HasNick

func (client *Client) HasNick() bool

HasNick returns true if the client's nickname is set (used in registration).

func (*Client) HasUsername

func (client *Client) HasUsername() bool

HasNick returns true if the client's username is set (used in registration).

func (*Client) Idle

func (client *Client) Idle()

Idle resets the timeout handlers and sends the client a PING.

func (*Client) IdleSeconds

func (client *Client) IdleSeconds() uint64

IdleSeconds returns the number of seconds this client's been idle.

func (*Client) IdleTime

func (client *Client) IdleTime() time.Duration

IdleTime returns how long this client's been idle.

func (*Client) ModeString

func (c *Client) ModeString() (str string)

<mode>

func (*Client) Notice

func (client *Client) Notice(text string)

Notice sends the client a notice from the server.

func (*Client) Quit

func (client *Client) Quit(message string)

func (*Client) Register

func (client *Client) Register()

Register sets the client details as appropriate when entering the network.

func (*Client) RplISupport

func (client *Client) RplISupport()

RplISupport outputs our ISUPPORT lines to the client. This is used on connection and in VERSION responses.

func (*Client) RplList

func (target *Client) RplList(channel *Channel)

func (*Client) RplWhoReply

func (target *Client) RplWhoReply(channel *Channel, client *Client)

<channel> <user> <host> <server> <nick> ( "H" / "G" ) ["*"] [ ( "@" / "+" ) ] :<hopcount> <real name>

func (*Client) Send

func (client *Client) Send(tags *map[string]ircmsg.TagValue, prefix string, command string, params ...string) error

Send sends an IRC line to the client.

func (*Client) SendFromClient

func (client *Client) SendFromClient(from *Client, tags *map[string]ircmsg.TagValue, prefix string, command string, params ...string) error

SendFromClient sends an IRC line coming from a specific client. Adds account-tag to the line as well.

func (*Client) SetNickname

func (client *Client) SetNickname(nickname string) error

SetNickname sets the very first nickname for the client.

func (*Client) SignonTime

func (client *Client) SignonTime() int64

SignonTime returns this client's signon time as a unix timestamp.

func (*Client) Touch

func (client *Client) Touch()

Touch marks the client as alive.

func (*Client) WhoisChannelsNames

func (client *Client) WhoisChannelsNames(target *Client) []string

type ClientAccount

type ClientAccount struct {
	// Name of the account.
	Name string
	// RegisteredAt represents the time that the account was registered.
	RegisteredAt time.Time
	// Clients that are currently logged into this account (useful for notifications).
	Clients []*Client
}

ClientAccount represents a user account.

type ClientLookupSet

type ClientLookupSet struct {
	ByNickMutex sync.Mutex
	ByNick      map[string]*Client
}

func NewClientLookupSet

func NewClientLookupSet() *ClientLookupSet

func (*ClientLookupSet) Add

func (clients *ClientLookupSet) Add(client *Client, nick string) error

func (*ClientLookupSet) AllWithCaps added in v0.3.0

func (clients *ClientLookupSet) AllWithCaps(caps ...Capability) (set ClientSet)

func (*ClientLookupSet) Count added in v0.5.0

func (clients *ClientLookupSet) Count() int

func (*ClientLookupSet) Find

func (clients *ClientLookupSet) Find(userhost string) *Client

func (*ClientLookupSet) FindAll

func (clients *ClientLookupSet) FindAll(userhost string) (set ClientSet)

func (*ClientLookupSet) Get

func (clients *ClientLookupSet) Get(nick string) *Client

func (*ClientLookupSet) Has added in v0.2.0

func (clients *ClientLookupSet) Has(nick string) bool

TODO(dan): wouldn't it be best to always use Get rather than this?

func (*ClientLookupSet) Remove

func (clients *ClientLookupSet) Remove(client *Client) error

func (*ClientLookupSet) Replace added in v0.5.0

func (clients *ClientLookupSet) Replace(oldNick, newNick string, client *Client) error

type ClientSet

type ClientSet map[*Client]bool

func (ClientSet) Add

func (clients ClientSet) Add(client *Client)

func (ClientSet) Has

func (clients ClientSet) Has(client *Client) bool

func (ClientSet) Remove

func (clients ClientSet) Remove(client *Client)

type ClientSocket

type ClientSocket struct {
	ReceiveEvents chan Message
	SendLines     chan string
	// contains filtered or unexported fields
}

ClientSocket listens to a socket using the IRC protocol, processes events, and also sends IRC lines out of that socket.

func NewClientSocket

func NewClientSocket(conn net.Conn, client Client) ClientSocket

NewClientSocket returns a new ClientSocket.

func (*ClientSocket) RunEvents

func (cs *ClientSocket) RunEvents()

RunEvents handles received IRC lines and processes incoming commands.

func (*ClientSocket) RunSocketListener

func (cs *ClientSocket) RunSocketListener()

RunSocketListener receives lines from the IRC socket.

func (*ClientSocket) RunSocketSender

func (cs *ClientSocket) RunSocketSender()

RunSocketSender sends lines to the IRC socket.

func (*ClientSocket) Send

func (cs *ClientSocket) Send(tags *map[string]ircmsg.TagValue, prefix string, command string, params ...string) error

Send sends an IRC line to the listener.

func (*ClientSocket) Start

func (cs *ClientSocket) Start()

Start creates and starts running the necessary event loops.

type Command

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

Command represents a command accepted from a client.

func (*Command) Run

func (cmd *Command) Run(server *Server, client *Client, msg ircmsg.IrcMessage) bool

Run runs this command with the given client/message.

type Config

type Config struct {
	Network struct {
		Name string
	}

	Server struct {
		PassConfig
		Password         string
		Name             string
		Listen           []string
		Wslisten         string                      `yaml:"ws-listen"`
		TLSListeners     map[string]*TLSListenConfig `yaml:"tls-listeners"`
		RestAPI          RestAPIConfig               `yaml:"rest-api"`
		CheckIdent       bool                        `yaml:"check-ident"`
		Log              string
		MOTD             string
		ConnectionLimits ConnectionLimitsConfig `yaml:"connection-limits"`
	}

	Datastore struct {
		Path string
	}

	AuthenticationEnabled bool `yaml:"authentication-enabled"`

	Registration struct {
		Accounts AccountRegistrationConfig
	}

	OperClasses map[string]*OperClassConfig `yaml:"oper-classes"`

	Opers map[string]*OperConfig

	Limits struct {
		NickLen        uint `yaml:"nicklen"`
		ChannelLen     uint `yaml:"channellen"`
		AwayLen        uint `yaml:"awaylen"`
		KickLen        uint `yaml:"kicklen"`
		TopicLen       uint `yaml:"topiclen"`
		WhowasEntries  uint `yaml:"whowas-entries"`
		MonitorEntries uint `yaml:"monitor-entries"`
		ChanListModes  uint `yaml:"chan-list-modes"`
	}
}

func LoadConfig

func LoadConfig(filename string) (config *Config, err error)

func (*Config) OperatorClasses added in v0.4.0

func (conf *Config) OperatorClasses() (*map[string]OperClass, error)

func (*Config) Operators

func (conf *Config) Operators(oc *map[string]OperClass) (map[string]Oper, error)

func (*Config) TLSListeners

func (conf *Config) TLSListeners() map[string]*tls.Config

type ConnectionLimits added in v0.4.0

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

ConnectionLimits manages the automated client connection limits.

func NewConnectionLimits added in v0.4.0

func NewConnectionLimits(config ConnectionLimitsConfig) (*ConnectionLimits, error)

NewConnectionLimits returns a new connection limit handler.

func (*ConnectionLimits) AddClient added in v0.4.0

func (cl *ConnectionLimits) AddClient(addr net.IP, force bool) error

AddClient adds a client to our population if possible. If we can't, throws an error instead. 'force' is used to add already-existing clients (i.e. ones that are already on the network).

func (*ConnectionLimits) RemoveClient added in v0.4.0

func (cl *ConnectionLimits) RemoveClient(addr net.IP)

RemoveClient removes the given address from our population

type ConnectionLimitsConfig added in v0.4.0

type ConnectionLimitsConfig struct {
	CidrLenIPv4 int `yaml:"cidr-len-ipv4"`
	CidrLenIPv6 int `yaml:"cidr-len-ipv6"`
	IPsPerCidr  int `yaml:"ips-per-subnet"`
	Exempted    []string
}

type DLineManager added in v0.5.0

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

DLineManager manages and dlines.

func NewDLineManager added in v0.5.0

func NewDLineManager() *DLineManager

NewDLineManager returns a new DLineManager.

func (*DLineManager) AddIP added in v0.5.0

func (dm *DLineManager) AddIP(addr net.IP, length *IPRestrictTime, reason string, operReason string)

AddIP adds an IP address to the blocked list.

func (*DLineManager) AddNetwork added in v0.5.0

func (dm *DLineManager) AddNetwork(network net.IPNet, length *IPRestrictTime, reason string, operReason string)

AddNetwork adds a network to the blocked list.

func (*DLineManager) AllBans added in v0.5.0

func (dm *DLineManager) AllBans() map[string]IPBanInfo

AllBans returns all bans (for use with APIs, etc).

func (*DLineManager) CheckIP added in v0.5.0

func (dm *DLineManager) CheckIP(addr net.IP) (isBanned bool, info *IPBanInfo)

CheckIP returns whether or not an IP address was banned, and how long it is banned for.

func (*DLineManager) RemoveIP added in v0.5.0

func (dm *DLineManager) RemoveIP(addr net.IP)

RemoveIP removes an IP from the blocked list.

func (*DLineManager) RemoveNetwork added in v0.5.0

func (dm *DLineManager) RemoveNetwork(network net.IPNet)

RemoveNetwork removes a network from the blocked list.

type HelpEntry added in v0.2.0

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

HelpEntry represents an entry in the Help map.

type IPBanInfo added in v0.5.0

type IPBanInfo struct {
	// Reason is the ban reason.
	Reason string
	// OperReason is an oper ban reason.
	OperReason string `json:"oper_reason"`
	// Time holds details about the duration, if it exists.
	Time *IPRestrictTime
}

IPBanInfo holds info about an IP/net ban.

type IPRestrictTime added in v0.5.0

type IPRestrictTime struct {
	// Duration is how long this block lasts for.
	Duration time.Duration
	// Expires is when this block expires.
	Expires time.Time
}

IPRestrictTime contains the expiration info about the given IP.

func (*IPRestrictTime) IsExpired added in v0.5.0

func (iptime *IPRestrictTime) IsExpired() bool

IsExpired returns true if the time has expired.

type ISupportList

type ISupportList struct {
	Tokens      map[string]*string
	CachedReply [][]string
}

ISupportList holds a list of ISUPPORT tokens

func NewISupportList

func NewISupportList() *ISupportList

NewISupportList returns a new ISupportList

func (*ISupportList) Add

func (il *ISupportList) Add(name string, value string)

Add adds an RPL_ISUPPORT token to our internal list

func (*ISupportList) AddNoValue

func (il *ISupportList) AddNoValue(name string)

AddNoValue adds an RPL_ISUPPORT token that does not have a value

func (*ISupportList) GetDifference added in v0.3.0

func (il *ISupportList) GetDifference(newil *ISupportList) [][]string

GetDifference returns the difference between two token lists.

func (*ISupportList) RegenerateCachedReply

func (il *ISupportList) RegenerateCachedReply()

RegenerateCachedReply regenerates the cached RPL_ISUPPORT reply

type Identifiable

type Identifiable interface {
	Id() string
	Nick() string
}

type Limits

type Limits struct {
	AwayLen        int
	ChannelLen     int
	KickLen        int
	MonitorEntries int
	NickLen        int
	TopicLen       int
	ChanListModes  int
}

Limits holds the maximum limits for various things such as topic lengths

type ListenerEvent added in v0.3.0

type ListenerEvent struct {
	Type      ListenerEventType
	NewConfig *tls.Config
}

ListenerEvent is an event that's passed to the listener.

type ListenerEventType added in v0.3.0

type ListenerEventType int

ListenerEventType is the type of event this is.

const (
	// DestroyListener instructs the listener to destroy itself.
	DestroyListener ListenerEventType = iota
	// UpdateListener instructs the listener to update itself (grab new certs, etc).
	UpdateListener = iota
)

type ListenerInterface added in v0.3.0

type ListenerInterface struct {
	Listener net.Listener
	Events   chan ListenerEvent
}

ListenerInterface represents an interface for a listener.

type Logging

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

func NewLogging

func NewLogging(level string) *Logging

func (*Logging) SetLevel

func (logging *Logging) SetLevel(level string)

type MemberSet

type MemberSet map[*Client]ChannelModeSet

func (MemberSet) Add

func (members MemberSet) Add(member *Client)

func (MemberSet) AnyHasMode

func (members MemberSet) AnyHasMode(mode ChannelMode) bool

func (MemberSet) Has

func (members MemberSet) Has(member *Client) bool

func (MemberSet) HasMode

func (members MemberSet) HasMode(member *Client, mode ChannelMode) bool

func (MemberSet) Remove

func (members MemberSet) Remove(member *Client)

type Message

type Message struct {
	Type MessageType
	Verb MessageVerb
	Info map[MessageInfoKey]interface{}
}

Message represents an internal message passed by oragono.

func NewMessage

func NewMessage(mt MessageType, mv MessageVerb) Message

NewMessage returns a new Message. This is purely a convenience function.

type MessageInfoKey

type MessageInfoKey int

MessageInfoKey represents a key in the Info attribute of a Message.

const (
	// LineIK represents an IRC line message info key
	LineIK MessageInfoKey = iota
)

type MessageType

type MessageType int

MessageType represents the type of message it is.

const (
	// LineMT represents an IRC line Message Type
	LineMT MessageType = iota
)

type MessageVerb

type MessageVerb int

MessageVerb represents the verb (i.e. the specific command, etc) of a message.

const (
	// NoMV represents no Message Verb
	NoMV MessageVerb = iota
)

type ModeChange

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

func (*ModeChange) String

func (change *ModeChange) String() string

type ModeChanges

type ModeChanges []*ModeChange

func (ModeChanges) String

func (changes ModeChanges) String() string

type ModeOp

type ModeOp rune
const (
	Add    ModeOp = '+'
	List   ModeOp = '='
	Remove ModeOp = '-'
)

func (ModeOp) String

func (op ModeOp) String() string

type Oper added in v0.4.0

type Oper struct {
	Class     *OperClass
	WhoisLine string
	Vhost     string
	Pass      []byte
}

type OperClass added in v0.4.0

type OperClass struct {
	Title        string
	WhoisLine    string          `yaml:"whois-line"`
	Capabilities map[string]bool // map to make lookups much easier
}

type OperClassConfig added in v0.4.0

type OperClassConfig struct {
	Title        string
	WhoisLine    string
	Extends      string
	Capabilities []string
}

type OperConfig added in v0.4.0

type OperConfig struct {
	Class     string
	Vhost     string
	WhoisLine string `yaml:"whois-line"`
	Password  string
}

func (*OperConfig) PasswordBytes added in v0.4.0

func (conf *OperConfig) PasswordBytes() []byte

type PassConfig

type PassConfig struct {
	Password string
}

func (*PassConfig) PasswordBytes

func (conf *PassConfig) PasswordBytes() []byte

type PasswordManager

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

PasswordManager supports the hashing and comparing of passwords with the given salt.

func NewPasswordManager

func NewPasswordManager(salt []byte) PasswordManager

NewPasswordManager returns a new PasswordManager with the given salt.

func (*PasswordManager) CompareHashAndPassword

func (pwm *PasswordManager) CompareHashAndPassword(hashedPassword []byte, specialSalt []byte, password string) error

CompareHashAndPassword compares a hashed password with its possible plaintext equivalent. Returns nil on success, or an error on failure.

func (*PasswordManager) GenerateFromPassword

func (pwm *PasswordManager) GenerateFromPassword(specialSalt []byte, password string) ([]byte, error)

GenerateFromPassword encrypts the given password.

type RestAPIConfig added in v0.5.0

type RestAPIConfig struct {
	Enabled bool
	Listen  string
}

type Server

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

Server is the main Oragono server.

func NewServer

func NewServer(configFilename string, config *Config) *Server

NewServer returns a new Oragono server.

func (*Server) Id

func (server *Server) Id() string

func (*Server) MOTD

func (server *Server) MOTD(client *Client)

func (*Server) Nick

func (server *Server) Nick() string

func (*Server) Run

func (server *Server) Run()

Run starts the server.

func (*Server) Shutdown

func (server *Server) Shutdown()

type Socket

type Socket struct {
	Closed bool
	// contains filtered or unexported fields
}

Socket represents an IRC socket.

func NewSocket

func NewSocket(conn net.Conn) Socket

NewSocket returns a new Socket.

func (*Socket) CertFP

func (socket *Socket) CertFP() (string, error)

CertFP returns the fingerprint of the certificate provided by the client.

func (*Socket) Close

func (socket *Socket) Close()

Close stops a Socket from being able to send/receive any more data.

func (*Socket) Read

func (socket *Socket) Read() (string, error)

Read returns a single IRC line from a Socket.

func (*Socket) Write

func (socket *Socket) Write(data string) error

Write sends the given string out of Socket.

func (*Socket) WriteLine

func (socket *Socket) WriteLine(line string) error

WriteLine writes the given line out of Socket.

type TLSListenConfig

type TLSListenConfig struct {
	Cert string
	Key  string
}

TLSListenConfig defines configuration options for listening on TLS

func (*TLSListenConfig) Config

func (conf *TLSListenConfig) Config() (*tls.Config, error)

Certificate returns the TLS certificate assicated with this TLSListenConfig

type UserMaskSet

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

TODO(dan): move this over to generally using glob syntax instead? kinda more expected in normal ban/etc masks, though regex is useful (probably as an extban?)

func NewUserMaskSet

func NewUserMaskSet() *UserMaskSet

func (*UserMaskSet) Add

func (set *UserMaskSet) Add(mask string) bool

func (*UserMaskSet) AddAll

func (set *UserMaskSet) AddAll(masks []string) (added bool)

func (*UserMaskSet) Match

func (set *UserMaskSet) Match(userhost string) bool

func (*UserMaskSet) Remove

func (set *UserMaskSet) Remove(mask string) bool

func (*UserMaskSet) String

func (set *UserMaskSet) String() string

type UserMode

type UserMode rune

user mode flags

const (
	Away            UserMode = 'a'
	Invisible       UserMode = 'i'
	LocalOperator   UserMode = 'O'
	Operator        UserMode = 'o'
	Restricted      UserMode = 'r'
	ServerNotice    UserMode = 's' // deprecated
	TLS             UserMode = 'Z'
	UserRoleplaying UserMode = 'E'
	WallOps         UserMode = 'w'
)

func (UserMode) String

func (mode UserMode) String() string

type UserModes

type UserModes []UserMode

func (UserModes) String

func (modes UserModes) String() string

type WSContainer

type WSContainer struct {
	*websocket.Conn
}

func (WSContainer) Read

func (this WSContainer) Read(msg []byte) (int, error)

func (WSContainer) SetDeadline

func (this WSContainer) SetDeadline(t time.Time) error

func (WSContainer) Write

func (this WSContainer) Write(msg []byte) (int, error)

type WhoWas

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

type WhoWasList

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

func NewWhoWasList

func NewWhoWasList(size uint) *WhoWasList

func (*WhoWasList) Append

func (list *WhoWasList) Append(client *Client)

func (*WhoWasList) Each

func (list *WhoWasList) Each() <-chan *WhoWas

Iterate the buffer in reverse.

func (*WhoWasList) Find

func (list *WhoWasList) Find(nickname string, limit int64) []*WhoWas

Jump to

Keyboard shortcuts

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