Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

server.go 70KB

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