You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

server.go 69KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280
  1. // Copyright (c) 2012-2014 Jeremy Latt
  2. // Copyright (c) 2014-2015 Edmund Huber
  3. // Copyright (c) 2016-2017 Daniel Oaks <daniel@danieloaks.net>
  4. // released under the MIT license
  5. package irc
  6. import (
  7. "bufio"
  8. "crypto/tls"
  9. "encoding/base64"
  10. "errors"
  11. "fmt"
  12. "log"
  13. "math/rand"
  14. "net"
  15. "os"
  16. "os/signal"
  17. "strconv"
  18. "strings"
  19. "sync"
  20. "syscall"
  21. "time"
  22. "github.com/goshuirc/irc-go/ircfmt"
  23. "github.com/goshuirc/irc-go/ircmsg"
  24. "github.com/oragono/oragono/irc/caps"
  25. "github.com/oragono/oragono/irc/connection_limits"
  26. "github.com/oragono/oragono/irc/isupport"
  27. "github.com/oragono/oragono/irc/logger"
  28. "github.com/oragono/oragono/irc/passwd"
  29. "github.com/oragono/oragono/irc/sno"
  30. "github.com/oragono/oragono/irc/utils"
  31. "github.com/tidwall/buntdb"
  32. )
  33. var (
  34. // common error line to sub values into
  35. errorMsg, _ = (&[]ircmsg.IrcMessage{ircmsg.MakeMessage(nil, "", "ERROR", "%s ")}[0]).Line()
  36. // common error responses
  37. couldNotParseIPMsg, _ = (&[]ircmsg.IrcMessage{ircmsg.MakeMessage(nil, "", "ERROR", "Unable to parse your IP address")}[0]).Line()
  38. RenamePrivsNeeded = errors.New("Only chanops can rename channels")
  39. )
  40. // Limits holds the maximum limits for various things such as topic lengths.
  41. type Limits struct {
  42. AwayLen int
  43. ChannelLen int
  44. KickLen int
  45. MonitorEntries int
  46. NickLen int
  47. TopicLen int
  48. ChanListModes int
  49. LineLen LineLenLimits
  50. }
  51. // LineLenLimits holds the maximum limits for IRC lines.
  52. type LineLenLimits struct {
  53. Tags int
  54. Rest int
  55. }
  56. // ListenerWrapper wraps a listener so it can be safely reconfigured or stopped
  57. type ListenerWrapper struct {
  58. listener net.Listener
  59. tlsConfig *tls.Config
  60. shouldStop bool
  61. // lets the ListenerWrapper inform the server that it has stopped:
  62. stopEvent chan bool
  63. // protects atomic update of tlsConfig and shouldStop:
  64. configMutex sync.Mutex // tier 1
  65. }
  66. // Server is the main Oragono server.
  67. type Server struct {
  68. accountAuthenticationEnabled bool
  69. accountRegistration *AccountRegistration
  70. accounts map[string]*ClientAccount
  71. channelRegistrationEnabled bool
  72. channels *ChannelManager
  73. channelRegistry *ChannelRegistry
  74. checkIdent bool
  75. clients *ClientManager
  76. commands chan Command
  77. configFilename string
  78. configurableStateMutex sync.RWMutex // tier 1; generic protection for server state modified by rehash()
  79. connectionLimiter *connection_limits.Limiter
  80. connectionThrottler *connection_limits.Throttler
  81. ctime time.Time
  82. defaultChannelModes Modes
  83. dlines *DLineManager
  84. loggingRawIO bool
  85. isupport *isupport.List
  86. klines *KLineManager
  87. languages *LanguageManager
  88. limits Limits
  89. listeners map[string]*ListenerWrapper
  90. logger *logger.Manager
  91. MaxSendQBytes uint64
  92. monitorManager *MonitorManager
  93. motdLines []string
  94. name string
  95. nameCasefolded string
  96. networkName string
  97. newConns chan clientConn
  98. operators map[string]Oper
  99. operclasses map[string]OperClass
  100. password []byte
  101. passwords *passwd.SaltedManager
  102. recoverFromErrors bool
  103. rehashMutex sync.Mutex // tier 3
  104. rehashSignal chan os.Signal
  105. proxyAllowedFrom []string
  106. signals chan os.Signal
  107. snomasks *SnoManager
  108. store *buntdb.DB
  109. stsEnabled bool
  110. webirc []webircConfig
  111. whoWas *WhoWasList
  112. }
  113. var (
  114. // ServerExitSignals are the signals the server will exit on.
  115. ServerExitSignals = []os.Signal{
  116. syscall.SIGINT,
  117. syscall.SIGTERM,
  118. syscall.SIGQUIT,
  119. }
  120. )
  121. type clientConn struct {
  122. Conn net.Conn
  123. IsTLS bool
  124. }
  125. // NewServer returns a new Oragono server.
  126. func NewServer(config *Config, logger *logger.Manager) (*Server, error) {
  127. // TODO move this to main?
  128. if err := GenerateHelpIndices(); err != nil {
  129. return nil, err
  130. }
  131. // initialize data structures
  132. server := &Server{
  133. accounts: make(map[string]*ClientAccount),
  134. channels: NewChannelManager(),
  135. clients: NewClientManager(),
  136. commands: make(chan Command),
  137. connectionLimiter: connection_limits.NewLimiter(),
  138. connectionThrottler: connection_limits.NewThrottler(),
  139. languages: NewLanguageManager(config.Languages.Data),
  140. listeners: make(map[string]*ListenerWrapper),
  141. logger: logger,
  142. monitorManager: NewMonitorManager(),
  143. newConns: make(chan clientConn),
  144. rehashSignal: make(chan os.Signal, 1),
  145. signals: make(chan os.Signal, len(ServerExitSignals)),
  146. snomasks: NewSnoManager(),
  147. whoWas: NewWhoWasList(config.Limits.WhowasEntries),
  148. }
  149. if err := server.applyConfig(config, true); err != nil {
  150. return nil, err
  151. }
  152. // Attempt to clean up when receiving these signals.
  153. signal.Notify(server.signals, ServerExitSignals...)
  154. signal.Notify(server.rehashSignal, syscall.SIGHUP)
  155. return server, nil
  156. }
  157. // setISupport sets up our RPL_ISUPPORT reply.
  158. func (server *Server) setISupport() {
  159. maxTargetsString := strconv.Itoa(maxTargets)
  160. server.configurableStateMutex.RLock()
  161. // add RPL_ISUPPORT tokens
  162. isupport := isupport.NewList()
  163. isupport.Add("AWAYLEN", strconv.Itoa(server.limits.AwayLen))
  164. isupport.Add("CASEMAPPING", "ascii")
  165. isupport.Add("CHANMODES", strings.Join([]string{Modes{BanMask, ExceptMask, InviteMask}.String(), "", Modes{UserLimit, Key}.String(), Modes{InviteOnly, Moderated, NoOutside, OpOnlyTopic, ChanRoleplaying, Secret}.String()}, ","))
  166. isupport.Add("CHANNELLEN", strconv.Itoa(server.limits.ChannelLen))
  167. isupport.Add("CHANTYPES", "#")
  168. isupport.Add("ELIST", "U")
  169. isupport.Add("EXCEPTS", "")
  170. isupport.Add("INVEX", "")
  171. isupport.Add("KICKLEN", strconv.Itoa(server.limits.KickLen))
  172. isupport.Add("MAXLIST", fmt.Sprintf("beI:%s", strconv.Itoa(server.limits.ChanListModes)))
  173. isupport.Add("MAXTARGETS", maxTargetsString)
  174. isupport.Add("MODES", "")
  175. isupport.Add("MONITOR", strconv.Itoa(server.limits.MonitorEntries))
  176. isupport.Add("NETWORK", server.networkName)
  177. isupport.Add("NICKLEN", strconv.Itoa(server.limits.NickLen))
  178. isupport.Add("PREFIX", "(qaohv)~&@%+")
  179. isupport.Add("RPCHAN", "E")
  180. isupport.Add("RPUSER", "E")
  181. isupport.Add("STATUSMSG", "~&@%+")
  182. isupport.Add("TARGMAX", fmt.Sprintf("NAMES:1,LIST:1,KICK:1,WHOIS:1,USERHOST:10,PRIVMSG:%s,TAGMSG:%s,NOTICE:%s,MONITOR:", maxTargetsString, maxTargetsString, maxTargetsString))
  183. isupport.Add("TOPICLEN", strconv.Itoa(server.limits.TopicLen))
  184. isupport.Add("UTF8MAPPING", casemappingName)
  185. // account registration
  186. if server.accountRegistration.Enabled {
  187. // 'none' isn't shown in the REGCALLBACKS vars
  188. var enabledCallbacks []string
  189. for _, name := range server.accountRegistration.EnabledCallbacks {
  190. if name != "*" {
  191. enabledCallbacks = append(enabledCallbacks, name)
  192. }
  193. }
  194. isupport.Add("REGCOMMANDS", "CREATE,VERIFY")
  195. isupport.Add("REGCALLBACKS", strings.Join(enabledCallbacks, ","))
  196. isupport.Add("REGCREDTYPES", "passphrase,certfp")
  197. }
  198. server.configurableStateMutex.RUnlock()
  199. isupport.RegenerateCachedReply()
  200. server.configurableStateMutex.Lock()
  201. server.isupport = isupport
  202. server.configurableStateMutex.Unlock()
  203. }
  204. func loadChannelList(channel *Channel, list string, maskMode Mode) {
  205. if list == "" {
  206. return
  207. }
  208. channel.lists[maskMode].AddAll(strings.Split(list, " "))
  209. }
  210. // Shutdown shuts down the server.
  211. func (server *Server) Shutdown() {
  212. //TODO(dan): Make sure we disallow new nicks
  213. for _, client := range server.clients.AllClients() {
  214. client.Notice("Server is shutting down")
  215. }
  216. if err := server.store.Close(); err != nil {
  217. server.logger.Error("shutdown", fmt.Sprintln("Could not close datastore:", err))
  218. }
  219. }
  220. // Run starts the server.
  221. func (server *Server) Run() {
  222. // defer closing db/store
  223. defer server.store.Close()
  224. done := false
  225. for !done {
  226. select {
  227. case <-server.signals:
  228. server.Shutdown()
  229. done = true
  230. case <-server.rehashSignal:
  231. server.logger.Info("rehash", "Rehashing due to SIGHUP")
  232. go func() {
  233. err := server.rehash()
  234. if err != nil {
  235. server.logger.Error("rehash", fmt.Sprintln("Failed to rehash:", err.Error()))
  236. }
  237. }()
  238. case conn := <-server.newConns:
  239. // check IP address
  240. ipaddr := net.ParseIP(utils.IPString(conn.Conn.RemoteAddr()))
  241. if ipaddr == nil {
  242. conn.Conn.Write([]byte(couldNotParseIPMsg))
  243. conn.Conn.Close()
  244. continue
  245. }
  246. isBanned, banMsg := server.checkBans(ipaddr)
  247. if isBanned {
  248. // this might not show up properly on some clients, but our objective here is just to close the connection out before it has a load impact on us
  249. conn.Conn.Write([]byte(fmt.Sprintf(errorMsg, banMsg)))
  250. conn.Conn.Close()
  251. continue
  252. }
  253. server.logger.Debug("localconnect-ip", fmt.Sprintf("Client connecting from %v", ipaddr))
  254. // prolly don't need to alert snomasks on this, only on connection reg
  255. go NewClient(server, conn.Conn, conn.IsTLS)
  256. continue
  257. }
  258. }
  259. }
  260. func (server *Server) checkBans(ipaddr net.IP) (banned bool, message string) {
  261. // check DLINEs
  262. isBanned, info := server.dlines.CheckIP(ipaddr)
  263. if isBanned {
  264. server.logger.Info("localconnect-ip", fmt.Sprintf("Client from %v rejected by d-line", ipaddr))
  265. return true, info.BanMessage("You are banned from this server (%s)")
  266. }
  267. // check connection limits
  268. err := server.connectionLimiter.AddClient(ipaddr, false)
  269. if err != nil {
  270. // too many connections from one client, tell the client and close the connection
  271. server.logger.Info("localconnect-ip", fmt.Sprintf("Client from %v rejected for connection limit", ipaddr))
  272. return true, "Too many clients from your network"
  273. }
  274. // check connection throttle
  275. err = server.connectionThrottler.AddClient(ipaddr)
  276. if err != nil {
  277. // too many connections too quickly from client, tell them and close the connection
  278. duration := server.connectionThrottler.BanDuration()
  279. length := &IPRestrictTime{
  280. Duration: duration,
  281. Expires: time.Now().Add(duration),
  282. }
  283. server.dlines.AddIP(ipaddr, length, server.connectionThrottler.BanMessage(), "Exceeded automated connection throttle", "auto.connection.throttler")
  284. // they're DLINE'd for 15 minutes or whatever, so we can reset the connection throttle now,
  285. // and once their temporary DLINE is finished they can fill up the throttler again
  286. server.connectionThrottler.ResetFor(ipaddr)
  287. // this might not show up properly on some clients, but our objective here is just to close it out before it has a load impact on us
  288. server.logger.Info(
  289. "localconnect-ip",
  290. fmt.Sprintf("Client from %v exceeded connection throttle, d-lining for %v", ipaddr, duration))
  291. return true, server.connectionThrottler.BanMessage()
  292. }
  293. return false, ""
  294. }
  295. //
  296. // IRC protocol listeners
  297. //
  298. // createListener starts the given listeners.
  299. func (server *Server) createListener(addr string, tlsConfig *tls.Config) *ListenerWrapper {
  300. // make listener
  301. listener, err := net.Listen("tcp", addr)
  302. if err != nil {
  303. log.Fatal(server, "listen error: ", err)
  304. }
  305. // throw our details to the server so we can be modified/killed later
  306. wrapper := ListenerWrapper{
  307. listener: listener,
  308. tlsConfig: tlsConfig,
  309. shouldStop: false,
  310. stopEvent: make(chan bool, 1),
  311. }
  312. var shouldStop bool
  313. // setup accept goroutine
  314. go func() {
  315. for {
  316. conn, err := listener.Accept()
  317. // synchronously access config data:
  318. // whether TLS is enabled and whether we should stop listening
  319. wrapper.configMutex.Lock()
  320. shouldStop = wrapper.shouldStop
  321. tlsConfig = wrapper.tlsConfig
  322. wrapper.configMutex.Unlock()
  323. if err == nil {
  324. if tlsConfig != nil {
  325. conn = tls.Server(conn, tlsConfig)
  326. }
  327. newConn := clientConn{
  328. Conn: conn,
  329. IsTLS: tlsConfig != nil,
  330. }
  331. // hand off the connection
  332. server.newConns <- newConn
  333. }
  334. if shouldStop {
  335. listener.Close()
  336. wrapper.stopEvent <- true
  337. return
  338. }
  339. }
  340. }()
  341. return &wrapper
  342. }
  343. // generateMessageID returns a network-unique message ID.
  344. func (server *Server) generateMessageID() string {
  345. // we don't need the full like 30 chars since the unixnano below handles
  346. // most of our uniqueness requirements, so just truncate at 5
  347. lastbit := strconv.FormatInt(rand.Int63(), 36)
  348. if 5 < len(lastbit) {
  349. lastbit = lastbit[:4]
  350. }
  351. return fmt.Sprintf("%s%s", strconv.FormatInt(time.Now().UTC().UnixNano(), 36), lastbit)
  352. }
  353. //
  354. // server functionality
  355. //
  356. func (server *Server) tryRegister(c *Client) {
  357. if c.registered || !c.HasNick() || !c.HasUsername() ||
  358. (c.capState == CapNegotiating) {
  359. return
  360. }
  361. // check KLINEs
  362. isBanned, info := server.klines.CheckMasks(c.AllNickmasks()...)
  363. if isBanned {
  364. reason := info.Reason
  365. if info.Time != nil {
  366. reason += fmt.Sprintf(" [%s]", info.Time.Duration.String())
  367. }
  368. c.Quit(fmt.Sprintf(c.t("You are banned from this server (%s)"), reason))
  369. c.destroy(false)
  370. return
  371. }
  372. // continue registration
  373. server.logger.Debug("localconnect", fmt.Sprintf("Client registered [%s] [u:%s] [r:%s]", c.nick, c.username, c.realname))
  374. server.snomasks.Send(sno.LocalConnects, fmt.Sprintf(ircfmt.Unescape("Client registered $c[grey][$r%s$c[grey]] [u:$r%s$c[grey]] [h:$r%s$c[grey]] [r:$r%s$c[grey]]"), c.nick, c.username, c.rawHostname, c.realname))
  375. c.Register()
  376. // send welcome text
  377. //NOTE(dan): we specifically use the NICK here instead of the nickmask
  378. // see http://modern.ircdocs.horse/#rplwelcome-001 for details on why we avoid using the nickmask
  379. c.Send(nil, server.name, RPL_WELCOME, c.nick, fmt.Sprintf(c.t("Welcome to the Internet Relay Network %s"), c.nick))
  380. c.Send(nil, server.name, RPL_YOURHOST, c.nick, fmt.Sprintf(c.t("Your host is %s, running version %s"), server.name, Ver))
  381. c.Send(nil, server.name, RPL_CREATED, c.nick, fmt.Sprintf(c.t("This server was created %s"), server.ctime.Format(time.RFC1123)))
  382. //TODO(dan): Look at adding last optional [<channel modes with a parameter>] parameter
  383. c.Send(nil, server.name, RPL_MYINFO, c.nick, server.name, Ver, supportedUserModesString, supportedChannelModesString)
  384. c.RplISupport()
  385. server.MOTD(c)
  386. c.Send(nil, c.nickMaskString, RPL_UMODEIS, c.nick, c.ModeString())
  387. if server.logger.IsLoggingRawIO() {
  388. c.Notice(c.t("This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect."))
  389. }
  390. // if resumed, send fake channel joins
  391. if c.resumeDetails != nil {
  392. for _, name := range c.resumeDetails.SendFakeJoinsFor {
  393. channel := server.channels.Get(name)
  394. if channel == nil {
  395. continue
  396. }
  397. if c.capabilities.Has(caps.ExtendedJoin) {
  398. c.Send(nil, c.nickMaskString, "JOIN", channel.name, c.account.Name, c.realname)
  399. } else {
  400. c.Send(nil, c.nickMaskString, "JOIN", channel.name)
  401. }
  402. channel.SendTopic(c)
  403. channel.Names(c)
  404. // construct and send fake modestring if necessary
  405. c.stateMutex.RLock()
  406. myModes := channel.members[c]
  407. c.stateMutex.RUnlock()
  408. if myModes == nil {
  409. continue
  410. }
  411. oldModes := myModes.String()
  412. if 0 < len(oldModes) {
  413. params := []string{channel.name, "+" + oldModes}
  414. for _ = range oldModes {
  415. params = append(params, c.nick)
  416. }
  417. c.Send(nil, server.name, "MODE", params...)
  418. }
  419. }
  420. }
  421. }
  422. // t returns the translated version of the given string, based on the languages configured by the client.
  423. func (client *Client) t(originalString string) string {
  424. // grab this mutex to protect client.languages
  425. client.stateMutex.RLock()
  426. defer client.stateMutex.RUnlock()
  427. return client.server.languages.Translate(client.languages, originalString)
  428. }
  429. // MOTD serves the Message of the Day.
  430. func (server *Server) MOTD(client *Client) {
  431. server.configurableStateMutex.RLock()
  432. motdLines := server.motdLines
  433. server.configurableStateMutex.RUnlock()
  434. if len(motdLines) < 1 {
  435. client.Send(nil, server.name, ERR_NOMOTD, client.nick, client.t("MOTD File is missing"))
  436. return
  437. }
  438. client.Send(nil, server.name, RPL_MOTDSTART, client.nick, fmt.Sprintf(client.t("- %s Message of the day - "), server.name))
  439. for _, line := range motdLines {
  440. client.Send(nil, server.name, RPL_MOTD, client.nick, line)
  441. }
  442. client.Send(nil, server.name, RPL_ENDOFMOTD, client.nick, client.t("End of MOTD command"))
  443. }
  444. //
  445. // registration commands
  446. //
  447. // PASS <password>
  448. func passHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  449. if client.registered {
  450. client.Send(nil, server.name, ERR_ALREADYREGISTRED, client.nick, client.t("You may not reregister"))
  451. return false
  452. }
  453. // if no password exists, skip checking
  454. if len(server.password) == 0 {
  455. client.authorized = true
  456. return false
  457. }
  458. // check the provided password
  459. password := []byte(msg.Params[0])
  460. if passwd.ComparePassword(server.password, password) != nil {
  461. client.Send(nil, server.name, ERR_PASSWDMISMATCH, client.nick, client.t("Password incorrect"))
  462. client.Send(nil, server.name, "ERROR", client.t("Password incorrect"))
  463. return true
  464. }
  465. client.authorized = true
  466. return false
  467. }
  468. // USER <username> * 0 <realname>
  469. func userHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  470. if client.registered {
  471. client.Send(nil, server.name, ERR_ALREADYREGISTRED, client.nick, client.t("You may not reregister"))
  472. return false
  473. }
  474. if !client.authorized {
  475. client.Quit("Bad password")
  476. return true
  477. }
  478. if client.username != "" && client.realname != "" {
  479. return false
  480. }
  481. // confirm that username is valid
  482. //
  483. _, err := CasefoldName(msg.Params[0])
  484. if err != nil {
  485. client.Send(nil, "", "ERROR", client.t("Malformed username"))
  486. return true
  487. }
  488. if !client.HasUsername() {
  489. client.username = "~" + msg.Params[0]
  490. // don't bother updating nickmask here, it's not valid anyway
  491. }
  492. if client.realname == "" {
  493. client.realname = msg.Params[3]
  494. }
  495. server.tryRegister(client)
  496. return false
  497. }
  498. // QUIT [<reason>]
  499. func quitHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  500. reason := "Quit"
  501. if len(msg.Params) > 0 {
  502. reason += ": " + msg.Params[0]
  503. }
  504. client.Quit(reason)
  505. return true
  506. }
  507. //
  508. // normal commands
  509. //
  510. // PING <server1> [<server2>]
  511. func pingHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  512. client.Send(nil, server.name, "PONG", msg.Params...)
  513. return false
  514. }
  515. // PONG <server> [ <server2> ]
  516. func pongHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  517. // client gets touched when they send this command, so we don't need to do anything
  518. return false
  519. }
  520. // RENAME <oldchan> <newchan> [<reason>]
  521. func renameHandler(server *Server, client *Client, msg ircmsg.IrcMessage) (result bool) {
  522. result = false
  523. errorResponse := func(err error, name string) {
  524. // TODO: send correct error codes, e.g., ERR_CANNOTRENAME, ERR_CHANNAMEINUSE
  525. var code string
  526. switch err {
  527. case NoSuchChannel:
  528. code = ERR_NOSUCHCHANNEL
  529. case RenamePrivsNeeded:
  530. code = ERR_CHANOPRIVSNEEDED
  531. case InvalidChannelName:
  532. code = ERR_UNKNOWNERROR
  533. case ChannelNameInUse:
  534. code = ERR_UNKNOWNERROR
  535. default:
  536. code = ERR_UNKNOWNERROR
  537. }
  538. client.Send(nil, server.name, code, client.Nick(), "RENAME", name, err.Error())
  539. }
  540. oldName := strings.TrimSpace(msg.Params[0])
  541. newName := strings.TrimSpace(msg.Params[1])
  542. if oldName == "" || newName == "" {
  543. errorResponse(InvalidChannelName, "<empty>")
  544. return
  545. }
  546. casefoldedOldName, err := CasefoldChannel(oldName)
  547. if err != nil {
  548. errorResponse(InvalidChannelName, oldName)
  549. return
  550. }
  551. reason := "No reason"
  552. if 2 < len(msg.Params) {
  553. reason = msg.Params[2]
  554. }
  555. channel := server.channels.Get(oldName)
  556. if channel == nil {
  557. errorResponse(NoSuchChannel, oldName)
  558. return
  559. }
  560. //TODO(dan): allow IRCops to do this?
  561. if !channel.ClientIsAtLeast(client, Operator) {
  562. errorResponse(RenamePrivsNeeded, oldName)
  563. return
  564. }
  565. founder := channel.Founder()
  566. if founder != "" && founder != client.AccountName() {
  567. //TODO(dan): Change this to ERR_CANNOTRENAME
  568. client.Send(nil, server.name, ERR_UNKNOWNERROR, client.nick, "RENAME", oldName, client.t("Only channel founders can change registered channels"))
  569. return false
  570. }
  571. // perform the channel rename
  572. err = server.channels.Rename(oldName, newName)
  573. if err != nil {
  574. errorResponse(err, newName)
  575. return
  576. }
  577. // rename succeeded, persist it
  578. go server.channelRegistry.Rename(channel, casefoldedOldName)
  579. // send RENAME messages
  580. for _, mcl := range channel.Members() {
  581. if mcl.capabilities.Has(caps.Rename) {
  582. mcl.Send(nil, client.nickMaskString, "RENAME", oldName, newName, reason)
  583. } else {
  584. mcl.Send(nil, mcl.nickMaskString, "PART", oldName, fmt.Sprintf(mcl.t("Channel renamed: %s"), reason))
  585. if mcl.capabilities.Has(caps.ExtendedJoin) {
  586. accountName := "*"
  587. if mcl.account != nil {
  588. accountName = mcl.account.Name
  589. }
  590. mcl.Send(nil, mcl.nickMaskString, "JOIN", newName, accountName, mcl.realname)
  591. } else {
  592. mcl.Send(nil, mcl.nickMaskString, "JOIN", newName)
  593. }
  594. }
  595. }
  596. return false
  597. }
  598. // JOIN <channel>{,<channel>} [<key>{,<key>}]
  599. func joinHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  600. // kill JOIN 0 requests
  601. if msg.Params[0] == "0" {
  602. client.Notice(client.t("JOIN 0 is not allowed"))
  603. return false
  604. }
  605. // handle regular JOINs
  606. channels := strings.Split(msg.Params[0], ",")
  607. var keys []string
  608. if len(msg.Params) > 1 {
  609. keys = strings.Split(msg.Params[1], ",")
  610. }
  611. for i, name := range channels {
  612. var key string
  613. if len(keys) > i {
  614. key = keys[i]
  615. }
  616. err := server.channels.Join(client, name, key)
  617. if err == NoSuchChannel {
  618. client.Send(nil, server.name, ERR_NOSUCHCHANNEL, client.Nick(), name, client.t("No such channel"))
  619. }
  620. }
  621. return false
  622. }
  623. // PART <channel>{,<channel>} [<reason>]
  624. func partHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  625. channels := strings.Split(msg.Params[0], ",")
  626. var reason string //TODO(dan): if this isn't supplied here, make sure the param doesn't exist in the PART message sent to other users
  627. if len(msg.Params) > 1 {
  628. reason = msg.Params[1]
  629. }
  630. for _, chname := range channels {
  631. err := server.channels.Part(client, chname, reason)
  632. if err == NoSuchChannel {
  633. client.Send(nil, server.name, ERR_NOSUCHCHANNEL, client.nick, chname, client.t("No such channel"))
  634. }
  635. }
  636. return false
  637. }
  638. // TOPIC <channel> [<topic>]
  639. func topicHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  640. name, err := CasefoldChannel(msg.Params[0])
  641. channel := server.channels.Get(name)
  642. if err != nil || channel == nil {
  643. if len(msg.Params[0]) > 0 {
  644. client.Send(nil, server.name, ERR_NOSUCHCHANNEL, client.nick, msg.Params[0], client.t("No such channel"))
  645. }
  646. return false
  647. }
  648. if len(msg.Params) > 1 {
  649. channel.SetTopic(client, msg.Params[1])
  650. } else {
  651. channel.SendTopic(client)
  652. }
  653. return false
  654. }
  655. // wordWrap wraps the given text into a series of lines that don't exceed lineWidth characters.
  656. func wordWrap(text string, lineWidth int) []string {
  657. var lines []string
  658. var cacheLine, cacheWord string
  659. for _, char := range text {
  660. if char == '\r' {
  661. continue
  662. } else if char == '\n' {
  663. cacheLine += cacheWord
  664. lines = append(lines, cacheLine)
  665. cacheWord = ""
  666. cacheLine = ""
  667. } else if (char == ' ' || char == '-') && len(cacheLine)+len(cacheWord)+1 < lineWidth {
  668. // natural word boundary
  669. cacheLine += cacheWord + string(char)
  670. cacheWord = ""
  671. } else if lineWidth <= len(cacheLine)+len(cacheWord)+1 {
  672. // time to wrap to next line
  673. if len(cacheLine) < (lineWidth / 2) {
  674. // this word takes up more than half a line... just split in the middle of the word
  675. cacheLine += cacheWord + string(char)
  676. cacheWord = ""
  677. } else {
  678. cacheWord += string(char)
  679. }
  680. lines = append(lines, cacheLine)
  681. cacheLine = ""
  682. } else {
  683. // normal character
  684. cacheWord += string(char)
  685. }
  686. }
  687. if 0 < len(cacheWord) {
  688. cacheLine += cacheWord
  689. }
  690. if 0 < len(cacheLine) {
  691. lines = append(lines, cacheLine)
  692. }
  693. return lines
  694. }
  695. // SplitMessage represents a message that's been split for sending.
  696. type SplitMessage struct {
  697. For512 []string
  698. ForMaxLine string
  699. }
  700. func (server *Server) splitMessage(original string, origIs512 bool) SplitMessage {
  701. var newSplit SplitMessage
  702. newSplit.ForMaxLine = original
  703. if !origIs512 {
  704. newSplit.For512 = wordWrap(original, 400)
  705. } else {
  706. newSplit.For512 = []string{original}
  707. }
  708. return newSplit
  709. }
  710. // PRIVMSG <target>{,<target>} <message>
  711. func privmsgHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  712. clientOnlyTags := GetClientOnlyTags(msg.Tags)
  713. targets := strings.Split(msg.Params[0], ",")
  714. message := msg.Params[1]
  715. // split privmsg
  716. splitMsg := server.splitMessage(message, !client.capabilities.Has(caps.MaxLine))
  717. for i, targetString := range targets {
  718. // max of four targets per privmsg
  719. if i > maxTargets-1 {
  720. break
  721. }
  722. prefixes, targetString := SplitChannelMembershipPrefixes(targetString)
  723. lowestPrefix := GetLowestChannelModePrefix(prefixes)
  724. // eh, no need to notify them
  725. if len(targetString) < 1 {
  726. continue
  727. }
  728. target, err := CasefoldChannel(targetString)
  729. if err == nil {
  730. channel := server.channels.Get(target)
  731. if channel == nil {
  732. client.Send(nil, server.name, ERR_NOSUCHCHANNEL, client.nick, targetString, client.t("No such channel"))
  733. continue
  734. }
  735. if !channel.CanSpeak(client) {
  736. client.Send(nil, client.server.name, ERR_CANNOTSENDTOCHAN, channel.name, client.t("Cannot send to channel"))
  737. continue
  738. }
  739. msgid := server.generateMessageID()
  740. channel.SplitPrivMsg(msgid, lowestPrefix, clientOnlyTags, client, splitMsg)
  741. } else {
  742. target, err = CasefoldName(targetString)
  743. if target == "chanserv" {
  744. server.chanservReceivePrivmsg(client, message)
  745. continue
  746. } else if target == "nickserv" {
  747. server.nickservReceivePrivmsg(client, message)
  748. continue
  749. }
  750. user := server.clients.Get(target)
  751. if err != nil || user == nil {
  752. if len(target) > 0 {
  753. client.Send(nil, server.name, ERR_NOSUCHNICK, client.nick, target, "No such nick")
  754. }
  755. continue
  756. }
  757. if !user.capabilities.Has(caps.MessageTags) {
  758. clientOnlyTags = nil
  759. }
  760. msgid := server.generateMessageID()
  761. // restrict messages appropriately when +R is set
  762. // intentionally make the sending user think the message went through fine
  763. if !user.flags[RegisteredOnly] || client.registered {
  764. user.SendSplitMsgFromClient(msgid, client, clientOnlyTags, "PRIVMSG", user.nick, splitMsg)
  765. }
  766. if client.capabilities.Has(caps.EchoMessage) {
  767. client.SendSplitMsgFromClient(msgid, client, clientOnlyTags, "PRIVMSG", user.nick, splitMsg)
  768. }
  769. if user.flags[Away] {
  770. //TODO(dan): possibly implement cooldown of away notifications to users
  771. client.Send(nil, server.name, RPL_AWAY, user.nick, user.awayMessage)
  772. }
  773. }
  774. }
  775. return false
  776. }
  777. // TAGMSG <target>{,<target>}
  778. func tagmsgHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  779. clientOnlyTags := GetClientOnlyTags(msg.Tags)
  780. // no client-only tags, so we can drop it
  781. if clientOnlyTags == nil {
  782. return false
  783. }
  784. targets := strings.Split(msg.Params[0], ",")
  785. for i, targetString := range targets {
  786. // max of four targets per privmsg
  787. if i > maxTargets-1 {
  788. break
  789. }
  790. prefixes, targetString := SplitChannelMembershipPrefixes(targetString)
  791. lowestPrefix := GetLowestChannelModePrefix(prefixes)
  792. // eh, no need to notify them
  793. if len(targetString) < 1 {
  794. continue
  795. }
  796. target, err := CasefoldChannel(targetString)
  797. if err == nil {
  798. channel := server.channels.Get(target)
  799. if channel == nil {
  800. client.Send(nil, server.name, ERR_NOSUCHCHANNEL, client.nick, targetString, client.t("No such channel"))
  801. continue
  802. }
  803. if !channel.CanSpeak(client) {
  804. client.Send(nil, client.server.name, ERR_CANNOTSENDTOCHAN, channel.name, client.t("Cannot send to channel"))
  805. continue
  806. }
  807. msgid := server.generateMessageID()
  808. channel.TagMsg(msgid, lowestPrefix, clientOnlyTags, client)
  809. } else {
  810. target, err = CasefoldName(targetString)
  811. user := server.clients.Get(target)
  812. if err != nil || user == nil {
  813. if len(target) > 0 {
  814. client.Send(nil, server.name, ERR_NOSUCHNICK, client.nick, target, client.t("No such nick"))
  815. }
  816. continue
  817. }
  818. msgid := server.generateMessageID()
  819. // end user can't receive tagmsgs
  820. if !user.capabilities.Has(caps.MessageTags) {
  821. continue
  822. }
  823. user.SendFromClient(msgid, client, clientOnlyTags, "TAGMSG", user.nick)
  824. if client.capabilities.Has(caps.EchoMessage) {
  825. client.SendFromClient(msgid, client, clientOnlyTags, "TAGMSG", user.nick)
  826. }
  827. if user.flags[Away] {
  828. //TODO(dan): possibly implement cooldown of away notifications to users
  829. client.Send(nil, server.name, RPL_AWAY, user.nick, user.awayMessage)
  830. }
  831. }
  832. }
  833. return false
  834. }
  835. // WhoisChannelsNames returns the common channel names between two users.
  836. func (client *Client) WhoisChannelsNames(target *Client) []string {
  837. isMultiPrefix := target.capabilities.Has(caps.MultiPrefix)
  838. var chstrs []string
  839. for _, channel := range client.Channels() {
  840. // channel is secret and the target can't see it
  841. if !target.flags[Operator] && channel.HasMode(Secret) && !channel.hasClient(target) {
  842. continue
  843. }
  844. chstrs = append(chstrs, channel.ClientPrefixes(client, isMultiPrefix)+channel.name)
  845. }
  846. return chstrs
  847. }
  848. // WHOIS [ <target> ] <mask> *( "," <mask> )
  849. func whoisHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  850. var masksString string
  851. //var target string
  852. if len(msg.Params) > 1 {
  853. //target = msg.Params[0]
  854. masksString = msg.Params[1]
  855. } else {
  856. masksString = msg.Params[0]
  857. }
  858. if len(strings.TrimSpace(masksString)) < 1 {
  859. client.Send(nil, server.name, ERR_UNKNOWNERROR, client.nick, msg.Command, client.t("No masks given"))
  860. return false
  861. }
  862. if client.flags[Operator] {
  863. masks := strings.Split(masksString, ",")
  864. for _, mask := range masks {
  865. casefoldedMask, err := Casefold(mask)
  866. if err != nil {
  867. client.Send(nil, client.server.name, ERR_NOSUCHNICK, client.nick, mask, client.t("No such nick"))
  868. continue
  869. }
  870. matches := server.clients.FindAll(casefoldedMask)
  871. if len(matches) == 0 {
  872. client.Send(nil, client.server.name, ERR_NOSUCHNICK, client.nick, mask, client.t("No such nick"))
  873. continue
  874. }
  875. for mclient := range matches {
  876. client.getWhoisOf(mclient)
  877. }
  878. }
  879. } else {
  880. // only get the first request
  881. casefoldedMask, err := Casefold(strings.Split(masksString, ",")[0])
  882. mclient := server.clients.Get(casefoldedMask)
  883. if err != nil || mclient == nil {
  884. client.Send(nil, client.server.name, ERR_NOSUCHNICK, client.nick, masksString, client.t("No such nick"))
  885. // fall through, ENDOFWHOIS is always sent
  886. } else {
  887. client.getWhoisOf(mclient)
  888. }
  889. }
  890. client.Send(nil, server.name, RPL_ENDOFWHOIS, client.nick, masksString, client.t("End of /WHOIS list"))
  891. return false
  892. }
  893. func (client *Client) getWhoisOf(target *Client) {
  894. target.stateMutex.RLock()
  895. defer target.stateMutex.RUnlock()
  896. client.Send(nil, client.server.name, RPL_WHOISUSER, client.nick, target.nick, target.username, target.hostname, "*", target.realname)
  897. whoischannels := client.WhoisChannelsNames(target)
  898. if whoischannels != nil {
  899. client.Send(nil, client.server.name, RPL_WHOISCHANNELS, client.nick, target.nick, strings.Join(whoischannels, " "))
  900. }
  901. if target.class != nil {
  902. client.Send(nil, client.server.name, RPL_WHOISOPERATOR, client.nick, target.nick, target.whoisLine)
  903. }
  904. if client.flags[Operator] || client == target {
  905. client.Send(nil, client.server.name, RPL_WHOISACTUALLY, client.nick, target.nick, fmt.Sprintf("%s@%s", target.username, utils.LookupHostname(target.IPString())), target.IPString(), client.t("Actual user@host, Actual IP"))
  906. }
  907. if target.flags[TLS] {
  908. client.Send(nil, client.server.name, RPL_WHOISSECURE, client.nick, target.nick, client.t("is using a secure connection"))
  909. }
  910. accountName := target.AccountName()
  911. if accountName != "" {
  912. client.Send(nil, client.server.name, RPL_WHOISACCOUNT, client.nick, accountName, client.t("is logged in as"))
  913. }
  914. if target.flags[Bot] {
  915. client.Send(nil, client.server.name, RPL_WHOISBOT, client.nick, target.nick, ircfmt.Unescape(fmt.Sprintf(client.t("is a $bBot$b on %s"), client.server.networkName)))
  916. }
  917. if 0 < len(target.languages) {
  918. params := []string{client.nick, target.nick}
  919. for _, str := range client.server.languages.Codes(target.languages) {
  920. params = append(params, str)
  921. }
  922. params = append(params, client.t("can speak these languages"))
  923. client.Send(nil, client.server.name, RPL_WHOISLANGUAGE, params...)
  924. }
  925. if target.certfp != "" && (client.flags[Operator] || client == target) {
  926. client.Send(nil, client.server.name, RPL_WHOISCERTFP, client.nick, target.nick, fmt.Sprintf(client.t("has client certificate fingerprint %s"), target.certfp))
  927. }
  928. client.Send(nil, client.server.name, RPL_WHOISIDLE, client.nick, target.nick, strconv.FormatUint(target.IdleSeconds(), 10), strconv.FormatInt(target.SignonTime(), 10), client.t("seconds idle, signon time"))
  929. }
  930. // rplWhoReply returns the WHO reply between one user and another channel/user.
  931. // <channel> <user> <host> <server> <nick> ( "H" / "G" ) ["*"] [ ( "@" / "+" ) ]
  932. // :<hopcount> <real name>
  933. func (target *Client) rplWhoReply(channel *Channel, client *Client) {
  934. channelName := "*"
  935. flags := ""
  936. if client.HasMode(Away) {
  937. flags = "G"
  938. } else {
  939. flags = "H"
  940. }
  941. if client.HasMode(Operator) {
  942. flags += "*"
  943. }
  944. if channel != nil {
  945. flags += channel.ClientPrefixes(client, target.capabilities.Has(caps.MultiPrefix))
  946. channelName = channel.name
  947. }
  948. target.Send(nil, target.server.name, RPL_WHOREPLY, target.nick, channelName, client.Username(), client.Hostname(), client.server.name, client.Nick(), flags, strconv.Itoa(client.hops)+" "+client.Realname())
  949. }
  950. func whoChannel(client *Client, channel *Channel, friends ClientSet) {
  951. for _, member := range channel.Members() {
  952. if !client.flags[Invisible] || friends[client] {
  953. client.rplWhoReply(channel, member)
  954. }
  955. }
  956. }
  957. // WHO [ <mask> [ "o" ] ]
  958. func whoHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  959. if msg.Params[0] == "" {
  960. client.Send(nil, server.name, ERR_UNKNOWNERROR, client.nick, "WHO", client.t("First param must be a mask or channel"))
  961. return false
  962. }
  963. var mask string
  964. if len(msg.Params) > 0 {
  965. casefoldedMask, err := Casefold(msg.Params[0])
  966. if err != nil {
  967. client.Send(nil, server.name, ERR_UNKNOWNERROR, "WHO", client.t("Mask isn't valid"))
  968. return false
  969. }
  970. mask = casefoldedMask
  971. }
  972. friends := client.Friends()
  973. //TODO(dan): is this used and would I put this param in the Modern doc?
  974. // if not, can we remove it?
  975. //var operatorOnly bool
  976. //if len(msg.Params) > 1 && msg.Params[1] == "o" {
  977. // operatorOnly = true
  978. //}
  979. if mask[0] == '#' {
  980. // TODO implement wildcard matching
  981. //TODO(dan): ^ only for opers
  982. channel := server.channels.Get(mask)
  983. if channel != nil {
  984. whoChannel(client, channel, friends)
  985. }
  986. } else {
  987. for mclient := range server.clients.FindAll(mask) {
  988. client.rplWhoReply(nil, mclient)
  989. }
  990. }
  991. client.Send(nil, server.name, RPL_ENDOFWHO, client.nick, mask, client.t("End of WHO list"))
  992. return false
  993. }
  994. // OPER <name> <password>
  995. func operHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  996. name, err := CasefoldName(msg.Params[0])
  997. if err != nil {
  998. client.Send(nil, server.name, ERR_PASSWDMISMATCH, client.nick, client.t("Password incorrect"))
  999. return true
  1000. }
  1001. if client.flags[Operator] == true {
  1002. client.Send(nil, server.name, ERR_UNKNOWNERROR, "OPER", client.t("You're already opered-up!"))
  1003. return false
  1004. }
  1005. server.configurableStateMutex.RLock()
  1006. oper := server.operators[name]
  1007. server.configurableStateMutex.RUnlock()
  1008. password := []byte(msg.Params[1])
  1009. err = passwd.ComparePassword(oper.Pass, password)
  1010. if (oper.Pass == nil) || (err != nil) {
  1011. client.Send(nil, server.name, ERR_PASSWDMISMATCH, client.nick, client.t("Password incorrect"))
  1012. return true
  1013. }
  1014. client.flags[Operator] = true
  1015. client.operName = name
  1016. client.class = oper.Class
  1017. client.whoisLine = oper.WhoisLine
  1018. // push new vhost if one is set
  1019. if len(oper.Vhost) > 0 {
  1020. for fClient := range client.Friends(caps.ChgHost) {
  1021. fClient.SendFromClient("", client, nil, "CHGHOST", client.username, oper.Vhost)
  1022. }
  1023. // CHGHOST requires prefix nickmask to have original hostname, so do that before updating nickmask
  1024. client.vhost = oper.Vhost
  1025. client.updateNickMask("")
  1026. }
  1027. // set new modes
  1028. var applied ModeChanges
  1029. if 0 < len(oper.Modes) {
  1030. modeChanges, unknownChanges := ParseUserModeChanges(strings.Split(oper.Modes, " ")...)
  1031. applied = client.applyUserModeChanges(true, modeChanges)
  1032. if 0 < len(unknownChanges) {
  1033. var runes string
  1034. for r := range unknownChanges {
  1035. runes += string(r)
  1036. }
  1037. client.Notice(fmt.Sprintf(client.t("Could not apply mode changes: +%s"), runes))
  1038. }
  1039. }
  1040. client.Send(nil, server.name, RPL_YOUREOPER, client.nick, client.t("You are now an IRC operator"))
  1041. applied = append(applied, ModeChange{
  1042. mode: Operator,
  1043. op: Add,
  1044. })
  1045. client.Send(nil, server.name, "MODE", client.nick, applied.String())
  1046. server.snomasks.Send(sno.LocalOpers, fmt.Sprintf(ircfmt.Unescape("Client opered up $c[grey][$r%s$c[grey], $r%s$c[grey]]"), client.nickMaskString, client.operName))
  1047. return false
  1048. }
  1049. // rehash reloads the config and applies the changes from the config file.
  1050. func (server *Server) rehash() error {
  1051. server.logger.Debug("rehash", "Starting rehash")
  1052. // only let one REHASH go on at a time
  1053. server.rehashMutex.Lock()
  1054. defer server.rehashMutex.Unlock()
  1055. server.logger.Debug("rehash", "Got rehash lock")
  1056. config, err := LoadConfig(server.configFilename)
  1057. if err != nil {
  1058. return fmt.Errorf("Error loading config file config: %s", err.Error())
  1059. }
  1060. err = server.applyConfig(config, false)
  1061. if err != nil {
  1062. return fmt.Errorf("Error applying config changes: %s", err.Error())
  1063. }
  1064. return nil
  1065. }
  1066. func (server *Server) applyConfig(config *Config, initial bool) error {
  1067. if initial {
  1068. server.ctime = time.Now()
  1069. server.configFilename = config.Filename
  1070. } else {
  1071. // enforce configs that can't be changed after launch:
  1072. if server.limits.LineLen.Tags != config.Limits.LineLen.Tags || server.limits.LineLen.Rest != config.Limits.LineLen.Rest {
  1073. return fmt.Errorf("Maximum line length (linelen) cannot be changed after launching the server, rehash aborted")
  1074. } else if server.name != config.Server.Name {
  1075. return fmt.Errorf("Server name cannot be changed after launching the server, rehash aborted")
  1076. }
  1077. }
  1078. casefoldedName, err := Casefold(config.Server.Name)
  1079. if err != nil {
  1080. return fmt.Errorf("Server name isn't valid [%s]: %s", config.Server.Name, err.Error())
  1081. }
  1082. // confirm operator stuff all exists and is fine
  1083. operclasses, err := config.OperatorClasses()
  1084. if err != nil {
  1085. return fmt.Errorf("Error rehashing config file operclasses: %s", err.Error())
  1086. }
  1087. opers, err := config.Operators(operclasses)
  1088. if err != nil {
  1089. return fmt.Errorf("Error rehashing config file opers: %s", err.Error())
  1090. }
  1091. // TODO: support rehash of existing operator perms?
  1092. // sanity checks complete, start modifying server state
  1093. if initial {
  1094. server.name = config.Server.Name
  1095. server.nameCasefolded = casefoldedName
  1096. }
  1097. server.configurableStateMutex.Lock()
  1098. server.networkName = config.Network.Name
  1099. if config.Server.Password != "" {
  1100. server.password = config.Server.PasswordBytes()
  1101. } else {
  1102. server.password = nil
  1103. }
  1104. // apply new WebIRC command restrictions
  1105. server.webirc = config.Server.WebIRC
  1106. // apply new PROXY command restrictions
  1107. server.proxyAllowedFrom = config.Server.ProxyAllowedFrom
  1108. server.recoverFromErrors = true
  1109. if config.Debug.RecoverFromErrors != nil {
  1110. server.recoverFromErrors = *config.Debug.RecoverFromErrors
  1111. }
  1112. server.configurableStateMutex.Unlock()
  1113. err = server.connectionLimiter.ApplyConfig(config.Server.ConnectionLimiter)
  1114. if err != nil {
  1115. return err
  1116. }
  1117. err = server.connectionThrottler.ApplyConfig(config.Server.ConnectionThrottler)
  1118. if err != nil {
  1119. return err
  1120. }
  1121. // setup new and removed caps
  1122. addedCaps := caps.NewSet()
  1123. removedCaps := caps.NewSet()
  1124. updatedCaps := caps.NewSet()
  1125. // Translations
  1126. currentLanguageValue, _ := CapValues.Get(caps.Languages)
  1127. langCodes := []string{strconv.Itoa(len(config.Languages.Data) + 1), "en"}
  1128. for _, info := range config.Languages.Data {
  1129. if info.Incomplete {
  1130. langCodes = append(langCodes, "~"+info.Code)
  1131. } else {
  1132. langCodes = append(langCodes, info.Code)
  1133. }
  1134. }
  1135. newLanguageValue := strings.Join(langCodes, ",")
  1136. server.logger.Debug("rehash", "Languages:", newLanguageValue)
  1137. if currentLanguageValue != newLanguageValue {
  1138. updatedCaps.Add(caps.Languages)
  1139. CapValues.Set(caps.Languages, newLanguageValue)
  1140. }
  1141. // SASL
  1142. if config.Accounts.AuthenticationEnabled && !server.accountAuthenticationEnabled {
  1143. // enabling SASL
  1144. SupportedCapabilities.Enable(caps.SASL)
  1145. CapValues.Set(caps.SASL, "PLAIN,EXTERNAL")
  1146. addedCaps.Add(caps.SASL)
  1147. }
  1148. if !config.Accounts.AuthenticationEnabled && server.accountAuthenticationEnabled {
  1149. // disabling SASL
  1150. SupportedCapabilities.Disable(caps.SASL)
  1151. removedCaps.Add(caps.SASL)
  1152. }
  1153. server.accountAuthenticationEnabled = config.Accounts.AuthenticationEnabled
  1154. // STS
  1155. stsValue := config.Server.STS.Value()
  1156. var stsDisabled bool
  1157. stsCurrentCapValue, _ := CapValues.Get(caps.STS)
  1158. server.logger.Debug("rehash", "STS Vals", stsCurrentCapValue, stsValue, fmt.Sprintf("server[%v] config[%v]", server.stsEnabled, config.Server.STS.Enabled))
  1159. if config.Server.STS.Enabled && !server.stsEnabled {
  1160. // enabling STS
  1161. SupportedCapabilities.Enable(caps.STS)
  1162. addedCaps.Add(caps.STS)
  1163. CapValues.Set(caps.STS, stsValue)
  1164. } else if !config.Server.STS.Enabled && server.stsEnabled {
  1165. // disabling STS
  1166. SupportedCapabilities.Disable(caps.STS)
  1167. removedCaps.Add(caps.STS)
  1168. stsDisabled = true
  1169. } else if config.Server.STS.Enabled && server.stsEnabled && stsValue != stsCurrentCapValue {
  1170. // STS policy updated
  1171. CapValues.Set(caps.STS, stsValue)
  1172. updatedCaps.Add(caps.STS)
  1173. }
  1174. server.stsEnabled = config.Server.STS.Enabled
  1175. // burst new and removed caps
  1176. var capBurstClients ClientSet
  1177. added := make(map[caps.Version]string)
  1178. var removed string
  1179. // updated caps get DEL'd and then NEW'd
  1180. // so, we can just add updated ones to both removed and added lists here and they'll be correctly handled
  1181. server.logger.Debug("rehash", "Updated Caps", updatedCaps.String(caps.Cap301, CapValues), strconv.Itoa(updatedCaps.Count()))
  1182. for _, capab := range updatedCaps.List() {
  1183. addedCaps.Enable(capab)
  1184. removedCaps.Enable(capab)
  1185. }
  1186. if 0 < addedCaps.Count() || 0 < removedCaps.Count() {
  1187. capBurstClients = server.clients.AllWithCaps(caps.CapNotify)
  1188. added[caps.Cap301] = addedCaps.String(caps.Cap301, CapValues)
  1189. added[caps.Cap302] = addedCaps.String(caps.Cap302, CapValues)
  1190. // removed never has values, so we leave it as Cap301
  1191. removed = removedCaps.String(caps.Cap301, CapValues)
  1192. }
  1193. for sClient := range capBurstClients {
  1194. if stsDisabled {
  1195. // remove STS policy
  1196. //TODO(dan): this is an ugly hack. we can write this better.
  1197. stsPolicy := "sts=duration=0"
  1198. if 0 < addedCaps.Count() {
  1199. added[caps.Cap302] = added[caps.Cap302] + " " + stsPolicy
  1200. } else {
  1201. addedCaps.Enable(caps.STS)
  1202. added[caps.Cap302] = stsPolicy
  1203. }
  1204. }
  1205. // DEL caps and then send NEW ones so that updated caps get removed/added correctly
  1206. if 0 < removedCaps.Count() {
  1207. sClient.Send(nil, server.name, "CAP", sClient.nick, "DEL", removed)
  1208. }
  1209. if 0 < addedCaps.Count() {
  1210. sClient.Send(nil, server.name, "CAP", sClient.nick, "NEW", added[sClient.capVersion])
  1211. }
  1212. }
  1213. // set server options
  1214. server.configurableStateMutex.Lock()
  1215. lineLenConfig := LineLenLimits{
  1216. Tags: config.Limits.LineLen.Tags,
  1217. Rest: config.Limits.LineLen.Rest,
  1218. }
  1219. server.limits = Limits{
  1220. AwayLen: int(config.Limits.AwayLen),
  1221. ChannelLen: int(config.Limits.ChannelLen),
  1222. KickLen: int(config.Limits.KickLen),
  1223. MonitorEntries: int(config.Limits.MonitorEntries),
  1224. NickLen: int(config.Limits.NickLen),
  1225. TopicLen: int(config.Limits.TopicLen),
  1226. ChanListModes: int(config.Limits.ChanListModes),
  1227. LineLen: lineLenConfig,
  1228. }
  1229. server.operclasses = *operclasses
  1230. server.operators = opers
  1231. server.checkIdent = config.Server.CheckIdent
  1232. // registration
  1233. accountReg := NewAccountRegistration(config.Accounts.Registration)
  1234. server.accountRegistration = &accountReg
  1235. server.channelRegistrationEnabled = config.Channels.Registration.Enabled
  1236. server.defaultChannelModes = ParseDefaultChannelModes(config)
  1237. server.configurableStateMutex.Unlock()
  1238. // set new sendqueue size
  1239. if config.Server.MaxSendQBytes != server.MaxSendQBytes {
  1240. server.configurableStateMutex.Lock()
  1241. server.MaxSendQBytes = config.Server.MaxSendQBytes
  1242. server.configurableStateMutex.Unlock()
  1243. // update on all clients
  1244. for _, sClient := range server.clients.AllClients() {
  1245. sClient.socket.MaxSendQBytes = config.Server.MaxSendQBytes
  1246. }
  1247. }
  1248. // set RPL_ISUPPORT
  1249. var newISupportReplies [][]string
  1250. oldISupportList := server.isupport
  1251. server.setISupport()
  1252. if oldISupportList != nil {
  1253. newISupportReplies = oldISupportList.GetDifference(server.isupport)
  1254. }
  1255. server.loadMOTD(config.Server.MOTD, config.Server.MOTDFormatting)
  1256. // reload logging config
  1257. err = server.logger.ApplyConfig(config.Logging)
  1258. if err != nil {
  1259. return err
  1260. }
  1261. nowLoggingRawIO := server.logger.IsLoggingRawIO()
  1262. // notify clients if raw i/o logging was enabled by a rehash
  1263. sendRawOutputNotice := !initial && !server.loggingRawIO && nowLoggingRawIO
  1264. server.loggingRawIO = nowLoggingRawIO
  1265. if initial {
  1266. if err := server.loadDatastore(config.Datastore.Path); err != nil {
  1267. return err
  1268. }
  1269. }
  1270. // we are now open for business
  1271. server.setupListeners(config)
  1272. if !initial {
  1273. // push new info to all of our clients
  1274. for _, sClient := range server.clients.AllClients() {
  1275. for _, tokenline := range newISupportReplies {
  1276. sClient.Send(nil, server.name, RPL_ISUPPORT, append([]string{sClient.nick}, tokenline...)...)
  1277. }
  1278. if sendRawOutputNotice {
  1279. sClient.Notice(sClient.t("This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect."))
  1280. }
  1281. }
  1282. }
  1283. return nil
  1284. }
  1285. func (server *Server) loadMOTD(motdPath string, useFormatting bool) error {
  1286. server.logger.Debug("rehash", "Loading MOTD")
  1287. motdLines := make([]string, 0)
  1288. if motdPath != "" {
  1289. file, err := os.Open(motdPath)
  1290. if err == nil {
  1291. defer file.Close()
  1292. reader := bufio.NewReader(file)
  1293. for {
  1294. line, err := reader.ReadString('\n')
  1295. if err != nil {
  1296. break
  1297. }
  1298. line = strings.TrimRight(line, "\r\n")
  1299. if useFormatting {
  1300. line = ircfmt.Unescape(line)
  1301. }
  1302. // "- " is the required prefix for MOTD, we just add it here to make
  1303. // bursting it out to clients easier
  1304. line = fmt.Sprintf("- %s", line)
  1305. motdLines = append(motdLines, line)
  1306. }
  1307. } else {
  1308. return err
  1309. }
  1310. }
  1311. server.configurableStateMutex.Lock()
  1312. server.motdLines = motdLines
  1313. server.configurableStateMutex.Unlock()
  1314. return nil
  1315. }
  1316. func (server *Server) loadDatastore(datastorePath string) error {
  1317. // open the datastore and load server state for which it (rather than config)
  1318. // is the source of truth
  1319. server.logger.Debug("startup", "Opening datastore")
  1320. db, err := OpenDatabase(datastorePath)
  1321. if err == nil {
  1322. server.store = db
  1323. } else {
  1324. return fmt.Errorf("Failed to open datastore: %s", err.Error())
  1325. }
  1326. // load *lines (from the datastores)
  1327. server.logger.Debug("startup", "Loading D/Klines")
  1328. server.loadDLines()
  1329. server.loadKLines()
  1330. // load password manager
  1331. server.logger.Debug("startup", "Loading passwords")
  1332. err = server.store.View(func(tx *buntdb.Tx) error {
  1333. saltString, err := tx.Get(keySalt)
  1334. if err != nil {
  1335. return fmt.Errorf("Could not retrieve salt string: %s", err.Error())
  1336. }
  1337. salt, err := base64.StdEncoding.DecodeString(saltString)
  1338. if err != nil {
  1339. return err
  1340. }
  1341. pwm := passwd.NewSaltedManager(salt)
  1342. server.passwords = &pwm
  1343. return nil
  1344. })
  1345. if err != nil {
  1346. return fmt.Errorf("Could not load salt: %s", err.Error())
  1347. }
  1348. server.channelRegistry = NewChannelRegistry(server)
  1349. return nil
  1350. }
  1351. func (server *Server) setupListeners(config *Config) {
  1352. // update or destroy all existing listeners
  1353. tlsListeners := config.TLSListeners()
  1354. for addr := range server.listeners {
  1355. currentListener := server.listeners[addr]
  1356. var stillConfigured bool
  1357. for _, newaddr := range config.Server.Listen {
  1358. if newaddr == addr {
  1359. stillConfigured = true
  1360. break
  1361. }
  1362. }
  1363. // pass new config information to the listener, to be picked up after
  1364. // its next Accept(). this is like sending over a buffered channel of
  1365. // size 1, but where sending a second item overwrites the buffered item
  1366. // instead of blocking.
  1367. currentListener.configMutex.Lock()
  1368. currentListener.shouldStop = !stillConfigured
  1369. currentListener.tlsConfig = tlsListeners[addr]
  1370. currentListener.configMutex.Unlock()
  1371. if stillConfigured {
  1372. server.logger.Info("listeners",
  1373. fmt.Sprintf("now listening on %s, tls=%t.", addr, (currentListener.tlsConfig != nil)),
  1374. )
  1375. } else {
  1376. // tell the listener it should stop by interrupting its Accept() call:
  1377. currentListener.listener.Close()
  1378. // TODO(golang1.10) delete stopEvent once issue #21856 is released
  1379. <-currentListener.stopEvent
  1380. delete(server.listeners, addr)
  1381. server.logger.Info("listeners", fmt.Sprintf("stopped listening on %s.", addr))
  1382. }
  1383. }
  1384. // create new listeners that were not previously configured
  1385. for _, newaddr := range config.Server.Listen {
  1386. _, exists := server.listeners[newaddr]
  1387. if !exists {
  1388. // make new listener
  1389. server.listeners[newaddr] = server.createListener(newaddr, tlsListeners[newaddr])
  1390. }
  1391. }
  1392. if len(tlsListeners) == 0 {
  1393. server.logger.Warning("startup", "You are not exposing an SSL/TLS listening port. You should expose at least one port (typically 6697) to accept TLS connections")
  1394. }
  1395. var usesStandardTLSPort bool
  1396. for addr := range config.TLSListeners() {
  1397. if strings.Contains(addr, "6697") {
  1398. usesStandardTLSPort = true
  1399. break
  1400. }
  1401. }
  1402. if 0 < len(tlsListeners) && !usesStandardTLSPort {
  1403. server.logger.Warning("startup", "Port 6697 is the standard TLS port for IRC. You should (also) expose port 6697 as a TLS port to ensure clients can connect securely")
  1404. }
  1405. }
  1406. // GetDefaultChannelModes returns our default channel modes.
  1407. func (server *Server) GetDefaultChannelModes() Modes {
  1408. server.configurableStateMutex.RLock()
  1409. defer server.configurableStateMutex.RUnlock()
  1410. return server.defaultChannelModes
  1411. }
  1412. // REHASH
  1413. func rehashHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  1414. server.logger.Info("rehash", fmt.Sprintf("REHASH command used by %s", client.nick))
  1415. err := server.rehash()
  1416. if err == nil {
  1417. client.Send(nil, server.name, RPL_REHASHING, client.nick, "ircd.yaml", client.t("Rehashing"))
  1418. } else {
  1419. server.logger.Error("rehash", fmt.Sprintln("Failed to rehash:", err.Error()))
  1420. client.Send(nil, server.name, ERR_UNKNOWNERROR, client.nick, "REHASH", err.Error())
  1421. }
  1422. return false
  1423. }
  1424. // AWAY [<message>]
  1425. func awayHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  1426. var isAway bool
  1427. var text string
  1428. if len(msg.Params) > 0 {
  1429. isAway = true
  1430. text = msg.Params[0]
  1431. awayLen := server.Limits().AwayLen
  1432. if len(text) > awayLen {
  1433. text = text[:awayLen]
  1434. }
  1435. }
  1436. if isAway {
  1437. client.flags[Away] = true
  1438. } else {
  1439. delete(client.flags, Away)
  1440. }
  1441. client.awayMessage = text
  1442. var op ModeOp
  1443. if client.flags[Away] {
  1444. op = Add
  1445. client.Send(nil, server.name, RPL_NOWAWAY, client.nick, client.t("You have been marked as being away"))
  1446. } else {
  1447. op = Remove
  1448. client.Send(nil, server.name, RPL_UNAWAY, client.nick, client.t("You are no longer marked as being away"))
  1449. }
  1450. //TODO(dan): Should this be sent automagically as part of setting the flag/mode?
  1451. modech := ModeChanges{ModeChange{
  1452. mode: Away,
  1453. op: op,
  1454. }}
  1455. client.Send(nil, server.name, "MODE", client.nick, modech.String())
  1456. // dispatch away-notify
  1457. for friend := range client.Friends(caps.AwayNotify) {
  1458. if client.flags[Away] {
  1459. friend.SendFromClient("", client, nil, "AWAY", client.awayMessage)
  1460. } else {
  1461. friend.SendFromClient("", client, nil, "AWAY")
  1462. }
  1463. }
  1464. return false
  1465. }
  1466. // ISON <nick>{ <nick>}
  1467. func isonHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  1468. var nicks = msg.Params
  1469. var err error
  1470. var casefoldedNick string
  1471. ison := make([]string, 0)
  1472. for _, nick := range nicks {
  1473. casefoldedNick, err = CasefoldName(nick)
  1474. if err != nil {
  1475. continue
  1476. }
  1477. if iclient := server.clients.Get(casefoldedNick); iclient != nil {
  1478. ison = append(ison, iclient.nick)
  1479. }
  1480. }
  1481. client.Send(nil, server.name, RPL_ISON, client.nick, strings.Join(nicks, " "))
  1482. return false
  1483. }
  1484. // MOTD [<target>]
  1485. func motdHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  1486. //TODO(dan): hook this up when we have multiple servers I guess???
  1487. //var target string
  1488. //if len(msg.Params) > 0 {
  1489. // target = msg.Params[0]
  1490. //}
  1491. server.MOTD(client)
  1492. return false
  1493. }
  1494. // NOTICE <target>{,<target>} <message>
  1495. func noticeHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  1496. clientOnlyTags := GetClientOnlyTags(msg.Tags)
  1497. targets := strings.Split(msg.Params[0], ",")
  1498. message := msg.Params[1]
  1499. // split privmsg
  1500. splitMsg := server.splitMessage(message, !client.capabilities.Has(caps.MaxLine))
  1501. for i, targetString := range targets {
  1502. // max of four targets per privmsg
  1503. if i > maxTargets-1 {
  1504. break
  1505. }
  1506. prefixes, targetString := SplitChannelMembershipPrefixes(targetString)
  1507. lowestPrefix := GetLowestChannelModePrefix(prefixes)
  1508. target, cerr := CasefoldChannel(targetString)
  1509. if cerr == nil {
  1510. channel := server.channels.Get(target)
  1511. if channel == nil {
  1512. // errors silently ignored with NOTICE as per RFC
  1513. continue
  1514. }
  1515. if !channel.CanSpeak(client) {
  1516. // errors silently ignored with NOTICE as per RFC
  1517. continue
  1518. }
  1519. msgid := server.generateMessageID()
  1520. channel.SplitNotice(msgid, lowestPrefix, clientOnlyTags, client, splitMsg)
  1521. } else {
  1522. target, err := CasefoldName(targetString)
  1523. if err != nil {
  1524. continue
  1525. }
  1526. if target == "chanserv" {
  1527. server.chanservReceiveNotice(client, message)
  1528. continue
  1529. } else if target == "nickserv" {
  1530. server.nickservReceiveNotice(client, message)
  1531. continue
  1532. }
  1533. user := server.clients.Get(target)
  1534. if user == nil {
  1535. // errors silently ignored with NOTICE as per RFC
  1536. continue
  1537. }
  1538. if !user.capabilities.Has(caps.MessageTags) {
  1539. clientOnlyTags = nil
  1540. }
  1541. msgid := server.generateMessageID()
  1542. // restrict messages appropriately when +R is set
  1543. // intentionally make the sending user think the message went through fine
  1544. if !user.flags[RegisteredOnly] || client.registered {
  1545. user.SendSplitMsgFromClient(msgid, client, clientOnlyTags, "NOTICE", user.nick, splitMsg)
  1546. }
  1547. if client.capabilities.Has(caps.EchoMessage) {
  1548. client.SendSplitMsgFromClient(msgid, client, clientOnlyTags, "NOTICE", user.nick, splitMsg)
  1549. }
  1550. }
  1551. }
  1552. return false
  1553. }
  1554. // KICK <channel>{,<channel>} <user>{,<user>} [<comment>]
  1555. func kickHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  1556. channels := strings.Split(msg.Params[0], ",")
  1557. users := strings.Split(msg.Params[1], ",")
  1558. if (len(channels) != len(users)) && (len(users) != 1) {
  1559. client.Send(nil, server.name, ERR_NEEDMOREPARAMS, client.nick, "KICK", client.t("Not enough parameters"))
  1560. return false
  1561. }
  1562. var kicks [][]string
  1563. for index, channel := range channels {
  1564. if len(users) == 1 {
  1565. kicks = append(kicks, []string{channel, users[0]})
  1566. } else {
  1567. kicks = append(kicks, []string{channel, users[index]})
  1568. }
  1569. }
  1570. var comment string
  1571. if len(msg.Params) > 2 {
  1572. comment = msg.Params[2]
  1573. }
  1574. for _, info := range kicks {
  1575. chname := info[0]
  1576. nickname := info[1]
  1577. casefoldedChname, err := CasefoldChannel(chname)
  1578. channel := server.channels.Get(casefoldedChname)
  1579. if err != nil || channel == nil {
  1580. client.Send(nil, server.name, ERR_NOSUCHCHANNEL, client.nick, chname, client.t("No such channel"))
  1581. continue
  1582. }
  1583. casefoldedNickname, err := CasefoldName(nickname)
  1584. target := server.clients.Get(casefoldedNickname)
  1585. if err != nil || target == nil {
  1586. client.Send(nil, server.name, ERR_NOSUCHNICK, client.nick, nickname, client.t("No such nick"))
  1587. continue
  1588. }
  1589. if comment == "" {
  1590. comment = nickname
  1591. }
  1592. channel.Kick(client, target, comment)
  1593. }
  1594. return false
  1595. }
  1596. // elistMatcher takes and matches ELIST conditions
  1597. type elistMatcher struct {
  1598. MinClientsActive bool
  1599. MinClients int
  1600. MaxClientsActive bool
  1601. MaxClients int
  1602. }
  1603. // Matches checks whether the given channel matches our matches.
  1604. func (matcher *elistMatcher) Matches(channel *Channel) bool {
  1605. if matcher.MinClientsActive {
  1606. if len(channel.Members()) < matcher.MinClients {
  1607. return false
  1608. }
  1609. }
  1610. if matcher.MaxClientsActive {
  1611. if len(channel.Members()) < len(channel.members) {
  1612. return false
  1613. }
  1614. }
  1615. return true
  1616. }
  1617. // LIST [<channel>{,<channel>}] [<elistcond>{,<elistcond>}]
  1618. func listHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  1619. // get channels
  1620. var channels []string
  1621. for _, param := range msg.Params {
  1622. if 0 < len(param) && param[0] == '#' {
  1623. for _, channame := range strings.Split(param, ",") {
  1624. if 0 < len(channame) && channame[0] == '#' {
  1625. channels = append(channels, channame)
  1626. }
  1627. }
  1628. }
  1629. }
  1630. // get elist conditions
  1631. var matcher elistMatcher
  1632. for _, param := range msg.Params {
  1633. if len(param) < 1 {
  1634. continue
  1635. }
  1636. if param[0] == '<' {
  1637. param = param[1:]
  1638. val, err := strconv.Atoi(param)
  1639. if err != nil {
  1640. continue
  1641. }
  1642. matcher.MaxClientsActive = true
  1643. matcher.MaxClients = val - 1 // -1 because < means less than the given number
  1644. }
  1645. if param[0] == '>' {
  1646. param = param[1:]
  1647. val, err := strconv.Atoi(param)
  1648. if err != nil {
  1649. continue
  1650. }
  1651. matcher.MinClientsActive = true
  1652. matcher.MinClients = val + 1 // +1 because > means more than the given number
  1653. }
  1654. }
  1655. if len(channels) == 0 {
  1656. for _, channel := range server.channels.Channels() {
  1657. if !client.flags[Operator] && channel.flags[Secret] {
  1658. continue
  1659. }
  1660. if matcher.Matches(channel) {
  1661. client.RplList(channel)
  1662. }
  1663. }
  1664. } else {
  1665. // limit regular users to only listing one channel
  1666. if !client.flags[Operator] {
  1667. channels = channels[:1]
  1668. }
  1669. for _, chname := range channels {
  1670. casefoldedChname, err := CasefoldChannel(chname)
  1671. channel := server.channels.Get(casefoldedChname)
  1672. if err != nil || channel == nil || (!client.flags[Operator] && channel.flags[Secret]) {
  1673. if len(chname) > 0 {
  1674. client.Send(nil, server.name, ERR_NOSUCHCHANNEL, client.nick, chname, client.t("No such channel"))
  1675. }
  1676. continue
  1677. }
  1678. if matcher.Matches(channel) {
  1679. client.RplList(channel)
  1680. }
  1681. }
  1682. }
  1683. client.Send(nil, server.name, RPL_LISTEND, client.nick, client.t("End of LIST"))
  1684. return false
  1685. }
  1686. // RplList returns the RPL_LIST numeric for the given channel.
  1687. func (target *Client) RplList(channel *Channel) {
  1688. // get the correct number of channel members
  1689. var memberCount int
  1690. if target.flags[Operator] || channel.hasClient(target) {
  1691. memberCount = len(channel.Members())
  1692. } else {
  1693. for _, member := range channel.Members() {
  1694. if !member.HasMode(Invisible) {
  1695. memberCount++
  1696. }
  1697. }
  1698. }
  1699. target.Send(nil, target.server.name, RPL_LIST, target.nick, channel.name, strconv.Itoa(memberCount), channel.topic)
  1700. }
  1701. // NAMES [<channel>{,<channel>}]
  1702. func namesHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  1703. var channels []string
  1704. if len(msg.Params) > 0 {
  1705. channels = strings.Split(msg.Params[0], ",")
  1706. }
  1707. //var target string
  1708. //if len(msg.Params) > 1 {
  1709. // target = msg.Params[1]
  1710. //}
  1711. if len(channels) == 0 {
  1712. for _, channel := range server.channels.Channels() {
  1713. channel.Names(client)
  1714. }
  1715. return false
  1716. }
  1717. // limit regular users to only listing one channel
  1718. if !client.flags[Operator] {
  1719. channels = channels[:1]
  1720. }
  1721. for _, chname := range channels {
  1722. casefoldedChname, err := CasefoldChannel(chname)
  1723. channel := server.channels.Get(casefoldedChname)
  1724. if err != nil || channel == nil {
  1725. if len(chname) > 0 {
  1726. client.Send(nil, server.name, ERR_NOSUCHCHANNEL, client.nick, chname, client.t("No such channel"))
  1727. }
  1728. continue
  1729. }
  1730. channel.Names(client)
  1731. }
  1732. return false
  1733. }
  1734. // VERSION [<server>]
  1735. func versionHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  1736. var target string
  1737. if len(msg.Params) > 0 {
  1738. target = msg.Params[0]
  1739. }
  1740. casefoldedTarget, err := Casefold(target)
  1741. if target != "" && (err != nil || casefoldedTarget != server.nameCasefolded) {
  1742. client.Send(nil, server.name, ERR_NOSUCHSERVER, client.nick, target, client.t("No such server"))
  1743. return false
  1744. }
  1745. client.Send(nil, server.name, RPL_VERSION, client.nick, Ver, server.name)
  1746. client.RplISupport()
  1747. return false
  1748. }
  1749. // INVITE <nickname> <channel>
  1750. func inviteHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  1751. nickname := msg.Params[0]
  1752. channelName := msg.Params[1]
  1753. casefoldedNickname, err := CasefoldName(nickname)
  1754. target := server.clients.Get(casefoldedNickname)
  1755. if err != nil || target == nil {
  1756. client.Send(nil, server.name, ERR_NOSUCHNICK, client.nick, nickname, client.t("No such nick"))
  1757. return false
  1758. }
  1759. casefoldedChannelName, err := CasefoldChannel(channelName)
  1760. channel := server.channels.Get(casefoldedChannelName)
  1761. if err != nil || channel == nil {
  1762. client.Send(nil, server.name, ERR_NOSUCHCHANNEL, client.nick, channelName, client.t("No such channel"))
  1763. return false
  1764. }
  1765. channel.Invite(target, client)
  1766. return false
  1767. }
  1768. // TIME [<server>]
  1769. func timeHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  1770. var target string
  1771. if len(msg.Params) > 0 {
  1772. target = msg.Params[0]
  1773. }
  1774. casefoldedTarget, err := Casefold(target)
  1775. if (target != "") && err != nil || (casefoldedTarget != server.nameCasefolded) {
  1776. client.Send(nil, server.name, ERR_NOSUCHSERVER, client.nick, target, client.t("No such server"))
  1777. return false
  1778. }
  1779. client.Send(nil, server.name, RPL_TIME, client.nick, server.name, time.Now().Format(time.RFC1123))
  1780. return false
  1781. }
  1782. // KILL <nickname> <comment>
  1783. func killHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  1784. nickname := msg.Params[0]
  1785. comment := "<no reason supplied>"
  1786. if len(msg.Params) > 1 {
  1787. comment = msg.Params[1]
  1788. }
  1789. casefoldedNickname, err := CasefoldName(nickname)
  1790. target := server.clients.Get(casefoldedNickname)
  1791. if err != nil || target == nil {
  1792. client.Send(nil, client.server.name, ERR_NOSUCHNICK, client.nick, nickname, client.t("No such nick"))
  1793. return false
  1794. }
  1795. quitMsg := fmt.Sprintf("Killed (%s (%s))", client.nick, comment)
  1796. server.snomasks.Send(sno.LocalKills, fmt.Sprintf(ircfmt.Unescape("%s$r was killed by %s $c[grey][$r%s$c[grey]]"), target.nick, client.nick, comment))
  1797. target.exitedSnomaskSent = true
  1798. target.Quit(quitMsg)
  1799. target.destroy(false)
  1800. return false
  1801. }
  1802. // WHOWAS <nickname> [<count> [<server>]]
  1803. func whowasHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  1804. nicknames := strings.Split(msg.Params[0], ",")
  1805. var count int64
  1806. if len(msg.Params) > 1 {
  1807. count, _ = strconv.ParseInt(msg.Params[1], 10, 64)
  1808. }
  1809. //var target string
  1810. //if len(msg.Params) > 2 {
  1811. // target = msg.Params[2]
  1812. //}
  1813. for _, nickname := range nicknames {
  1814. results := server.whoWas.Find(nickname, count)
  1815. if len(results) == 0 {
  1816. if len(nickname) > 0 {
  1817. client.Send(nil, server.name, ERR_WASNOSUCHNICK, client.nick, nickname, client.t("There was no such nickname"))
  1818. }
  1819. } else {
  1820. for _, whoWas := range results {
  1821. client.Send(nil, server.name, RPL_WHOWASUSER, client.nick, whoWas.nickname, whoWas.username, whoWas.hostname, "*", whoWas.realname)
  1822. }
  1823. }
  1824. if len(nickname) > 0 {
  1825. client.Send(nil, server.name, RPL_ENDOFWHOWAS, client.nick, nickname, client.t("End of WHOWAS"))
  1826. }
  1827. }
  1828. return false
  1829. }
  1830. // LUSERS [<mask> [<server>]]
  1831. func lusersHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  1832. //TODO(vegax87) Fix network statistics and additional parameters
  1833. var totalcount, invisiblecount, opercount int
  1834. for _, onlineusers := range server.clients.AllClients() {
  1835. totalcount++
  1836. if onlineusers.flags[Invisible] {
  1837. invisiblecount++
  1838. }
  1839. if onlineusers.flags[Operator] {
  1840. opercount++
  1841. }
  1842. }
  1843. client.Send(nil, server.name, RPL_LUSERCLIENT, client.nick, fmt.Sprintf(client.t("There are %d users and %d invisible on %d server(s)"), totalcount, invisiblecount, 1))
  1844. client.Send(nil, server.name, RPL_LUSEROP, client.nick, fmt.Sprintf(client.t("%d IRC Operators online"), opercount))
  1845. client.Send(nil, server.name, RPL_LUSERCHANNELS, client.nick, fmt.Sprintf(client.t("%d channels formed"), server.channels.Len()))
  1846. client.Send(nil, server.name, RPL_LUSERME, client.nick, fmt.Sprintf(client.t("I have %d clients and %d servers"), totalcount, 1))
  1847. return false
  1848. }
  1849. // ResumeDetails are the details that we use to resume connections.
  1850. type ResumeDetails struct {
  1851. OldNick string
  1852. Timestamp *time.Time
  1853. SendFakeJoinsFor []string
  1854. }
  1855. // RESUME <oldnick> [timestamp]
  1856. func resumeHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  1857. oldnick := msg.Params[0]
  1858. if strings.Contains(oldnick, " ") {
  1859. client.Send(nil, server.name, ERR_CANNOT_RESUME, "*", client.t("Cannot resume connection, old nickname contains spaces"))
  1860. return false
  1861. }
  1862. if client.Registered() {
  1863. client.Send(nil, server.name, ERR_CANNOT_RESUME, oldnick, client.t("Cannot resume connection, connection registration has already been completed"))
  1864. return false
  1865. }
  1866. var timestamp *time.Time
  1867. if 1 < len(msg.Params) {
  1868. ts, err := time.Parse("2006-01-02T15:04:05.999Z", msg.Params[1])
  1869. if err == nil {
  1870. timestamp = &ts
  1871. } else {
  1872. client.Send(nil, server.name, ERR_CANNOT_RESUME, oldnick, client.t("Timestamp is not in 2006-01-02T15:04:05.999Z format, ignoring it"))
  1873. }
  1874. }
  1875. client.resumeDetails = &ResumeDetails{
  1876. OldNick: oldnick,
  1877. Timestamp: timestamp,
  1878. }
  1879. return false
  1880. }
  1881. // USERHOST <nickname> [<nickname> <nickname> ...]
  1882. func userhostHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  1883. returnedNicks := make(map[string]bool)
  1884. for i, nickname := range msg.Params {
  1885. if i >= 10 {
  1886. break
  1887. }
  1888. casefoldedNickname, err := CasefoldName(nickname)
  1889. target := server.clients.Get(casefoldedNickname)
  1890. if err != nil || target == nil {
  1891. client.Send(nil, client.server.name, ERR_NOSUCHNICK, client.nick, nickname, client.t("No such nick"))
  1892. return false
  1893. }
  1894. if returnedNicks[casefoldedNickname] {
  1895. continue
  1896. }
  1897. // to prevent returning multiple results for a single nick
  1898. returnedNicks[casefoldedNickname] = true
  1899. var isOper, isAway string
  1900. if target.flags[Operator] {
  1901. isOper = "*"
  1902. }
  1903. if target.flags[Away] {
  1904. isAway = "-"
  1905. } else {
  1906. isAway = "+"
  1907. }
  1908. client.Send(nil, client.server.name, RPL_USERHOST, client.nick, fmt.Sprintf("%s%s=%s%s@%s", target.nick, isOper, isAway, target.username, target.hostname))
  1909. }
  1910. return false
  1911. }
  1912. // LANGUAGE <code>{ <code>}
  1913. func languageHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  1914. alreadyDoneLanguages := make(map[string]bool)
  1915. var appliedLanguages []string
  1916. supportedLanguagesCount := server.languages.Count()
  1917. if supportedLanguagesCount < len(msg.Params) {
  1918. client.Send(nil, client.server.name, ERR_TOOMANYLANGUAGES, client.nick, strconv.Itoa(supportedLanguagesCount), client.t("You specified too many languages"))
  1919. return false
  1920. }
  1921. for _, value := range msg.Params {
  1922. value = strings.ToLower(value)
  1923. // strip ~ from the language if it has it
  1924. value = strings.TrimPrefix(value, "~")
  1925. // silently ignore empty languages or those with spaces in them
  1926. if len(value) == 0 || strings.Contains(value, " ") {
  1927. continue
  1928. }
  1929. _, exists := server.languages.Info[value]
  1930. if !exists {
  1931. client.Send(nil, client.server.name, ERR_NOLANGUAGE, client.nick, client.t("Languages are not supported by this server"))
  1932. return false
  1933. }
  1934. // if we've already applied the given language, skip it
  1935. _, exists = alreadyDoneLanguages[value]
  1936. if exists {
  1937. continue
  1938. }
  1939. appliedLanguages = append(appliedLanguages, value)
  1940. }
  1941. client.stateMutex.Lock()
  1942. if len(appliedLanguages) == 1 && appliedLanguages[0] == "en" {
  1943. // premature optimisation ahoy!
  1944. client.languages = []string{}
  1945. } else {
  1946. client.languages = appliedLanguages
  1947. }
  1948. client.stateMutex.Unlock()
  1949. params := []string{client.nick}
  1950. for _, lang := range appliedLanguages {
  1951. params = append(params, lang)
  1952. }
  1953. params = append(params, client.t("Language preferences have been set"))
  1954. client.Send(nil, client.server.name, RPL_YOURLANGUAGESARE, params...)
  1955. return false
  1956. }
  1957. var (
  1958. infoString = strings.Split(` ▄▄▄ ▄▄▄· ▄▄ • ▐ ▄
  1959. ▪ ▀▄ █·▐█ ▀█ ▐█ ▀ ▪▪ •█▌▐█▪
  1960. ▄█▀▄ ▐▀▀▄ ▄█▀▀█ ▄█ ▀█▄ ▄█▀▄▪▐█▐▐▌ ▄█▀▄
  1961. ▐█▌.▐▌▐█•█▌▐█ ▪▐▌▐█▄▪▐█▐█▌ ▐▌██▐█▌▐█▌.▐▌
  1962. ▀█▄▀▪.▀ ▀ ▀ ▀ ·▀▀▀▀ ▀█▄▀ ▀▀ █▪ ▀█▄▀▪
  1963. https://oragono.io/
  1964. https://github.com/oragono/oragono
  1965. Oragono is released under the MIT license.
  1966. Thanks to Jeremy Latt for founding Ergonomadic, the project this is based on <3
  1967. Core Developers:
  1968. Daniel Oakley, DanielOaks, <daniel@danieloaks.net>
  1969. Shivaram Lingamneni, slingamn, <slingamn@cs.stanford.edu>
  1970. Contributors and Former Developers:
  1971. 3onyc
  1972. Edmund Huber
  1973. Euan Kemp (euank)
  1974. Jeremy Latt
  1975. Martin Lindhe (martinlindhe)
  1976. Roberto Besser (besser)
  1977. Robin Burchell (rburchell)
  1978. Sean Enck (enckse)
  1979. soul9
  1980. Vegax
  1981. `, "\n")
  1982. )
  1983. func infoHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
  1984. for _, line := range infoString {
  1985. client.Send(nil, server.name, RPL_INFO, client.nick, line)
  1986. }
  1987. client.Send(nil, server.name, RPL_ENDOFINFO, client.nick, "End of /INFO")
  1988. return false
  1989. }