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

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