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 70KB

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